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