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 MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
38 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 /*======================================================================
68 Linux resource management extensions
70 ======================================================================*/
72 static struct resource *
73 make_resource(resource_size_t b, resource_size_t n, int flags, const char *name)
75 struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
86 static struct resource *
87 claim_region(struct pcmcia_socket *s, resource_size_t base,
88 resource_size_t size, int type, char *name)
90 struct resource *res, *parent;
92 parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource;
93 res = make_resource(base, size, type | IORESOURCE_BUSY, name);
98 parent = pci_find_parent_resource(s->cb_dev, res);
100 if (!parent || request_resource(parent, res)) {
108 static void free_region(struct resource *res)
111 release_resource(res);
116 /*======================================================================
118 These manage the internal databases of available resources.
120 ======================================================================*/
122 static int add_interval(struct resource_map *map, u_long base, u_long num)
124 struct resource_map *p, *q;
126 for (p = map; ; p = p->next) {
127 if ((p != map) && (p->base+p->num >= base)) {
128 p->num = max(num + base - p->base, p->num);
131 if ((p->next == map) || (p->next->base > base+num-1))
134 q = kmalloc(sizeof(struct resource_map), GFP_KERNEL);
136 printk(KERN_WARNING "out of memory to update resources\n");
139 q->base = base; q->num = num;
140 q->next = p->next; p->next = q;
144 /*====================================================================*/
146 static int sub_interval(struct resource_map *map, u_long base, u_long num)
148 struct resource_map *p, *q;
150 for (p = map; ; p = q) {
154 if ((q->base+q->num > base) && (base+num > q->base)) {
155 if (q->base >= base) {
156 if (q->base+q->num <= base+num) {
157 /* Delete whole block */
160 /* don't advance the pointer yet */
163 /* Cut off bit from the front */
164 q->num = q->base + q->num - base - num;
165 q->base = base + num;
167 } else if (q->base+q->num <= base+num) {
168 /* Cut off bit from the end */
169 q->num = base - q->base;
171 /* Split the block into two pieces */
172 p = kmalloc(sizeof(struct resource_map),
175 printk(KERN_WARNING "out of memory to update resources\n");
179 p->num = q->base+q->num - p->base;
180 q->num = base - q->base;
181 p->next = q->next ; q->next = p;
188 /*======================================================================
190 These routines examine a region of IO or memory addresses to
191 determine what ranges might be genuinely available.
193 ======================================================================*/
195 #ifdef CONFIG_PCMCIA_PROBE
196 static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
199 struct resource *res;
200 struct socket_data *s_data = s->resource_data;
201 unsigned int i, j, bad;
203 u_char *b, hole, most;
205 dev_printk(KERN_INFO, &s->dev, "cs: IO port probe %#x-%#x:",
208 /* First, what does a floating port look like? */
209 b = kzalloc(256, GFP_KERNEL);
212 dev_printk(KERN_ERR, &s->dev,
213 "do_io_probe: unable to kmalloc 256 bytes");
216 for (i = base, most = 0; i < base+num; i += 8) {
217 res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
221 for (j = 1; j < 8; j++)
222 if (inb(i+j) != hole)
225 if ((j == 8) && (++b[hole] > b[most]))
233 for (i = base; i < base+num; i += 8) {
234 res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
237 printk(" excluding");
242 for (j = 0; j < 8; j++)
243 if (inb(i+j) != most)
248 printk(" excluding");
253 sub_interval(&s_data->io_db, bad, i-bad);
254 printk(" %#x-%#x", bad, i-1);
260 if ((num > 16) && (bad == base) && (i == base+num)) {
261 sub_interval(&s_data->io_db, bad, i-bad);
262 printk(" nothing: probe failed.\n");
265 sub_interval(&s_data->io_db, bad, i-bad);
266 printk(" %#x-%#x", bad, i-1);
270 printk(any ? "\n" : " clean.\n");
274 /*======================================================================*/
277 * readable() - iomem validation function for cards with a valid CIS
279 static int readable(struct pcmcia_socket *s, struct resource *res,
285 dev_dbg(&s->dev, "fake CIS is being used: can't validate mem\n");
289 s->cis_mem.res = res;
290 s->cis_virt = ioremap(res->start, s->map_size);
292 mutex_unlock(&s->ops_mutex);
293 /* as we're only called from pcmcia.c, we're safe */
294 if (s->callback->validate)
295 ret = s->callback->validate(s, count);
296 /* invalidate mapping */
297 mutex_lock(&s->ops_mutex);
298 iounmap(s->cis_virt);
301 s->cis_mem.res = NULL;
302 if ((ret) || (*count == 0))
308 * checksum() - iomem validation function for simple memory cards
310 static int checksum(struct pcmcia_socket *s, struct resource *res,
314 int i, a = 0, b = -1, d;
317 virt = ioremap(res->start, s->map_size);
320 map.flags = MAP_ACTIVE;
324 s->ops->set_mem_map(s, &map);
326 /* Don't bother checking every word... */
327 for (i = 0; i < s->map_size; i += 44) {
334 s->ops->set_mem_map(s, &map);
348 * do_validate_mem() - low level validate a memory region for PCMCIA use
349 * @s: PCMCIA socket to validate
350 * @base: start address of resource to check
351 * @size: size of resource to check
352 * @validate: validation function to use
354 * do_validate_mem() splits up the memory region which is to be checked
355 * into two parts. Both are passed to the @validate() function. If
356 * @validate() returns non-zero, or the value parameter to @validate()
357 * is zero, or the value parameter is different between both calls,
358 * the check fails, and -EINVAL is returned. Else, 0 is returned.
360 static int do_validate_mem(struct pcmcia_socket *s,
361 unsigned long base, unsigned long size,
362 int validate (struct pcmcia_socket *s,
363 struct resource *res,
364 unsigned int *value))
366 struct socket_data *s_data = s->resource_data;
367 struct resource *res1, *res2;
368 unsigned int info1 = 1, info2 = 1;
371 res1 = claim_region(s, base, size/2, IORESOURCE_MEM, "PCMCIA memprobe");
372 res2 = claim_region(s, base + size/2, size/2, IORESOURCE_MEM,
378 ret = validate(s, res1, &info1);
379 ret += validate(s, res2, &info2);
386 dev_dbg(&s->dev, "cs: memory probe 0x%06lx-0x%06lx: %p %p %u %u %u",
387 base, base+size-1, res1, res2, ret, info1, info2);
389 if ((ret) || (info1 != info2) || (info1 == 0))
392 if (validate && !s->fake_cis) {
393 /* move it to the validated data set */
394 add_interval(&s_data->mem_db_valid, base, size);
395 sub_interval(&s_data->mem_db, base, size);
403 * do_mem_probe() - validate a memory region for PCMCIA use
404 * @s: PCMCIA socket to validate
405 * @base: start address of resource to check
406 * @num: size of resource to check
407 * @validate: validation function to use
408 * @fallback: validation function to use if validate fails
410 * do_mem_probe() checks a memory region for use by the PCMCIA subsystem.
411 * To do so, the area is split up into sensible parts, and then passed
412 * into the @validate() function. Only if @validate() and @fallback() fail,
413 * the area is marked as unavaibale for use by the PCMCIA subsystem. The
414 * function returns the size of the usable memory area.
416 static int do_mem_probe(struct pcmcia_socket *s, u_long base, u_long num,
417 int validate (struct pcmcia_socket *s,
418 struct resource *res,
419 unsigned int *value),
420 int fallback (struct pcmcia_socket *s,
421 struct resource *res,
422 unsigned int *value))
424 struct socket_data *s_data = s->resource_data;
425 u_long i, j, bad, fail, step;
427 dev_printk(KERN_INFO, &s->dev, "cs: memory probe 0x%06lx-0x%06lx:",
430 step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
431 /* don't allow too large steps */
434 /* cis_readable wants to map 2x map_size */
435 if (step < 2 * s->map_size)
436 step = 2 * s->map_size;
437 for (i = j = base; i < base+num; i = j + step) {
439 for (j = i; j < base+num; j += step) {
440 if (!do_validate_mem(s, j, step, validate))
443 fail = ((i == base) && (j == base+num));
445 if ((fail) && (fallback)) {
446 for (j = i; j < base+num; j += step)
447 if (!do_validate_mem(s, j, step, fallback))
452 printk(" excluding");
453 printk(" %#05lx-%#05lx", i, j-1);
454 sub_interval(&s_data->mem_db, i, j-i);
458 printk(bad ? "\n" : " clean.\n");
463 #ifdef CONFIG_PCMCIA_PROBE
466 * inv_probe() - top-to-bottom search for one usuable high memory area
467 * @s: PCMCIA socket to validate
468 * @m: resource_map to check
470 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
472 struct socket_data *s_data = s->resource_data;
474 if (m == &s_data->mem_db)
476 ok = inv_probe(m->next, s);
478 if (m->base >= 0x100000)
479 sub_interval(&s_data->mem_db, m->base, m->num);
482 if (m->base < 0x100000)
484 return do_mem_probe(s, m->base, m->num, readable, checksum);
488 * validate_mem() - memory probe function
489 * @s: PCMCIA socket to validate
490 * @probe_mask: MEM_PROBE_LOW | MEM_PROBE_HIGH
492 * The memory probe. If the memory list includes a 64K-aligned block
493 * below 1MB, we probe in 64K chunks, and as soon as we accumulate at
494 * least mem_limit free space, we quit. Returns 0 on usuable ports.
496 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
498 struct resource_map *m, mm;
499 static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
500 unsigned long b, i, ok = 0;
501 struct socket_data *s_data = s->resource_data;
503 /* We do up to four passes through the list */
504 if (probe_mask & MEM_PROBE_HIGH) {
505 if (inv_probe(s_data->mem_db.next, s) > 0)
507 if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
509 dev_printk(KERN_NOTICE, &s->dev,
510 "cs: warning: no high memory space available!\n");
514 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
516 /* Only probe < 1 MB */
517 if (mm.base >= 0x100000)
519 if ((mm.base | mm.num) & 0xffff) {
520 ok += do_mem_probe(s, mm.base, mm.num, readable,
524 /* Special probe for 64K-aligned block */
525 for (i = 0; i < 4; i++) {
527 if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
529 sub_interval(&s_data->mem_db, b, 0x10000);
531 ok += do_mem_probe(s, b, 0x10000,
543 #else /* CONFIG_PCMCIA_PROBE */
546 * validate_mem() - memory probe function
547 * @s: PCMCIA socket to validate
548 * @probe_mask: ignored
550 * Returns 0 on usuable ports.
552 static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
554 struct resource_map *m, mm;
555 struct socket_data *s_data = s->resource_data;
556 unsigned long ok = 0;
558 for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
560 ok += do_mem_probe(s, mm.base, mm.num, readable, checksum);
567 #endif /* CONFIG_PCMCIA_PROBE */
571 * pcmcia_nonstatic_validate_mem() - try to validate iomem for PCMCIA use
572 * @s: PCMCIA socket to validate
574 * This is tricky... when we set up CIS memory, we try to validate
575 * the memory window space allocations.
577 * Locking note: Must be called with skt_mutex held!
579 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
581 struct socket_data *s_data = s->resource_data;
582 unsigned int probe_mask = MEM_PROBE_LOW;
585 if (!probe_mem || !(s->state & SOCKET_PRESENT))
588 if (s->features & SS_CAP_PAGE_REGS)
589 probe_mask = MEM_PROBE_HIGH;
591 ret = validate_mem(s, probe_mask);
593 if (s_data->mem_db_valid.next != &s_data->mem_db_valid)
599 struct pcmcia_align_data {
601 unsigned long offset;
602 struct resource_map *map;
605 static resource_size_t pcmcia_common_align(struct pcmcia_align_data *align_data,
606 resource_size_t start)
610 * Ensure that we have the correct start address
612 ret = (start & ~align_data->mask) + align_data->offset;
614 ret += align_data->mask + 1;
618 static resource_size_t
619 pcmcia_align(void *align_data, const struct resource *res,
620 resource_size_t size, resource_size_t align)
622 struct pcmcia_align_data *data = align_data;
623 struct resource_map *m;
624 resource_size_t start;
626 start = pcmcia_common_align(data, res->start);
628 for (m = data->map->next; m != data->map; m = m->next) {
629 unsigned long map_start = m->base;
630 unsigned long map_end = m->base + m->num - 1;
633 * If the lower resources are not available, try aligning
634 * to this entry of the resource database to see if it'll
637 if (start < map_start)
638 start = pcmcia_common_align(data, map_start);
641 * If we're above the area which was passed in, there's
642 * no point proceeding.
644 if (start >= res->end)
647 if ((start + size - 1) <= map_end)
652 * If we failed to find something suitable, ensure we fail.
661 * Adjust an existing IO region allocation, but making sure that we don't
662 * encroach outside the resources which the user supplied.
664 static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_start,
665 unsigned long r_end, struct pcmcia_socket *s)
667 struct resource_map *m;
668 struct socket_data *s_data = s->resource_data;
671 for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
672 unsigned long start = m->base;
673 unsigned long end = m->base + m->num - 1;
675 if (start > r_start || r_end > end)
678 ret = adjust_resource(res, r_start, r_end - r_start + 1);
685 /*======================================================================
687 These find ranges of I/O ports or memory addresses that are not
688 currently allocated by other devices.
690 The 'align' field should reflect the number of bits of address
691 that need to be preserved from the initial value of *base. It
692 should be a power of two, greater than or equal to 'num'. A value
693 of 0 means that all bits of *base are significant. *base should
694 also be strictly less than 'align'.
696 ======================================================================*/
698 static struct resource *nonstatic_find_io_region(unsigned long base, int num,
699 unsigned long align, struct pcmcia_socket *s)
701 struct resource *res = make_resource(0, num, IORESOURCE_IO, dev_name(&s->dev));
702 struct socket_data *s_data = s->resource_data;
703 struct pcmcia_align_data data;
704 unsigned long min = base;
710 data.mask = align - 1;
711 data.offset = base & data.mask;
712 data.map = &s_data->io_db;
716 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
717 min, 0, pcmcia_align, &data);
720 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
721 1, pcmcia_align, &data);
730 static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
731 u_long align, int low, struct pcmcia_socket *s)
733 struct resource *res = make_resource(0, num, IORESOURCE_MEM, dev_name(&s->dev));
734 struct socket_data *s_data = s->resource_data;
735 struct pcmcia_align_data data;
736 unsigned long min, max;
739 low = low || !(s->features & SS_CAP_PAGE_REGS);
741 data.mask = align - 1;
742 data.offset = base & data.mask;
744 for (i = 0; i < 2; i++) {
745 data.map = &s_data->mem_db_valid;
748 min = base < max ? base : 0;
751 min = 0x100000UL + base;
754 for (j = 0; j < 2; j++) {
757 ret = pci_bus_alloc_resource(s->cb_dev->bus,
759 pcmcia_align, &data);
763 ret = allocate_resource(&iomem_resource,
764 res, num, min, max, 1,
765 pcmcia_align, &data);
769 data.map = &s_data->mem_db;
784 static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
786 struct socket_data *data = s->resource_data;
787 unsigned long size = end - start + 1;
794 case ADD_MANAGED_RESOURCE:
795 ret = add_interval(&data->mem_db, start, size);
797 do_mem_probe(s, start, size, NULL, NULL);
799 case REMOVE_MANAGED_RESOURCE:
800 ret = sub_interval(&data->mem_db, start, size);
810 static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
812 struct socket_data *data = s->resource_data;
816 #if defined(CONFIG_X86)
817 /* on x86, avoid anything < 0x100 for it is often used for
818 * legacy platform devices */
823 size = end - start + 1;
828 if (end > IO_SPACE_LIMIT)
832 case ADD_MANAGED_RESOURCE:
833 if (add_interval(&data->io_db, start, size) != 0) {
837 #ifdef CONFIG_PCMCIA_PROBE
839 do_io_probe(s, start, size);
842 case REMOVE_MANAGED_RESOURCE:
843 sub_interval(&data->io_db, start, size);
855 static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
857 struct resource *res;
860 if (!s->cb_dev || !s->cb_dev->bus)
863 #if defined(CONFIG_X86)
864 /* If this is the root bus, the risk of hitting
865 * some strange system devices which aren't protected
866 * by either ACPI resource tables or properly requested
867 * resources is too big. Therefore, don't do auto-adding
868 * of resources at the moment.
870 if (s->cb_dev->bus->number == 0)
874 pci_bus_for_each_resource(s->cb_dev->bus, res, i) {
878 if (res->flags & IORESOURCE_IO) {
879 if (res == &ioport_resource)
881 dev_printk(KERN_INFO, &s->cb_dev->dev,
882 "pcmcia: parent PCI bridge window: %pR\n",
884 if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
885 done |= IORESOURCE_IO;
889 if (res->flags & IORESOURCE_MEM) {
890 if (res == &iomem_resource)
892 dev_printk(KERN_INFO, &s->cb_dev->dev,
893 "pcmcia: parent PCI bridge window: %pR\n",
895 if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
896 done |= IORESOURCE_MEM;
900 /* if we got at least one of IO, and one of MEM, we can be glad and
901 * activate the PCMCIA subsystem */
902 if (done == (IORESOURCE_MEM | IORESOURCE_IO))
903 s->resource_setup_done = 1;
910 static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
918 static int nonstatic_init(struct pcmcia_socket *s)
920 struct socket_data *data;
922 data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
926 data->mem_db.next = &data->mem_db;
927 data->mem_db_valid.next = &data->mem_db_valid;
928 data->io_db.next = &data->io_db;
930 s->resource_data = (void *) data;
932 nonstatic_autoadd_resources(s);
937 static void nonstatic_release_resource_db(struct pcmcia_socket *s)
939 struct socket_data *data = s->resource_data;
940 struct resource_map *p, *q;
942 for (p = data->mem_db_valid.next; p != &data->mem_db_valid; p = q) {
946 for (p = data->mem_db.next; p != &data->mem_db; p = q) {
950 for (p = data->io_db.next; p != &data->io_db; p = q) {
957 struct pccard_resource_ops pccard_nonstatic_ops = {
958 .validate_mem = pcmcia_nonstatic_validate_mem,
959 .adjust_io_region = nonstatic_adjust_io_region,
960 .find_io = nonstatic_find_io_region,
961 .find_mem = nonstatic_find_mem_region,
963 .add_mem = adjust_memory,
964 .init = nonstatic_init,
965 .exit = nonstatic_release_resource_db,
967 EXPORT_SYMBOL(pccard_nonstatic_ops);
970 /* sysfs interface to the resource database */
972 static ssize_t show_io_db(struct device *dev,
973 struct device_attribute *attr, char *buf)
975 struct pcmcia_socket *s = dev_get_drvdata(dev);
976 struct socket_data *data;
977 struct resource_map *p;
980 mutex_lock(&s->ops_mutex);
981 data = s->resource_data;
983 for (p = data->io_db.next; p != &data->io_db; p = p->next) {
984 if (ret > (PAGE_SIZE - 10))
986 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
987 "0x%08lx - 0x%08lx\n",
988 ((unsigned long) p->base),
989 ((unsigned long) p->base + p->num - 1));
992 mutex_unlock(&s->ops_mutex);
996 static ssize_t store_io_db(struct device *dev,
997 struct device_attribute *attr,
998 const char *buf, size_t count)
1000 struct pcmcia_socket *s = dev_get_drvdata(dev);
1001 unsigned long start_addr, end_addr;
1002 unsigned int add = ADD_MANAGED_RESOURCE;
1005 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1007 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1008 add = REMOVE_MANAGED_RESOURCE;
1010 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1012 add = ADD_MANAGED_RESOURCE;
1017 if (end_addr < start_addr)
1020 mutex_lock(&s->ops_mutex);
1021 ret = adjust_io(s, add, start_addr, end_addr);
1023 s->resource_setup_new = 1;
1024 mutex_unlock(&s->ops_mutex);
1026 return ret ? ret : count;
1028 static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
1030 static ssize_t show_mem_db(struct device *dev,
1031 struct device_attribute *attr, char *buf)
1033 struct pcmcia_socket *s = dev_get_drvdata(dev);
1034 struct socket_data *data;
1035 struct resource_map *p;
1038 mutex_lock(&s->ops_mutex);
1039 data = s->resource_data;
1041 for (p = data->mem_db_valid.next; p != &data->mem_db_valid;
1043 if (ret > (PAGE_SIZE - 10))
1045 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1046 "0x%08lx - 0x%08lx\n",
1047 ((unsigned long) p->base),
1048 ((unsigned long) p->base + p->num - 1));
1051 for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
1052 if (ret > (PAGE_SIZE - 10))
1054 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1055 "0x%08lx - 0x%08lx\n",
1056 ((unsigned long) p->base),
1057 ((unsigned long) p->base + p->num - 1));
1060 mutex_unlock(&s->ops_mutex);
1064 static ssize_t store_mem_db(struct device *dev,
1065 struct device_attribute *attr,
1066 const char *buf, size_t count)
1068 struct pcmcia_socket *s = dev_get_drvdata(dev);
1069 unsigned long start_addr, end_addr;
1070 unsigned int add = ADD_MANAGED_RESOURCE;
1073 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1075 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1076 add = REMOVE_MANAGED_RESOURCE;
1078 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1080 add = ADD_MANAGED_RESOURCE;
1085 if (end_addr < start_addr)
1088 mutex_lock(&s->ops_mutex);
1089 ret = adjust_memory(s, add, start_addr, end_addr);
1091 s->resource_setup_new = 1;
1092 mutex_unlock(&s->ops_mutex);
1094 return ret ? ret : count;
1096 static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
1098 static struct attribute *pccard_rsrc_attributes[] = {
1099 &dev_attr_available_resources_io.attr,
1100 &dev_attr_available_resources_mem.attr,
1104 static const struct attribute_group rsrc_attributes = {
1105 .attrs = pccard_rsrc_attributes,
1108 static int __devinit pccard_sysfs_add_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 return sysfs_create_group(&dev->kobj, &rsrc_attributes);
1118 static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
1119 struct class_interface *class_intf)
1121 struct pcmcia_socket *s = dev_get_drvdata(dev);
1123 if (s->resource_ops != &pccard_nonstatic_ops)
1125 sysfs_remove_group(&dev->kobj, &rsrc_attributes);
1128 static struct class_interface pccard_rsrc_interface __refdata = {
1129 .class = &pcmcia_socket_class,
1130 .add_dev = &pccard_sysfs_add_rsrc,
1131 .remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc),
1134 static int __init nonstatic_sysfs_init(void)
1136 return class_interface_register(&pccard_rsrc_interface);
1139 static void __exit nonstatic_sysfs_exit(void)
1141 class_interface_unregister(&pccard_rsrc_interface);
1144 module_init(nonstatic_sysfs_init);
1145 module_exit(nonstatic_sysfs_exit);