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/cs_types.h>
32 #include <pcmcia/ss.h>
33 #include <pcmcia/cs.h>
34 #include <pcmcia/cistpl.h>
35 #include "cs_internal.h"
37 /* moved to rsrc_mgr.c
38 MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
39 MODULE_LICENSE("GPL");
42 /* Parameters that can be set with 'insmod' */
44 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
46 INT_MODULE_PARM(probe_mem, 1); /* memory probe? */
47 #ifdef CONFIG_PCMCIA_PROBE
48 INT_MODULE_PARM(probe_io, 1); /* IO port probe? */
49 INT_MODULE_PARM(mem_limit, 0x10000);
52 /* for io_db and mem_db */
55 struct resource_map *next;
59 struct resource_map mem_db;
60 struct resource_map mem_db_valid;
61 struct resource_map io_db;
64 #define MEM_PROBE_LOW (1 << 0)
65 #define MEM_PROBE_HIGH (1 << 1)
68 /*======================================================================
70 Linux resource management extensions
72 ======================================================================*/
74 static struct resource *
75 claim_region(struct pcmcia_socket *s, resource_size_t base,
76 resource_size_t size, int type, char *name)
78 struct resource *res, *parent;
80 parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
81 res = pcmcia_make_resource(base, size, type | IORESOURCE_BUSY, name);
86 parent = pci_find_parent_resource(s->cb_dev, res);
88 if (!parent || request_resource(parent, res)) {
96 static void free_region(struct resource *res)
99 release_resource(res);
104 /*======================================================================
106 These manage the internal databases of available resources.
108 ======================================================================*/
110 static int add_interval(struct resource_map *map, u_long base, u_long num)
112 struct resource_map *p, *q;
114 for (p = map; ; p = p->next) {
115 if ((p != map) && (p->base+p->num >= base)) {
116 p->num = max(num + base - p->base, p->num);
119 if ((p->next == map) || (p->next->base > base+num-1))
122 q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
124 printk(KERN_WARNING "out of memory to update resources\n");
127 q->base = base; q->num = num;
128 q->next = p->next; p->next = q;
132 /*====================================================================*/
134 static int sub_interval(struct resource_map *map, u_long base, u_long num)
136 struct resource_map *p, *q;
138 for (p = map; ; p = q) {
142 if ((q->base+q->num > base) && (base+num > q->base)) {
143 if (q->base >= base) {
144 if (q->base+q->num <= base+num) {
145 /* Delete whole block */
148 /* don't advance the pointer yet */
151 /* Cut off bit from the front */
152 q->num = q->base + q->num - base - num;
153 q->base = base + num;
155 } else if (q->base+q->num <= base+num) {
156 /* Cut off bit from the end */
157 q->num = base - q->base;
159 /* Split the block into two pieces */
160 p = kmalloc(sizeof(struct resource_map),
163 printk(KERN_WARNING "out of memory to update resources\n");
167 p->num = q->base+q->num - p->base;
168 q->num = base - q->base;
169 p->next = q->next ; q->next = p;
176 /*======================================================================
178 These routines examine a region of IO or memory addresses to
179 determine what ranges might be genuinely available.
181 ======================================================================*/
183 #ifdef CONFIG_PCMCIA_PROBE
184 static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
187 struct resource *res;
188 struct socket_data *s_data = s->resource_data;
189 unsigned int i, j, bad;
191 u_char *b, hole, most;
193 dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:",
196 /* First, what does a floating port look like? */
197 b = kzalloc(256, GFP_KERNEL);
200 dev_printk(KERN_ERR, &s->dev,
201 "do_io_probe: unable to kmalloc 256 bytes");
204 for (i = base, most = 0; i < base+num; i += 8) {
205 res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
209 for (j = 1; j < 8; j++)
210 if (inb(i+j) != hole)
213 if ((j == 8) && (++b[hole] > b[most]))
221 for (i = base; i < base+num; i += 8) {
222 res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
225 printk(" excluding");
230 for (j = 0; j < 8; j++)
231 if (inb(i+j) != most)
236 printk(" excluding");
241 sub_interval(&s_data->io_db, bad, i-bad);
242 printk(" %#x-%#x", bad, i-1);
248 if ((num > 16) && (bad == base) && (i == base+num)) {
249 sub_interval(&s_data->io_db, bad, i-bad);
250 printk(" nothing: probe failed.\n");
253 sub_interval(&s_data->io_db, bad, i-bad);
254 printk(" %#x-%#x", bad, i-1);
258 printk(any ? "\n" : " clean.\n");
262 /*======================================================================*/
265 * readable() - iomem validation function for cards with a valid CIS
267 static int readable(struct pcmcia_socket *s, struct resource *res,
273 dev_dbg(&s->dev, "fake CIS is being used: can't validate mem\n");
277 s->cis_mem.res = res;
278 s->cis_virt = ioremap(res->start, s->map_size);
280 mutex_unlock(&s->ops_mutex);
281 /* as we're only called from pcmcia.c, we're safe */
282 if (s->callback->validate)
283 ret = s->callback->validate(s, count);
284 /* invalidate mapping */
285 mutex_lock(&s->ops_mutex);
286 iounmap(s->cis_virt);
289 s->cis_mem.res = NULL;
290 if ((ret) || (*count == 0))
296 * checksum() - iomem validation function for simple memory cards
298 static int checksum(struct pcmcia_socket *s, struct resource *res,
302 int i, a = 0, b = -1, d;
305 virt = ioremap(res->start, s->map_size);
308 map.flags = MAP_ACTIVE;
312 s->ops->set_mem_map(s, &map);
314 /* Don't bother checking every word... */
315 for (i = 0; i < s->map_size; i += 44) {
322 s->ops->set_mem_map(s, &map);
336 * do_validate_mem() - low level validate a memory region for PCMCIA use
337 * @s: PCMCIA socket to validate
338 * @base: start address of resource to check
339 * @size: size of resource to check
340 * @validate: validation function to use
342 * do_validate_mem() splits up the memory region which is to be checked
343 * into two parts. Both are passed to the @validate() function. If
344 * @validate() returns non-zero, or the value parameter to @validate()
345 * is zero, or the value parameter is different between both calls,
346 * the check fails, and -EINVAL is returned. Else, 0 is returned.
348 static int do_validate_mem(struct pcmcia_socket *s,
349 unsigned long base, unsigned long size,
350 int validate (struct pcmcia_socket *s,
351 struct resource *res,
352 unsigned int *value))
354 struct socket_data *s_data = s->resource_data;
355 struct resource *res1, *res2;
356 unsigned int info1 = 1, info2 = 1;
359 res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
360 res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
366 ret = validate(s, res1, &info1);
367 ret += validate(s, res2, &info2);
374 dev_dbg(&s->dev, "cs: memory probe 0x%06lx-0x%06lx: %p %p %u %u %u",
375 base, base+size-1, res1, res2, ret, info1, info2);
377 if ((ret) || (info1 != info2) || (info1 == 0))
380 if (validate && !s->fake_cis) {
381 /* move it to the validated data set */
382 add_interval(&s_data->mem_db_valid, base, size);
383 sub_interval(&s_data->mem_db, base, size);
391 * do_mem_probe() - validate a memory region for PCMCIA use
392 * @s: PCMCIA socket to validate
393 * @base: start address of resource to check
394 * @num: size of resource to check
395 * @validate: validation function to use
396 * @fallback: validation function to use if validate fails
398 * do_mem_probe() checks a memory region for use by the PCMCIA subsystem.
399 * To do so, the area is split up into sensible parts, and then passed
400 * into the @validate() function. Only if @validate() and @fallback() fail,
401 * the area is marked as unavaibale for use by the PCMCIA subsystem. The
402 * function returns the size of the usable memory area.
404 static int do_mem_probe(struct pcmcia_socket *s, u_long base, u_long num,
405 int validate (struct pcmcia_socket *s,
406 struct resource *res,
407 unsigned int *value),
408 int fallback (struct pcmcia_socket *s,
409 struct resource *res,
410 unsigned int *value))
412 struct socket_data *s_data = s->resource_data;
413 u_long i, j, bad, fail, step;
415 dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
418 step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
419 /* don't allow too large steps */
422 /* cis_readable wants to map 2x map_size */
423 if (step < 2 * s->map_size)
424 step = 2 * s->map_size;
425 for (i = j = base; i < base+num; i = j + step) {
427 for (j = i; j < base+num; j += step) {
428 if (!do_validate_mem(s, j, step, validate))
431 fail = ((i == base) && (j == base+num));
433 if ((fail) && (fallback)) {
434 for (j = i; j < base+num; j += step)
435 if (!do_validate_mem(s, j, step, fallback))
440 printk(" excluding");
441 printk(" %#05lx-%#05lx", i, j-1);
442 sub_interval(&s_data->mem_db, i, j-i);
446 printk(bad ? "\n" : " clean.\n");
451 #ifdef CONFIG_PCMCIA_PROBE
454 * inv_probe() - top-to-bottom search for one usuable high memory area
455 * @s: PCMCIA socket to validate
456 * @m: resource_map to check
458 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
460 struct socket_data *s_data = s->resource_data;
462 if (m == &s_data->mem_db)
464 ok = inv_probe(m->next, s);
466 if (m->base >= 0x100000)
467 sub_interval(&s_data->mem_db, m->base, m->num);
470 if (m->base < 0x100000)
472 return do_mem_probe(s, m->base, m->num, readable, checksum);
476 * validate_mem() - memory probe function
477 * @s: PCMCIA socket to validate
478 * @probe_mask: MEM_PROBE_LOW | MEM_PROBE_HIGH
480 * The memory probe. If the memory list includes a 64K-aligned block
481 * below 1MB, we probe in 64K chunks, and as soon as we accumulate at
482 * least mem_limit free space, we quit. Returns 0 on usuable ports.
484 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
486 struct resource_map *m, mm;
487 static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
488 unsigned long b, i, ok = 0;
489 struct socket_data *s_data = s->resource_data;
491 /* We do up to four passes through the list */
492 if (probe_mask & MEM_PROBE_HIGH) {
493 if (inv_probe(s_data->mem_db.next, s) > 0)
495 if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
497 dev_printk(KERN_NOTICE, &s->dev,
498 "cs: warning: no high memory space available!\n");
502 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
504 /* Only probe < 1 MB */
505 if (mm.base >= 0x100000)
507 if ((mm.base | mm.num) & 0xffff) {
508 ok += do_mem_probe(s, mm.base, mm.num, readable,
512 /* Special probe for 64K-aligned block */
513 for (i = 0; i < 4; i++) {
515 if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
517 sub_interval(&s_data->mem_db, b, 0x10000);
519 ok += do_mem_probe(s, b, 0x10000,
531 #else /* CONFIG_PCMCIA_PROBE */
534 * validate_mem() - memory probe function
535 * @s: PCMCIA socket to validate
536 * @probe_mask: ignored
538 * Returns 0 on usuable ports.
540 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
542 struct resource_map *m, mm;
543 struct socket_data *s_data = s->resource_data;
544 unsigned long ok = 0;
546 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
548 ok += do_mem_probe(s, mm.base, mm.num, readable, checksum);
555 #endif /* CONFIG_PCMCIA_PROBE */
559 * pcmcia_nonstatic_validate_mem() - try to validate iomem for PCMCIA use
560 * @s: PCMCIA socket to validate
562 * This is tricky... when we set up CIS memory, we try to validate
563 * the memory window space allocations.
565 * Locking note: Must be called with skt_mutex held!
567 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
569 struct socket_data *s_data = s->resource_data;
570 unsigned int probe_mask = MEM_PROBE_LOW;
573 if (!probe_mem || !(s->state & SOCKET_PRESENT))
576 if (s->features & SS_CAP_PAGE_REGS)
577 probe_mask = MEM_PROBE_HIGH;
579 ret = validate_mem(s, probe_mask);
581 if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
587 struct pcmcia_align_data {
589 unsigned long offset;
590 struct resource_map *map;
593 static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data,
594 resource_size_t start)
598 * Ensure that we have the correct start address
600 ret = (start & ~align_data->mask) + align_data->offset;
602 ret += align_data->mask + 1;
606 static resource_size_t
607 pcmcia_align(void *align_data, const struct resource *res,
608 resource_size_t size, resource_size_t align)
610 struct pcmcia_align_data *data = align_data;
611 struct resource_map *m;
612 resource_size_t start;
614 start = pcmcia_common_align(data, res->start);
616 for (m = data->map->next; m != data->map; m = m->next) {
617 unsigned long map_start = m->base;
618 unsigned long map_end = m->base + m->num - 1;
621 * If the lower resources are not available, try aligning
622 * to this entry of the resource database to see if it'll
625 if (start < map_start)
626 start = pcmcia_common_align(data, map_start);
629 * If we're above the area which was passed in, there's
630 * no point proceeding.
632 if (start >= res->end)
635 if ((start + size - 1) <= map_end)
640 * If we failed to find something suitable, ensure we fail.
649 * Adjust an existing IO region allocation, but making sure that we don't
650 * encroach outside the resources which the user supplied.
652 static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start,
653 unsigned long r_end, struct pcmcia_socket *s)
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)
666 ret = adjust_resource(res, r_start, r_end - r_start + 1);
673 /*======================================================================
675 These find ranges of I/O ports or memory addresses that are not
676 currently allocated by other devices.
678 The 'align' field should reflect the number of bits of address
679 that need to be preserved from the initial value of *base. It
680 should be a power of two, greater than or equal to 'num'. A value
681 of 0 means that all bits of *base are significant. *base should
682 also be strictly less than 'align'.
684 ======================================================================*/
686 static struct resource *nonstatic_find_io_region(unsigned long base, int num,
687 unsigned long align, struct pcmcia_socket *s)
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 struct resource *nonstatic_find_mem_region(u_long base, u_long num,
720 u_long align, int low, struct pcmcia_socket *s)
722 struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM,
724 struct socket_data *s_data = s->resource_data;
725 struct pcmcia_align_data data;
726 unsigned long min, max;
729 low = low || !(s->features & SS_CAP_PAGE_REGS);
731 data.mask = align - 1;
732 data.offset = base & data.mask;
734 for (i = 0; i < 2; i++) {
735 data.map = &s_data->mem_db_valid;
738 min = base < max ? base : 0;
741 min = 0x100000UL + base;
744 for (j = 0; j < 2; j++) {
747 ret = pci_bus_alloc_resource(s->cb_dev->bus,
749 pcmcia_align, &data);
753 ret = allocate_resource(&iomem_resource,
754 res, num, min, max, 1,
755 pcmcia_align, &data);
759 data.map = &s_data->mem_db;
774 static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
776 struct socket_data *data = s->resource_data;
777 unsigned long size = end - start + 1;
784 case ADD_MANAGED_RESOURCE:
785 ret = add_interval(&data->mem_db, start, size);
787 do_mem_probe(s, start, size, NULL, NULL);
789 case REMOVE_MANAGED_RESOURCE:
790 ret = sub_interval(&data->mem_db, start, size);
800 static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
802 struct socket_data *data = s->resource_data;
806 #if defined(CONFIG_X86)
807 /* on x86, avoid anything < 0x100 for it is often used for
808 * legacy platform devices */
813 size = end - start + 1;
818 if (end > IO_SPACE_LIMIT)
822 case ADD_MANAGED_RESOURCE:
823 if (add_interval(&data->io_db, start, size) != 0) {
827 #ifdef CONFIG_PCMCIA_PROBE
829 do_io_probe(s, start, size);
832 case REMOVE_MANAGED_RESOURCE:
833 sub_interval(&data->io_db, start, size);
845 static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
847 struct resource *res;
850 if (!s->cb_dev || !s->cb_dev->bus)
853 #if defined(CONFIG_X86)
854 /* If this is the root bus, the risk of hitting
855 * some strange system devices which aren't protected
856 * by either ACPI resource tables or properly requested
857 * resources is too big. Therefore, don't do auto-adding
858 * of resources at the moment.
860 if (s->cb_dev->bus->number == 0)
864 pci_bus_for_each_resource(s->cb_dev->bus, res, i) {
868 if (res->flags & IORESOURCE_IO) {
869 if (res == &ioport_resource)
871 dev_printk(KERN_INFO, &s->cb_dev->dev,
872 "pcmcia: parent PCI bridge window: %pR\n",
874 if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
875 done |= IORESOURCE_IO;
879 if (res->flags & IORESOURCE_MEM) {
880 if (res == &iomem_resource)
882 dev_printk(KERN_INFO, &s->cb_dev->dev,
883 "pcmcia: parent PCI bridge window: %pR\n",
885 if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
886 done |= IORESOURCE_MEM;
890 /* if we got at least one of IO, and one of MEM, we can be glad and
891 * activate the PCMCIA subsystem */
892 if (done == (IORESOURCE_MEM | IORESOURCE_IO))
893 s->resource_setup_done = 1;
900 static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
908 static int nonstatic_init(struct pcmcia_socket *s)
910 struct socket_data *data;
912 data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
916 data->mem_db.next = &data->mem_db;
917 data->mem_db_valid.next = &data->mem_db_valid;
918 data->io_db.next = &data->io_db;
920 s->resource_data = (void *) data;
922 nonstatic_autoadd_resources(s);
927 static void nonstatic_release_resource_db(struct pcmcia_socket *s)
929 struct socket_data *data = s->resource_data;
930 struct resource_map *p, *q;
932 for (p = data->mem_db_valid.next; p != &data->mem_db_valid; p = q) {
936 for (p = data->mem_db.next; p != &data->mem_db; p = q) {
940 for (p = data->io_db.next; p != &data->io_db; p = q) {
947 struct pccard_resource_ops pccard_nonstatic_ops = {
948 .validate_mem = pcmcia_nonstatic_validate_mem,
949 .adjust_io_region = nonstatic_adjust_io_region,
950 .find_io = nonstatic_find_io_region,
951 .find_mem = nonstatic_find_mem_region,
953 .add_mem = adjust_memory,
954 .init = nonstatic_init,
955 .exit = nonstatic_release_resource_db,
957 EXPORT_SYMBOL(pccard_nonstatic_ops);
960 /* sysfs interface to the resource database */
962 static ssize_t show_io_db(struct device *dev,
963 struct device_attribute *attr, char *buf)
965 struct pcmcia_socket *s = dev_get_drvdata(dev);
966 struct socket_data *data;
967 struct resource_map *p;
970 mutex_lock(&s->ops_mutex);
971 data = s->resource_data;
973 for (p = data->io_db.next; p != &data->io_db; p = p->next) {
974 if (ret > (PAGE_SIZE - 10))
976 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
977 "0x%08lx - 0x%08lx\n",
978 ((unsigned long) p->base),
979 ((unsigned long) p->base + p->num - 1));
982 mutex_unlock(&s->ops_mutex);
986 static ssize_t store_io_db(struct device *dev,
987 struct device_attribute *attr,
988 const char *buf, size_t count)
990 struct pcmcia_socket *s = dev_get_drvdata(dev);
991 unsigned long start_addr, end_addr;
992 unsigned int add = ADD_MANAGED_RESOURCE;
995 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
997 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
998 add = REMOVE_MANAGED_RESOURCE;
1000 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1002 add = ADD_MANAGED_RESOURCE;
1007 if (end_addr < start_addr)
1010 mutex_lock(&s->ops_mutex);
1011 ret = adjust_io(s, add, start_addr, end_addr);
1013 s->resource_setup_new = 1;
1014 mutex_unlock(&s->ops_mutex);
1016 return ret ? ret : count;
1018 static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
1020 static ssize_t show_mem_db(struct device *dev,
1021 struct device_attribute *attr, char *buf)
1023 struct pcmcia_socket *s = dev_get_drvdata(dev);
1024 struct socket_data *data;
1025 struct resource_map *p;
1028 mutex_lock(&s->ops_mutex);
1029 data = s->resource_data;
1031 for (p = data->mem_db_valid.next; p != &data->mem_db_valid;
1033 if (ret > (PAGE_SIZE - 10))
1035 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1036 "0x%08lx - 0x%08lx\n",
1037 ((unsigned long) p->base),
1038 ((unsigned long) p->base + p->num - 1));
1041 for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
1042 if (ret > (PAGE_SIZE - 10))
1044 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1045 "0x%08lx - 0x%08lx\n",
1046 ((unsigned long) p->base),
1047 ((unsigned long) p->base + p->num - 1));
1050 mutex_unlock(&s->ops_mutex);
1054 static ssize_t store_mem_db(struct device *dev,
1055 struct device_attribute *attr,
1056 const char *buf, size_t count)
1058 struct pcmcia_socket *s = dev_get_drvdata(dev);
1059 unsigned long start_addr, end_addr;
1060 unsigned int add = ADD_MANAGED_RESOURCE;
1063 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1065 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1066 add = REMOVE_MANAGED_RESOURCE;
1068 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1070 add = ADD_MANAGED_RESOURCE;
1075 if (end_addr < start_addr)
1078 mutex_lock(&s->ops_mutex);
1079 ret = adjust_memory(s, add, start_addr, end_addr);
1081 s->resource_setup_new = 1;
1082 mutex_unlock(&s->ops_mutex);
1084 return ret ? ret : count;
1086 static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
1088 static struct attribute *pccard_rsrc_attributes[] = {
1089 &dev_attr_available_resources_io.attr,
1090 &dev_attr_available_resources_mem.attr,
1094 static const struct attribute_group rsrc_attributes = {
1095 .attrs = pccard_rsrc_attributes,
1098 static int __devinit pccard_sysfs_add_rsrc(struct device *dev,
1099 struct class_interface *class_intf)
1101 struct pcmcia_socket *s = dev_get_drvdata(dev);
1103 if (s->resource_ops != &pccard_nonstatic_ops)
1105 return sysfs_create_group(&dev->kobj, &rsrc_attributes);
1108 static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
1109 struct class_interface *class_intf)
1111 struct pcmcia_socket *s = dev_get_drvdata(dev);
1113 if (s->resource_ops != &pccard_nonstatic_ops)
1115 sysfs_remove_group(&dev->kobj, &rsrc_attributes);
1118 static struct class_interface pccard_rsrc_interface __refdata = {
1119 .class = &pcmcia_socket_class,
1120 .add_dev = &pccard_sysfs_add_rsrc,
1121 .remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc),
1124 static int __init nonstatic_sysfs_init(void)
1126 return class_interface_register(&pccard_rsrc_interface);
1129 static void __exit nonstatic_sysfs_exit(void)
1131 class_interface_unregister(&pccard_rsrc_interface);
1134 module_init(nonstatic_sysfs_init);
1135 module_exit(nonstatic_sysfs_exit);