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