vserver 2.0 rc7
[linux-2.6.git] / drivers / pcmcia / rsrc_nonstatic.c
1 /*
2  * rsrc_nonstatic.c -- Resource management routines for !SS_CAP_STATIC_MAP sockets
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * The initial developer of the original code is David A. Hinds
9  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
10  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
11  *
12  * (C) 1999             David A. Hinds
13  */
14
15 #include <linux/config.h>
16 #include <linux/module.h>
17 #include <linux/moduleparam.h>
18 #include <linux/init.h>
19 #include <linux/interrupt.h>
20 #include <linux/kernel.h>
21 #include <linux/errno.h>
22 #include <linux/types.h>
23 #include <linux/slab.h>
24 #include <linux/ioport.h>
25 #include <linux/timer.h>
26 #include <linux/pci.h>
27 #include <linux/device.h>
28
29 #include <asm/irq.h>
30 #include <asm/io.h>
31
32 #include <pcmcia/cs_types.h>
33 #include <pcmcia/ss.h>
34 #include <pcmcia/cs.h>
35 #include <pcmcia/bulkmem.h>
36 #include <pcmcia/cistpl.h>
37 #include "cs_internal.h"
38
39 MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
40 MODULE_LICENSE("GPL");
41
42 /* Parameters that can be set with 'insmod' */
43
44 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
45
46 INT_MODULE_PARM(probe_mem,      1);             /* memory probe? */
47 #ifdef CONFIG_PCMCIA_PROBE
48 INT_MODULE_PARM(probe_io,       1);             /* IO port probe? */
49 INT_MODULE_PARM(mem_limit,      0x10000);
50 #endif
51
52 /* for io_db and mem_db */
53 struct resource_map {
54         u_long                  base, num;
55         struct resource_map     *next;
56 };
57
58 struct socket_data {
59         struct resource_map             mem_db;
60         struct resource_map             io_db;
61         unsigned int                    rsrc_mem_probe;
62 };
63
64 static DECLARE_MUTEX(rsrc_sem);
65 #define MEM_PROBE_LOW   (1 << 0)
66 #define MEM_PROBE_HIGH  (1 << 1)
67
68
69 /*======================================================================
70
71     Linux resource management extensions
72
73 ======================================================================*/
74
75 static struct resource *
76 make_resource(unsigned long b, unsigned long n, int flags, char *name)
77 {
78         struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL);
79
80         if (res) {
81                 memset(res, 0, sizeof(*res));
82                 res->name = name;
83                 res->start = b;
84                 res->end = b + n - 1;
85                 res->flags = flags;
86         }
87         return res;
88 }
89
90 static struct resource *
91 claim_region(struct pcmcia_socket *s, unsigned long base, unsigned long size,
92              int type, char *name)
93 {
94         struct resource *res, *parent;
95
96         parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
97         res = make_resource(base, size, type | IORESOURCE_BUSY, name);
98
99         if (res) {
100 #ifdef CONFIG_PCI
101                 if (s && s->cb_dev)
102                         parent = pci_find_parent_resource(s->cb_dev, res);
103 #endif
104                 if (!parent || request_resource(parent, res)) {
105                         kfree(res);
106                         res = NULL;
107                 }
108         }
109         return res;
110 }
111
112 static void free_region(struct resource *res)
113 {
114         if (res) {
115                 release_resource(res);
116                 kfree(res);
117         }
118 }
119
120 /*======================================================================
121
122     These manage the internal databases of available resources.
123
124 ======================================================================*/
125
126 static int add_interval(struct resource_map *map, u_long base, u_long num)
127 {
128     struct resource_map *p, *q;
129
130     for (p = map; ; p = p->next) {
131         if ((p != map) && (p->base+p->num-1 >= base))
132             return -1;
133         if ((p->next == map) || (p->next->base > base+num-1))
134             break;
135     }
136     q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
137     if (!q) return CS_OUT_OF_RESOURCE;
138     q->base = base; q->num = num;
139     q->next = p->next; p->next = q;
140     return CS_SUCCESS;
141 }
142
143 /*====================================================================*/
144
145 static int sub_interval(struct resource_map *map, u_long base, u_long num)
146 {
147     struct resource_map *p, *q;
148
149     for (p = map; ; p = q) {
150         q = p->next;
151         if (q == map)
152             break;
153         if ((q->base+q->num > base) && (base+num > q->base)) {
154             if (q->base >= base) {
155                 if (q->base+q->num <= base+num) {
156                     /* Delete whole block */
157                     p->next = q->next;
158                     kfree(q);
159                     /* don't advance the pointer yet */
160                     q = p;
161                 } else {
162                     /* Cut off bit from the front */
163                     q->num = q->base + q->num - base - num;
164                     q->base = base + num;
165                 }
166             } else if (q->base+q->num <= base+num) {
167                 /* Cut off bit from the end */
168                 q->num = base - q->base;
169             } else {
170                 /* Split the block into two pieces */
171                 p = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
172                 if (!p) return CS_OUT_OF_RESOURCE;
173                 p->base = base+num;
174                 p->num = q->base+q->num - p->base;
175                 q->num = base - q->base;
176                 p->next = q->next ; q->next = p;
177             }
178         }
179     }
180     return CS_SUCCESS;
181 }
182
183 /*======================================================================
184
185     These routines examine a region of IO or memory addresses to
186     determine what ranges might be genuinely available.
187
188 ======================================================================*/
189
190 #ifdef CONFIG_PCMCIA_PROBE
191 static void do_io_probe(struct pcmcia_socket *s, kio_addr_t base, kio_addr_t num)
192 {
193     struct resource *res;
194     struct socket_data *s_data = s->resource_data;
195     kio_addr_t i, j, bad;
196     int any;
197     u_char *b, hole, most;
198
199     printk(KERN_INFO "cs: IO port probe %#lx-%#lx:",
200            base, base+num-1);
201
202     /* First, what does a floating port look like? */
203     b = kmalloc(256, GFP_KERNEL);
204     if (!b) {
205             printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
206             return;
207     }
208     memset(b, 0, 256);
209     for (i = base, most = 0; i < base+num; i += 8) {
210         res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
211         if (!res)
212             continue;
213         hole = inb(i);
214         for (j = 1; j < 8; j++)
215             if (inb(i+j) != hole) break;
216         free_region(res);
217         if ((j == 8) && (++b[hole] > b[most]))
218             most = hole;
219         if (b[most] == 127) break;
220     }
221     kfree(b);
222
223     bad = any = 0;
224     for (i = base; i < base+num; i += 8) {
225         res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
226         if (!res)
227             continue;
228         for (j = 0; j < 8; j++)
229             if (inb(i+j) != most) break;
230         free_region(res);
231         if (j < 8) {
232             if (!any)
233                 printk(" excluding");
234             if (!bad)
235                 bad = any = i;
236         } else {
237             if (bad) {
238                 sub_interval(&s_data->io_db, bad, i-bad);
239                 printk(" %#lx-%#lx", bad, i-1);
240                 bad = 0;
241             }
242         }
243     }
244     if (bad) {
245         if ((num > 16) && (bad == base) && (i == base+num)) {
246             printk(" nothing: probe failed.\n");
247             return;
248         } else {
249             sub_interval(&s_data->io_db, bad, i-bad);
250             printk(" %#lx-%#lx", bad, i-1);
251         }
252     }
253
254     printk(any ? "\n" : " clean.\n");
255 }
256 #endif
257
258 /*======================================================================
259
260     This is tricky... when we set up CIS memory, we try to validate
261     the memory window space allocations.
262
263 ======================================================================*/
264
265 /* Validation function for cards with a valid CIS */
266 static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *info)
267 {
268         int ret = -1;
269
270         s->cis_mem.res = res;
271         s->cis_virt = ioremap(res->start, s->map_size);
272         if (s->cis_virt) {
273                 ret = pccard_validate_cis(s, BIND_FN_ALL, info);
274                 /* invalidate mapping and CIS cache */
275                 iounmap(s->cis_virt);
276                 s->cis_virt = NULL;
277                 destroy_cis_cache(s);
278         }
279         s->cis_mem.res = NULL;
280         if ((ret != 0) || (info->Chains == 0))
281                 return 0;
282         return 1;
283 }
284
285 /* Validation function for simple memory cards */
286 static int checksum(struct pcmcia_socket *s, struct resource *res)
287 {
288         pccard_mem_map map;
289         int i, a = 0, b = -1, d;
290         void __iomem *virt;
291
292         virt = ioremap(res->start, s->map_size);
293         if (virt) {
294                 map.map = 0;
295                 map.flags = MAP_ACTIVE;
296                 map.speed = 0;
297                 map.res = res;
298                 map.card_start = 0;
299                 s->ops->set_mem_map(s, &map);
300
301                 /* Don't bother checking every word... */
302                 for (i = 0; i < s->map_size; i += 44) {
303                         d = readl(virt+i);
304                         a += d;
305                         b &= d;
306                 }
307
308                 map.flags = 0;
309                 s->ops->set_mem_map(s, &map);
310
311                 iounmap(virt);
312         }
313
314         return (b == -1) ? -1 : (a>>1);
315 }
316
317 static int
318 cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size)
319 {
320         struct resource *res1, *res2;
321         cisinfo_t info1, info2;
322         int ret = 0;
323
324         res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
325         res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
326
327         if (res1 && res2) {
328                 ret = readable(s, res1, &info1);
329                 ret += readable(s, res2, &info2);
330         }
331
332         free_region(res2);
333         free_region(res1);
334
335         return (ret == 2) && (info1.Chains == info2.Chains);
336 }
337
338 static int
339 checksum_match(struct pcmcia_socket *s, unsigned long base, unsigned long size)
340 {
341         struct resource *res1, *res2;
342         int a = -1, b = -1;
343
344         res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
345         res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
346
347         if (res1 && res2) {
348                 a = checksum(s, res1);
349                 b = checksum(s, res2);
350         }
351
352         free_region(res2);
353         free_region(res1);
354
355         return (a == b) && (a >= 0);
356 }
357
358 /*======================================================================
359
360     The memory probe.  If the memory list includes a 64K-aligned block
361     below 1MB, we probe in 64K chunks, and as soon as we accumulate at
362     least mem_limit free space, we quit.
363
364 ======================================================================*/
365
366 static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
367 {
368     struct socket_data *s_data = s->resource_data;
369     u_long i, j, bad, fail, step;
370
371     printk(KERN_INFO "cs: memory probe 0x%06lx-0x%06lx:",
372            base, base+num-1);
373     bad = fail = 0;
374     step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
375     /* cis_readable wants to map 2x map_size */
376     if (step < 2 * s->map_size)
377         step = 2 * s->map_size;
378     for (i = j = base; i < base+num; i = j + step) {
379         if (!fail) {
380             for (j = i; j < base+num; j += step) {
381                 if (cis_readable(s, j, step))
382                     break;
383             }
384             fail = ((i == base) && (j == base+num));
385         }
386         if (fail) {
387             for (j = i; j < base+num; j += 2*step)
388                 if (checksum_match(s, j, step) &&
389                     checksum_match(s, j + step, step))
390                     break;
391         }
392         if (i != j) {
393             if (!bad) printk(" excluding");
394             printk(" %#05lx-%#05lx", i, j-1);
395             sub_interval(&s_data->mem_db, i, j-i);
396             bad += j-i;
397         }
398     }
399     printk(bad ? "\n" : " clean.\n");
400     return (num - bad);
401 }
402
403 #ifdef CONFIG_PCMCIA_PROBE
404
405 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
406 {
407     struct socket_data *s_data = s->resource_data;
408     u_long ok;
409     if (m == &s_data->mem_db)
410         return 0;
411     ok = inv_probe(m->next, s);
412     if (ok) {
413         if (m->base >= 0x100000)
414             sub_interval(&s_data->mem_db, m->base, m->num);
415         return ok;
416     }
417     if (m->base < 0x100000)
418         return 0;
419     return do_mem_probe(m->base, m->num, s);
420 }
421
422 static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
423 {
424     struct resource_map *m, mm;
425     static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
426     u_long b, i, ok = 0;
427     struct socket_data *s_data = s->resource_data;
428
429     /* We do up to four passes through the list */
430     if (probe_mask & MEM_PROBE_HIGH) {
431         if (inv_probe(s_data->mem_db.next, s) > 0)
432             return;
433         printk(KERN_NOTICE "cs: warning: no high memory space "
434                "available!\n");
435     }
436     if ((probe_mask & MEM_PROBE_LOW) == 0)
437         return;
438     for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
439         mm = *m;
440         /* Only probe < 1 MB */
441         if (mm.base >= 0x100000) continue;
442         if ((mm.base | mm.num) & 0xffff) {
443             ok += do_mem_probe(mm.base, mm.num, s);
444             continue;
445         }
446         /* Special probe for 64K-aligned block */
447         for (i = 0; i < 4; i++) {
448             b = order[i] << 12;
449             if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
450                 if (ok >= mem_limit)
451                     sub_interval(&s_data->mem_db, b, 0x10000);
452                 else
453                     ok += do_mem_probe(b, 0x10000, s);
454             }
455         }
456     }
457 }
458
459 #else /* CONFIG_PCMCIA_PROBE */
460
461 static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
462 {
463         struct resource_map *m, mm;
464         struct socket_data *s_data = s->resource_data;
465
466         for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
467                 mm = *m;
468                 if (do_mem_probe(mm.base, mm.num, s))
469                         break;
470         }
471 }
472
473 #endif /* CONFIG_PCMCIA_PROBE */
474
475
476 /*
477  * Locking note: Must be called with skt_sem held!
478  */
479 static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
480 {
481         struct socket_data *s_data = s->resource_data;
482         if (probe_mem) {
483                 unsigned int probe_mask;
484
485                 down(&rsrc_sem);
486
487                 probe_mask = MEM_PROBE_LOW;
488                 if (s->features & SS_CAP_PAGE_REGS)
489                         probe_mask = MEM_PROBE_HIGH;
490
491                 if (probe_mask & ~s_data->rsrc_mem_probe) {
492                         s_data->rsrc_mem_probe |= probe_mask;
493
494                         if (s->state & SOCKET_PRESENT)
495                                 validate_mem(s, probe_mask);
496                 }
497
498                 up(&rsrc_sem);
499         }
500 }
501
502 struct pcmcia_align_data {
503         unsigned long   mask;
504         unsigned long   offset;
505         struct resource_map     *map;
506 };
507
508 static void
509 pcmcia_common_align(void *align_data, struct resource *res,
510                     unsigned long size, unsigned long align)
511 {
512         struct pcmcia_align_data *data = align_data;
513         unsigned long start;
514         /*
515          * Ensure that we have the correct start address
516          */
517         start = (res->start & ~data->mask) + data->offset;
518         if (start < res->start)
519                 start += data->mask + 1;
520         res->start = start;
521 }
522
523 static void
524 pcmcia_align(void *align_data, struct resource *res,
525              unsigned long size, unsigned long align)
526 {
527         struct pcmcia_align_data *data = align_data;
528         struct resource_map *m;
529
530         pcmcia_common_align(data, res, size, align);
531
532         for (m = data->map->next; m != data->map; m = m->next) {
533                 unsigned long start = m->base;
534                 unsigned long end = m->base + m->num - 1;
535
536                 /*
537                  * If the lower resources are not available, try aligning
538                  * to this entry of the resource database to see if it'll
539                  * fit here.
540                  */
541                 if (res->start < start) {
542                         res->start = start;
543                         pcmcia_common_align(data, res, size, align);
544                 }
545
546                 /*
547                  * If we're above the area which was passed in, there's
548                  * no point proceeding.
549                  */
550                 if (res->start >= res->end)
551                         break;
552
553                 if ((res->start + size - 1) <= end)
554                         break;
555         }
556
557         /*
558          * If we failed to find something suitable, ensure we fail.
559          */
560         if (m == data->map)
561                 res->start = res->end;
562 }
563
564 /*
565  * Adjust an existing IO region allocation, but making sure that we don't
566  * encroach outside the resources which the user supplied.
567  */
568 static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start,
569                                       unsigned long r_end, struct pcmcia_socket *s)
570 {
571         struct resource_map *m;
572         struct socket_data *s_data = s->resource_data;
573         int ret = -ENOMEM;
574
575         down(&rsrc_sem);
576         for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
577                 unsigned long start = m->base;
578                 unsigned long end = m->base + m->num - 1;
579
580                 if (start > r_start || r_end > end)
581                         continue;
582
583                 ret = adjust_resource(res, r_start, r_end - r_start + 1);
584                 break;
585         }
586         up(&rsrc_sem);
587
588         return ret;
589 }
590
591 /*======================================================================
592
593     These find ranges of I/O ports or memory addresses that are not
594     currently allocated by other devices.
595
596     The 'align' field should reflect the number of bits of address
597     that need to be preserved from the initial value of *base.  It
598     should be a power of two, greater than or equal to 'num'.  A value
599     of 0 means that all bits of *base are significant.  *base should
600     also be strictly less than 'align'.
601
602 ======================================================================*/
603
604 struct resource *nonstatic_find_io_region(unsigned long base, int num,
605                    unsigned long align, struct pcmcia_socket *s)
606 {
607         struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id);
608         struct socket_data *s_data = s->resource_data;
609         struct pcmcia_align_data data;
610         unsigned long min = base;
611         int ret;
612
613         if (align == 0)
614                 align = 0x10000;
615
616         data.mask = align - 1;
617         data.offset = base & data.mask;
618         data.map = &s_data->io_db;
619
620         down(&rsrc_sem);
621 #ifdef CONFIG_PCI
622         if (s->cb_dev) {
623                 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
624                                              min, 0, pcmcia_align, &data);
625         } else
626 #endif
627                 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
628                                         1, pcmcia_align, &data);
629         up(&rsrc_sem);
630
631         if (ret != 0) {
632                 kfree(res);
633                 res = NULL;
634         }
635         return res;
636 }
637
638 struct resource * nonstatic_find_mem_region(u_long base, u_long num, u_long align,
639                                  int low, struct pcmcia_socket *s)
640 {
641         struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id);
642         struct socket_data *s_data = s->resource_data;
643         struct pcmcia_align_data data;
644         unsigned long min, max;
645         int ret, i;
646
647         low = low || !(s->features & SS_CAP_PAGE_REGS);
648
649         data.mask = align - 1;
650         data.offset = base & data.mask;
651         data.map = &s_data->mem_db;
652
653         for (i = 0; i < 2; i++) {
654                 if (low) {
655                         max = 0x100000UL;
656                         min = base < max ? base : 0;
657                 } else {
658                         max = ~0UL;
659                         min = 0x100000UL + base;
660                 }
661
662                 down(&rsrc_sem);
663 #ifdef CONFIG_PCI
664                 if (s->cb_dev) {
665                         ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
666                                                      1, min, 0,
667                                                      pcmcia_align, &data);
668                 } else
669 #endif
670                         ret = allocate_resource(&iomem_resource, res, num, min,
671                                                 max, 1, pcmcia_align, &data);
672                 up(&rsrc_sem);
673                 if (ret == 0 || low)
674                         break;
675                 low = 1;
676         }
677
678         if (ret != 0) {
679                 kfree(res);
680                 res = NULL;
681         }
682         return res;
683 }
684
685
686 static int adjust_memory(struct pcmcia_socket *s, adjust_t *adj)
687 {
688         u_long base, num;
689         struct socket_data *data = s->resource_data;
690         int ret;
691
692         base = adj->resource.memory.Base;
693         num = adj->resource.memory.Size;
694         if ((num == 0) || (base+num-1 < base))
695                 return CS_BAD_SIZE;
696
697         ret = CS_SUCCESS;
698
699         down(&rsrc_sem);
700         switch (adj->Action) {
701         case ADD_MANAGED_RESOURCE:
702                 ret = add_interval(&data->mem_db, base, num);
703                 break;
704         case REMOVE_MANAGED_RESOURCE:
705                 ret = sub_interval(&data->mem_db, base, num);
706                 if (ret == CS_SUCCESS) {
707                         struct pcmcia_socket *socket;
708                         down_read(&pcmcia_socket_list_rwsem);
709                         list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
710                                 release_cis_mem(socket);
711                         up_read(&pcmcia_socket_list_rwsem);
712                 }
713                 break;
714         default:
715                 ret = CS_UNSUPPORTED_FUNCTION;
716         }
717         up(&rsrc_sem);
718
719         return ret;
720 }
721
722
723 static int adjust_io(struct pcmcia_socket *s, adjust_t *adj)
724 {
725         struct socket_data *data = s->resource_data;
726         kio_addr_t base, num;
727         int ret = CS_SUCCESS;
728
729         base = adj->resource.io.BasePort;
730         num = adj->resource.io.NumPorts;
731         if ((base < 0) || (base > 0xffff))
732                 return CS_BAD_BASE;
733         if ((num <= 0) || (base+num > 0x10000) || (base+num <= base))
734                 return CS_BAD_SIZE;
735
736         down(&rsrc_sem);
737         switch (adj->Action) {
738         case ADD_MANAGED_RESOURCE:
739                 if (add_interval(&data->io_db, base, num) != 0) {
740                         ret = CS_IN_USE;
741                         break;
742                 }
743 #ifdef CONFIG_PCMCIA_PROBE
744                 if (probe_io)
745                         do_io_probe(s, base, num);
746 #endif
747                 break;
748         case REMOVE_MANAGED_RESOURCE:
749                 sub_interval(&data->io_db, base, num);
750                 break;
751         default:
752                 ret = CS_UNSUPPORTED_FUNCTION;
753                 break;
754         }
755         up(&rsrc_sem);
756
757         return ret;
758 }
759
760
761 static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj)
762 {
763         switch (adj->Resource) {
764         case RES_MEMORY_RANGE:
765                 return adjust_memory(s, adj);
766         case RES_IO_RANGE:
767                 return adjust_io(s, adj);
768         }
769         return CS_UNSUPPORTED_FUNCTION;
770 }
771
772 static int nonstatic_init(struct pcmcia_socket *s)
773 {
774         struct socket_data *data;
775
776         data = kmalloc(sizeof(struct socket_data), GFP_KERNEL);
777         if (!data)
778                 return -ENOMEM;
779         memset(data, 0, sizeof(struct socket_data));
780
781         data->mem_db.next = &data->mem_db;
782         data->io_db.next = &data->io_db;
783
784         s->resource_data = (void *) data;
785
786         return 0;
787 }
788
789 static void nonstatic_release_resource_db(struct pcmcia_socket *s)
790 {
791         struct socket_data *data = s->resource_data;
792         struct resource_map *p, *q;
793
794         down(&rsrc_sem);
795         for (p = data->mem_db.next; p != &data->mem_db; p = q) {
796                 q = p->next;
797                 kfree(p);
798         }
799         for (p = data->io_db.next; p != &data->io_db; p = q) {
800                 q = p->next;
801                 kfree(p);
802         }
803         up(&rsrc_sem);
804 }
805
806
807 struct pccard_resource_ops pccard_nonstatic_ops = {
808         .validate_mem = pcmcia_nonstatic_validate_mem,
809         .adjust_io_region = nonstatic_adjust_io_region,
810         .find_io = nonstatic_find_io_region,
811         .find_mem = nonstatic_find_mem_region,
812         .adjust_resource = nonstatic_adjust_resource_info,
813         .init = nonstatic_init,
814         .exit = nonstatic_release_resource_db,
815 };
816 EXPORT_SYMBOL(pccard_nonstatic_ops);
817
818
819 /* sysfs interface to the resource database */
820
821 static ssize_t show_io_db(struct class_device *class_dev, char *buf)
822 {
823         struct pcmcia_socket *s = class_get_devdata(class_dev);
824         struct socket_data *data;
825         struct resource_map *p;
826         ssize_t ret = 0;
827
828         down(&rsrc_sem);
829         data = s->resource_data;
830
831         for (p = data->io_db.next; p != &data->io_db; p = p->next) {
832                 if (ret > (PAGE_SIZE - 10))
833                         continue;
834                 ret += snprintf (&buf[ret], (PAGE_SIZE - ret - 1),
835                                  "0x%08lx - 0x%08lx\n",
836                                  ((unsigned long) p->base),
837                                  ((unsigned long) p->base + p->num - 1));
838         }
839
840         up(&rsrc_sem);
841         return (ret);
842 }
843
844 static ssize_t store_io_db(struct class_device *class_dev, const char *buf, size_t count)
845 {
846         struct pcmcia_socket *s = class_get_devdata(class_dev);
847         unsigned long start_addr, end_addr;
848         unsigned int add = 1;
849         adjust_t adj;
850         ssize_t ret = 0;
851
852         ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
853         if (ret != 2) {
854                 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
855                 add = 0;
856                 if (ret != 2) {
857                         ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
858                         add = 1;
859                         if (ret != 2)
860                                 return -EINVAL;
861                 }
862         }
863         if (end_addr <= start_addr)
864                 return -EINVAL;
865
866         adj.Action = add ? ADD_MANAGED_RESOURCE : REMOVE_MANAGED_RESOURCE;
867         adj.Resource = RES_IO_RANGE;
868         adj.resource.io.BasePort = start_addr;
869         adj.resource.io.NumPorts = end_addr - start_addr + 1;
870
871         ret = adjust_io(s, &adj);
872
873         return ret ? ret : count;
874 }
875 static CLASS_DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
876
877 static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
878 {
879         struct pcmcia_socket *s = class_get_devdata(class_dev);
880         struct socket_data *data;
881         struct resource_map *p;
882         ssize_t ret = 0;
883
884         down(&rsrc_sem);
885         data = s->resource_data;
886
887         for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
888                 if (ret > (PAGE_SIZE - 10))
889                         continue;
890                 ret += snprintf (&buf[ret], (PAGE_SIZE - ret - 1),
891                                  "0x%08lx - 0x%08lx\n",
892                                  ((unsigned long) p->base),
893                                  ((unsigned long) p->base + p->num - 1));
894         }
895
896         up(&rsrc_sem);
897         return (ret);
898 }
899
900 static ssize_t store_mem_db(struct class_device *class_dev, const char *buf, size_t count)
901 {
902         struct pcmcia_socket *s = class_get_devdata(class_dev);
903         unsigned long start_addr, end_addr;
904         unsigned int add = 1;
905         adjust_t adj;
906         ssize_t ret = 0;
907
908         ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
909         if (ret != 2) {
910                 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
911                 add = 0;
912                 if (ret != 2) {
913                         ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
914                         add = 1;
915                         if (ret != 2)
916                                 return -EINVAL;
917                 }
918         }
919         if (end_addr <= start_addr)
920                 return -EINVAL;
921
922         adj.Action = add ? ADD_MANAGED_RESOURCE : REMOVE_MANAGED_RESOURCE;
923         adj.Resource = RES_MEMORY_RANGE;
924         adj.resource.memory.Base = start_addr;
925         adj.resource.memory.Size = end_addr - start_addr + 1;
926
927         ret = adjust_memory(s, &adj);
928
929         return ret ? ret : count;
930 }
931 static CLASS_DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
932
933 static struct class_device_attribute *pccard_rsrc_attributes[] = {
934         &class_device_attr_available_resources_io,
935         &class_device_attr_available_resources_mem,
936         NULL,
937 };
938
939 static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev)
940 {
941         struct pcmcia_socket *s = class_get_devdata(class_dev);
942         struct class_device_attribute **attr;
943         int ret = 0;
944         if (s->resource_ops != &pccard_nonstatic_ops)
945                 return 0;
946
947         for (attr = pccard_rsrc_attributes; *attr; attr++) {
948                 ret = class_device_create_file(class_dev, *attr);
949                 if (ret)
950                         break;
951         }
952
953         return ret;
954 }
955
956 static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev)
957 {
958         struct pcmcia_socket *s = class_get_devdata(class_dev);
959         struct class_device_attribute **attr;
960
961         if (s->resource_ops != &pccard_nonstatic_ops)
962                 return;
963
964         for (attr = pccard_rsrc_attributes; *attr; attr++)
965                 class_device_remove_file(class_dev, *attr);
966 }
967
968 static struct class_interface pccard_rsrc_interface = {
969         .class = &pcmcia_socket_class,
970         .add = &pccard_sysfs_add_rsrc,
971         .remove = __devexit_p(&pccard_sysfs_remove_rsrc),
972 };
973
974 static int __init nonstatic_sysfs_init(void)
975 {
976         return class_interface_register(&pccard_rsrc_interface);
977 }
978
979 static void __exit nonstatic_sysfs_exit(void)
980 {
981         class_interface_unregister(&pccard_rsrc_interface);
982 }
983
984 module_init(nonstatic_sysfs_init);
985 module_exit(nonstatic_sysfs_exit);