- patches.fixes/patch-2.6.11-rc1: 2.6.11-rc1.
[linux-flexiantxendom0-3.2.10.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 <asm/irq.h>
28 #include <asm/io.h>
29
30 #include <pcmcia/cs_types.h>
31 #include <pcmcia/ss.h>
32 #include <pcmcia/cs.h>
33 #include <pcmcia/bulkmem.h>
34 #include <pcmcia/cistpl.h>
35 #include "cs_internal.h"
36
37 MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
38 MODULE_LICENSE("GPL");
39
40 /* Parameters that can be set with 'insmod' */
41
42 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
43
44 INT_MODULE_PARM(probe_mem,      1);             /* memory probe? */
45 #ifdef CONFIG_PCMCIA_PROBE
46 INT_MODULE_PARM(probe_io,       1);             /* IO port probe? */
47 INT_MODULE_PARM(mem_limit,      0x10000);
48 #endif
49
50 /* for io_db and mem_db */
51 struct resource_map {
52         u_long                  base, num;
53         struct resource_map     *next;
54 };
55
56 struct socket_data {
57         struct resource_map             mem_db;
58         struct resource_map             io_db;
59         unsigned int                    rsrc_mem_probe;
60 };
61
62 static DECLARE_MUTEX(rsrc_sem);
63 #define MEM_PROBE_LOW   (1 << 0)
64 #define MEM_PROBE_HIGH  (1 << 1)
65
66
67 /*======================================================================
68
69     Linux resource management extensions
70
71 ======================================================================*/
72
73 static struct resource *
74 make_resource(unsigned long b, unsigned long n, int flags, char *name)
75 {
76         struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL);
77
78         if (res) {
79                 memset(res, 0, sizeof(*res));
80                 res->name = name;
81                 res->start = b;
82                 res->end = b + n - 1;
83                 res->flags = flags;
84         }
85         return res;
86 }
87
88 static struct resource *
89 claim_region(struct pcmcia_socket *s, unsigned long base, unsigned long size,
90              int type, char *name)
91 {
92         struct resource *res, *parent;
93
94         parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
95         res = make_resource(base, size, type | IORESOURCE_BUSY, name);
96
97         if (res) {
98 #ifdef CONFIG_PCI
99                 if (s && s->cb_dev)
100                         parent = pci_find_parent_resource(s->cb_dev, res);
101 #endif
102                 if (!parent || request_resource(parent, res)) {
103                         kfree(res);
104                         res = NULL;
105                 }
106         }
107         return res;
108 }
109
110 static void free_region(struct resource *res)
111 {
112         if (res) {
113                 release_resource(res);
114                 kfree(res);
115         }
116 }
117
118 /*======================================================================
119
120     These manage the internal databases of available resources.
121
122 ======================================================================*/
123
124 static int add_interval(struct resource_map *map, u_long base, u_long num)
125 {
126     struct resource_map *p, *q;
127
128     for (p = map; ; p = p->next) {
129         if ((p != map) && (p->base+p->num-1 >= base))
130             return -1;
131         if ((p->next == map) || (p->next->base > base+num-1))
132             break;
133     }
134     q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
135     if (!q) return CS_OUT_OF_RESOURCE;
136     q->base = base; q->num = num;
137     q->next = p->next; p->next = q;
138     return CS_SUCCESS;
139 }
140
141 /*====================================================================*/
142
143 static int sub_interval(struct resource_map *map, u_long base, u_long num)
144 {
145     struct resource_map *p, *q;
146
147     for (p = map; ; p = q) {
148         q = p->next;
149         if (q == map)
150             break;
151         if ((q->base+q->num > base) && (base+num > q->base)) {
152             if (q->base >= base) {
153                 if (q->base+q->num <= base+num) {
154                     /* Delete whole block */
155                     p->next = q->next;
156                     kfree(q);
157                     /* don't advance the pointer yet */
158                     q = p;
159                 } else {
160                     /* Cut off bit from the front */
161                     q->num = q->base + q->num - base - num;
162                     q->base = base + num;
163                 }
164             } else if (q->base+q->num <= base+num) {
165                 /* Cut off bit from the end */
166                 q->num = base - q->base;
167             } else {
168                 /* Split the block into two pieces */
169                 p = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
170                 if (!p) return CS_OUT_OF_RESOURCE;
171                 p->base = base+num;
172                 p->num = q->base+q->num - p->base;
173                 q->num = base - q->base;
174                 p->next = q->next ; q->next = p;
175             }
176         }
177     }
178     return CS_SUCCESS;
179 }
180
181 /*======================================================================
182
183     These routines examine a region of IO or memory addresses to
184     determine what ranges might be genuinely available.
185
186 ======================================================================*/
187
188 #ifdef CONFIG_PCMCIA_PROBE
189 static void do_io_probe(struct pcmcia_socket *s, ioaddr_t base, ioaddr_t num)
190 {
191     struct resource *res;
192     struct socket_data *s_data = s->resource_data;
193     ioaddr_t i, j, bad, any;
194     u_char *b, hole, most;
195
196     printk(KERN_INFO "cs: IO port probe 0x%04x-0x%04x:",
197            base, base+num-1);
198
199     /* First, what does a floating port look like? */
200     b = kmalloc(256, GFP_KERNEL);
201     if (!b) {
202             printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
203             return;
204     }
205     memset(b, 0, 256);
206     for (i = base, most = 0; i < base+num; i += 8) {
207         res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
208         if (!res)
209             continue;
210         hole = inb(i);
211         for (j = 1; j < 8; j++)
212             if (inb(i+j) != hole) break;
213         free_region(res);
214         if ((j == 8) && (++b[hole] > b[most]))
215             most = hole;
216         if (b[most] == 127) break;
217     }
218     kfree(b);
219
220     bad = any = 0;
221     for (i = base; i < base+num; i += 8) {
222         res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
223         if (!res)
224             continue;
225         for (j = 0; j < 8; j++)
226             if (inb(i+j) != most) break;
227         free_region(res);
228         if (j < 8) {
229             if (!any)
230                 printk(" excluding");
231             if (!bad)
232                 bad = any = i;
233         } else {
234             if (bad) {
235                 sub_interval(&s_data->io_db, bad, i-bad);
236                 printk(" %#04x-%#04x", bad, i-1);
237                 bad = 0;
238             }
239         }
240     }
241     if (bad) {
242         if ((num > 16) && (bad == base) && (i == base+num)) {
243             printk(" nothing: probe failed.\n");
244             return;
245         } else {
246             sub_interval(&s_data->io_db, bad, i-bad);
247             printk(" %#04x-%#04x", bad, i-1);
248         }
249     }
250
251     printk(any ? "\n" : " clean.\n");
252 }
253 #endif
254
255 /*======================================================================
256
257     This is tricky... when we set up CIS memory, we try to validate
258     the memory window space allocations.
259
260 ======================================================================*/
261
262 /* Validation function for cards with a valid CIS */
263 static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *info)
264 {
265         int ret = -1;
266
267         s->cis_mem.res = res;
268         s->cis_virt = ioremap(res->start, s->map_size);
269         if (s->cis_virt) {
270                 ret = pccard_validate_cis(s, BIND_FN_ALL, info);
271                 /* invalidate mapping and CIS cache */
272                 iounmap(s->cis_virt);
273                 s->cis_virt = NULL;
274                 destroy_cis_cache(s);
275         }
276         s->cis_mem.res = NULL;
277         if ((ret != 0) || (info->Chains == 0))
278                 return 0;
279         return 1;
280 }
281
282 /* Validation function for simple memory cards */
283 static int checksum(struct pcmcia_socket *s, struct resource *res)
284 {
285         pccard_mem_map map;
286         int i, a = 0, b = -1, d;
287         void __iomem *virt;
288
289         virt = ioremap(res->start, s->map_size);
290         if (virt) {
291                 map.map = 0;
292                 map.flags = MAP_ACTIVE;
293                 map.speed = 0;
294                 map.res = res;
295                 map.card_start = 0;
296                 s->ops->set_mem_map(s, &map);
297
298                 /* Don't bother checking every word... */
299                 for (i = 0; i < s->map_size; i += 44) {
300                         d = readl(virt+i);
301                         a += d;
302                         b &= d;
303                 }
304
305                 map.flags = 0;
306                 s->ops->set_mem_map(s, &map);
307
308                 iounmap(virt);
309         }
310
311         return (b == -1) ? -1 : (a>>1);
312 }
313
314 static int
315 cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size)
316 {
317         struct resource *res1, *res2;
318         cisinfo_t info1, info2;
319         int ret = 0;
320
321         res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
322         res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
323
324         if (res1 && res2) {
325                 ret = readable(s, res1, &info1);
326                 ret += readable(s, res2, &info2);
327         }
328
329         free_region(res2);
330         free_region(res1);
331
332         return (ret == 2) && (info1.Chains == info2.Chains);
333 }
334
335 static int
336 checksum_match(struct pcmcia_socket *s, unsigned long base, unsigned long size)
337 {
338         struct resource *res1, *res2;
339         int a = -1, b = -1;
340
341         res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
342         res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
343
344         if (res1 && res2) {
345                 a = checksum(s, res1);
346                 b = checksum(s, res2);
347         }
348
349         free_region(res2);
350         free_region(res1);
351
352         return (a == b) && (a >= 0);
353 }
354
355 /*======================================================================
356
357     The memory probe.  If the memory list includes a 64K-aligned block
358     below 1MB, we probe in 64K chunks, and as soon as we accumulate at
359     least mem_limit free space, we quit.
360
361 ======================================================================*/
362
363 static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
364 {
365     struct socket_data *s_data = s->resource_data;
366     u_long i, j, bad, fail, step;
367
368     printk(KERN_INFO "cs: memory probe 0x%06lx-0x%06lx:",
369            base, base+num-1);
370     bad = fail = 0;
371     step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
372     /* cis_readable wants to map 2x map_size */
373     if (step < 2 * s->map_size)
374         step = 2 * s->map_size;
375     for (i = j = base; i < base+num; i = j + step) {
376         if (!fail) {
377             for (j = i; j < base+num; j += step) {
378                 if (cis_readable(s, j, step))
379                     break;
380             }
381             fail = ((i == base) && (j == base+num));
382         }
383         if (fail) {
384             for (j = i; j < base+num; j += 2*step)
385                 if (checksum_match(s, j, step) &&
386                     checksum_match(s, j + step, step))
387                     break;
388         }
389         if (i != j) {
390             if (!bad) printk(" excluding");
391             printk(" %#05lx-%#05lx", i, j-1);
392             sub_interval(&s_data->mem_db, i, j-i);
393             bad += j-i;
394         }
395     }
396     printk(bad ? "\n" : " clean.\n");
397     return (num - bad);
398 }
399
400 #ifdef CONFIG_PCMCIA_PROBE
401
402 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
403 {
404     struct socket_data *s_data = s->resource_data;
405     u_long ok;
406     if (m == &s_data->mem_db)
407         return 0;
408     ok = inv_probe(m->next, s);
409     if (ok) {
410         if (m->base >= 0x100000)
411             sub_interval(&s_data->mem_db, m->base, m->num);
412         return ok;
413     }
414     if (m->base < 0x100000)
415         return 0;
416     return do_mem_probe(m->base, m->num, s);
417 }
418
419 static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
420 {
421     struct resource_map *m, mm;
422     static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
423     u_long b, i, ok = 0;
424     struct socket_data *s_data = s->resource_data;
425
426     /* We do up to four passes through the list */
427     if (probe_mask & MEM_PROBE_HIGH) {
428         if (inv_probe(s_data->mem_db.next, s) > 0)
429             return;
430         printk(KERN_NOTICE "cs: warning: no high memory space "
431                "available!\n");
432     }
433     if ((probe_mask & MEM_PROBE_LOW) == 0)
434         return;
435     for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
436         mm = *m;
437         /* Only probe < 1 MB */
438         if (mm.base >= 0x100000) continue;
439         if ((mm.base | mm.num) & 0xffff) {
440             ok += do_mem_probe(mm.base, mm.num, s);
441             continue;
442         }
443         /* Special probe for 64K-aligned block */
444         for (i = 0; i < 4; i++) {
445             b = order[i] << 12;
446             if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
447                 if (ok >= mem_limit)
448                     sub_interval(&s_data->mem_db, b, 0x10000);
449                 else
450                     ok += do_mem_probe(b, 0x10000, s);
451             }
452         }
453     }
454 }
455
456 #else /* CONFIG_PCMCIA_PROBE */
457
458 static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
459 {
460         struct resource_map *m, mm;
461         struct socket_data *s_data = s->resource_data;
462
463         for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
464                 mm = *m;
465                 if (do_mem_probe(mm.base, mm.num, s))
466                         break;
467         }
468 }
469
470 #endif /* CONFIG_PCMCIA_PROBE */
471
472
473 /*
474  * Locking note: this is the only place where we take
475  * both rsrc_sem and skt_sem.
476  */
477 static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
478 {
479         struct socket_data *s_data = s->resource_data;
480         if (probe_mem) {
481                 unsigned int probe_mask;
482
483                 down(&rsrc_sem);
484
485                 probe_mask = MEM_PROBE_LOW;
486                 if (s->features & SS_CAP_PAGE_REGS)
487                         probe_mask = MEM_PROBE_HIGH;
488
489                 if (probe_mask & ~s_data->rsrc_mem_probe) {
490                         s_data->rsrc_mem_probe |= probe_mask;
491
492                         down(&s->skt_sem);
493
494                         if (s->state & SOCKET_PRESENT)
495                                 validate_mem(s, probe_mask);
496
497                         up(&s->skt_sem);
498                 }
499
500                 up(&rsrc_sem);
501         }
502 }
503
504 struct pcmcia_align_data {
505         unsigned long   mask;
506         unsigned long   offset;
507         struct resource_map     *map;
508 };
509
510 static void
511 pcmcia_common_align(void *align_data, struct resource *res,
512                     unsigned long size, unsigned long align)
513 {
514         struct pcmcia_align_data *data = align_data;
515         unsigned long start;
516         /*
517          * Ensure that we have the correct start address
518          */
519         start = (res->start & ~data->mask) + data->offset;
520         if (start < res->start)
521                 start += data->mask + 1;
522         res->start = start;
523 }
524
525 static void
526 pcmcia_align(void *align_data, struct resource *res,
527              unsigned long size, unsigned long align)
528 {
529         struct pcmcia_align_data *data = align_data;
530         struct resource_map *m;
531
532         pcmcia_common_align(data, res, size, align);
533
534         for (m = data->map->next; m != data->map; m = m->next) {
535                 unsigned long start = m->base;
536                 unsigned long end = m->base + m->num - 1;
537
538                 /*
539                  * If the lower resources are not available, try aligning
540                  * to this entry of the resource database to see if it'll
541                  * fit here.
542                  */
543                 if (res->start < start) {
544                         res->start = start;
545                         pcmcia_common_align(data, res, size, align);
546                 }
547
548                 /*
549                  * If we're above the area which was passed in, there's
550                  * no point proceeding.
551                  */
552                 if (res->start >= res->end)
553                         break;
554
555                 if ((res->start + size - 1) <= end)
556                         break;
557         }
558
559         /*
560          * If we failed to find something suitable, ensure we fail.
561          */
562         if (m == data->map)
563                 res->start = res->end;
564 }
565
566 /*
567  * Adjust an existing IO region allocation, but making sure that we don't
568  * encroach outside the resources which the user supplied.
569  */
570 static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start,
571                                       unsigned long r_end, struct pcmcia_socket *s)
572 {
573         struct resource_map *m;
574         struct socket_data *s_data = s->resource_data;
575         int ret = -ENOMEM;
576
577         down(&rsrc_sem);
578         for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
579                 unsigned long start = m->base;
580                 unsigned long end = m->base + m->num - 1;
581
582                 if (start > r_start || r_end > end)
583                         continue;
584
585                 ret = adjust_resource(res, r_start, r_end - r_start + 1);
586                 break;
587         }
588         up(&rsrc_sem);
589
590         return ret;
591 }
592
593 /*======================================================================
594
595     These find ranges of I/O ports or memory addresses that are not
596     currently allocated by other devices.
597
598     The 'align' field should reflect the number of bits of address
599     that need to be preserved from the initial value of *base.  It
600     should be a power of two, greater than or equal to 'num'.  A value
601     of 0 means that all bits of *base are significant.  *base should
602     also be strictly less than 'align'.
603
604 ======================================================================*/
605
606 struct resource *nonstatic_find_io_region(unsigned long base, int num,
607                    unsigned long align, struct pcmcia_socket *s)
608 {
609         struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id);
610         struct socket_data *s_data = s->resource_data;
611         struct pcmcia_align_data data;
612         unsigned long min = base;
613         int ret;
614
615         if (align == 0)
616                 align = 0x10000;
617
618         data.mask = align - 1;
619         data.offset = base & data.mask;
620         data.map = &s_data->io_db;
621
622         down(&rsrc_sem);
623 #ifdef CONFIG_PCI
624         if (s->cb_dev) {
625                 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
626                                              min, 0, pcmcia_align, &data);
627         } else
628 #endif
629                 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
630                                         1, pcmcia_align, &data);
631         up(&rsrc_sem);
632
633         if (ret != 0) {
634                 kfree(res);
635                 res = NULL;
636         }
637         return res;
638 }
639
640 struct resource * nonstatic_find_mem_region(u_long base, u_long num, u_long align,
641                                  int low, struct pcmcia_socket *s)
642 {
643         struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id);
644         struct socket_data *s_data = s->resource_data;
645         struct pcmcia_align_data data;
646         unsigned long min, max;
647         int ret, i;
648
649         low = low || !(s->features & SS_CAP_PAGE_REGS);
650
651         data.mask = align - 1;
652         data.offset = base & data.mask;
653         data.map = &s_data->mem_db;
654
655         for (i = 0; i < 2; i++) {
656                 if (low) {
657                         max = 0x100000UL;
658                         min = base < max ? base : 0;
659                 } else {
660                         max = ~0UL;
661                         min = 0x100000UL + base;
662                 }
663
664                 down(&rsrc_sem);
665 #ifdef CONFIG_PCI
666                 if (s->cb_dev) {
667                         ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
668                                                      1, min, 0,
669                                                      pcmcia_align, &data);
670                 } else
671 #endif
672                         ret = allocate_resource(&iomem_resource, res, num, min,
673                                                 max, 1, pcmcia_align, &data);
674                 up(&rsrc_sem);
675                 if (ret == 0 || low)
676                         break;
677                 low = 1;
678         }
679
680         if (ret != 0) {
681                 kfree(res);
682                 res = NULL;
683         }
684         return res;
685 }
686
687
688 static int adjust_memory(struct pcmcia_socket *s, adjust_t *adj)
689 {
690         u_long base, num;
691         struct socket_data *data = s->resource_data;
692         int ret;
693
694         base = adj->resource.memory.Base;
695         num = adj->resource.memory.Size;
696         if ((num == 0) || (base+num-1 < base))
697                 return CS_BAD_SIZE;
698
699         ret = CS_SUCCESS;
700
701         down(&rsrc_sem);
702         switch (adj->Action) {
703         case ADD_MANAGED_RESOURCE:
704                 ret = add_interval(&data->mem_db, base, num);
705                 break;
706         case REMOVE_MANAGED_RESOURCE:
707                 ret = sub_interval(&data->mem_db, base, num);
708                 if (ret == CS_SUCCESS) {
709                         struct pcmcia_socket *socket;
710                         down_read(&pcmcia_socket_list_rwsem);
711                         list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
712                                 release_cis_mem(socket);
713                         up_read(&pcmcia_socket_list_rwsem);
714                 }
715                 break;
716         default:
717                 ret = CS_UNSUPPORTED_FUNCTION;
718         }
719         up(&rsrc_sem);
720
721         return ret;
722 }
723
724
725 static int adjust_io(struct pcmcia_socket *s, adjust_t *adj)
726 {
727         struct socket_data *data = s->resource_data;
728         int base, num, ret = CS_SUCCESS;
729
730         base = adj->resource.io.BasePort;
731         num = adj->resource.io.NumPorts;
732         if ((base < 0) || (base > 0xffff))
733                 return CS_BAD_BASE;
734         if ((num <= 0) || (base+num > 0x10000) || (base+num <= base))
735                 return CS_BAD_SIZE;
736
737         down(&rsrc_sem);
738         switch (adj->Action) {
739         case ADD_MANAGED_RESOURCE:
740                 if (add_interval(&data->io_db, base, num) != 0) {
741                         ret = CS_IN_USE;
742                         break;
743                 }
744 #ifdef CONFIG_PCMCIA_PROBE
745                 if (probe_io)
746                         do_io_probe(s, base, num);
747 #endif
748                 break;
749         case REMOVE_MANAGED_RESOURCE:
750                 sub_interval(&data->io_db, base, num);
751                 break;
752         default:
753                 ret = CS_UNSUPPORTED_FUNCTION;
754                 break;
755         }
756         up(&rsrc_sem);
757
758         return ret;
759 }
760
761
762 static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj)
763 {
764         switch (adj->Resource) {
765         case RES_MEMORY_RANGE:
766                 return adjust_memory(s, adj);
767         case RES_IO_RANGE:
768                 return adjust_io(s, adj);
769         }
770         return CS_UNSUPPORTED_FUNCTION;
771 }
772
773 static int nonstatic_init(struct pcmcia_socket *s)
774 {
775         struct socket_data *data;
776
777         data = kmalloc(sizeof(struct socket_data), GFP_KERNEL);
778         if (!data)
779                 return -ENOMEM;
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);