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