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>
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);
50 /* for io_db and mem_db */
53 struct resource_map *next;
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)
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);
87 parent = pci_find_parent_resource(s->cb_dev, res);
89 if (!parent || request_resource(parent, res)) {
97 static void free_region(struct resource *res)
100 release_resource(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);
120 if ((p->next == map) || (p->next->base > base+num-1))
123 q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
125 printk(KERN_WARNING "out of memory to update resources\n");
128 q->base = base; q->num = num;
129 q->next = p->next; p->next = q;
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) {
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 */
149 /* don't advance the pointer yet */
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;
160 /* Split the block into two pieces */
161 p = kmalloc(sizeof(struct resource_map),
164 printk(KERN_WARNING "out of memory to update resources\n");
168 p->num = q->base+q->num - p->base;
169 q->num = base - q->base;
170 p->next = q->next ; q->next = p;
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,
188 struct resource *res;
189 struct socket_data *s_data = s->resource_data;
190 unsigned int i, j, bad;
192 u_char *b, hole, most;
194 dev_info(&s->dev, "cs: IO port probe %#x-%#x:", base, base+num-1);
196 /* First, what does a floating port look like? */
197 b = kzalloc(256, GFP_KERNEL);
200 dev_err(&s->dev, "do_io_probe: unable to kmalloc 256 bytes\n");
203 for (i = base, most = 0; i < base+num; i += 8) {
204 res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
208 for (j = 1; j < 8; j++)
209 if (inb(i+j) != hole)
212 if ((j == 8) && (++b[hole] > b[most]))
220 for (i = base; i < base+num; i += 8) {
221 res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
224 pr_cont(" excluding");
229 for (j = 0; j < 8; j++)
230 if (inb(i+j) != most)
235 pr_cont(" excluding");
240 sub_interval(&s_data->io_db, bad, i-bad);
241 pr_cont(" %#x-%#x", bad, i-1);
247 if ((num > 16) && (bad == base) && (i == base+num)) {
248 sub_interval(&s_data->io_db, bad, i-bad);
249 pr_cont(" nothing: probe failed.\n");
252 sub_interval(&s_data->io_db, bad, i-bad);
253 pr_cont(" %#x-%#x", bad, i-1);
257 pr_cont("%s\n", !any ? " clean" : "");
261 /*======================================================================*/
264 * readable() - iomem validation function for cards with a valid CIS
266 static int readable(struct pcmcia_socket *s, struct resource *res,
272 dev_dbg(&s->dev, "fake CIS is being used: can't validate mem\n");
276 s->cis_mem.res = res;
277 s->cis_virt = ioremap(res->start, s->map_size);
279 mutex_unlock(&s->ops_mutex);
280 /* as we're only called from pcmcia.c, we're safe */
281 if (s->callback->validate)
282 ret = s->callback->validate(s, count);
283 /* invalidate mapping */
284 mutex_lock(&s->ops_mutex);
285 iounmap(s->cis_virt);
288 s->cis_mem.res = NULL;
289 if ((ret) || (*count == 0))
295 * checksum() - iomem validation function for simple memory cards
297 static int checksum(struct pcmcia_socket *s, struct resource *res,
301 int i, a = 0, b = -1, d;
304 virt = ioremap(res->start, s->map_size);
307 map.flags = MAP_ACTIVE;
311 s->ops->set_mem_map(s, &map);
313 /* Don't bother checking every word... */
314 for (i = 0; i < s->map_size; i += 44) {
321 s->ops->set_mem_map(s, &map);
335 * do_validate_mem() - low level validate a memory region for PCMCIA use
336 * @s: PCMCIA socket to validate
337 * @base: start address of resource to check
338 * @size: size of resource to check
339 * @validate: validation function to use
341 * do_validate_mem() splits up the memory region which is to be checked
342 * into two parts. Both are passed to the @validate() function. If
343 * @validate() returns non-zero, or the value parameter to @validate()
344 * is zero, or the value parameter is different between both calls,
345 * the check fails, and -EINVAL is returned. Else, 0 is returned.
347 static int do_validate_mem(struct pcmcia_socket *s,
348 unsigned long base, unsigned long size,
349 int validate (struct pcmcia_socket *s,
350 struct resource *res,
351 unsigned int *value))
353 struct socket_data *s_data = s->resource_data;
354 struct resource *res1, *res2;
355 unsigned int info1 = 1, info2 = 1;
358 res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
359 res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
365 ret = validate(s, res1, &info1);
366 ret += validate(s, res2, &info2);
370 dev_dbg(&s->dev, "cs: memory probe 0x%06lx-0x%06lx: %pr %pr %u %u %u",
371 base, base+size-1, res1, res2, ret, info1, info2);
376 if ((ret) || (info1 != info2) || (info1 == 0))
379 if (validate && !s->fake_cis) {
380 /* move it to the validated data set */
381 add_interval(&s_data->mem_db_valid, base, size);
382 sub_interval(&s_data->mem_db, base, size);
390 * do_mem_probe() - validate a memory region for PCMCIA use
391 * @s: PCMCIA socket to validate
392 * @base: start address of resource to check
393 * @num: size of resource to check
394 * @validate: validation function to use
395 * @fallback: validation function to use if validate fails
397 * do_mem_probe() checks a memory region for use by the PCMCIA subsystem.
398 * To do so, the area is split up into sensible parts, and then passed
399 * into the @validate() function. Only if @validate() and @fallback() fail,
400 * the area is marked as unavaibale for use by the PCMCIA subsystem. The
401 * function returns the size of the usable memory area.
403 static int do_mem_probe(struct pcmcia_socket *s, u_long base, u_long num,
404 int validate (struct pcmcia_socket *s,
405 struct resource *res,
406 unsigned int *value),
407 int fallback (struct pcmcia_socket *s,
408 struct resource *res,
409 unsigned int *value))
411 struct socket_data *s_data = s->resource_data;
412 u_long i, j, bad, fail, step;
414 dev_info(&s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
417 step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
418 /* don't allow too large steps */
421 /* cis_readable wants to map 2x map_size */
422 if (step < 2 * s->map_size)
423 step = 2 * s->map_size;
424 for (i = j = base; i < base+num; i = j + step) {
426 for (j = i; j < base+num; j += step) {
427 if (!do_validate_mem(s, j, step, validate))
430 fail = ((i == base) && (j == base+num));
432 if ((fail) && (fallback)) {
433 for (j = i; j < base+num; j += step)
434 if (!do_validate_mem(s, j, step, fallback))
439 pr_cont(" excluding");
440 pr_cont(" %#05lx-%#05lx", i, j-1);
441 sub_interval(&s_data->mem_db, i, j-i);
445 pr_cont("%s\n", !bad ? " clean" : "");
450 #ifdef CONFIG_PCMCIA_PROBE
453 * inv_probe() - top-to-bottom search for one usuable high memory area
454 * @s: PCMCIA socket to validate
455 * @m: resource_map to check
457 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
459 struct socket_data *s_data = s->resource_data;
461 if (m == &s_data->mem_db)
463 ok = inv_probe(m->next, s);
465 if (m->base >= 0x100000)
466 sub_interval(&s_data->mem_db, m->base, m->num);
469 if (m->base < 0x100000)
471 return do_mem_probe(s, m->base, m->num, readable, checksum);
475 * validate_mem() - memory probe function
476 * @s: PCMCIA socket to validate
477 * @probe_mask: MEM_PROBE_LOW | MEM_PROBE_HIGH
479 * The memory probe. If the memory list includes a 64K-aligned block
480 * below 1MB, we probe in 64K chunks, and as soon as we accumulate at
481 * least mem_limit free space, we quit. Returns 0 on usuable ports.
483 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
485 struct resource_map *m, mm;
486 static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
487 unsigned long b, i, ok = 0;
488 struct socket_data *s_data = s->resource_data;
490 /* We do up to four passes through the list */
491 if (probe_mask & MEM_PROBE_HIGH) {
492 if (inv_probe(s_data->mem_db.next, s) > 0)
494 if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
497 "cs: warning: no high memory space available!\n");
501 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
503 /* Only probe < 1 MB */
504 if (mm.base >= 0x100000)
506 if ((mm.base | mm.num) & 0xffff) {
507 ok += do_mem_probe(s, mm.base, mm.num, readable,
511 /* Special probe for 64K-aligned block */
512 for (i = 0; i < 4; i++) {
514 if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
516 sub_interval(&s_data->mem_db, b, 0x10000);
518 ok += do_mem_probe(s, b, 0x10000,
530 #else /* CONFIG_PCMCIA_PROBE */
533 * validate_mem() - memory probe function
534 * @s: PCMCIA socket to validate
535 * @probe_mask: ignored
537 * Returns 0 on usuable ports.
539 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
541 struct resource_map *m, mm;
542 struct socket_data *s_data = s->resource_data;
543 unsigned long ok = 0;
545 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
547 ok += do_mem_probe(s, mm.base, mm.num, readable, checksum);
554 #endif /* CONFIG_PCMCIA_PROBE */
558 * pcmcia_nonstatic_validate_mem() - try to validate iomem for PCMCIA use
559 * @s: PCMCIA socket to validate
561 * This is tricky... when we set up CIS memory, we try to validate
562 * the memory window space allocations.
564 * Locking note: Must be called with skt_mutex held!
566 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
568 struct socket_data *s_data = s->resource_data;
569 unsigned int probe_mask = MEM_PROBE_LOW;
572 if (!probe_mem || !(s->state & SOCKET_PRESENT))
575 if (s->features & SS_CAP_PAGE_REGS)
576 probe_mask = MEM_PROBE_HIGH;
578 ret = validate_mem(s, probe_mask);
580 if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
586 struct pcmcia_align_data {
588 unsigned long offset;
589 struct resource_map *map;
592 static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data,
593 resource_size_t start)
597 * Ensure that we have the correct start address
599 ret = (start & ~align_data->mask) + align_data->offset;
601 ret += align_data->mask + 1;
605 static resource_size_t
606 pcmcia_align(void *align_data, const struct resource *res,
607 resource_size_t size, resource_size_t align)
609 struct pcmcia_align_data *data = align_data;
610 struct resource_map *m;
611 resource_size_t start;
613 start = pcmcia_common_align(data, res->start);
615 for (m = data->map->next; m != data->map; m = m->next) {
616 unsigned long map_start = m->base;
617 unsigned long map_end = m->base + m->num - 1;
620 * If the lower resources are not available, try aligning
621 * to this entry of the resource database to see if it'll
624 if (start < map_start)
625 start = pcmcia_common_align(data, map_start);
628 * If we're above the area which was passed in, there's
629 * no point proceeding.
631 if (start >= res->end)
634 if ((start + size - 1) <= map_end)
639 * If we failed to find something suitable, ensure we fail.
648 * Adjust an existing IO region allocation, but making sure that we don't
649 * encroach outside the resources which the user supplied.
651 static int __nonstatic_adjust_io_region(struct pcmcia_socket *s,
652 unsigned long r_start,
655 struct resource_map *m;
656 struct socket_data *s_data = s->resource_data;
659 for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
660 unsigned long start = m->base;
661 unsigned long end = m->base + m->num - 1;
663 if (start > r_start || r_end > end)
672 /*======================================================================
674 These find ranges of I/O ports or memory addresses that are not
675 currently allocated by other devices.
677 The 'align' field should reflect the number of bits of address
678 that need to be preserved from the initial value of *base. It
679 should be a power of two, greater than or equal to 'num'. A value
680 of 0 means that all bits of *base are significant. *base should
681 also be strictly less than 'align'.
683 ======================================================================*/
685 static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s,
686 unsigned long base, int num,
689 struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO,
691 struct socket_data *s_data = s->resource_data;
692 struct pcmcia_align_data data;
693 unsigned long min = base;
699 data.mask = align - 1;
700 data.offset = base & data.mask;
701 data.map = &s_data->io_db;
705 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
706 min, 0, pcmcia_align, &data);
709 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
710 1, pcmcia_align, &data);
719 static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr,
720 unsigned int *base, unsigned int num,
721 unsigned int align, struct resource **parent)
725 /* Check for an already-allocated window that must conflict with
726 * what was asked for. It is a hack because it does not catch all
727 * potential conflicts, just the most obvious ones.
729 for (i = 0; i < MAX_IO_WIN; i++) {
736 if ((s->io[i].res->start & (align-1)) == *base)
740 for (i = 0; i < MAX_IO_WIN; i++) {
741 struct resource *res = s->io[i].res;
744 if (res && (res->flags & IORESOURCE_BITS) !=
745 (attr & IORESOURCE_BITS))
752 res = s->io[i].res = __nonstatic_find_io_region(s,
759 s->io[i].res->flags =
760 ((res->flags & ~IORESOURCE_BITS) |
761 (attr & IORESOURCE_BITS));
762 s->io[i].InUse = num;
767 /* Try to extend top of window */
769 if ((*base == 0) || (*base == try)) {
770 ret = __nonstatic_adjust_io_region(s, res->start,
773 ret = adjust_resource(s->io[i].res, res->start,
774 resource_size(res) + num);
778 s->io[i].InUse += num;
784 /* Try to extend bottom of window */
785 try = res->start - num;
786 if ((*base == 0) || (*base == try)) {
787 ret = __nonstatic_adjust_io_region(s,
791 ret = adjust_resource(s->io[i].res,
793 resource_size(res) + num);
797 s->io[i].InUse += num;
808 static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
809 u_long align, int low, struct pcmcia_socket *s)
811 struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM,
813 struct socket_data *s_data = s->resource_data;
814 struct pcmcia_align_data data;
815 unsigned long min, max;
821 low = low || !(s->features & SS_CAP_PAGE_REGS);
823 data.mask = align - 1;
824 data.offset = base & data.mask;
826 for (i = 0; i < 2; i++) {
827 data.map = &s_data->mem_db_valid;
830 min = base < max ? base : 0;
833 min = 0x100000UL + base;
836 for (j = 0; j < 2; j++) {
839 ret = pci_bus_alloc_resource(s->cb_dev->bus,
841 pcmcia_align, &data);
845 ret = allocate_resource(&iomem_resource,
846 res, num, min, max, 1,
847 pcmcia_align, &data);
851 data.map = &s_data->mem_db;
866 static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
868 struct socket_data *data = s->resource_data;
869 unsigned long size = end - start + 1;
876 case ADD_MANAGED_RESOURCE:
877 ret = add_interval(&data->mem_db, start, size);
879 do_mem_probe(s, start, size, NULL, NULL);
881 case REMOVE_MANAGED_RESOURCE:
882 ret = sub_interval(&data->mem_db, start, size);
892 static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
894 struct socket_data *data = s->resource_data;
898 #if defined(CONFIG_X86)
899 /* on x86, avoid anything < 0x100 for it is often used for
900 * legacy platform devices */
905 size = end - start + 1;
910 if (end > IO_SPACE_LIMIT)
914 case ADD_MANAGED_RESOURCE:
915 if (add_interval(&data->io_db, start, size) != 0) {
919 #ifdef CONFIG_PCMCIA_PROBE
921 do_io_probe(s, start, size);
924 case REMOVE_MANAGED_RESOURCE:
925 sub_interval(&data->io_db, start, size);
937 static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
939 struct resource *res;
942 if (!s->cb_dev || !s->cb_dev->bus)
945 #if defined(CONFIG_X86)
946 /* If this is the root bus, the risk of hitting some strange
947 * system devices is too high: If a driver isn't loaded, the
948 * resources are not claimed; even if a driver is loaded, it
949 * may not request all resources or even the wrong one. We
950 * can neither trust the rest of the kernel nor ACPI/PNP and
951 * CRS parsing to get it right. Therefore, use several
954 * - Do not auto-add resources if the CardBus bridge is on
957 * - Avoid any I/O ports < 0x100.
959 * - On PCI-PCI bridges, only use resources which are set up
960 * exclusively for the secondary PCI bus: the risk of hitting
961 * system devices is quite low, as they usually aren't
962 * connected to the secondary PCI bus.
964 if (s->cb_dev->bus->number == 0)
967 for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
968 res = s->cb_dev->bus->resource[i];
970 pci_bus_for_each_resource(s->cb_dev->bus, res, i) {
975 if (res->flags & IORESOURCE_IO) {
976 /* safeguard against the root resource, where the
977 * risk of hitting any other device would be too
979 if (res == &ioport_resource)
982 dev_info(&s->cb_dev->dev,
983 "pcmcia: parent PCI bridge window: %pR\n",
985 if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
986 done |= IORESOURCE_IO;
990 if (res->flags & IORESOURCE_MEM) {
991 /* safeguard against the root resource, where the
992 * risk of hitting any other device would be too
994 if (res == &iomem_resource)
997 dev_info(&s->cb_dev->dev,
998 "pcmcia: parent PCI bridge window: %pR\n",
1000 if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
1001 done |= IORESOURCE_MEM;
1005 /* if we got at least one of IO, and one of MEM, we can be glad and
1006 * activate the PCMCIA subsystem */
1007 if (done == (IORESOURCE_MEM | IORESOURCE_IO))
1008 s->resource_setup_done = 1;
1015 static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
1023 static int nonstatic_init(struct pcmcia_socket *s)
1025 struct socket_data *data;
1027 data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
1031 data->mem_db.next = &data->mem_db;
1032 data->mem_db_valid.next = &data->mem_db_valid;
1033 data->io_db.next = &data->io_db;
1035 s->resource_data = (void *) data;
1037 nonstatic_autoadd_resources(s);
1042 static void nonstatic_release_resource_db(struct pcmcia_socket *s)
1044 struct socket_data *data = s->resource_data;
1045 struct resource_map *p, *q;
1047 for (p = data->mem_db_valid.next; p != &data->mem_db_valid; p = q) {
1051 for (p = data->mem_db.next; p != &data->mem_db; p = q) {
1055 for (p = data->io_db.next; p != &data->io_db; p = q) {
1062 struct pccard_resource_ops pccard_nonstatic_ops = {
1063 .validate_mem = pcmcia_nonstatic_validate_mem,
1064 .find_io = nonstatic_find_io,
1065 .find_mem = nonstatic_find_mem_region,
1066 .init = nonstatic_init,
1067 .exit = nonstatic_release_resource_db,
1069 EXPORT_SYMBOL(pccard_nonstatic_ops);
1072 /* sysfs interface to the resource database */
1074 static ssize_t show_io_db(struct device *dev,
1075 struct device_attribute *attr, char *buf)
1077 struct pcmcia_socket *s = dev_get_drvdata(dev);
1078 struct socket_data *data;
1079 struct resource_map *p;
1082 mutex_lock(&s->ops_mutex);
1083 data = s->resource_data;
1085 for (p = data->io_db.next; p != &data->io_db; p = p->next) {
1086 if (ret > (PAGE_SIZE - 10))
1088 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1089 "0x%08lx - 0x%08lx\n",
1090 ((unsigned long) p->base),
1091 ((unsigned long) p->base + p->num - 1));
1094 mutex_unlock(&s->ops_mutex);
1098 static ssize_t store_io_db(struct device *dev,
1099 struct device_attribute *attr,
1100 const char *buf, size_t count)
1102 struct pcmcia_socket *s = dev_get_drvdata(dev);
1103 unsigned long start_addr, end_addr;
1104 unsigned int add = ADD_MANAGED_RESOURCE;
1107 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1109 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1110 add = REMOVE_MANAGED_RESOURCE;
1112 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1114 add = ADD_MANAGED_RESOURCE;
1119 if (end_addr < start_addr)
1122 mutex_lock(&s->ops_mutex);
1123 ret = adjust_io(s, add, start_addr, end_addr);
1124 mutex_unlock(&s->ops_mutex);
1126 return ret ? ret : count;
1128 static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
1130 static ssize_t show_mem_db(struct device *dev,
1131 struct device_attribute *attr, char *buf)
1133 struct pcmcia_socket *s = dev_get_drvdata(dev);
1134 struct socket_data *data;
1135 struct resource_map *p;
1138 mutex_lock(&s->ops_mutex);
1139 data = s->resource_data;
1141 for (p = data->mem_db_valid.next; p != &data->mem_db_valid;
1143 if (ret > (PAGE_SIZE - 10))
1145 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1146 "0x%08lx - 0x%08lx\n",
1147 ((unsigned long) p->base),
1148 ((unsigned long) p->base + p->num - 1));
1151 for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
1152 if (ret > (PAGE_SIZE - 10))
1154 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1155 "0x%08lx - 0x%08lx\n",
1156 ((unsigned long) p->base),
1157 ((unsigned long) p->base + p->num - 1));
1160 mutex_unlock(&s->ops_mutex);
1164 static ssize_t store_mem_db(struct device *dev,
1165 struct device_attribute *attr,
1166 const char *buf, size_t count)
1168 struct pcmcia_socket *s = dev_get_drvdata(dev);
1169 unsigned long start_addr, end_addr;
1170 unsigned int add = ADD_MANAGED_RESOURCE;
1173 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1175 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1176 add = REMOVE_MANAGED_RESOURCE;
1178 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1180 add = ADD_MANAGED_RESOURCE;
1185 if (end_addr < start_addr)
1188 mutex_lock(&s->ops_mutex);
1189 ret = adjust_memory(s, add, start_addr, end_addr);
1190 mutex_unlock(&s->ops_mutex);
1192 return ret ? ret : count;
1194 static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
1196 static struct attribute *pccard_rsrc_attributes[] = {
1197 &dev_attr_available_resources_io.attr,
1198 &dev_attr_available_resources_mem.attr,
1202 static const struct attribute_group rsrc_attributes = {
1203 .attrs = pccard_rsrc_attributes,
1206 static int pccard_sysfs_add_rsrc(struct device *dev,
1207 struct class_interface *class_intf)
1209 struct pcmcia_socket *s = dev_get_drvdata(dev);
1211 if (s->resource_ops != &pccard_nonstatic_ops)
1213 return sysfs_create_group(&dev->kobj, &rsrc_attributes);
1216 static void pccard_sysfs_remove_rsrc(struct device *dev,
1217 struct class_interface *class_intf)
1219 struct pcmcia_socket *s = dev_get_drvdata(dev);
1221 if (s->resource_ops != &pccard_nonstatic_ops)
1223 sysfs_remove_group(&dev->kobj, &rsrc_attributes);
1226 static struct class_interface pccard_rsrc_interface __refdata = {
1227 .class = &pcmcia_socket_class,
1228 .add_dev = &pccard_sysfs_add_rsrc,
1229 .remove_dev = &pccard_sysfs_remove_rsrc,
1232 static int __init nonstatic_sysfs_init(void)
1234 return class_interface_register(&pccard_rsrc_interface);
1237 static void __exit nonstatic_sysfs_exit(void)
1239 class_interface_unregister(&pccard_rsrc_interface);
1242 module_init(nonstatic_sysfs_init);
1243 module_exit(nonstatic_sysfs_exit);