Merge master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
[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/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
28 #include <asm/irq.h>
29 #include <asm/io.h>
30
31 #include <pcmcia/cs_types.h>
32 #include <pcmcia/ss.h>
33 #include <pcmcia/cs.h>
34 #include <pcmcia/bulkmem.h>
35 #include <pcmcia/cistpl.h>
36 #include "cs_internal.h"
37
38 MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
39 MODULE_LICENSE("GPL");
40
41 /* Parameters that can be set with 'insmod' */
42
43 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
44
45 INT_MODULE_PARM(probe_mem,      1);             /* memory probe? */
46 #ifdef CONFIG_PCMCIA_PROBE
47 INT_MODULE_PARM(probe_io,       1);             /* IO port probe? */
48 INT_MODULE_PARM(mem_limit,      0x10000);
49 #endif
50
51 /* for io_db and mem_db */
52 struct resource_map {
53         u_long                  base, num;
54         struct resource_map     *next;
55 };
56
57 struct socket_data {
58         struct resource_map             mem_db;
59         struct resource_map             io_db;
60         unsigned int                    rsrc_mem_probe;
61 };
62
63 static DEFINE_MUTEX(rsrc_mutex);
64 #define MEM_PROBE_LOW   (1 << 0)
65 #define MEM_PROBE_HIGH  (1 << 1)
66
67
68 /*======================================================================
69
70     Linux resource management extensions
71
72 ======================================================================*/
73
74 static struct resource *
75 make_resource(unsigned long b, unsigned long n, int flags, char *name)
76 {
77         struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
78
79         if (res) {
80                 res->name = name;
81                 res->start = b;
82                 res->end = b + n - 1;
83                 res->flags = flags;
84         }
85         return res;
86 }
87
88 static struct resource *
89 claim_region(struct pcmcia_socket *s, unsigned long base, unsigned long size,
90              int type, char *name)
91 {
92         struct resource *res, *parent;
93
94         parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
95         res = make_resource(base, size, type | IORESOURCE_BUSY, name);
96
97         if (res) {
98 #ifdef CONFIG_PCI
99                 if (s && s->cb_dev)
100                         parent = pci_find_parent_resource(s->cb_dev, res);
101 #endif
102                 if (!parent || request_resource(parent, res)) {
103                         kfree(res);
104                         res = NULL;
105                 }
106         }
107         return res;
108 }
109
110 static void free_region(struct resource *res)
111 {
112         if (res) {
113                 release_resource(res);
114                 kfree(res);
115         }
116 }
117
118 /*======================================================================
119
120     These manage the internal databases of available resources.
121
122 ======================================================================*/
123
124 static int add_interval(struct resource_map *map, u_long base, u_long num)
125 {
126     struct resource_map *p, *q;
127
128     for (p = map; ; p = p->next) {
129         if ((p != map) && (p->base+p->num-1 >= base))
130             return -1;
131         if ((p->next == map) || (p->next->base > base+num-1))
132             break;
133     }
134     q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
135     if (!q) return CS_OUT_OF_RESOURCE;
136     q->base = base; q->num = num;
137     q->next = p->next; p->next = q;
138     return CS_SUCCESS;
139 }
140
141 /*====================================================================*/
142
143 static int sub_interval(struct resource_map *map, u_long base, u_long num)
144 {
145     struct resource_map *p, *q;
146
147     for (p = map; ; p = q) {
148         q = p->next;
149         if (q == map)
150             break;
151         if ((q->base+q->num > base) && (base+num > q->base)) {
152             if (q->base >= base) {
153                 if (q->base+q->num <= base+num) {
154                     /* Delete whole block */
155                     p->next = q->next;
156                     kfree(q);
157                     /* don't advance the pointer yet */
158                     q = p;
159                 } else {
160                     /* Cut off bit from the front */
161                     q->num = q->base + q->num - base - num;
162                     q->base = base + num;
163                 }
164             } else if (q->base+q->num <= base+num) {
165                 /* Cut off bit from the end */
166                 q->num = base - q->base;
167             } else {
168                 /* Split the block into two pieces */
169                 p = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
170                 if (!p) return CS_OUT_OF_RESOURCE;
171                 p->base = base+num;
172                 p->num = q->base+q->num - p->base;
173                 q->num = base - q->base;
174                 p->next = q->next ; q->next = p;
175             }
176         }
177     }
178     return CS_SUCCESS;
179 }
180
181 /*======================================================================
182
183     These routines examine a region of IO or memory addresses to
184     determine what ranges might be genuinely available.
185
186 ======================================================================*/
187
188 #ifdef CONFIG_PCMCIA_PROBE
189 static void do_io_probe(struct pcmcia_socket *s, kio_addr_t base, kio_addr_t num)
190 {
191     struct resource *res;
192     struct socket_data *s_data = s->resource_data;
193     kio_addr_t i, j, bad;
194     int any;
195     u_char *b, hole, most;
196
197     printk(KERN_INFO "cs: IO port probe %#lx-%#lx:",
198            base, base+num-1);
199
200     /* First, what does a floating port look like? */
201     b = kzalloc(256, GFP_KERNEL);
202     if (!b) {
203             printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
204             return;
205     }
206     for (i = base, most = 0; i < base+num; i += 8) {
207         res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
208         if (!res)
209             continue;
210         hole = inb(i);
211         for (j = 1; j < 8; j++)
212             if (inb(i+j) != hole) break;
213         free_region(res);
214         if ((j == 8) && (++b[hole] > b[most]))
215             most = hole;
216         if (b[most] == 127) break;
217     }
218     kfree(b);
219
220     bad = any = 0;
221     for (i = base; i < base+num; i += 8) {
222         res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
223         if (!res)
224             continue;
225         for (j = 0; j < 8; j++)
226             if (inb(i+j) != most) break;
227         free_region(res);
228         if (j < 8) {
229             if (!any)
230                 printk(" excluding");
231             if (!bad)
232                 bad = any = i;
233         } else {
234             if (bad) {
235                 sub_interval(&s_data->io_db, bad, i-bad);
236                 printk(" %#lx-%#lx", bad, i-1);
237                 bad = 0;
238             }
239         }
240     }
241     if (bad) {
242         if ((num > 16) && (bad == base) && (i == base+num)) {
243             printk(" nothing: probe failed.\n");
244             return;
245         } else {
246             sub_interval(&s_data->io_db, bad, i-bad);
247             printk(" %#lx-%#lx", bad, i-1);
248         }
249     }
250
251     printk(any ? "\n" : " clean.\n");
252 }
253 #endif
254
255 /*======================================================================
256
257     This is tricky... when we set up CIS memory, we try to validate
258     the memory window space allocations.
259
260 ======================================================================*/
261
262 /* Validation function for cards with a valid CIS */
263 static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *info)
264 {
265         int ret = -1;
266
267         s->cis_mem.res = res;
268         s->cis_virt = ioremap(res->start, s->map_size);
269         if (s->cis_virt) {
270                 ret = pccard_validate_cis(s, BIND_FN_ALL, info);
271                 /* invalidate mapping and CIS cache */
272                 iounmap(s->cis_virt);
273                 s->cis_virt = NULL;
274                 destroy_cis_cache(s);
275         }
276         s->cis_mem.res = NULL;
277         if ((ret != 0) || (info->Chains == 0))
278                 return 0;
279         return 1;
280 }
281
282 /* Validation function for simple memory cards */
283 static int checksum(struct pcmcia_socket *s, struct resource *res)
284 {
285         pccard_mem_map map;
286         int i, a = 0, b = -1, d;
287         void __iomem *virt;
288
289         virt = ioremap(res->start, s->map_size);
290         if (virt) {
291                 map.map = 0;
292                 map.flags = MAP_ACTIVE;
293                 map.speed = 0;
294                 map.res = res;
295                 map.card_start = 0;
296                 s->ops->set_mem_map(s, &map);
297
298                 /* Don't bother checking every word... */
299                 for (i = 0; i < s->map_size; i += 44) {
300                         d = readl(virt+i);
301                         a += d;
302                         b &= d;
303                 }
304
305                 map.flags = 0;
306                 s->ops->set_mem_map(s, &map);
307
308                 iounmap(virt);
309         }
310
311         return (b == -1) ? -1 : (a>>1);
312 }
313
314 static int
315 cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size)
316 {
317         struct resource *res1, *res2;
318         cisinfo_t info1, info2;
319         int ret = 0;
320
321         res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
322         res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
323
324         if (res1 && res2) {
325                 ret = readable(s, res1, &info1);
326                 ret += readable(s, res2, &info2);
327         }
328
329         free_region(res2);
330         free_region(res1);
331
332         return (ret == 2) && (info1.Chains == info2.Chains);
333 }
334
335 static int
336 checksum_match(struct pcmcia_socket *s, unsigned long base, unsigned long size)
337 {
338         struct resource *res1, *res2;
339         int a = -1, b = -1;
340
341         res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "cs memory probe");
342         res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM, "cs memory probe");
343
344         if (res1 && res2) {
345                 a = checksum(s, res1);
346                 b = checksum(s, res2);
347         }
348
349         free_region(res2);
350         free_region(res1);
351
352         return (a == b) && (a >= 0);
353 }
354
355 /*======================================================================
356
357     The memory probe.  If the memory list includes a 64K-aligned block
358     below 1MB, we probe in 64K chunks, and as soon as we accumulate at
359     least mem_limit free space, we quit.
360
361 ======================================================================*/
362
363 static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)
364 {
365     struct socket_data *s_data = s->resource_data;
366     u_long i, j, bad, fail, step;
367
368     printk(KERN_INFO "cs: memory probe 0x%06lx-0x%06lx:",
369            base, base+num-1);
370     bad = fail = 0;
371     step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
372     /* don't allow too large steps */
373     if (step > 0x800000)
374         step = 0x800000;
375     /* cis_readable wants to map 2x map_size */
376     if (step < 2 * s->map_size)
377         step = 2 * s->map_size;
378     for (i = j = base; i < base+num; i = j + step) {
379         if (!fail) {
380             for (j = i; j < base+num; j += step) {
381                 if (cis_readable(s, j, step))
382                     break;
383             }
384             fail = ((i == base) && (j == base+num));
385         }
386         if (fail) {
387             for (j = i; j < base+num; j += 2*step)
388                 if (checksum_match(s, j, step) &&
389                     checksum_match(s, j + step, step))
390                     break;
391         }
392         if (i != j) {
393             if (!bad) printk(" excluding");
394             printk(" %#05lx-%#05lx", i, j-1);
395             sub_interval(&s_data->mem_db, i, j-i);
396             bad += j-i;
397         }
398     }
399     printk(bad ? "\n" : " clean.\n");
400     return (num - bad);
401 }
402
403 #ifdef CONFIG_PCMCIA_PROBE
404
405 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
406 {
407         struct socket_data *s_data = s->resource_data;
408         u_long ok;
409         if (m == &s_data->mem_db)
410                 return 0;
411         ok = inv_probe(m->next, s);
412         if (ok) {
413                 if (m->base >= 0x100000)
414                         sub_interval(&s_data->mem_db, m->base, m->num);
415                 return ok;
416         }
417         if (m->base < 0x100000)
418                 return 0;
419         return do_mem_probe(m->base, m->num, s);
420 }
421
422 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
423 {
424         struct resource_map *m, mm;
425         static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
426         unsigned long b, i, ok = 0;
427         struct socket_data *s_data = s->resource_data;
428
429         /* We do up to four passes through the list */
430         if (probe_mask & MEM_PROBE_HIGH) {
431                 if (inv_probe(s_data->mem_db.next, s) > 0)
432                         return 0;
433                 printk(KERN_NOTICE "cs: warning: no high memory space "
434                        "available!\n");
435                 return -ENODEV;
436         }
437
438         for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
439                 mm = *m;
440                 /* Only probe < 1 MB */
441                 if (mm.base >= 0x100000)
442                         continue;
443                 if ((mm.base | mm.num) & 0xffff) {
444                         ok += do_mem_probe(mm.base, mm.num, s);
445                         continue;
446                 }
447                 /* Special probe for 64K-aligned block */
448                 for (i = 0; i < 4; i++) {
449                         b = order[i] << 12;
450                         if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
451                                 if (ok >= mem_limit)
452                                         sub_interval(&s_data->mem_db, b, 0x10000);
453                                 else
454                                         ok += do_mem_probe(b, 0x10000, s);
455                         }
456                 }
457         }
458
459         if (ok > 0)
460                 return 0;
461
462         return -ENODEV;
463 }
464
465 #else /* CONFIG_PCMCIA_PROBE */
466
467 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
468 {
469         struct resource_map *m, mm;
470         struct socket_data *s_data = s->resource_data;
471         unsigned long ok = 0;
472
473         for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
474                 mm = *m;
475                 ok += do_mem_probe(mm.base, mm.num, s);
476         }
477         if (ok > 0)
478                 return 0;
479         return -ENODEV;
480 }
481
482 #endif /* CONFIG_PCMCIA_PROBE */
483
484
485 /*
486  * Locking note: Must be called with skt_mutex held!
487  */
488 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
489 {
490         struct socket_data *s_data = s->resource_data;
491         unsigned int probe_mask = MEM_PROBE_LOW;
492         int ret = 0;
493
494         if (!probe_mem)
495                 return 0;
496
497         mutex_lock(&rsrc_mutex);
498
499         if (s->features & SS_CAP_PAGE_REGS)
500                 probe_mask = MEM_PROBE_HIGH;
501
502         if (probe_mask & ~s_data->rsrc_mem_probe) {
503                 if (s->state & SOCKET_PRESENT)
504                         ret = validate_mem(s, probe_mask);
505                 if (!ret)
506                         s_data->rsrc_mem_probe |= probe_mask;
507         }
508
509         mutex_unlock(&rsrc_mutex);
510
511         return ret;
512 }
513
514 struct pcmcia_align_data {
515         unsigned long   mask;
516         unsigned long   offset;
517         struct resource_map     *map;
518 };
519
520 static void
521 pcmcia_common_align(void *align_data, struct resource *res,
522                     unsigned long size, unsigned long align)
523 {
524         struct pcmcia_align_data *data = align_data;
525         unsigned long start;
526         /*
527          * Ensure that we have the correct start address
528          */
529         start = (res->start & ~data->mask) + data->offset;
530         if (start < res->start)
531                 start += data->mask + 1;
532         res->start = start;
533 }
534
535 static void
536 pcmcia_align(void *align_data, struct resource *res,
537              unsigned long size, unsigned long align)
538 {
539         struct pcmcia_align_data *data = align_data;
540         struct resource_map *m;
541
542         pcmcia_common_align(data, res, size, align);
543
544         for (m = data->map->next; m != data->map; m = m->next) {
545                 unsigned long start = m->base;
546                 unsigned long end = m->base + m->num - 1;
547
548                 /*
549                  * If the lower resources are not available, try aligning
550                  * to this entry of the resource database to see if it'll
551                  * fit here.
552                  */
553                 if (res->start < start) {
554                         res->start = start;
555                         pcmcia_common_align(data, res, size, align);
556                 }
557
558                 /*
559                  * If we're above the area which was passed in, there's
560                  * no point proceeding.
561                  */
562                 if (res->start >= res->end)
563                         break;
564
565                 if ((res->start + size - 1) <= end)
566                         break;
567         }
568
569         /*
570          * If we failed to find something suitable, ensure we fail.
571          */
572         if (m == data->map)
573                 res->start = res->end;
574 }
575
576 /*
577  * Adjust an existing IO region allocation, but making sure that we don't
578  * encroach outside the resources which the user supplied.
579  */
580 static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start,
581                                       unsigned long r_end, struct pcmcia_socket *s)
582 {
583         struct resource_map *m;
584         struct socket_data *s_data = s->resource_data;
585         int ret = -ENOMEM;
586
587         mutex_lock(&rsrc_mutex);
588         for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
589                 unsigned long start = m->base;
590                 unsigned long end = m->base + m->num - 1;
591
592                 if (start > r_start || r_end > end)
593                         continue;
594
595                 ret = adjust_resource(res, r_start, r_end - r_start + 1);
596                 break;
597         }
598         mutex_unlock(&rsrc_mutex);
599
600         return ret;
601 }
602
603 /*======================================================================
604
605     These find ranges of I/O ports or memory addresses that are not
606     currently allocated by other devices.
607
608     The 'align' field should reflect the number of bits of address
609     that need to be preserved from the initial value of *base.  It
610     should be a power of two, greater than or equal to 'num'.  A value
611     of 0 means that all bits of *base are significant.  *base should
612     also be strictly less than 'align'.
613
614 ======================================================================*/
615
616 static struct resource *nonstatic_find_io_region(unsigned long base, int num,
617                    unsigned long align, struct pcmcia_socket *s)
618 {
619         struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id);
620         struct socket_data *s_data = s->resource_data;
621         struct pcmcia_align_data data;
622         unsigned long min = base;
623         int ret;
624
625         if (align == 0)
626                 align = 0x10000;
627
628         data.mask = align - 1;
629         data.offset = base & data.mask;
630         data.map = &s_data->io_db;
631
632         mutex_lock(&rsrc_mutex);
633 #ifdef CONFIG_PCI
634         if (s->cb_dev) {
635                 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
636                                              min, 0, pcmcia_align, &data);
637         } else
638 #endif
639                 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
640                                         1, pcmcia_align, &data);
641         mutex_unlock(&rsrc_mutex);
642
643         if (ret != 0) {
644                 kfree(res);
645                 res = NULL;
646         }
647         return res;
648 }
649
650 static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
651                 u_long align, int low, struct pcmcia_socket *s)
652 {
653         struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id);
654         struct socket_data *s_data = s->resource_data;
655         struct pcmcia_align_data data;
656         unsigned long min, max;
657         int ret, i;
658
659         low = low || !(s->features & SS_CAP_PAGE_REGS);
660
661         data.mask = align - 1;
662         data.offset = base & data.mask;
663         data.map = &s_data->mem_db;
664
665         for (i = 0; i < 2; i++) {
666                 if (low) {
667                         max = 0x100000UL;
668                         min = base < max ? base : 0;
669                 } else {
670                         max = ~0UL;
671                         min = 0x100000UL + base;
672                 }
673
674                 mutex_lock(&rsrc_mutex);
675 #ifdef CONFIG_PCI
676                 if (s->cb_dev) {
677                         ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
678                                                      1, min, 0,
679                                                      pcmcia_align, &data);
680                 } else
681 #endif
682                         ret = allocate_resource(&iomem_resource, res, num, min,
683                                                 max, 1, pcmcia_align, &data);
684                 mutex_unlock(&rsrc_mutex);
685                 if (ret == 0 || low)
686                         break;
687                 low = 1;
688         }
689
690         if (ret != 0) {
691                 kfree(res);
692                 res = NULL;
693         }
694         return res;
695 }
696
697
698 static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
699 {
700         struct socket_data *data = s->resource_data;
701         unsigned long size = end - start + 1;
702         int ret = 0;
703
704         if (end < start)
705                 return -EINVAL;
706
707         mutex_lock(&rsrc_mutex);
708         switch (action) {
709         case ADD_MANAGED_RESOURCE:
710                 ret = add_interval(&data->mem_db, start, size);
711                 break;
712         case REMOVE_MANAGED_RESOURCE:
713                 ret = sub_interval(&data->mem_db, start, size);
714                 if (!ret) {
715                         struct pcmcia_socket *socket;
716                         down_read(&pcmcia_socket_list_rwsem);
717                         list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
718                                 release_cis_mem(socket);
719                         up_read(&pcmcia_socket_list_rwsem);
720                 }
721                 break;
722         default:
723                 ret = -EINVAL;
724         }
725         mutex_unlock(&rsrc_mutex);
726
727         return ret;
728 }
729
730
731 static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
732 {
733         struct socket_data *data = s->resource_data;
734         unsigned long size = end - start + 1;
735         int ret = 0;
736
737         if (end < start)
738                 return -EINVAL;
739
740         if (end > IO_SPACE_LIMIT)
741                 return -EINVAL;
742
743         mutex_lock(&rsrc_mutex);
744         switch (action) {
745         case ADD_MANAGED_RESOURCE:
746                 if (add_interval(&data->io_db, start, size) != 0) {
747                         ret = -EBUSY;
748                         break;
749                 }
750 #ifdef CONFIG_PCMCIA_PROBE
751                 if (probe_io)
752                         do_io_probe(s, start, size);
753 #endif
754                 break;
755         case REMOVE_MANAGED_RESOURCE:
756                 sub_interval(&data->io_db, start, size);
757                 break;
758         default:
759                 ret = -EINVAL;
760                 break;
761         }
762         mutex_unlock(&rsrc_mutex);
763
764         return ret;
765 }
766
767
768 static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj)
769 {
770         unsigned long end;
771
772         switch (adj->Resource) {
773         case RES_MEMORY_RANGE:
774                 end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
775                 return adjust_memory(s, adj->Action, adj->resource.memory.Base, end);
776         case RES_IO_RANGE:
777                 end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
778                 return adjust_io(s, adj->Action, adj->resource.io.BasePort, end);
779         }
780         return CS_UNSUPPORTED_FUNCTION;
781 }
782
783 #ifdef CONFIG_PCI
784 static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
785 {
786         struct resource *res;
787         int i, done = 0;
788
789         if (!s->cb_dev || !s->cb_dev->bus)
790                 return -ENODEV;
791
792 #if defined(CONFIG_X86)
793         /* If this is the root bus, the risk of hitting
794          * some strange system devices which aren't protected
795          * by either ACPI resource tables or properly requested
796          * resources is too big. Therefore, don't do auto-adding
797          * of resources at the moment.
798          */
799         if (s->cb_dev->bus->number == 0)
800                 return -EINVAL;
801 #endif
802
803         for (i=0; i < PCI_BUS_NUM_RESOURCES; i++) {
804                 res = s->cb_dev->bus->resource[i];
805                 if (!res)
806                         continue;
807
808                 if (res->flags & IORESOURCE_IO) {
809                         if (res == &ioport_resource)
810                                 continue;
811                         printk(KERN_INFO "pcmcia: parent PCI bridge I/O window: 0x%lx - 0x%lx\n",
812                                res->start, res->end);
813                         if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
814                                 done |= IORESOURCE_IO;
815
816                 }
817
818                 if (res->flags & IORESOURCE_MEM) {
819                         if (res == &iomem_resource)
820                                 continue;
821                         printk(KERN_INFO "pcmcia: parent PCI bridge Memory window: 0x%lx - 0x%lx\n",
822                                res->start, res->end);
823                         if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
824                                 done |= IORESOURCE_MEM;
825                 }
826         }
827
828         /* if we got at least one of IO, and one of MEM, we can be glad and
829          * activate the PCMCIA subsystem */
830         if (done == (IORESOURCE_MEM | IORESOURCE_IO))
831                 s->resource_setup_done = 1;
832
833         return 0;
834 }
835
836 #else
837
838 static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
839 {
840         return -ENODEV;
841 }
842
843 #endif
844
845
846 static int nonstatic_init(struct pcmcia_socket *s)
847 {
848         struct socket_data *data;
849
850         data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
851         if (!data)
852                 return -ENOMEM;
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         mutex_lock(&rsrc_mutex);
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         mutex_unlock(&rsrc_mutex);
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         mutex_lock(&rsrc_mutex);
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         mutex_unlock(&rsrc_mutex);
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         mutex_lock(&rsrc_mutex);
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         mutex_unlock(&rsrc_mutex);
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);