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