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