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