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