[PATCH] pcmcia: validate_mem shouldn't be void
[safe/jmp/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 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 void 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
475         for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
476                 mm = *m;
477                 do_mem_probe(mm.base, mm.num, s);
478         }
479 }
480
481 #endif /* CONFIG_PCMCIA_PROBE */
482
483
484 /*
485  * Locking note: Must be called with skt_sem held!
486  */
487 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
488 {
489         struct socket_data *s_data = s->resource_data;
490         unsigned int probe_mask = MEM_PROBE_LOW;
491         int ret = 0;
492
493         if (!probe_mem)
494                 return 0;
495
496         down(&rsrc_sem);
497
498         if (s->features & SS_CAP_PAGE_REGS)
499                 probe_mask = MEM_PROBE_HIGH;
500
501         if (probe_mask & ~s_data->rsrc_mem_probe) {
502                 if (s->state & SOCKET_PRESENT)
503                         ret = validate_mem(s, probe_mask);
504                 if (!ret)
505                         s_data->rsrc_mem_probe |= probe_mask;
506         }
507
508         up(&rsrc_sem);
509
510         return ret;
511 }
512
513 struct pcmcia_align_data {
514         unsigned long   mask;
515         unsigned long   offset;
516         struct resource_map     *map;
517 };
518
519 static void
520 pcmcia_common_align(void *align_data, struct resource *res,
521                     unsigned long size, unsigned long align)
522 {
523         struct pcmcia_align_data *data = align_data;
524         unsigned long start;
525         /*
526          * Ensure that we have the correct start address
527          */
528         start = (res->start & ~data->mask) + data->offset;
529         if (start < res->start)
530                 start += data->mask + 1;
531         res->start = start;
532 }
533
534 static void
535 pcmcia_align(void *align_data, struct resource *res,
536              unsigned long size, unsigned long align)
537 {
538         struct pcmcia_align_data *data = align_data;
539         struct resource_map *m;
540
541         pcmcia_common_align(data, res, size, align);
542
543         for (m = data->map->next; m != data->map; m = m->next) {
544                 unsigned long start = m->base;
545                 unsigned long end = m->base + m->num - 1;
546
547                 /*
548                  * If the lower resources are not available, try aligning
549                  * to this entry of the resource database to see if it'll
550                  * fit here.
551                  */
552                 if (res->start < start) {
553                         res->start = start;
554                         pcmcia_common_align(data, res, size, align);
555                 }
556
557                 /*
558                  * If we're above the area which was passed in, there's
559                  * no point proceeding.
560                  */
561                 if (res->start >= res->end)
562                         break;
563
564                 if ((res->start + size - 1) <= end)
565                         break;
566         }
567
568         /*
569          * If we failed to find something suitable, ensure we fail.
570          */
571         if (m == data->map)
572                 res->start = res->end;
573 }
574
575 /*
576  * Adjust an existing IO region allocation, but making sure that we don't
577  * encroach outside the resources which the user supplied.
578  */
579 static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start,
580                                       unsigned long r_end, struct pcmcia_socket *s)
581 {
582         struct resource_map *m;
583         struct socket_data *s_data = s->resource_data;
584         int ret = -ENOMEM;
585
586         down(&rsrc_sem);
587         for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
588                 unsigned long start = m->base;
589                 unsigned long end = m->base + m->num - 1;
590
591                 if (start > r_start || r_end > end)
592                         continue;
593
594                 ret = adjust_resource(res, r_start, r_end - r_start + 1);
595                 break;
596         }
597         up(&rsrc_sem);
598
599         return ret;
600 }
601
602 /*======================================================================
603
604     These find ranges of I/O ports or memory addresses that are not
605     currently allocated by other devices.
606
607     The 'align' field should reflect the number of bits of address
608     that need to be preserved from the initial value of *base.  It
609     should be a power of two, greater than or equal to 'num'.  A value
610     of 0 means that all bits of *base are significant.  *base should
611     also be strictly less than 'align'.
612
613 ======================================================================*/
614
615 static struct resource *nonstatic_find_io_region(unsigned long base, int num,
616                    unsigned long align, struct pcmcia_socket *s)
617 {
618         struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id);
619         struct socket_data *s_data = s->resource_data;
620         struct pcmcia_align_data data;
621         unsigned long min = base;
622         int ret;
623
624         if (align == 0)
625                 align = 0x10000;
626
627         data.mask = align - 1;
628         data.offset = base & data.mask;
629         data.map = &s_data->io_db;
630
631         down(&rsrc_sem);
632 #ifdef CONFIG_PCI
633         if (s->cb_dev) {
634                 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
635                                              min, 0, pcmcia_align, &data);
636         } else
637 #endif
638                 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
639                                         1, pcmcia_align, &data);
640         up(&rsrc_sem);
641
642         if (ret != 0) {
643                 kfree(res);
644                 res = NULL;
645         }
646         return res;
647 }
648
649 static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
650                 u_long align, int low, struct pcmcia_socket *s)
651 {
652         struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id);
653         struct socket_data *s_data = s->resource_data;
654         struct pcmcia_align_data data;
655         unsigned long min, max;
656         int ret, i;
657
658         low = low || !(s->features & SS_CAP_PAGE_REGS);
659
660         data.mask = align - 1;
661         data.offset = base & data.mask;
662         data.map = &s_data->mem_db;
663
664         for (i = 0; i < 2; i++) {
665                 if (low) {
666                         max = 0x100000UL;
667                         min = base < max ? base : 0;
668                 } else {
669                         max = ~0UL;
670                         min = 0x100000UL + base;
671                 }
672
673                 down(&rsrc_sem);
674 #ifdef CONFIG_PCI
675                 if (s->cb_dev) {
676                         ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
677                                                      1, min, 0,
678                                                      pcmcia_align, &data);
679                 } else
680 #endif
681                         ret = allocate_resource(&iomem_resource, res, num, min,
682                                                 max, 1, pcmcia_align, &data);
683                 up(&rsrc_sem);
684                 if (ret == 0 || low)
685                         break;
686                 low = 1;
687         }
688
689         if (ret != 0) {
690                 kfree(res);
691                 res = NULL;
692         }
693         return res;
694 }
695
696
697 static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
698 {
699         struct socket_data *data = s->resource_data;
700         unsigned long size = end - start + 1;
701         int ret = 0;
702
703         if (end < start)
704                 return -EINVAL;
705
706         down(&rsrc_sem);
707         switch (action) {
708         case ADD_MANAGED_RESOURCE:
709                 ret = add_interval(&data->mem_db, start, size);
710                 break;
711         case REMOVE_MANAGED_RESOURCE:
712                 ret = sub_interval(&data->mem_db, start, size);
713                 if (!ret) {
714                         struct pcmcia_socket *socket;
715                         down_read(&pcmcia_socket_list_rwsem);
716                         list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
717                                 release_cis_mem(socket);
718                         up_read(&pcmcia_socket_list_rwsem);
719                 }
720                 break;
721         default:
722                 ret = -EINVAL;
723         }
724         up(&rsrc_sem);
725
726         return ret;
727 }
728
729
730 static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
731 {
732         struct socket_data *data = s->resource_data;
733         unsigned long size = end - start + 1;
734         int ret = 0;
735
736         if (end < start)
737                 return -EINVAL;
738
739         if (end > IO_SPACE_LIMIT)
740                 return -EINVAL;
741
742         down(&rsrc_sem);
743         switch (action) {
744         case ADD_MANAGED_RESOURCE:
745                 if (add_interval(&data->io_db, start, size) != 0) {
746                         ret = -EBUSY;
747                         break;
748                 }
749 #ifdef CONFIG_PCMCIA_PROBE
750                 if (probe_io)
751                         do_io_probe(s, start, size);
752 #endif
753                 break;
754         case REMOVE_MANAGED_RESOURCE:
755                 sub_interval(&data->io_db, start, size);
756                 break;
757         default:
758                 ret = -EINVAL;
759                 break;
760         }
761         up(&rsrc_sem);
762
763         return ret;
764 }
765
766
767 static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj)
768 {
769         unsigned long end;
770
771         switch (adj->Resource) {
772         case RES_MEMORY_RANGE:
773                 end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
774                 return adjust_memory(s, adj->Action, adj->resource.memory.Base, end);
775         case RES_IO_RANGE:
776                 end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
777                 return adjust_io(s, adj->Action, adj->resource.io.BasePort, end);
778         }
779         return CS_UNSUPPORTED_FUNCTION;
780 }
781
782 #ifdef CONFIG_PCI
783 static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
784 {
785         struct resource *res;
786         int i, done = 0;
787
788         if (!s->cb_dev || !s->cb_dev->bus)
789                 return -ENODEV;
790
791 #if defined(CONFIG_X86)
792         /* If this is the root bus, the risk of hitting
793          * some strange system devices which aren't protected
794          * by either ACPI resource tables or properly requested
795          * resources is too big. Therefore, don't do auto-adding
796          * of resources at the moment.
797          */
798         if (s->cb_dev->bus->number == 0)
799                 return -EINVAL;
800 #endif
801
802         for (i=0; i < PCI_BUS_NUM_RESOURCES; i++) {
803                 res = s->cb_dev->bus->resource[i];
804                 if (!res)
805                         continue;
806
807                 if (res->flags & IORESOURCE_IO) {
808                         if (res == &ioport_resource)
809                                 continue;
810                         printk(KERN_INFO "pcmcia: parent PCI bridge I/O window: 0x%lx - 0x%lx\n",
811                                res->start, res->end);
812                         if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
813                                 done |= IORESOURCE_IO;
814
815                 }
816
817                 if (res->flags & IORESOURCE_MEM) {
818                         if (res == &iomem_resource)
819                                 continue;
820                         printk(KERN_INFO "pcmcia: parent PCI bridge Memory window: 0x%lx - 0x%lx\n",
821                                res->start, res->end);
822                         if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
823                                 done |= IORESOURCE_MEM;
824                 }
825         }
826
827         /* if we got at least one of IO, and one of MEM, we can be glad and
828          * activate the PCMCIA subsystem */
829         if (done == (IORESOURCE_MEM | IORESOURCE_IO))
830                 s->resource_setup_done = 1;
831
832         return 0;
833 }
834
835 #else
836
837 static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
838 {
839         return -ENODEV;
840 }
841
842 #endif
843
844
845 static int nonstatic_init(struct pcmcia_socket *s)
846 {
847         struct socket_data *data;
848
849         data = kmalloc(sizeof(struct socket_data), GFP_KERNEL);
850         if (!data)
851                 return -ENOMEM;
852         memset(data, 0, sizeof(struct socket_data));
853
854         data->mem_db.next = &data->mem_db;
855         data->io_db.next = &data->io_db;
856
857         s->resource_data = (void *) data;
858
859         nonstatic_autoadd_resources(s);
860
861         return 0;
862 }
863
864 static void nonstatic_release_resource_db(struct pcmcia_socket *s)
865 {
866         struct socket_data *data = s->resource_data;
867         struct resource_map *p, *q;
868
869         down(&rsrc_sem);
870         for (p = data->mem_db.next; p != &data->mem_db; p = q) {
871                 q = p->next;
872                 kfree(p);
873         }
874         for (p = data->io_db.next; p != &data->io_db; p = q) {
875                 q = p->next;
876                 kfree(p);
877         }
878         up(&rsrc_sem);
879 }
880
881
882 struct pccard_resource_ops pccard_nonstatic_ops = {
883         .validate_mem = pcmcia_nonstatic_validate_mem,
884         .adjust_io_region = nonstatic_adjust_io_region,
885         .find_io = nonstatic_find_io_region,
886         .find_mem = nonstatic_find_mem_region,
887         .adjust_resource = nonstatic_adjust_resource_info,
888         .init = nonstatic_init,
889         .exit = nonstatic_release_resource_db,
890 };
891 EXPORT_SYMBOL(pccard_nonstatic_ops);
892
893
894 /* sysfs interface to the resource database */
895
896 static ssize_t show_io_db(struct class_device *class_dev, char *buf)
897 {
898         struct pcmcia_socket *s = class_get_devdata(class_dev);
899         struct socket_data *data;
900         struct resource_map *p;
901         ssize_t ret = 0;
902
903         down(&rsrc_sem);
904         data = s->resource_data;
905
906         for (p = data->io_db.next; p != &data->io_db; p = p->next) {
907                 if (ret > (PAGE_SIZE - 10))
908                         continue;
909                 ret += snprintf (&buf[ret], (PAGE_SIZE - ret - 1),
910                                  "0x%08lx - 0x%08lx\n",
911                                  ((unsigned long) p->base),
912                                  ((unsigned long) p->base + p->num - 1));
913         }
914
915         up(&rsrc_sem);
916         return (ret);
917 }
918
919 static ssize_t store_io_db(struct class_device *class_dev, const char *buf, size_t count)
920 {
921         struct pcmcia_socket *s = class_get_devdata(class_dev);
922         unsigned long start_addr, end_addr;
923         unsigned int add = ADD_MANAGED_RESOURCE;
924         ssize_t ret = 0;
925
926         ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
927         if (ret != 2) {
928                 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
929                 add = REMOVE_MANAGED_RESOURCE;
930                 if (ret != 2) {
931                         ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
932                         add = ADD_MANAGED_RESOURCE;
933                         if (ret != 2)
934                                 return -EINVAL;
935                 }
936         }
937         if (end_addr < start_addr)
938                 return -EINVAL;
939
940         ret = adjust_io(s, add, start_addr, end_addr);
941         if (!ret)
942                 s->resource_setup_new = 1;
943
944         return ret ? ret : count;
945 }
946 static CLASS_DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
947
948 static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
949 {
950         struct pcmcia_socket *s = class_get_devdata(class_dev);
951         struct socket_data *data;
952         struct resource_map *p;
953         ssize_t ret = 0;
954
955         down(&rsrc_sem);
956         data = s->resource_data;
957
958         for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
959                 if (ret > (PAGE_SIZE - 10))
960                         continue;
961                 ret += snprintf (&buf[ret], (PAGE_SIZE - ret - 1),
962                                  "0x%08lx - 0x%08lx\n",
963                                  ((unsigned long) p->base),
964                                  ((unsigned long) p->base + p->num - 1));
965         }
966
967         up(&rsrc_sem);
968         return (ret);
969 }
970
971 static ssize_t store_mem_db(struct class_device *class_dev, const char *buf, size_t count)
972 {
973         struct pcmcia_socket *s = class_get_devdata(class_dev);
974         unsigned long start_addr, end_addr;
975         unsigned int add = ADD_MANAGED_RESOURCE;
976         ssize_t ret = 0;
977
978         ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
979         if (ret != 2) {
980                 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
981                 add = REMOVE_MANAGED_RESOURCE;
982                 if (ret != 2) {
983                         ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
984                         add = ADD_MANAGED_RESOURCE;
985                         if (ret != 2)
986                                 return -EINVAL;
987                 }
988         }
989         if (end_addr < start_addr)
990                 return -EINVAL;
991
992         ret = adjust_memory(s, add, start_addr, end_addr);
993         if (!ret)
994                 s->resource_setup_new = 1;
995
996         return ret ? ret : count;
997 }
998 static CLASS_DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
999
1000 static struct class_device_attribute *pccard_rsrc_attributes[] = {
1001         &class_device_attr_available_resources_io,
1002         &class_device_attr_available_resources_mem,
1003         NULL,
1004 };
1005
1006 static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev,
1007                                            struct class_interface *class_intf)
1008 {
1009         struct pcmcia_socket *s = class_get_devdata(class_dev);
1010         struct class_device_attribute **attr;
1011         int ret = 0;
1012         if (s->resource_ops != &pccard_nonstatic_ops)
1013                 return 0;
1014
1015         for (attr = pccard_rsrc_attributes; *attr; attr++) {
1016                 ret = class_device_create_file(class_dev, *attr);
1017                 if (ret)
1018                         break;
1019         }
1020
1021         return ret;
1022 }
1023
1024 static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev,
1025                                                struct class_interface *class_intf)
1026 {
1027         struct pcmcia_socket *s = class_get_devdata(class_dev);
1028         struct class_device_attribute **attr;
1029
1030         if (s->resource_ops != &pccard_nonstatic_ops)
1031                 return;
1032
1033         for (attr = pccard_rsrc_attributes; *attr; attr++)
1034                 class_device_remove_file(class_dev, *attr);
1035 }
1036
1037 static struct class_interface pccard_rsrc_interface = {
1038         .class = &pcmcia_socket_class,
1039         .add = &pccard_sysfs_add_rsrc,
1040         .remove = __devexit_p(&pccard_sysfs_remove_rsrc),
1041 };
1042
1043 static int __init nonstatic_sysfs_init(void)
1044 {
1045         return class_interface_register(&pccard_rsrc_interface);
1046 }
1047
1048 static void __exit nonstatic_sysfs_exit(void)
1049 {
1050         class_interface_unregister(&pccard_rsrc_interface);
1051 }
1052
1053 module_init(nonstatic_sysfs_init);
1054 module_exit(nonstatic_sysfs_exit);