This commit was manufactured by cvs2svn to create branch 'vserver'.
[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 <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, kio_addr_t base, kio_addr_t num)
190 {
191     struct resource *res;
192     struct socket_data *s_data = s->resource_data;
193     kio_addr_t i, j, bad;
194     int any;
195     u_char *b, hole, most;
196
197     printk(KERN_INFO "cs: IO port probe %#lx-%#lx:",
198            base, base+num-1);
199
200     /* First, what does a floating port look like? */
201     b = kmalloc(256, GFP_KERNEL);
202     if (!b) {
203             printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
204             return;
205     }
206     memset(b, 0, 256);
207     for (i = base, most = 0; i < base+num; i += 8) {
208         res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
209         if (!res)
210             continue;
211         hole = inb(i);
212         for (j = 1; j < 8; j++)
213             if (inb(i+j) != hole) break;
214         free_region(res);
215         if ((j == 8) && (++b[hole] > b[most]))
216             most = hole;
217         if (b[most] == 127) break;
218     }
219     kfree(b);
220
221     bad = any = 0;
222     for (i = base; i < base+num; i += 8) {
223         res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
224         if (!res)
225             continue;
226         for (j = 0; j < 8; j++)
227             if (inb(i+j) != most) break;
228         free_region(res);
229         if (j < 8) {
230             if (!any)
231                 printk(" excluding");
232             if (!bad)
233                 bad = any = i;
234         } else {
235             if (bad) {
236                 sub_interval(&s_data->io_db, bad, i-bad);
237                 printk(" %#lx-%#lx", bad, i-1);
238                 bad = 0;
239             }
240         }
241     }
242     if (bad) {
243         if ((num > 16) && (bad == base) && (i == base+num)) {
244             printk(" nothing: probe failed.\n");
245             return;
246         } else {
247             sub_interval(&s_data->io_db, bad, i-bad);
248             printk(" %#lx-%#lx", bad, i-1);
249         }
250     }
251
252     printk(any ? "\n" : " clean.\n");
253 }
254 #endif
255
256 /*======================================================================
257
258     This is tricky... when we set up CIS memory, we try to validate
259     the memory window space allocations.
260
261 ======================================================================*/
262
263 /* Validation function for cards with a valid CIS */
264 static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *info)
265 {
266         int ret = -1;
267
268         s->cis_mem.res = res;
269         s->cis_virt = ioremap(res->start, s->map_size);
270         if (s->cis_virt) {
271                 ret = pccard_validate_cis(s, BIND_FN_ALL, info);
272                 /* invalidate mapping and CIS cache */
273                 iounmap(s->cis_virt);
274                 s->cis_virt = NULL;
275                 destroy_cis_cache(s);
276         }
277         s->cis_mem.res = NULL;
278         if ((ret != 0) || (info->Chains == 0))
279                 return 0;
280         return 1;
281 }
282
283 /* Validation function for simple memory cards */
284 static int checksum(struct pcmcia_socket *s, struct resource *res)
285 {
286         pccard_mem_map map;
287         int i, a = 0, b = -1, d;
288         void __iomem *virt;
289
290         virt = ioremap(res->start, s->map_size);
291         if (virt) {
292                 map.map = 0;
293                 map.flags = MAP_ACTIVE;
294                 map.speed = 0;
295                 map.res = res;
296                 map.card_start = 0;
297                 s->ops->set_mem_map(s, &map);
298
299                 /* Don't bother checking every word... */
300                 for (i = 0; i < s->map_size; i += 44) {
301                         d = readl(virt+i);
302                         a += d;
303                         b &= d;
304                 }
305
306                 map.flags = 0;
307                 s->ops->set_mem_map(s, &map);
308
309                 iounmap(virt);
310         }
311
312         return (b == -1) ? -1 : (a>>1);
313 }
314
315 static int
316 cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size)
317 {
318         struct resource *res1, *res2;
319         cisinfo_t info1, info2;
320         int ret = 0;
321
322         res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
323         res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
324
325         if (res1 && res2) {
326                 ret = readable(s, res1, &info1);
327                 ret += readable(s, res2, &info2);
328         }
329
330         free_region(res2);
331         free_region(res1);
332
333         return (ret == 2) && (info1.Chains == info2.Chains);
334 }
335
336 static int
337 checksum_match(struct pcmcia_socket *s, unsigned long base, unsigned long size)
338 {
339         struct resource *res1, *res2;
340         int a = -1, b = -1;
341
342         res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
343         res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
344
345         if (res1 && res2) {
346                 a = checksum(s, res1);
347                 b = checksum(s, res2);
348         }
349
350         free_region(res2);
351         free_region(res1);
352
353         return (a == b) && (a >= 0);
354 }
355
356 /*======================================================================
357
358     The memory probe.  If the memory list includes a 64K-aligned block
359     below 1MB, we probe in 64K chunks, and as soon as we accumulate at
360     least mem_limit free space, we quit.
361
362 ======================================================================*/
363
364 static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
365 {
366     struct socket_data *s_data = s->resource_data;
367     u_long i, j, bad, fail, step;
368
369     printk(KERN_INFO "cs: memory probe 0x%06lx-0x%06lx:",
370            base, base+num-1);
371     bad = fail = 0;
372     step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
373     /* cis_readable wants to map 2x map_size */
374     if (step < 2 * s->map_size)
375         step = 2 * s->map_size;
376     for (i = j = base; i < base+num; i = j + step) {
377         if (!fail) {
378             for (j = i; j < base+num; j += step) {
379                 if (cis_readable(s, j, step))
380                     break;
381             }
382             fail = ((i == base) && (j == base+num));
383         }
384         if (fail) {
385             for (j = i; j < base+num; j += 2*step)
386                 if (checksum_match(s, j, step) &&
387                     checksum_match(s, j + step, step))
388                     break;
389         }
390         if (i != j) {
391             if (!bad) printk(" excluding");
392             printk(" %#05lx-%#05lx", i, j-1);
393             sub_interval(&s_data->mem_db, i, j-i);
394             bad += j-i;
395         }
396     }
397     printk(bad ? "\n" : " clean.\n");
398     return (num - bad);
399 }
400
401 #ifdef CONFIG_PCMCIA_PROBE
402
403 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
404 {
405     struct socket_data *s_data = s->resource_data;
406     u_long ok;
407     if (m == &s_data->mem_db)
408         return 0;
409     ok = inv_probe(m->next, s);
410     if (ok) {
411         if (m->base >= 0x100000)
412             sub_interval(&s_data->mem_db, m->base, m->num);
413         return ok;
414     }
415     if (m->base < 0x100000)
416         return 0;
417     return do_mem_probe(m->base, m->num, s);
418 }
419
420 static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
421 {
422     struct resource_map *m, mm;
423     static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
424     u_long b, i, ok = 0;
425     struct socket_data *s_data = s->resource_data;
426
427     /* We do up to four passes through the list */
428     if (probe_mask & MEM_PROBE_HIGH) {
429         if (inv_probe(s_data->mem_db.next, s) > 0)
430             return;
431         printk(KERN_NOTICE "cs: warning: no high memory space "
432                "available!\n");
433     }
434     if ((probe_mask & MEM_PROBE_LOW) == 0)
435         return;
436     for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
437         mm = *m;
438         /* Only probe < 1 MB */
439         if (mm.base >= 0x100000) continue;
440         if ((mm.base | mm.num) & 0xffff) {
441             ok += do_mem_probe(mm.base, mm.num, s);
442             continue;
443         }
444         /* Special probe for 64K-aligned block */
445         for (i = 0; i < 4; i++) {
446             b = order[i] << 12;
447             if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
448                 if (ok >= mem_limit)
449                     sub_interval(&s_data->mem_db, b, 0x10000);
450                 else
451                     ok += do_mem_probe(b, 0x10000, s);
452             }
453         }
454     }
455 }
456
457 #else /* CONFIG_PCMCIA_PROBE */
458
459 static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
460 {
461         struct resource_map *m, mm;
462         struct socket_data *s_data = s->resource_data;
463
464         for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
465                 mm = *m;
466                 if (do_mem_probe(mm.base, mm.num, s))
467                         break;
468         }
469 }
470
471 #endif /* CONFIG_PCMCIA_PROBE */
472
473
474 /*
475  * Locking note: this is the only place where we take
476  * both rsrc_sem and skt_sem.
477  */
478 static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
479 {
480         struct socket_data *s_data = s->resource_data;
481         if (probe_mem) {
482                 unsigned int probe_mask;
483
484                 down(&rsrc_sem);
485
486                 probe_mask = MEM_PROBE_LOW;
487                 if (s->features & SS_CAP_PAGE_REGS)
488                         probe_mask = MEM_PROBE_HIGH;
489
490                 if (probe_mask & ~s_data->rsrc_mem_probe) {
491                         s_data->rsrc_mem_probe |= probe_mask;
492
493                         down(&s->skt_sem);
494
495                         if (s->state & SOCKET_PRESENT)
496                                 validate_mem(s, probe_mask);
497
498                         up(&s->skt_sem);
499                 }
500
501                 up(&rsrc_sem);
502         }
503 }
504
505 struct pcmcia_align_data {
506         unsigned long   mask;
507         unsigned long   offset;
508         struct resource_map     *map;
509 };
510
511 static void
512 pcmcia_common_align(void *align_data, struct resource *res,
513                     unsigned long size, unsigned long align)
514 {
515         struct pcmcia_align_data *data = align_data;
516         unsigned long start;
517         /*
518          * Ensure that we have the correct start address
519          */
520         start = (res->start & ~data->mask) + data->offset;
521         if (start < res->start)
522                 start += data->mask + 1;
523         res->start = start;
524 }
525
526 static void
527 pcmcia_align(void *align_data, struct resource *res,
528              unsigned long size, unsigned long align)
529 {
530         struct pcmcia_align_data *data = align_data;
531         struct resource_map *m;
532
533         pcmcia_common_align(data, res, size, align);
534
535         for (m = data->map->next; m != data->map; m = m->next) {
536                 unsigned long start = m->base;
537                 unsigned long end = m->base + m->num - 1;
538
539                 /*
540                  * If the lower resources are not available, try aligning
541                  * to this entry of the resource database to see if it'll
542                  * fit here.
543                  */
544                 if (res->start < start) {
545                         res->start = start;
546                         pcmcia_common_align(data, res, size, align);
547                 }
548
549                 /*
550                  * If we're above the area which was passed in, there's
551                  * no point proceeding.
552                  */
553                 if (res->start >= res->end)
554                         break;
555
556                 if ((res->start + size - 1) <= end)
557                         break;
558         }
559
560         /*
561          * If we failed to find something suitable, ensure we fail.
562          */
563         if (m == data->map)
564                 res->start = res->end;
565 }
566
567 /*
568  * Adjust an existing IO region allocation, but making sure that we don't
569  * encroach outside the resources which the user supplied.
570  */
571 static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start,
572                                       unsigned long r_end, struct pcmcia_socket *s)
573 {
574         struct resource_map *m;
575         struct socket_data *s_data = s->resource_data;
576         int ret = -ENOMEM;
577
578         down(&rsrc_sem);
579         for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
580                 unsigned long start = m->base;
581                 unsigned long end = m->base + m->num - 1;
582
583                 if (start > r_start || r_end > end)
584                         continue;
585
586                 ret = adjust_resource(res, r_start, r_end - r_start + 1);
587                 break;
588         }
589         up(&rsrc_sem);
590
591         return ret;
592 }
593
594 /*======================================================================
595
596     These find ranges of I/O ports or memory addresses that are not
597     currently allocated by other devices.
598
599     The 'align' field should reflect the number of bits of address
600     that need to be preserved from the initial value of *base.  It
601     should be a power of two, greater than or equal to 'num'.  A value
602     of 0 means that all bits of *base are significant.  *base should
603     also be strictly less than 'align'.
604
605 ======================================================================*/
606
607 struct resource *nonstatic_find_io_region(unsigned long base, int num,
608                    unsigned long align, struct pcmcia_socket *s)
609 {
610         struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id);
611         struct socket_data *s_data = s->resource_data;
612         struct pcmcia_align_data data;
613         unsigned long min = base;
614         int ret;
615
616         if (align == 0)
617                 align = 0x10000;
618
619         data.mask = align - 1;
620         data.offset = base & data.mask;
621         data.map = &s_data->io_db;
622
623         down(&rsrc_sem);
624 #ifdef CONFIG_PCI
625         if (s->cb_dev) {
626                 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
627                                              min, 0, pcmcia_align, &data);
628         } else
629 #endif
630                 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
631                                         1, pcmcia_align, &data);
632         up(&rsrc_sem);
633
634         if (ret != 0) {
635                 kfree(res);
636                 res = NULL;
637         }
638         return res;
639 }
640
641 struct resource * nonstatic_find_mem_region(u_long base, u_long num, u_long align,
642                                  int low, struct pcmcia_socket *s)
643 {
644         struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id);
645         struct socket_data *s_data = s->resource_data;
646         struct pcmcia_align_data data;
647         unsigned long min, max;
648         int ret, i;
649
650         low = low || !(s->features & SS_CAP_PAGE_REGS);
651
652         data.mask = align - 1;
653         data.offset = base & data.mask;
654         data.map = &s_data->mem_db;
655
656         for (i = 0; i < 2; i++) {
657                 if (low) {
658                         max = 0x100000UL;
659                         min = base < max ? base : 0;
660                 } else {
661                         max = ~0UL;
662                         min = 0x100000UL + base;
663                 }
664
665                 down(&rsrc_sem);
666 #ifdef CONFIG_PCI
667                 if (s->cb_dev) {
668                         ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
669                                                      1, min, 0,
670                                                      pcmcia_align, &data);
671                 } else
672 #endif
673                         ret = allocate_resource(&iomem_resource, res, num, min,
674                                                 max, 1, pcmcia_align, &data);
675                 up(&rsrc_sem);
676                 if (ret == 0 || low)
677                         break;
678                 low = 1;
679         }
680
681         if (ret != 0) {
682                 kfree(res);
683                 res = NULL;
684         }
685         return res;
686 }
687
688
689 static int adjust_memory(struct pcmcia_socket *s, adjust_t *adj)
690 {
691         u_long base, num;
692         struct socket_data *data = s->resource_data;
693         int ret;
694
695         base = adj->resource.memory.Base;
696         num = adj->resource.memory.Size;
697         if ((num == 0) || (base+num-1 < base))
698                 return CS_BAD_SIZE;
699
700         ret = CS_SUCCESS;
701
702         down(&rsrc_sem);
703         switch (adj->Action) {
704         case ADD_MANAGED_RESOURCE:
705                 ret = add_interval(&data->mem_db, base, num);
706                 break;
707         case REMOVE_MANAGED_RESOURCE:
708                 ret = sub_interval(&data->mem_db, base, num);
709                 if (ret == CS_SUCCESS) {
710                         struct pcmcia_socket *socket;
711                         down_read(&pcmcia_socket_list_rwsem);
712                         list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
713                                 release_cis_mem(socket);
714                         up_read(&pcmcia_socket_list_rwsem);
715                 }
716                 break;
717         default:
718                 ret = CS_UNSUPPORTED_FUNCTION;
719         }
720         up(&rsrc_sem);
721
722         return ret;
723 }
724
725
726 static int adjust_io(struct pcmcia_socket *s, adjust_t *adj)
727 {
728         struct socket_data *data = s->resource_data;
729         kio_addr_t base, num;
730         int ret = CS_SUCCESS;
731
732         base = adj->resource.io.BasePort;
733         num = adj->resource.io.NumPorts;
734         if ((base < 0) || (base > 0xffff))
735                 return CS_BAD_BASE;
736         if ((num <= 0) || (base+num > 0x10000) || (base+num <= base))
737                 return CS_BAD_SIZE;
738
739         down(&rsrc_sem);
740         switch (adj->Action) {
741         case ADD_MANAGED_RESOURCE:
742                 if (add_interval(&data->io_db, base, num) != 0) {
743                         ret = CS_IN_USE;
744                         break;
745                 }
746 #ifdef CONFIG_PCMCIA_PROBE
747                 if (probe_io)
748                         do_io_probe(s, base, num);
749 #endif
750                 break;
751         case REMOVE_MANAGED_RESOURCE:
752                 sub_interval(&data->io_db, base, num);
753                 break;
754         default:
755                 ret = CS_UNSUPPORTED_FUNCTION;
756                 break;
757         }
758         up(&rsrc_sem);
759
760         return ret;
761 }
762
763
764 static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj)
765 {
766         switch (adj->Resource) {
767         case RES_MEMORY_RANGE:
768                 return adjust_memory(s, adj);
769         case RES_IO_RANGE:
770                 return adjust_io(s, adj);
771         }
772         return CS_UNSUPPORTED_FUNCTION;
773 }
774
775 static int nonstatic_init(struct pcmcia_socket *s)
776 {
777         struct socket_data *data;
778
779         data = kmalloc(sizeof(struct socket_data), GFP_KERNEL);
780         if (!data)
781                 return -ENOMEM;
782
783         data->mem_db.next = &data->mem_db;
784         data->io_db.next = &data->io_db;
785
786         s->resource_data = (void *) data;
787
788         return 0;
789 }
790
791 static void nonstatic_release_resource_db(struct pcmcia_socket *s)
792 {
793         struct socket_data *data = s->resource_data;
794         struct resource_map *p, *q;
795
796         down(&rsrc_sem);
797         for (p = data->mem_db.next; p != &data->mem_db; p = q) {
798                 q = p->next;
799                 kfree(p);
800         }
801         for (p = data->io_db.next; p != &data->io_db; p = q) {
802                 q = p->next;
803                 kfree(p);
804         }
805         up(&rsrc_sem);
806 }
807
808
809 struct pccard_resource_ops pccard_nonstatic_ops = {
810         .validate_mem = pcmcia_nonstatic_validate_mem,
811         .adjust_io_region = nonstatic_adjust_io_region,
812         .find_io = nonstatic_find_io_region,
813         .find_mem = nonstatic_find_mem_region,
814         .adjust_resource = nonstatic_adjust_resource_info,
815         .init = nonstatic_init,
816         .exit = nonstatic_release_resource_db,
817 };
818 EXPORT_SYMBOL(pccard_nonstatic_ops);