[PATCH] kill sigqueue->lock
[linux-2.6] / 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     /* don't allow too large steps */
376     if (step > 0x800000)
377         step = 0x800000;
378     /* cis_readable wants to map 2x map_size */
379     if (step < 2 * s->map_size)
380         step = 2 * s->map_size;
381     for (i = j = base; i < base+num; i = j + step) {
382         if (!fail) {
383             for (j = i; j < base+num; j += step) {
384                 if (cis_readable(s, j, step))
385                     break;
386             }
387             fail = ((i == base) && (j == base+num));
388         }
389         if (fail) {
390             for (j = i; j < base+num; j += 2*step)
391                 if (checksum_match(s, j, step) &&
392                     checksum_match(s, j + step, step))
393                     break;
394         }
395         if (i != j) {
396             if (!bad) printk(" excluding");
397             printk(" %#05lx-%#05lx", i, j-1);
398             sub_interval(&s_data->mem_db, i, j-i);
399             bad += j-i;
400         }
401     }
402     printk(bad ? "\n" : " clean.\n");
403     return (num - bad);
404 }
405
406 #ifdef CONFIG_PCMCIA_PROBE
407
408 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
409 {
410     struct socket_data *s_data = s->resource_data;
411     u_long ok;
412     if (m == &s_data->mem_db)
413         return 0;
414     ok = inv_probe(m->next, s);
415     if (ok) {
416         if (m->base >= 0x100000)
417             sub_interval(&s_data->mem_db, m->base, m->num);
418         return ok;
419     }
420     if (m->base < 0x100000)
421         return 0;
422     return do_mem_probe(m->base, m->num, s);
423 }
424
425 static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
426 {
427     struct resource_map *m, mm;
428     static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
429     u_long b, i, ok = 0;
430     struct socket_data *s_data = s->resource_data;
431
432     /* We do up to four passes through the list */
433     if (probe_mask & MEM_PROBE_HIGH) {
434         if (inv_probe(s_data->mem_db.next, s) > 0)
435             return;
436         printk(KERN_NOTICE "cs: warning: no high memory space "
437                "available!\n");
438     }
439     if ((probe_mask & MEM_PROBE_LOW) == 0)
440         return;
441     for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
442         mm = *m;
443         /* Only probe < 1 MB */
444         if (mm.base >= 0x100000) continue;
445         if ((mm.base | mm.num) & 0xffff) {
446             ok += do_mem_probe(mm.base, mm.num, s);
447             continue;
448         }
449         /* Special probe for 64K-aligned block */
450         for (i = 0; i < 4; i++) {
451             b = order[i] << 12;
452             if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
453                 if (ok >= mem_limit)
454                     sub_interval(&s_data->mem_db, b, 0x10000);
455                 else
456                     ok += do_mem_probe(b, 0x10000, s);
457             }
458         }
459     }
460 }
461
462 #else /* CONFIG_PCMCIA_PROBE */
463
464 static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
465 {
466         struct resource_map *m, mm;
467         struct socket_data *s_data = s->resource_data;
468
469         for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
470                 mm = *m;
471                 do_mem_probe(mm.base, mm.num, s);
472         }
473 }
474
475 #endif /* CONFIG_PCMCIA_PROBE */
476
477
478 /*
479  * Locking note: Must be called with skt_sem held!
480  */
481 static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
482 {
483         struct socket_data *s_data = s->resource_data;
484         if (probe_mem) {
485                 unsigned int probe_mask;
486
487                 down(&rsrc_sem);
488
489                 probe_mask = MEM_PROBE_LOW;
490                 if (s->features & SS_CAP_PAGE_REGS)
491                         probe_mask = MEM_PROBE_HIGH;
492
493                 if (probe_mask & ~s_data->rsrc_mem_probe) {
494                         s_data->rsrc_mem_probe |= probe_mask;
495
496                         if (s->state & SOCKET_PRESENT)
497                                 validate_mem(s, probe_mask);
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 static 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 static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
641                 u_long align, 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, unsigned int action, unsigned long start, unsigned long end)
689 {
690         struct socket_data *data = s->resource_data;
691         unsigned long size = end - start + 1;
692         int ret = 0;
693
694         if (end < start)
695                 return -EINVAL;
696
697         down(&rsrc_sem);
698         switch (action) {
699         case ADD_MANAGED_RESOURCE:
700                 ret = add_interval(&data->mem_db, start, size);
701                 break;
702         case REMOVE_MANAGED_RESOURCE:
703                 ret = sub_interval(&data->mem_db, start, size);
704                 if (!ret) {
705                         struct pcmcia_socket *socket;
706                         down_read(&pcmcia_socket_list_rwsem);
707                         list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
708                                 release_cis_mem(socket);
709                         up_read(&pcmcia_socket_list_rwsem);
710                 }
711                 break;
712         default:
713                 ret = -EINVAL;
714         }
715         up(&rsrc_sem);
716
717         return ret;
718 }
719
720
721 static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
722 {
723         struct socket_data *data = s->resource_data;
724         unsigned long size = end - start + 1;
725         int ret = 0;
726
727         if (end < start)
728                 return -EINVAL;
729
730         if (end > IO_SPACE_LIMIT)
731                 return -EINVAL;
732
733         down(&rsrc_sem);
734         switch (action) {
735         case ADD_MANAGED_RESOURCE:
736                 if (add_interval(&data->io_db, start, size) != 0) {
737                         ret = -EBUSY;
738                         break;
739                 }
740 #ifdef CONFIG_PCMCIA_PROBE
741                 if (probe_io)
742                         do_io_probe(s, start, size);
743 #endif
744                 break;
745         case REMOVE_MANAGED_RESOURCE:
746                 sub_interval(&data->io_db, start, size);
747                 break;
748         default:
749                 ret = -EINVAL;
750                 break;
751         }
752         up(&rsrc_sem);
753
754         return ret;
755 }
756
757
758 static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj)
759 {
760         unsigned long end;
761
762         switch (adj->Resource) {
763         case RES_MEMORY_RANGE:
764                 end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
765                 return adjust_memory(s, adj->Action, adj->resource.memory.Base, end);
766         case RES_IO_RANGE:
767                 end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
768                 return adjust_io(s, adj->Action, adj->resource.io.BasePort, end);
769         }
770         return CS_UNSUPPORTED_FUNCTION;
771 }
772
773 #ifdef CONFIG_PCI
774 static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
775 {
776         struct resource *res;
777         int i, done = 0;
778
779         if (!s->cb_dev || !s->cb_dev->bus)
780                 return -ENODEV;
781
782 #if defined(CONFIG_X86)
783         /* If this is the root bus, the risk of hitting
784          * some strange system devices which aren't protected
785          * by either ACPI resource tables or properly requested
786          * resources is too big. Therefore, don't do auto-adding
787          * of resources at the moment.
788          */
789         if (s->cb_dev->bus->number == 0)
790                 return -EINVAL;
791 #endif
792
793         for (i=0; i < PCI_BUS_NUM_RESOURCES; i++) {
794                 res = s->cb_dev->bus->resource[i];
795                 if (!res)
796                         continue;
797
798                 if (res->flags & IORESOURCE_IO) {
799                         if (res == &ioport_resource)
800                                 continue;
801                         printk(KERN_INFO "pcmcia: parent PCI bridge I/O window: 0x%lx - 0x%lx\n",
802                                res->start, res->end);
803                         if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
804                                 done |= IORESOURCE_IO;
805
806                 }
807
808                 if (res->flags & IORESOURCE_MEM) {
809                         if (res == &iomem_resource)
810                                 continue;
811                         printk(KERN_INFO "pcmcia: parent PCI bridge Memory window: 0x%lx - 0x%lx\n",
812                                res->start, res->end);
813                         if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
814                                 done |= IORESOURCE_MEM;
815                 }
816         }
817
818         /* if we got at least one of IO, and one of MEM, we can be glad and
819          * activate the PCMCIA subsystem */
820         if (done == (IORESOURCE_MEM | IORESOURCE_IO))
821                 s->resource_setup_done = 1;
822
823         return 0;
824 }
825
826 #else
827
828 static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
829 {
830         return -ENODEV;
831 }
832
833 #endif
834
835
836 static int nonstatic_init(struct pcmcia_socket *s)
837 {
838         struct socket_data *data;
839
840         data = kmalloc(sizeof(struct socket_data), GFP_KERNEL);
841         if (!data)
842                 return -ENOMEM;
843         memset(data, 0, sizeof(struct socket_data));
844
845         data->mem_db.next = &data->mem_db;
846         data->io_db.next = &data->io_db;
847
848         s->resource_data = (void *) data;
849
850         nonstatic_autoadd_resources(s);
851
852         return 0;
853 }
854
855 static void nonstatic_release_resource_db(struct pcmcia_socket *s)
856 {
857         struct socket_data *data = s->resource_data;
858         struct resource_map *p, *q;
859
860         down(&rsrc_sem);
861         for (p = data->mem_db.next; p != &data->mem_db; p = q) {
862                 q = p->next;
863                 kfree(p);
864         }
865         for (p = data->io_db.next; p != &data->io_db; p = q) {
866                 q = p->next;
867                 kfree(p);
868         }
869         up(&rsrc_sem);
870 }
871
872
873 struct pccard_resource_ops pccard_nonstatic_ops = {
874         .validate_mem = pcmcia_nonstatic_validate_mem,
875         .adjust_io_region = nonstatic_adjust_io_region,
876         .find_io = nonstatic_find_io_region,
877         .find_mem = nonstatic_find_mem_region,
878         .adjust_resource = nonstatic_adjust_resource_info,
879         .init = nonstatic_init,
880         .exit = nonstatic_release_resource_db,
881 };
882 EXPORT_SYMBOL(pccard_nonstatic_ops);
883
884
885 /* sysfs interface to the resource database */
886
887 static ssize_t show_io_db(struct class_device *class_dev, char *buf)
888 {
889         struct pcmcia_socket *s = class_get_devdata(class_dev);
890         struct socket_data *data;
891         struct resource_map *p;
892         ssize_t ret = 0;
893
894         down(&rsrc_sem);
895         data = s->resource_data;
896
897         for (p = data->io_db.next; p != &data->io_db; p = p->next) {
898                 if (ret > (PAGE_SIZE - 10))
899                         continue;
900                 ret += snprintf (&buf[ret], (PAGE_SIZE - ret - 1),
901                                  "0x%08lx - 0x%08lx\n",
902                                  ((unsigned long) p->base),
903                                  ((unsigned long) p->base + p->num - 1));
904         }
905
906         up(&rsrc_sem);
907         return (ret);
908 }
909
910 static ssize_t store_io_db(struct class_device *class_dev, const char *buf, size_t count)
911 {
912         struct pcmcia_socket *s = class_get_devdata(class_dev);
913         unsigned long start_addr, end_addr;
914         unsigned int add = ADD_MANAGED_RESOURCE;
915         ssize_t ret = 0;
916
917         ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
918         if (ret != 2) {
919                 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
920                 add = REMOVE_MANAGED_RESOURCE;
921                 if (ret != 2) {
922                         ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
923                         add = ADD_MANAGED_RESOURCE;
924                         if (ret != 2)
925                                 return -EINVAL;
926                 }
927         }
928         if (end_addr < start_addr)
929                 return -EINVAL;
930
931         ret = adjust_io(s, add, start_addr, end_addr);
932         if (!ret)
933                 s->resource_setup_new = 1;
934
935         return ret ? ret : count;
936 }
937 static CLASS_DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
938
939 static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
940 {
941         struct pcmcia_socket *s = class_get_devdata(class_dev);
942         struct socket_data *data;
943         struct resource_map *p;
944         ssize_t ret = 0;
945
946         down(&rsrc_sem);
947         data = s->resource_data;
948
949         for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
950                 if (ret > (PAGE_SIZE - 10))
951                         continue;
952                 ret += snprintf (&buf[ret], (PAGE_SIZE - ret - 1),
953                                  "0x%08lx - 0x%08lx\n",
954                                  ((unsigned long) p->base),
955                                  ((unsigned long) p->base + p->num - 1));
956         }
957
958         up(&rsrc_sem);
959         return (ret);
960 }
961
962 static ssize_t store_mem_db(struct class_device *class_dev, const char *buf, size_t count)
963 {
964         struct pcmcia_socket *s = class_get_devdata(class_dev);
965         unsigned long start_addr, end_addr;
966         unsigned int add = ADD_MANAGED_RESOURCE;
967         ssize_t ret = 0;
968
969         ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
970         if (ret != 2) {
971                 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
972                 add = REMOVE_MANAGED_RESOURCE;
973                 if (ret != 2) {
974                         ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
975                         add = ADD_MANAGED_RESOURCE;
976                         if (ret != 2)
977                                 return -EINVAL;
978                 }
979         }
980         if (end_addr < start_addr)
981                 return -EINVAL;
982
983         ret = adjust_memory(s, add, start_addr, end_addr);
984         if (!ret)
985                 s->resource_setup_new = 1;
986
987         return ret ? ret : count;
988 }
989 static CLASS_DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
990
991 static struct class_device_attribute *pccard_rsrc_attributes[] = {
992         &class_device_attr_available_resources_io,
993         &class_device_attr_available_resources_mem,
994         NULL,
995 };
996
997 static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev,
998                                            struct class_interface *class_intf)
999 {
1000         struct pcmcia_socket *s = class_get_devdata(class_dev);
1001         struct class_device_attribute **attr;
1002         int ret = 0;
1003         if (s->resource_ops != &pccard_nonstatic_ops)
1004                 return 0;
1005
1006         for (attr = pccard_rsrc_attributes; *attr; attr++) {
1007                 ret = class_device_create_file(class_dev, *attr);
1008                 if (ret)
1009                         break;
1010         }
1011
1012         return ret;
1013 }
1014
1015 static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev,
1016                                                struct class_interface *class_intf)
1017 {
1018         struct pcmcia_socket *s = class_get_devdata(class_dev);
1019         struct class_device_attribute **attr;
1020
1021         if (s->resource_ops != &pccard_nonstatic_ops)
1022                 return;
1023
1024         for (attr = pccard_rsrc_attributes; *attr; attr++)
1025                 class_device_remove_file(class_dev, *attr);
1026 }
1027
1028 static struct class_interface pccard_rsrc_interface = {
1029         .class = &pcmcia_socket_class,
1030         .add = &pccard_sysfs_add_rsrc,
1031         .remove = __devexit_p(&pccard_sysfs_remove_rsrc),
1032 };
1033
1034 static int __init nonstatic_sysfs_init(void)
1035 {
1036         return class_interface_register(&pccard_rsrc_interface);
1037 }
1038
1039 static void __exit nonstatic_sysfs_exit(void)
1040 {
1041         class_interface_unregister(&pccard_rsrc_interface);
1042 }
1043
1044 module_init(nonstatic_sysfs_init);
1045 module_exit(nonstatic_sysfs_exit);