enic: Add wrapper routines for new fw devcmds for port profile handling
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / pcmcia / rsrc_nonstatic.c
blobb187555d4388d394345f06997ffaa39361ed1de3
1 /*
2 * rsrc_nonstatic.c -- Resource management routines for !SS_CAP_STATIC_MAP sockets
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.
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.
12 * (C) 1999 David A. Hinds
15 #include <linux/module.h>
16 #include <linux/moduleparam.h>
17 #include <linux/init.h>
18 #include <linux/interrupt.h>
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/types.h>
22 #include <linux/slab.h>
23 #include <linux/ioport.h>
24 #include <linux/timer.h>
25 #include <linux/pci.h>
26 #include <linux/device.h>
27 #include <linux/io.h>
29 #include <asm/irq.h>
31 #include <pcmcia/ss.h>
32 #include <pcmcia/cistpl.h>
33 #include "cs_internal.h"
35 /* moved to rsrc_mgr.c
36 MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
37 MODULE_LICENSE("GPL");
40 /* Parameters that can be set with 'insmod' */
42 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
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
50 /* for io_db and mem_db */
51 struct resource_map {
52 u_long base, num;
53 struct resource_map *next;
56 struct socket_data {
57 struct resource_map mem_db;
58 struct resource_map mem_db_valid;
59 struct resource_map io_db;
62 #define MEM_PROBE_LOW (1 << 0)
63 #define MEM_PROBE_HIGH (1 << 1)
65 /* Action field */
66 #define REMOVE_MANAGED_RESOURCE 1
67 #define ADD_MANAGED_RESOURCE 2
69 /*======================================================================
71 Linux resource management extensions
73 ======================================================================*/
75 static struct resource *
76 claim_region(struct pcmcia_socket *s, resource_size_t base,
77 resource_size_t size, int type, char *name)
79 struct resource *res, *parent;
81 parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
82 res = pcmcia_make_resource(base, size, type | IORESOURCE_BUSY, name);
84 if (res) {
85 #ifdef CONFIG_PCI
86 if (s && s->cb_dev)
87 parent = pci_find_parent_resource(s->cb_dev, res);
88 #endif
89 if (!parent || request_resource(parent, res)) {
90 kfree(res);
91 res = NULL;
94 return res;
97 static void free_region(struct resource *res)
99 if (res) {
100 release_resource(res);
101 kfree(res);
105 /*======================================================================
107 These manage the internal databases of available resources.
109 ======================================================================*/
111 static int add_interval(struct resource_map *map, u_long base, u_long num)
113 struct resource_map *p, *q;
115 for (p = map; ; p = p->next) {
116 if ((p != map) && (p->base+p->num >= base)) {
117 p->num = max(num + base - p->base, p->num);
118 return 0;
120 if ((p->next == map) || (p->next->base > base+num-1))
121 break;
123 q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
124 if (!q) {
125 printk(KERN_WARNING "out of memory to update resources\n");
126 return -ENOMEM;
128 q->base = base; q->num = num;
129 q->next = p->next; p->next = q;
130 return 0;
133 /*====================================================================*/
135 static int sub_interval(struct resource_map *map, u_long base, u_long num)
137 struct resource_map *p, *q;
139 for (p = map; ; p = q) {
140 q = p->next;
141 if (q == map)
142 break;
143 if ((q->base+q->num > base) && (base+num > q->base)) {
144 if (q->base >= base) {
145 if (q->base+q->num <= base+num) {
146 /* Delete whole block */
147 p->next = q->next;
148 kfree(q);
149 /* don't advance the pointer yet */
150 q = p;
151 } else {
152 /* Cut off bit from the front */
153 q->num = q->base + q->num - base - num;
154 q->base = base + num;
156 } else if (q->base+q->num <= base+num) {
157 /* Cut off bit from the end */
158 q->num = base - q->base;
159 } else {
160 /* Split the block into two pieces */
161 p = kmalloc(sizeof(struct resource_map),
162 GFP_KERNEL);
163 if (!p) {
164 printk(KERN_WARNING "out of memory to update resources\n");
165 return -ENOMEM;
167 p->base = base+num;
168 p->num = q->base+q->num - p->base;
169 q->num = base - q->base;
170 p->next = q->next ; q->next = p;
174 return 0;
177 /*======================================================================
179 These routines examine a region of IO or memory addresses to
180 determine what ranges might be genuinely available.
182 ======================================================================*/
184 #ifdef CONFIG_PCMCIA_PROBE
185 static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
186 unsigned int num)
188 struct resource *res;
189 struct socket_data *s_data = s->resource_data;
190 unsigned int i, j, bad;
191 int any;
192 u_char *b, hole, most;
194 dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:",
195 base, base+num-1);
197 /* First, what does a floating port look like? */
198 b = kzalloc(256, GFP_KERNEL);
199 if (!b) {
200 printk("\n");
201 dev_printk(KERN_ERR, &s->dev,
202 "do_io_probe: unable to kmalloc 256 bytes");
203 return;
205 for (i = base, most = 0; i < base+num; i += 8) {
206 res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
207 if (!res)
208 continue;
209 hole = inb(i);
210 for (j = 1; j < 8; j++)
211 if (inb(i+j) != hole)
212 break;
213 free_region(res);
214 if ((j == 8) && (++b[hole] > b[most]))
215 most = hole;
216 if (b[most] == 127)
217 break;
219 kfree(b);
221 bad = any = 0;
222 for (i = base; i < base+num; i += 8) {
223 res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
224 if (!res) {
225 if (!any)
226 printk(" excluding");
227 if (!bad)
228 bad = any = i;
229 continue;
231 for (j = 0; j < 8; j++)
232 if (inb(i+j) != most)
233 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;
248 if (bad) {
249 if ((num > 16) && (bad == base) && (i == base+num)) {
250 sub_interval(&s_data->io_db, bad, i-bad);
251 printk(" nothing: probe failed.\n");
252 return;
253 } else {
254 sub_interval(&s_data->io_db, bad, i-bad);
255 printk(" %#x-%#x", bad, i-1);
259 printk(any ? "\n" : " clean.\n");
261 #endif
263 /*======================================================================*/
266 * readable() - iomem validation function for cards with a valid CIS
268 static int readable(struct pcmcia_socket *s, struct resource *res,
269 unsigned int *count)
271 int ret = -EINVAL;
273 if (s->fake_cis) {
274 dev_dbg(&s->dev, "fake CIS is being used: can't validate mem\n");
275 return 0;
278 s->cis_mem.res = res;
279 s->cis_virt = ioremap(res->start, s->map_size);
280 if (s->cis_virt) {
281 mutex_unlock(&s->ops_mutex);
282 /* as we're only called from pcmcia.c, we're safe */
283 if (s->callback->validate)
284 ret = s->callback->validate(s, count);
285 /* invalidate mapping */
286 mutex_lock(&s->ops_mutex);
287 iounmap(s->cis_virt);
288 s->cis_virt = NULL;
290 s->cis_mem.res = NULL;
291 if ((ret) || (*count == 0))
292 return -EINVAL;
293 return 0;
297 * checksum() - iomem validation function for simple memory cards
299 static int checksum(struct pcmcia_socket *s, struct resource *res,
300 unsigned int *value)
302 pccard_mem_map map;
303 int i, a = 0, b = -1, d;
304 void __iomem *virt;
306 virt = ioremap(res->start, s->map_size);
307 if (virt) {
308 map.map = 0;
309 map.flags = MAP_ACTIVE;
310 map.speed = 0;
311 map.res = res;
312 map.card_start = 0;
313 s->ops->set_mem_map(s, &map);
315 /* Don't bother checking every word... */
316 for (i = 0; i < s->map_size; i += 44) {
317 d = readl(virt+i);
318 a += d;
319 b &= d;
322 map.flags = 0;
323 s->ops->set_mem_map(s, &map);
325 iounmap(virt);
328 if (b == -1)
329 return -EINVAL;
331 *value = a;
333 return 0;
337 * do_validate_mem() - low level validate a memory region for PCMCIA use
338 * @s: PCMCIA socket to validate
339 * @base: start address of resource to check
340 * @size: size of resource to check
341 * @validate: validation function to use
343 * do_validate_mem() splits up the memory region which is to be checked
344 * into two parts. Both are passed to the @validate() function. If
345 * @validate() returns non-zero, or the value parameter to @validate()
346 * is zero, or the value parameter is different between both calls,
347 * the check fails, and -EINVAL is returned. Else, 0 is returned.
349 static int do_validate_mem(struct pcmcia_socket *s,
350 unsigned long base, unsigned long size,
351 int validate (struct pcmcia_socket *s,
352 struct resource *res,
353 unsigned int *value))
355 struct socket_data *s_data = s->resource_data;
356 struct resource *res1, *res2;
357 unsigned int info1 = 1, info2 = 1;
358 int ret = -EINVAL;
360 res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
361 res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
362 "PCMCIA memprobe");
364 if (res1 && res2) {
365 ret = 0;
366 if (validate) {
367 ret = validate(s, res1, &info1);
368 ret += validate(s, res2, &info2);
372 free_region(res2);
373 free_region(res1);
375 dev_dbg(&s->dev, "cs: memory probe 0x%06lx-0x%06lx: %p %p %u %u %u",
376 base, base+size-1, res1, res2, ret, info1, info2);
378 if ((ret) || (info1 != info2) || (info1 == 0))
379 return -EINVAL;
381 if (validate && !s->fake_cis) {
382 /* move it to the validated data set */
383 add_interval(&s_data->mem_db_valid, base, size);
384 sub_interval(&s_data->mem_db, base, size);
387 return 0;
392 * do_mem_probe() - validate a memory region for PCMCIA use
393 * @s: PCMCIA socket to validate
394 * @base: start address of resource to check
395 * @num: size of resource to check
396 * @validate: validation function to use
397 * @fallback: validation function to use if validate fails
399 * do_mem_probe() checks a memory region for use by the PCMCIA subsystem.
400 * To do so, the area is split up into sensible parts, and then passed
401 * into the @validate() function. Only if @validate() and @fallback() fail,
402 * the area is marked as unavaibale for use by the PCMCIA subsystem. The
403 * function returns the size of the usable memory area.
405 static int do_mem_probe(struct pcmcia_socket *s, u_long base, u_long num,
406 int validate (struct pcmcia_socket *s,
407 struct resource *res,
408 unsigned int *value),
409 int fallback (struct pcmcia_socket *s,
410 struct resource *res,
411 unsigned int *value))
413 struct socket_data *s_data = s->resource_data;
414 u_long i, j, bad, fail, step;
416 dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
417 base, base+num-1);
418 bad = fail = 0;
419 step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
420 /* don't allow too large steps */
421 if (step > 0x800000)
422 step = 0x800000;
423 /* cis_readable wants to map 2x map_size */
424 if (step < 2 * s->map_size)
425 step = 2 * s->map_size;
426 for (i = j = base; i < base+num; i = j + step) {
427 if (!fail) {
428 for (j = i; j < base+num; j += step) {
429 if (!do_validate_mem(s, j, step, validate))
430 break;
432 fail = ((i == base) && (j == base+num));
434 if ((fail) && (fallback)) {
435 for (j = i; j < base+num; j += step)
436 if (!do_validate_mem(s, j, step, fallback))
437 break;
439 if (i != j) {
440 if (!bad)
441 printk(" excluding");
442 printk(" %#05lx-%#05lx", i, j-1);
443 sub_interval(&s_data->mem_db, i, j-i);
444 bad += j-i;
447 printk(bad ? "\n" : " clean.\n");
448 return num - bad;
452 #ifdef CONFIG_PCMCIA_PROBE
455 * inv_probe() - top-to-bottom search for one usuable high memory area
456 * @s: PCMCIA socket to validate
457 * @m: resource_map to check
459 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
461 struct socket_data *s_data = s->resource_data;
462 u_long ok;
463 if (m == &s_data->mem_db)
464 return 0;
465 ok = inv_probe(m->next, s);
466 if (ok) {
467 if (m->base >= 0x100000)
468 sub_interval(&s_data->mem_db, m->base, m->num);
469 return ok;
471 if (m->base < 0x100000)
472 return 0;
473 return do_mem_probe(s, m->base, m->num, readable, checksum);
477 * validate_mem() - memory probe function
478 * @s: PCMCIA socket to validate
479 * @probe_mask: MEM_PROBE_LOW | MEM_PROBE_HIGH
481 * The memory probe. If the memory list includes a 64K-aligned block
482 * below 1MB, we probe in 64K chunks, and as soon as we accumulate at
483 * least mem_limit free space, we quit. Returns 0 on usuable ports.
485 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
487 struct resource_map *m, mm;
488 static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
489 unsigned long b, i, ok = 0;
490 struct socket_data *s_data = s->resource_data;
492 /* We do up to four passes through the list */
493 if (probe_mask & MEM_PROBE_HIGH) {
494 if (inv_probe(s_data->mem_db.next, s) > 0)
495 return 0;
496 if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
497 return 0;
498 dev_printk(KERN_NOTICE, &s->dev,
499 "cs: warning: no high memory space available!\n");
500 return -ENODEV;
503 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
504 mm = *m;
505 /* Only probe < 1 MB */
506 if (mm.base >= 0x100000)
507 continue;
508 if ((mm.base | mm.num) & 0xffff) {
509 ok += do_mem_probe(s, mm.base, mm.num, readable,
510 checksum);
511 continue;
513 /* Special probe for 64K-aligned block */
514 for (i = 0; i < 4; i++) {
515 b = order[i] << 12;
516 if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
517 if (ok >= mem_limit)
518 sub_interval(&s_data->mem_db, b, 0x10000);
519 else
520 ok += do_mem_probe(s, b, 0x10000,
521 readable, checksum);
526 if (ok > 0)
527 return 0;
529 return -ENODEV;
532 #else /* CONFIG_PCMCIA_PROBE */
535 * validate_mem() - memory probe function
536 * @s: PCMCIA socket to validate
537 * @probe_mask: ignored
539 * Returns 0 on usuable ports.
541 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
543 struct resource_map *m, mm;
544 struct socket_data *s_data = s->resource_data;
545 unsigned long ok = 0;
547 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
548 mm = *m;
549 ok += do_mem_probe(s, mm.base, mm.num, readable, checksum);
551 if (ok > 0)
552 return 0;
553 return -ENODEV;
556 #endif /* CONFIG_PCMCIA_PROBE */
560 * pcmcia_nonstatic_validate_mem() - try to validate iomem for PCMCIA use
561 * @s: PCMCIA socket to validate
563 * This is tricky... when we set up CIS memory, we try to validate
564 * the memory window space allocations.
566 * Locking note: Must be called with skt_mutex held!
568 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
570 struct socket_data *s_data = s->resource_data;
571 unsigned int probe_mask = MEM_PROBE_LOW;
572 int ret;
574 if (!probe_mem || !(s->state & SOCKET_PRESENT))
575 return 0;
577 if (s->features & SS_CAP_PAGE_REGS)
578 probe_mask = MEM_PROBE_HIGH;
580 ret = validate_mem(s, probe_mask);
582 if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
583 return 0;
585 return ret;
588 struct pcmcia_align_data {
589 unsigned long mask;
590 unsigned long offset;
591 struct resource_map *map;
594 static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data,
595 resource_size_t start)
597 resource_size_t ret;
599 * Ensure that we have the correct start address
601 ret = (start & ~align_data->mask) + align_data->offset;
602 if (ret < start)
603 ret += align_data->mask + 1;
604 return ret;
607 static resource_size_t
608 pcmcia_align(void *align_data, const struct resource *res,
609 resource_size_t size, resource_size_t align)
611 struct pcmcia_align_data *data = align_data;
612 struct resource_map *m;
613 resource_size_t start;
615 start = pcmcia_common_align(data, res->start);
617 for (m = data->map->next; m != data->map; m = m->next) {
618 unsigned long map_start = m->base;
619 unsigned long map_end = m->base + m->num - 1;
622 * If the lower resources are not available, try aligning
623 * to this entry of the resource database to see if it'll
624 * fit here.
626 if (start < map_start)
627 start = pcmcia_common_align(data, map_start);
630 * If we're above the area which was passed in, there's
631 * no point proceeding.
633 if (start >= res->end)
634 break;
636 if ((start + size - 1) <= map_end)
637 break;
641 * If we failed to find something suitable, ensure we fail.
643 if (m == data->map)
644 start = res->end;
646 return start;
650 * Adjust an existing IO region allocation, but making sure that we don't
651 * encroach outside the resources which the user supplied.
653 static int __nonstatic_adjust_io_region(struct pcmcia_socket *s,
654 unsigned long r_start,
655 unsigned long r_end)
657 struct resource_map *m;
658 struct socket_data *s_data = s->resource_data;
659 int ret = -ENOMEM;
661 for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
662 unsigned long start = m->base;
663 unsigned long end = m->base + m->num - 1;
665 if (start > r_start || r_end > end)
666 continue;
668 ret = 0;
671 return ret;
674 /*======================================================================
676 These find ranges of I/O ports or memory addresses that are not
677 currently allocated by other devices.
679 The 'align' field should reflect the number of bits of address
680 that need to be preserved from the initial value of *base. It
681 should be a power of two, greater than or equal to 'num'. A value
682 of 0 means that all bits of *base are significant. *base should
683 also be strictly less than 'align'.
685 ======================================================================*/
687 static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s,
688 unsigned long base, int num,
689 unsigned long align)
691 struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO,
692 dev_name(&s->dev));
693 struct socket_data *s_data = s->resource_data;
694 struct pcmcia_align_data data;
695 unsigned long min = base;
696 int ret;
698 data.mask = align - 1;
699 data.offset = base & data.mask;
700 data.map = &s_data->io_db;
702 #ifdef CONFIG_PCI
703 if (s->cb_dev) {
704 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
705 min, 0, pcmcia_align, &data);
706 } else
707 #endif
708 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
709 1, pcmcia_align, &data);
711 if (ret != 0) {
712 kfree(res);
713 res = NULL;
715 return res;
718 static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
719 unsigned int *base, unsigned int num,
720 unsigned int align, struct resource **parent)
722 int i, ret = 0;
724 /* Check for an already-allocated window that must conflict with
725 * what was asked for. It is a hack because it does not catch all
726 * potential conflicts, just the most obvious ones.
728 for (i = 0; i < MAX_IO_WIN; i++) {
729 if (!s->io[i].res)
730 continue;
732 if (!*base)
733 continue;
735 if ((s->io[i].res->start & (align-1)) == *base)
736 return -EBUSY;
739 for (i = 0; i < MAX_IO_WIN; i++) {
740 struct resource *res = s->io[i].res;
741 unsigned int try;
743 if (res && (res->flags & IORESOURCE_BITS) !=
744 (attr & IORESOURCE_BITS))
745 continue;
747 if (!res) {
748 if (align == 0)
749 align = 0x10000;
751 res = s->io[i].res = __nonstatic_find_io_region(s,
752 *base, num,
753 align);
754 if (!res)
755 return -EINVAL;
757 *base = res->start;
758 s->io[i].res->flags =
759 ((res->flags & ~IORESOURCE_BITS) |
760 (attr & IORESOURCE_BITS));
761 s->io[i].InUse = num;
762 *parent = res;
763 return 0;
766 /* Try to extend top of window */
767 try = res->end + 1;
768 if ((*base == 0) || (*base == try)) {
769 ret = __nonstatic_adjust_io_region(s, res->start,
770 res->end + num);
771 if (!ret) {
772 ret = adjust_resource(s->io[i].res, res->start,
773 res->end - res->start + num + 1);
774 if (ret)
775 continue;
776 *base = try;
777 s->io[i].InUse += num;
778 *parent = res;
779 return 0;
783 /* Try to extend bottom of window */
784 try = res->start - num;
785 if ((*base == 0) || (*base == try)) {
786 ret = __nonstatic_adjust_io_region(s,
787 res->start - num,
788 res->end);
789 if (!ret) {
790 ret = adjust_resource(s->io[i].res,
791 res->start - num,
792 res->end - res->start + num + 1);
793 if (ret)
794 continue;
795 *base = try;
796 s->io[i].InUse += num;
797 *parent = res;
798 return 0;
803 return -EINVAL;
807 static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
808 u_long align, int low, struct pcmcia_socket *s)
810 struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM,
811 dev_name(&s->dev));
812 struct socket_data *s_data = s->resource_data;
813 struct pcmcia_align_data data;
814 unsigned long min, max;
815 int ret, i, j;
817 low = low || !(s->features & SS_CAP_PAGE_REGS);
819 data.mask = align - 1;
820 data.offset = base & data.mask;
822 for (i = 0; i < 2; i++) {
823 data.map = &s_data->mem_db_valid;
824 if (low) {
825 max = 0x100000UL;
826 min = base < max ? base : 0;
827 } else {
828 max = ~0UL;
829 min = 0x100000UL + base;
832 for (j = 0; j < 2; j++) {
833 #ifdef CONFIG_PCI
834 if (s->cb_dev) {
835 ret = pci_bus_alloc_resource(s->cb_dev->bus,
836 res, num, 1, min, 0,
837 pcmcia_align, &data);
838 } else
839 #endif
841 ret = allocate_resource(&iomem_resource,
842 res, num, min, max, 1,
843 pcmcia_align, &data);
845 if (ret == 0)
846 break;
847 data.map = &s_data->mem_db;
849 if (ret == 0 || low)
850 break;
851 low = 1;
854 if (ret != 0) {
855 kfree(res);
856 res = NULL;
858 return res;
862 static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
864 struct socket_data *data = s->resource_data;
865 unsigned long size = end - start + 1;
866 int ret = 0;
868 if (end < start)
869 return -EINVAL;
871 switch (action) {
872 case ADD_MANAGED_RESOURCE:
873 ret = add_interval(&data->mem_db, start, size);
874 if (!ret)
875 do_mem_probe(s, start, size, NULL, NULL);
876 break;
877 case REMOVE_MANAGED_RESOURCE:
878 ret = sub_interval(&data->mem_db, start, size);
879 break;
880 default:
881 ret = -EINVAL;
884 return ret;
888 static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
890 struct socket_data *data = s->resource_data;
891 unsigned long size;
892 int ret = 0;
894 #if defined(CONFIG_X86)
895 /* on x86, avoid anything < 0x100 for it is often used for
896 * legacy platform devices */
897 if (start < 0x100)
898 start = 0x100;
899 #endif
901 size = end - start + 1;
903 if (end < start)
904 return -EINVAL;
906 if (end > IO_SPACE_LIMIT)
907 return -EINVAL;
909 switch (action) {
910 case ADD_MANAGED_RESOURCE:
911 if (add_interval(&data->io_db, start, size) != 0) {
912 ret = -EBUSY;
913 break;
915 #ifdef CONFIG_PCMCIA_PROBE
916 if (probe_io)
917 do_io_probe(s, start, size);
918 #endif
919 break;
920 case REMOVE_MANAGED_RESOURCE:
921 sub_interval(&data->io_db, start, size);
922 break;
923 default:
924 ret = -EINVAL;
925 break;
928 return ret;
932 #ifdef CONFIG_PCI
933 static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
935 struct resource *res;
936 int i, done = 0;
938 if (!s->cb_dev || !s->cb_dev->bus)
939 return -ENODEV;
941 #if defined(CONFIG_X86)
942 /* If this is the root bus, the risk of hitting some strange
943 * system devices is too high: If a driver isn't loaded, the
944 * resources are not claimed; even if a driver is loaded, it
945 * may not request all resources or even the wrong one. We
946 * can neither trust the rest of the kernel nor ACPI/PNP and
947 * CRS parsing to get it right. Therefore, use several
948 * safeguards:
950 * - Do not auto-add resources if the CardBus bridge is on
951 * the PCI root bus
953 * - Avoid any I/O ports < 0x100.
955 * - On PCI-PCI bridges, only use resources which are set up
956 * exclusively for the secondary PCI bus: the risk of hitting
957 * system devices is quite low, as they usually aren't
958 * connected to the secondary PCI bus.
960 if (s->cb_dev->bus->number == 0)
961 return -EINVAL;
963 for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
964 res = s->cb_dev->bus->resource[i];
965 #else
966 pci_bus_for_each_resource(s->cb_dev->bus, res, i) {
967 #endif
968 if (!res)
969 continue;
971 if (res->flags & IORESOURCE_IO) {
972 /* safeguard against the root resource, where the
973 * risk of hitting any other device would be too
974 * high */
975 if (res == &ioport_resource)
976 continue;
978 dev_printk(KERN_INFO, &s->cb_dev->dev,
979 "pcmcia: parent PCI bridge window: %pR\n",
980 res);
981 if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
982 done |= IORESOURCE_IO;
986 if (res->flags & IORESOURCE_MEM) {
987 /* safeguard against the root resource, where the
988 * risk of hitting any other device would be too
989 * high */
990 if (res == &iomem_resource)
991 continue;
993 dev_printk(KERN_INFO, &s->cb_dev->dev,
994 "pcmcia: parent PCI bridge window: %pR\n",
995 res);
996 if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
997 done |= IORESOURCE_MEM;
1001 /* if we got at least one of IO, and one of MEM, we can be glad and
1002 * activate the PCMCIA subsystem */
1003 if (done == (IORESOURCE_MEM | IORESOURCE_IO))
1004 s->resource_setup_done = 1;
1006 return 0;
1009 #else
1011 static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
1013 return -ENODEV;
1016 #endif
1019 static int nonstatic_init(struct pcmcia_socket *s)
1021 struct socket_data *data;
1023 data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
1024 if (!data)
1025 return -ENOMEM;
1027 data->mem_db.next = &data->mem_db;
1028 data->mem_db_valid.next = &data->mem_db_valid;
1029 data->io_db.next = &data->io_db;
1031 s->resource_data = (void *) data;
1033 nonstatic_autoadd_resources(s);
1035 return 0;
1038 static void nonstatic_release_resource_db(struct pcmcia_socket *s)
1040 struct socket_data *data = s->resource_data;
1041 struct resource_map *p, *q;
1043 for (p = data->mem_db_valid.next; p != &data->mem_db_valid; p = q) {
1044 q = p->next;
1045 kfree(p);
1047 for (p = data->mem_db.next; p != &data->mem_db; p = q) {
1048 q = p->next;
1049 kfree(p);
1051 for (p = data->io_db.next; p != &data->io_db; p = q) {
1052 q = p->next;
1053 kfree(p);
1058 struct pccard_resource_ops pccard_nonstatic_ops = {
1059 .validate_mem = pcmcia_nonstatic_validate_mem,
1060 .find_io = nonstatic_find_io,
1061 .find_mem = nonstatic_find_mem_region,
1062 .init = nonstatic_init,
1063 .exit = nonstatic_release_resource_db,
1065 EXPORT_SYMBOL(pccard_nonstatic_ops);
1068 /* sysfs interface to the resource database */
1070 static ssize_t show_io_db(struct device *dev,
1071 struct device_attribute *attr, char *buf)
1073 struct pcmcia_socket *s = dev_get_drvdata(dev);
1074 struct socket_data *data;
1075 struct resource_map *p;
1076 ssize_t ret = 0;
1078 mutex_lock(&s->ops_mutex);
1079 data = s->resource_data;
1081 for (p = data->io_db.next; p != &data->io_db; p = p->next) {
1082 if (ret > (PAGE_SIZE - 10))
1083 continue;
1084 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1085 "0x%08lx - 0x%08lx\n",
1086 ((unsigned long) p->base),
1087 ((unsigned long) p->base + p->num - 1));
1090 mutex_unlock(&s->ops_mutex);
1091 return ret;
1094 static ssize_t store_io_db(struct device *dev,
1095 struct device_attribute *attr,
1096 const char *buf, size_t count)
1098 struct pcmcia_socket *s = dev_get_drvdata(dev);
1099 unsigned long start_addr, end_addr;
1100 unsigned int add = ADD_MANAGED_RESOURCE;
1101 ssize_t ret = 0;
1103 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1104 if (ret != 2) {
1105 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1106 add = REMOVE_MANAGED_RESOURCE;
1107 if (ret != 2) {
1108 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1109 &end_addr);
1110 add = ADD_MANAGED_RESOURCE;
1111 if (ret != 2)
1112 return -EINVAL;
1115 if (end_addr < start_addr)
1116 return -EINVAL;
1118 mutex_lock(&s->ops_mutex);
1119 ret = adjust_io(s, add, start_addr, end_addr);
1120 mutex_unlock(&s->ops_mutex);
1122 return ret ? ret : count;
1124 static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
1126 static ssize_t show_mem_db(struct device *dev,
1127 struct device_attribute *attr, char *buf)
1129 struct pcmcia_socket *s = dev_get_drvdata(dev);
1130 struct socket_data *data;
1131 struct resource_map *p;
1132 ssize_t ret = 0;
1134 mutex_lock(&s->ops_mutex);
1135 data = s->resource_data;
1137 for (p = data->mem_db_valid.next; p != &data->mem_db_valid;
1138 p = p->next) {
1139 if (ret > (PAGE_SIZE - 10))
1140 continue;
1141 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1142 "0x%08lx - 0x%08lx\n",
1143 ((unsigned long) p->base),
1144 ((unsigned long) p->base + p->num - 1));
1147 for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
1148 if (ret > (PAGE_SIZE - 10))
1149 continue;
1150 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1151 "0x%08lx - 0x%08lx\n",
1152 ((unsigned long) p->base),
1153 ((unsigned long) p->base + p->num - 1));
1156 mutex_unlock(&s->ops_mutex);
1157 return ret;
1160 static ssize_t store_mem_db(struct device *dev,
1161 struct device_attribute *attr,
1162 const char *buf, size_t count)
1164 struct pcmcia_socket *s = dev_get_drvdata(dev);
1165 unsigned long start_addr, end_addr;
1166 unsigned int add = ADD_MANAGED_RESOURCE;
1167 ssize_t ret = 0;
1169 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1170 if (ret != 2) {
1171 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1172 add = REMOVE_MANAGED_RESOURCE;
1173 if (ret != 2) {
1174 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1175 &end_addr);
1176 add = ADD_MANAGED_RESOURCE;
1177 if (ret != 2)
1178 return -EINVAL;
1181 if (end_addr < start_addr)
1182 return -EINVAL;
1184 mutex_lock(&s->ops_mutex);
1185 ret = adjust_memory(s, add, start_addr, end_addr);
1186 mutex_unlock(&s->ops_mutex);
1188 return ret ? ret : count;
1190 static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
1192 static struct attribute *pccard_rsrc_attributes[] = {
1193 &dev_attr_available_resources_io.attr,
1194 &dev_attr_available_resources_mem.attr,
1195 NULL,
1198 static const struct attribute_group rsrc_attributes = {
1199 .attrs = pccard_rsrc_attributes,
1202 static int __devinit pccard_sysfs_add_rsrc(struct device *dev,
1203 struct class_interface *class_intf)
1205 struct pcmcia_socket *s = dev_get_drvdata(dev);
1207 if (s->resource_ops != &pccard_nonstatic_ops)
1208 return 0;
1209 return sysfs_create_group(&dev->kobj, &rsrc_attributes);
1212 static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
1213 struct class_interface *class_intf)
1215 struct pcmcia_socket *s = dev_get_drvdata(dev);
1217 if (s->resource_ops != &pccard_nonstatic_ops)
1218 return;
1219 sysfs_remove_group(&dev->kobj, &rsrc_attributes);
1222 static struct class_interface pccard_rsrc_interface __refdata = {
1223 .class = &pcmcia_socket_class,
1224 .add_dev = &pccard_sysfs_add_rsrc,
1225 .remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc),
1228 static int __init nonstatic_sysfs_init(void)
1230 return class_interface_register(&pccard_rsrc_interface);
1233 static void __exit nonstatic_sysfs_exit(void)
1235 class_interface_unregister(&pccard_rsrc_interface);
1238 module_init(nonstatic_sysfs_init);
1239 module_exit(nonstatic_sysfs_exit);