[PATCH] pcmcia: at91_cf update
[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(resource_size_t b, resource_size_t 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, resource_size_t base,
90                 resource_size_t size, 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                         resource_size_t size, resource_size_t align)
523 {
524         struct pcmcia_align_data *data = align_data;
525         resource_size_t 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, resource_size_t size,
537                 resource_size_t 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 "
812                                 "window: 0x%llx - 0x%llx\n",
813                                 (unsigned long long)res->start,
814                                 (unsigned long long)res->end);
815                         if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
816                                 done |= IORESOURCE_IO;
817
818                 }
819
820                 if (res->flags & IORESOURCE_MEM) {
821                         if (res == &iomem_resource)
822                                 continue;
823                         printk(KERN_INFO "pcmcia: parent PCI bridge Memory "
824                                 "window: 0x%llx - 0x%llx\n",
825                                 (unsigned long long)res->start,
826                                 (unsigned long long)res->end);
827                         if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
828                                 done |= IORESOURCE_MEM;
829                 }
830         }
831
832         /* if we got at least one of IO, and one of MEM, we can be glad and
833          * activate the PCMCIA subsystem */
834         if (done == (IORESOURCE_MEM | IORESOURCE_IO))
835                 s->resource_setup_done = 1;
836
837         return 0;
838 }
839
840 #else
841
842 static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
843 {
844         return -ENODEV;
845 }
846
847 #endif
848
849
850 static int nonstatic_init(struct pcmcia_socket *s)
851 {
852         struct socket_data *data;
853
854         data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
855         if (!data)
856                 return -ENOMEM;
857
858         data->mem_db.next = &data->mem_db;
859         data->io_db.next = &data->io_db;
860
861         s->resource_data = (void *) data;
862
863         nonstatic_autoadd_resources(s);
864
865         return 0;
866 }
867
868 static void nonstatic_release_resource_db(struct pcmcia_socket *s)
869 {
870         struct socket_data *data = s->resource_data;
871         struct resource_map *p, *q;
872
873         mutex_lock(&rsrc_mutex);
874         for (p = data->mem_db.next; p != &data->mem_db; p = q) {
875                 q = p->next;
876                 kfree(p);
877         }
878         for (p = data->io_db.next; p != &data->io_db; p = q) {
879                 q = p->next;
880                 kfree(p);
881         }
882         mutex_unlock(&rsrc_mutex);
883 }
884
885
886 struct pccard_resource_ops pccard_nonstatic_ops = {
887         .validate_mem = pcmcia_nonstatic_validate_mem,
888         .adjust_io_region = nonstatic_adjust_io_region,
889         .find_io = nonstatic_find_io_region,
890         .find_mem = nonstatic_find_mem_region,
891         .adjust_resource = nonstatic_adjust_resource_info,
892         .init = nonstatic_init,
893         .exit = nonstatic_release_resource_db,
894 };
895 EXPORT_SYMBOL(pccard_nonstatic_ops);
896
897
898 /* sysfs interface to the resource database */
899
900 static ssize_t show_io_db(struct class_device *class_dev, char *buf)
901 {
902         struct pcmcia_socket *s = class_get_devdata(class_dev);
903         struct socket_data *data;
904         struct resource_map *p;
905         ssize_t ret = 0;
906
907         mutex_lock(&rsrc_mutex);
908         data = s->resource_data;
909
910         for (p = data->io_db.next; p != &data->io_db; p = p->next) {
911                 if (ret > (PAGE_SIZE - 10))
912                         continue;
913                 ret += snprintf (&buf[ret], (PAGE_SIZE - ret - 1),
914                                  "0x%08lx - 0x%08lx\n",
915                                  ((unsigned long) p->base),
916                                  ((unsigned long) p->base + p->num - 1));
917         }
918
919         mutex_unlock(&rsrc_mutex);
920         return (ret);
921 }
922
923 static ssize_t store_io_db(struct class_device *class_dev, const char *buf, size_t count)
924 {
925         struct pcmcia_socket *s = class_get_devdata(class_dev);
926         unsigned long start_addr, end_addr;
927         unsigned int add = ADD_MANAGED_RESOURCE;
928         ssize_t ret = 0;
929
930         ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
931         if (ret != 2) {
932                 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
933                 add = REMOVE_MANAGED_RESOURCE;
934                 if (ret != 2) {
935                         ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
936                         add = ADD_MANAGED_RESOURCE;
937                         if (ret != 2)
938                                 return -EINVAL;
939                 }
940         }
941         if (end_addr < start_addr)
942                 return -EINVAL;
943
944         ret = adjust_io(s, add, start_addr, end_addr);
945         if (!ret)
946                 s->resource_setup_new = 1;
947
948         return ret ? ret : count;
949 }
950 static CLASS_DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
951
952 static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
953 {
954         struct pcmcia_socket *s = class_get_devdata(class_dev);
955         struct socket_data *data;
956         struct resource_map *p;
957         ssize_t ret = 0;
958
959         mutex_lock(&rsrc_mutex);
960         data = s->resource_data;
961
962         for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
963                 if (ret > (PAGE_SIZE - 10))
964                         continue;
965                 ret += snprintf (&buf[ret], (PAGE_SIZE - ret - 1),
966                                  "0x%08lx - 0x%08lx\n",
967                                  ((unsigned long) p->base),
968                                  ((unsigned long) p->base + p->num - 1));
969         }
970
971         mutex_unlock(&rsrc_mutex);
972         return (ret);
973 }
974
975 static ssize_t store_mem_db(struct class_device *class_dev, const char *buf, size_t count)
976 {
977         struct pcmcia_socket *s = class_get_devdata(class_dev);
978         unsigned long start_addr, end_addr;
979         unsigned int add = ADD_MANAGED_RESOURCE;
980         ssize_t ret = 0;
981
982         ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
983         if (ret != 2) {
984                 ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
985                 add = REMOVE_MANAGED_RESOURCE;
986                 if (ret != 2) {
987                         ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
988                         add = ADD_MANAGED_RESOURCE;
989                         if (ret != 2)
990                                 return -EINVAL;
991                 }
992         }
993         if (end_addr < start_addr)
994                 return -EINVAL;
995
996         ret = adjust_memory(s, add, start_addr, end_addr);
997         if (!ret)
998                 s->resource_setup_new = 1;
999
1000         return ret ? ret : count;
1001 }
1002 static CLASS_DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
1003
1004 static struct class_device_attribute *pccard_rsrc_attributes[] = {
1005         &class_device_attr_available_resources_io,
1006         &class_device_attr_available_resources_mem,
1007         NULL,
1008 };
1009
1010 static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev,
1011                                            struct class_interface *class_intf)
1012 {
1013         struct pcmcia_socket *s = class_get_devdata(class_dev);
1014         struct class_device_attribute **attr;
1015         int ret = 0;
1016         if (s->resource_ops != &pccard_nonstatic_ops)
1017                 return 0;
1018
1019         for (attr = pccard_rsrc_attributes; *attr; attr++) {
1020                 ret = class_device_create_file(class_dev, *attr);
1021                 if (ret)
1022                         break;
1023         }
1024
1025         return ret;
1026 }
1027
1028 static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev,
1029                                                struct class_interface *class_intf)
1030 {
1031         struct pcmcia_socket *s = class_get_devdata(class_dev);
1032         struct class_device_attribute **attr;
1033
1034         if (s->resource_ops != &pccard_nonstatic_ops)
1035                 return;
1036
1037         for (attr = pccard_rsrc_attributes; *attr; attr++)
1038                 class_device_remove_file(class_dev, *attr);
1039 }
1040
1041 static struct class_interface pccard_rsrc_interface = {
1042         .class = &pcmcia_socket_class,
1043         .add = &pccard_sysfs_add_rsrc,
1044         .remove = __devexit_p(&pccard_sysfs_remove_rsrc),
1045 };
1046
1047 static int __init nonstatic_sysfs_init(void)
1048 {
1049         return class_interface_register(&pccard_rsrc_interface);
1050 }
1051
1052 static void __exit nonstatic_sysfs_exit(void)
1053 {
1054         class_interface_unregister(&pccard_rsrc_interface);
1055 }
1056
1057 module_init(nonstatic_sysfs_init);
1058 module_exit(nonstatic_sysfs_exit);