Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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