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;
813 unsigned long size = end - start + 1;
816 #if defined(CONFIG_X86)
817 /* on x86, avoid anything < 0x100 for it is often used for
818 * legacy platform devices */
826 if (end > IO_SPACE_LIMIT)
830 case ADD_MANAGED_RESOURCE:
831 if (add_interval(&data->io_db, start, size) != 0) {
835 #ifdef CONFIG_PCMCIA_PROBE
837 do_io_probe(s, start, size);
840 case REMOVE_MANAGED_RESOURCE:
841 sub_interval(&data->io_db, start, size);
853 static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
855 struct resource *res;
858 if (!s->cb_dev || !s->cb_dev->bus)
861 #if defined(CONFIG_X86)
862 /* If this is the root bus, the risk of hitting
863 * some strange system devices which aren't protected
864 * by either ACPI resource tables or properly requested
865 * resources is too big. Therefore, don't do auto-adding
866 * of resources at the moment.
868 if (s->cb_dev->bus->number == 0)
872 pci_bus_for_each_resource(s->cb_dev->bus, res, i) {
876 if (res->flags & IORESOURCE_IO) {
877 if (res == &ioport_resource)
879 dev_printk(KERN_INFO, &s->cb_dev->dev,
880 "pcmcia: parent PCI bridge window: %pR\n",
882 if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
883 done |= IORESOURCE_IO;
887 if (res->flags & IORESOURCE_MEM) {
888 if (res == &iomem_resource)
890 dev_printk(KERN_INFO, &s->cb_dev->dev,
891 "pcmcia: parent PCI bridge window: %pR\n",
893 if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
894 done |= IORESOURCE_MEM;
898 /* if we got at least one of IO, and one of MEM, we can be glad and
899 * activate the PCMCIA subsystem */
900 if (done == (IORESOURCE_MEM | IORESOURCE_IO))
901 s->resource_setup_done = 1;
908 static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
916 static int nonstatic_init(struct pcmcia_socket *s)
918 struct socket_data *data;
920 data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
924 data->mem_db.next = &data->mem_db;
925 data->mem_db_valid.next = &data->mem_db_valid;
926 data->io_db.next = &data->io_db;
928 s->resource_data = (void *) data;
930 nonstatic_autoadd_resources(s);
935 static void nonstatic_release_resource_db(struct pcmcia_socket *s)
937 struct socket_data *data = s->resource_data;
938 struct resource_map *p, *q;
940 for (p = data->mem_db_valid.next; p != &data->mem_db_valid; p = q) {
944 for (p = data->mem_db.next; p != &data->mem_db; p = q) {
948 for (p = data->io_db.next; p != &data->io_db; p = q) {
955 struct pccard_resource_ops pccard_nonstatic_ops = {
956 .validate_mem = pcmcia_nonstatic_validate_mem,
957 .adjust_io_region = nonstatic_adjust_io_region,
958 .find_io = nonstatic_find_io_region,
959 .find_mem = nonstatic_find_mem_region,
961 .add_mem = adjust_memory,
962 .init = nonstatic_init,
963 .exit = nonstatic_release_resource_db,
965 EXPORT_SYMBOL(pccard_nonstatic_ops);
968 /* sysfs interface to the resource database */
970 static ssize_t show_io_db(struct device *dev,
971 struct device_attribute *attr, char *buf)
973 struct pcmcia_socket *s = dev_get_drvdata(dev);
974 struct socket_data *data;
975 struct resource_map *p;
978 mutex_lock(&s->ops_mutex);
979 data = s->resource_data;
981 for (p = data->io_db.next; p != &data->io_db; p = p->next) {
982 if (ret > (PAGE_SIZE - 10))
984 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
985 "0x%08lx - 0x%08lx\n",
986 ((unsigned long) p->base),
987 ((unsigned long) p->base + p->num - 1));
990 mutex_unlock(&s->ops_mutex);
994 static ssize_t store_io_db(struct device *dev,
995 struct device_attribute *attr,
996 const char *buf, size_t count)
998 struct pcmcia_socket *s = dev_get_drvdata(dev);
999 unsigned long start_addr, end_addr;
1000 unsigned int add = ADD_MANAGED_RESOURCE;
1003 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1005 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1006 add = REMOVE_MANAGED_RESOURCE;
1008 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1010 add = ADD_MANAGED_RESOURCE;
1015 if (end_addr < start_addr)
1018 mutex_lock(&s->ops_mutex);
1019 ret = adjust_io(s, add, start_addr, end_addr);
1021 s->resource_setup_new = 1;
1022 mutex_unlock(&s->ops_mutex);
1024 return ret ? ret : count;
1026 static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
1028 static ssize_t show_mem_db(struct device *dev,
1029 struct device_attribute *attr, char *buf)
1031 struct pcmcia_socket *s = dev_get_drvdata(dev);
1032 struct socket_data *data;
1033 struct resource_map *p;
1036 mutex_lock(&s->ops_mutex);
1037 data = s->resource_data;
1039 for (p = data->mem_db_valid.next; p != &data->mem_db_valid;
1041 if (ret > (PAGE_SIZE - 10))
1043 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1044 "0x%08lx - 0x%08lx\n",
1045 ((unsigned long) p->base),
1046 ((unsigned long) p->base + p->num - 1));
1049 for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
1050 if (ret > (PAGE_SIZE - 10))
1052 ret += snprintf(&buf[ret], (PAGE_SIZE - ret - 1),
1053 "0x%08lx - 0x%08lx\n",
1054 ((unsigned long) p->base),
1055 ((unsigned long) p->base + p->num - 1));
1058 mutex_unlock(&s->ops_mutex);
1062 static ssize_t store_mem_db(struct device *dev,
1063 struct device_attribute *attr,
1064 const char *buf, size_t count)
1066 struct pcmcia_socket *s = dev_get_drvdata(dev);
1067 unsigned long start_addr, end_addr;
1068 unsigned int add = ADD_MANAGED_RESOURCE;
1071 ret = sscanf(buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
1073 ret = sscanf(buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
1074 add = REMOVE_MANAGED_RESOURCE;
1076 ret = sscanf(buf, "0x%lx - 0x%lx", &start_addr,
1078 add = ADD_MANAGED_RESOURCE;
1083 if (end_addr < start_addr)
1086 mutex_lock(&s->ops_mutex);
1087 ret = adjust_memory(s, add, start_addr, end_addr);
1089 s->resource_setup_new = 1;
1090 mutex_unlock(&s->ops_mutex);
1092 return ret ? ret : count;
1094 static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
1096 static struct attribute *pccard_rsrc_attributes[] = {
1097 &dev_attr_available_resources_io.attr,
1098 &dev_attr_available_resources_mem.attr,
1102 static const struct attribute_group rsrc_attributes = {
1103 .attrs = pccard_rsrc_attributes,
1106 static int __devinit pccard_sysfs_add_rsrc(struct device *dev,
1107 struct class_interface *class_intf)
1109 struct pcmcia_socket *s = dev_get_drvdata(dev);
1111 if (s->resource_ops != &pccard_nonstatic_ops)
1113 return sysfs_create_group(&dev->kobj, &rsrc_attributes);
1116 static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
1117 struct class_interface *class_intf)
1119 struct pcmcia_socket *s = dev_get_drvdata(dev);
1121 if (s->resource_ops != &pccard_nonstatic_ops)
1123 sysfs_remove_group(&dev->kobj, &rsrc_attributes);
1126 static struct class_interface pccard_rsrc_interface __refdata = {
1127 .class = &pcmcia_socket_class,
1128 .add_dev = &pccard_sysfs_add_rsrc,
1129 .remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc),
1132 static int __init nonstatic_sysfs_init(void)
1134 return class_interface_register(&pccard_rsrc_interface);
1137 static void __exit nonstatic_sysfs_exit(void)
1139 class_interface_unregister(&pccard_rsrc_interface);
1142 module_init(nonstatic_sysfs_init);
1143 module_exit(nonstatic_sysfs_exit);