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 io_db
;
59 unsigned int rsrc_mem_probe
;
62 static DEFINE_MUTEX(rsrc_mutex
);
63 #define MEM_PROBE_LOW (1 << 0)
64 #define MEM_PROBE_HIGH (1 << 1)
67 /*======================================================================
69 Linux resource management extensions
71 ======================================================================*/
73 static struct resource
*
74 make_resource(resource_size_t b
, resource_size_t n
, int flags
, char *name
)
76 struct resource
*res
= kzalloc(sizeof(*res
), GFP_KERNEL
);
87 static struct resource
*
88 claim_region(struct pcmcia_socket
*s
, resource_size_t base
,
89 resource_size_t size
, int type
, char *name
)
91 struct resource
*res
, *parent
;
93 parent
= type
& IORESOURCE_MEM
? &iomem_resource
: &ioport_resource
;
94 res
= make_resource(base
, size
, type
| IORESOURCE_BUSY
, name
);
99 parent
= pci_find_parent_resource(s
->cb_dev
, res
);
101 if (!parent
|| request_resource(parent
, res
)) {
109 static void free_region(struct resource
*res
)
112 release_resource(res
);
117 /*======================================================================
119 These manage the internal databases of available resources.
121 ======================================================================*/
123 static int add_interval(struct resource_map
*map
, u_long base
, u_long num
)
125 struct resource_map
*p
, *q
;
127 for (p
= map
; ; p
= p
->next
) {
128 if ((p
!= map
) && (p
->base
+p
->num
-1 >= base
))
130 if ((p
->next
== map
) || (p
->next
->base
> base
+num
-1))
133 q
= kmalloc(sizeof(struct resource_map
), GFP_KERNEL
);
135 printk(KERN_WARNING
"out of memory to update resources\n");
138 q
->base
= base
; q
->num
= num
;
139 q
->next
= p
->next
; p
->next
= q
;
143 /*====================================================================*/
145 static int sub_interval(struct resource_map
*map
, u_long base
, u_long num
)
147 struct resource_map
*p
, *q
;
149 for (p
= map
; ; p
= q
) {
153 if ((q
->base
+q
->num
> base
) && (base
+num
> q
->base
)) {
154 if (q
->base
>= base
) {
155 if (q
->base
+q
->num
<= base
+num
) {
156 /* Delete whole block */
159 /* don't advance the pointer yet */
162 /* Cut off bit from the front */
163 q
->num
= q
->base
+ q
->num
- base
- num
;
164 q
->base
= base
+ num
;
166 } else if (q
->base
+q
->num
<= base
+num
) {
167 /* Cut off bit from the end */
168 q
->num
= base
- q
->base
;
170 /* Split the block into two pieces */
171 p
= kmalloc(sizeof(struct resource_map
), GFP_KERNEL
);
173 printk(KERN_WARNING
"out of memory to update resources\n");
177 p
->num
= q
->base
+q
->num
- p
->base
;
178 q
->num
= base
- q
->base
;
179 p
->next
= q
->next
; q
->next
= p
;
186 /*======================================================================
188 These routines examine a region of IO or memory addresses to
189 determine what ranges might be genuinely available.
191 ======================================================================*/
193 #ifdef CONFIG_PCMCIA_PROBE
194 static void do_io_probe(struct pcmcia_socket
*s
, unsigned int base
,
197 struct resource
*res
;
198 struct socket_data
*s_data
= s
->resource_data
;
199 unsigned int i
, j
, bad
;
201 u_char
*b
, hole
, most
;
203 dev_printk(KERN_INFO
, &s
->dev
, "cs: IO port probe %#x-%#x:",
206 /* First, what does a floating port look like? */
207 b
= kzalloc(256, GFP_KERNEL
);
209 dev_printk(KERN_ERR
, &s
->dev
,
210 "do_io_probe: unable to kmalloc 256 bytes");
213 for (i
= base
, most
= 0; i
< base
+num
; i
+= 8) {
214 res
= claim_region(NULL
, i
, 8, IORESOURCE_IO
, "PCMCIA IO probe");
218 for (j
= 1; j
< 8; j
++)
219 if (inb(i
+j
) != hole
) break;
221 if ((j
== 8) && (++b
[hole
] > b
[most
]))
223 if (b
[most
] == 127) break;
228 for (i
= base
; i
< base
+num
; i
+= 8) {
229 res
= claim_region(NULL
, i
, 8, IORESOURCE_IO
, "PCMCIA IO probe");
232 for (j
= 0; j
< 8; j
++)
233 if (inb(i
+j
) != most
) break;
237 printk(" excluding");
242 sub_interval(&s_data
->io_db
, bad
, i
-bad
);
243 printk(" %#x-%#x", bad
, i
-1);
249 if ((num
> 16) && (bad
== base
) && (i
== base
+num
)) {
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 /*======================================================================
264 This is tricky... when we set up CIS memory, we try to validate
265 the memory window space allocations.
267 ======================================================================*/
269 /* Validation function for cards with a valid CIS */
270 static int readable(struct pcmcia_socket
*s
, struct resource
*res
,
275 s
->cis_mem
.res
= res
;
276 s
->cis_virt
= ioremap(res
->start
, s
->map_size
);
278 ret
= pccard_validate_cis(s
, BIND_FN_ALL
, count
);
279 /* invalidate mapping and CIS cache */
280 iounmap(s
->cis_virt
);
282 destroy_cis_cache(s
);
284 s
->cis_mem
.res
= NULL
;
285 if ((ret
!= 0) || (*count
== 0))
290 /* Validation function for simple memory cards */
291 static int checksum(struct pcmcia_socket
*s
, struct resource
*res
)
294 int i
, a
= 0, b
= -1, d
;
297 virt
= ioremap(res
->start
, s
->map_size
);
300 map
.flags
= MAP_ACTIVE
;
304 s
->ops
->set_mem_map(s
, &map
);
306 /* Don't bother checking every word... */
307 for (i
= 0; i
< s
->map_size
; i
+= 44) {
314 s
->ops
->set_mem_map(s
, &map
);
319 return (b
== -1) ? -1 : (a
>>1);
323 cis_readable(struct pcmcia_socket
*s
, unsigned long base
, unsigned long size
)
325 struct resource
*res1
, *res2
;
326 unsigned int info1
, info2
;
329 res1
= claim_region(s
, base
, size
/2, IORESOURCE_MEM
, "cs memory probe");
330 res2
= claim_region(s
, base
+ size
/2, size
/2, IORESOURCE_MEM
, "cs memory probe");
333 ret
= readable(s
, res1
, &info1
);
334 ret
+= readable(s
, res2
, &info2
);
340 return (ret
== 2) && (info1
== info2
);
344 checksum_match(struct pcmcia_socket
*s
, unsigned long base
, unsigned long size
)
346 struct resource
*res1
, *res2
;
349 res1
= claim_region(s
, base
, size
/2, IORESOURCE_MEM
, "cs memory probe");
350 res2
= claim_region(s
, base
+ size
/2, size
/2, IORESOURCE_MEM
, "cs memory probe");
353 a
= checksum(s
, res1
);
354 b
= checksum(s
, res2
);
360 return (a
== b
) && (a
>= 0);
363 /*======================================================================
365 The memory probe. If the memory list includes a 64K-aligned block
366 below 1MB, we probe in 64K chunks, and as soon as we accumulate at
367 least mem_limit free space, we quit.
369 ======================================================================*/
371 static int do_mem_probe(u_long base
, u_long num
, struct pcmcia_socket
*s
)
373 struct socket_data
*s_data
= s
->resource_data
;
374 u_long i
, j
, bad
, fail
, step
;
376 dev_printk(KERN_INFO
, &s
->dev
, "cs: memory probe 0x%06lx-0x%06lx:",
379 step
= (num
< 0x20000) ? 0x2000 : ((num
>>4) & ~0x1fff);
380 /* don't allow too large steps */
383 /* cis_readable wants to map 2x map_size */
384 if (step
< 2 * s
->map_size
)
385 step
= 2 * s
->map_size
;
386 for (i
= j
= base
; i
< base
+num
; i
= j
+ step
) {
388 for (j
= i
; j
< base
+num
; j
+= step
) {
389 if (cis_readable(s
, j
, step
))
392 fail
= ((i
== base
) && (j
== base
+num
));
395 for (j
= i
; j
< base
+num
; j
+= 2*step
)
396 if (checksum_match(s
, j
, step
) &&
397 checksum_match(s
, j
+ step
, step
))
401 if (!bad
) printk(" excluding");
402 printk(" %#05lx-%#05lx", i
, j
-1);
403 sub_interval(&s_data
->mem_db
, i
, j
-i
);
407 printk(bad
? "\n" : " clean.\n");
411 #ifdef CONFIG_PCMCIA_PROBE
413 static u_long
inv_probe(struct resource_map
*m
, struct pcmcia_socket
*s
)
415 struct socket_data
*s_data
= s
->resource_data
;
417 if (m
== &s_data
->mem_db
)
419 ok
= inv_probe(m
->next
, s
);
421 if (m
->base
>= 0x100000)
422 sub_interval(&s_data
->mem_db
, m
->base
, m
->num
);
425 if (m
->base
< 0x100000)
427 return do_mem_probe(m
->base
, m
->num
, s
);
430 static int validate_mem(struct pcmcia_socket
*s
, unsigned int probe_mask
)
432 struct resource_map
*m
, mm
;
433 static unsigned char order
[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
434 unsigned long b
, i
, ok
= 0;
435 struct socket_data
*s_data
= s
->resource_data
;
437 /* We do up to four passes through the list */
438 if (probe_mask
& MEM_PROBE_HIGH
) {
439 if (inv_probe(s_data
->mem_db
.next
, s
) > 0)
441 dev_printk(KERN_NOTICE
, &s
->dev
,
442 "cs: warning: no high memory space available!\n");
446 for (m
= s_data
->mem_db
.next
; m
!= &s_data
->mem_db
; m
= mm
.next
) {
448 /* Only probe < 1 MB */
449 if (mm
.base
>= 0x100000)
451 if ((mm
.base
| mm
.num
) & 0xffff) {
452 ok
+= do_mem_probe(mm
.base
, mm
.num
, s
);
455 /* Special probe for 64K-aligned block */
456 for (i
= 0; i
< 4; i
++) {
458 if ((b
>= mm
.base
) && (b
+0x10000 <= mm
.base
+mm
.num
)) {
460 sub_interval(&s_data
->mem_db
, b
, 0x10000);
462 ok
+= do_mem_probe(b
, 0x10000, s
);
473 #else /* CONFIG_PCMCIA_PROBE */
475 static int validate_mem(struct pcmcia_socket
*s
, unsigned int probe_mask
)
477 struct resource_map
*m
, mm
;
478 struct socket_data
*s_data
= s
->resource_data
;
479 unsigned long ok
= 0;
481 for (m
= s_data
->mem_db
.next
; m
!= &s_data
->mem_db
; m
= mm
.next
) {
483 ok
+= do_mem_probe(mm
.base
, mm
.num
, s
);
490 #endif /* CONFIG_PCMCIA_PROBE */
494 * Locking note: Must be called with skt_mutex held!
496 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket
*s
)
498 struct socket_data
*s_data
= s
->resource_data
;
499 unsigned int probe_mask
= MEM_PROBE_LOW
;
505 mutex_lock(&rsrc_mutex
);
507 if (s
->features
& SS_CAP_PAGE_REGS
)
508 probe_mask
= MEM_PROBE_HIGH
;
510 if (probe_mask
& ~s_data
->rsrc_mem_probe
) {
511 if (s
->state
& SOCKET_PRESENT
)
512 ret
= validate_mem(s
, probe_mask
);
514 s_data
->rsrc_mem_probe
|= probe_mask
;
517 mutex_unlock(&rsrc_mutex
);
522 struct pcmcia_align_data
{
524 unsigned long offset
;
525 struct resource_map
*map
;
529 pcmcia_common_align(void *align_data
, struct resource
*res
,
530 resource_size_t size
, resource_size_t align
)
532 struct pcmcia_align_data
*data
= align_data
;
533 resource_size_t start
;
535 * Ensure that we have the correct start address
537 start
= (res
->start
& ~data
->mask
) + data
->offset
;
538 if (start
< res
->start
)
539 start
+= data
->mask
+ 1;
544 pcmcia_align(void *align_data
, struct resource
*res
, resource_size_t size
,
545 resource_size_t align
)
547 struct pcmcia_align_data
*data
= align_data
;
548 struct resource_map
*m
;
550 pcmcia_common_align(data
, res
, size
, align
);
552 for (m
= data
->map
->next
; m
!= data
->map
; m
= m
->next
) {
553 unsigned long start
= m
->base
;
554 unsigned long end
= m
->base
+ m
->num
- 1;
557 * If the lower resources are not available, try aligning
558 * to this entry of the resource database to see if it'll
561 if (res
->start
< start
) {
563 pcmcia_common_align(data
, res
, size
, align
);
567 * If we're above the area which was passed in, there's
568 * no point proceeding.
570 if (res
->start
>= res
->end
)
573 if ((res
->start
+ size
- 1) <= end
)
578 * If we failed to find something suitable, ensure we fail.
581 res
->start
= res
->end
;
585 * Adjust an existing IO region allocation, but making sure that we don't
586 * encroach outside the resources which the user supplied.
588 static int nonstatic_adjust_io_region(struct resource
*res
, unsigned long r_start
,
589 unsigned long r_end
, struct pcmcia_socket
*s
)
591 struct resource_map
*m
;
592 struct socket_data
*s_data
= s
->resource_data
;
595 mutex_lock(&rsrc_mutex
);
596 for (m
= s_data
->io_db
.next
; m
!= &s_data
->io_db
; m
= m
->next
) {
597 unsigned long start
= m
->base
;
598 unsigned long end
= m
->base
+ m
->num
- 1;
600 if (start
> r_start
|| r_end
> end
)
603 ret
= adjust_resource(res
, r_start
, r_end
- r_start
+ 1);
606 mutex_unlock(&rsrc_mutex
);
611 /*======================================================================
613 These find ranges of I/O ports or memory addresses that are not
614 currently allocated by other devices.
616 The 'align' field should reflect the number of bits of address
617 that need to be preserved from the initial value of *base. It
618 should be a power of two, greater than or equal to 'num'. A value
619 of 0 means that all bits of *base are significant. *base should
620 also be strictly less than 'align'.
622 ======================================================================*/
624 static struct resource
*nonstatic_find_io_region(unsigned long base
, int num
,
625 unsigned long align
, struct pcmcia_socket
*s
)
627 struct resource
*res
= make_resource(0, num
, IORESOURCE_IO
, s
->dev
.bus_id
);
628 struct socket_data
*s_data
= s
->resource_data
;
629 struct pcmcia_align_data data
;
630 unsigned long min
= base
;
636 data
.mask
= align
- 1;
637 data
.offset
= base
& data
.mask
;
638 data
.map
= &s_data
->io_db
;
640 mutex_lock(&rsrc_mutex
);
643 ret
= pci_bus_alloc_resource(s
->cb_dev
->bus
, res
, num
, 1,
644 min
, 0, pcmcia_align
, &data
);
647 ret
= allocate_resource(&ioport_resource
, res
, num
, min
, ~0UL,
648 1, pcmcia_align
, &data
);
649 mutex_unlock(&rsrc_mutex
);
658 static struct resource
* nonstatic_find_mem_region(u_long base
, u_long num
,
659 u_long align
, int low
, struct pcmcia_socket
*s
)
661 struct resource
*res
= make_resource(0, num
, IORESOURCE_MEM
, s
->dev
.bus_id
);
662 struct socket_data
*s_data
= s
->resource_data
;
663 struct pcmcia_align_data data
;
664 unsigned long min
, max
;
667 low
= low
|| !(s
->features
& SS_CAP_PAGE_REGS
);
669 data
.mask
= align
- 1;
670 data
.offset
= base
& data
.mask
;
671 data
.map
= &s_data
->mem_db
;
673 for (i
= 0; i
< 2; i
++) {
676 min
= base
< max
? base
: 0;
679 min
= 0x100000UL
+ base
;
682 mutex_lock(&rsrc_mutex
);
685 ret
= pci_bus_alloc_resource(s
->cb_dev
->bus
, res
, num
,
687 pcmcia_align
, &data
);
690 ret
= allocate_resource(&iomem_resource
, res
, num
, min
,
691 max
, 1, pcmcia_align
, &data
);
692 mutex_unlock(&rsrc_mutex
);
706 static int adjust_memory(struct pcmcia_socket
*s
, unsigned int action
, unsigned long start
, unsigned long end
)
708 struct socket_data
*data
= s
->resource_data
;
709 unsigned long size
= end
- start
+ 1;
715 mutex_lock(&rsrc_mutex
);
717 case ADD_MANAGED_RESOURCE
:
718 ret
= add_interval(&data
->mem_db
, start
, size
);
720 case REMOVE_MANAGED_RESOURCE
:
721 ret
= sub_interval(&data
->mem_db
, start
, size
);
723 struct pcmcia_socket
*socket
;
724 down_read(&pcmcia_socket_list_rwsem
);
725 list_for_each_entry(socket
, &pcmcia_socket_list
, socket_list
)
726 release_cis_mem(socket
);
727 up_read(&pcmcia_socket_list_rwsem
);
733 mutex_unlock(&rsrc_mutex
);
739 static int adjust_io(struct pcmcia_socket
*s
, unsigned int action
, unsigned long start
, unsigned long end
)
741 struct socket_data
*data
= s
->resource_data
;
742 unsigned long size
= end
- start
+ 1;
748 if (end
> IO_SPACE_LIMIT
)
751 mutex_lock(&rsrc_mutex
);
753 case ADD_MANAGED_RESOURCE
:
754 if (add_interval(&data
->io_db
, start
, size
) != 0) {
758 #ifdef CONFIG_PCMCIA_PROBE
760 do_io_probe(s
, start
, size
);
763 case REMOVE_MANAGED_RESOURCE
:
764 sub_interval(&data
->io_db
, start
, size
);
770 mutex_unlock(&rsrc_mutex
);
777 static int nonstatic_autoadd_resources(struct pcmcia_socket
*s
)
779 struct resource
*res
;
782 if (!s
->cb_dev
|| !s
->cb_dev
->bus
)
785 #if defined(CONFIG_X86)
786 /* If this is the root bus, the risk of hitting
787 * some strange system devices which aren't protected
788 * by either ACPI resource tables or properly requested
789 * resources is too big. Therefore, don't do auto-adding
790 * of resources at the moment.
792 if (s
->cb_dev
->bus
->number
== 0)
796 for (i
=0; i
< PCI_BUS_NUM_RESOURCES
; i
++) {
797 res
= s
->cb_dev
->bus
->resource
[i
];
801 if (res
->flags
& IORESOURCE_IO
) {
802 if (res
== &ioport_resource
)
804 dev_printk(KERN_INFO
, &s
->cb_dev
->dev
,
805 "pcmcia: parent PCI bridge I/O "
806 "window: 0x%llx - 0x%llx\n",
807 (unsigned long long)res
->start
,
808 (unsigned long long)res
->end
);
809 if (!adjust_io(s
, ADD_MANAGED_RESOURCE
, res
->start
, res
->end
))
810 done
|= IORESOURCE_IO
;
814 if (res
->flags
& IORESOURCE_MEM
) {
815 if (res
== &iomem_resource
)
817 dev_printk(KERN_INFO
, &s
->cb_dev
->dev
,
818 "pcmcia: parent PCI bridge Memory "
819 "window: 0x%llx - 0x%llx\n",
820 (unsigned long long)res
->start
,
821 (unsigned long long)res
->end
);
822 if (!adjust_memory(s
, ADD_MANAGED_RESOURCE
, res
->start
, res
->end
))
823 done
|= IORESOURCE_MEM
;
827 /* if we got at least one of IO, and one of MEM, we can be glad and
828 * activate the PCMCIA subsystem */
829 if (done
== (IORESOURCE_MEM
| IORESOURCE_IO
))
830 s
->resource_setup_done
= 1;
837 static inline int nonstatic_autoadd_resources(struct pcmcia_socket
*s
)
845 static int nonstatic_init(struct pcmcia_socket
*s
)
847 struct socket_data
*data
;
849 data
= kzalloc(sizeof(struct socket_data
), GFP_KERNEL
);
853 data
->mem_db
.next
= &data
->mem_db
;
854 data
->io_db
.next
= &data
->io_db
;
856 s
->resource_data
= (void *) data
;
858 nonstatic_autoadd_resources(s
);
863 static void nonstatic_release_resource_db(struct pcmcia_socket
*s
)
865 struct socket_data
*data
= s
->resource_data
;
866 struct resource_map
*p
, *q
;
868 mutex_lock(&rsrc_mutex
);
869 for (p
= data
->mem_db
.next
; p
!= &data
->mem_db
; p
= q
) {
873 for (p
= data
->io_db
.next
; p
!= &data
->io_db
; p
= q
) {
877 mutex_unlock(&rsrc_mutex
);
881 struct pccard_resource_ops pccard_nonstatic_ops
= {
882 .validate_mem
= pcmcia_nonstatic_validate_mem
,
883 .adjust_io_region
= nonstatic_adjust_io_region
,
884 .find_io
= nonstatic_find_io_region
,
885 .find_mem
= nonstatic_find_mem_region
,
887 .add_mem
= adjust_memory
,
888 .init
= nonstatic_init
,
889 .exit
= nonstatic_release_resource_db
,
891 EXPORT_SYMBOL(pccard_nonstatic_ops
);
894 /* sysfs interface to the resource database */
896 static ssize_t
show_io_db(struct device
*dev
,
897 struct device_attribute
*attr
, char *buf
)
899 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
900 struct socket_data
*data
;
901 struct resource_map
*p
;
904 mutex_lock(&rsrc_mutex
);
905 data
= s
->resource_data
;
907 for (p
= data
->io_db
.next
; p
!= &data
->io_db
; p
= p
->next
) {
908 if (ret
> (PAGE_SIZE
- 10))
910 ret
+= snprintf (&buf
[ret
], (PAGE_SIZE
- ret
- 1),
911 "0x%08lx - 0x%08lx\n",
912 ((unsigned long) p
->base
),
913 ((unsigned long) p
->base
+ p
->num
- 1));
916 mutex_unlock(&rsrc_mutex
);
920 static ssize_t
store_io_db(struct device
*dev
,
921 struct device_attribute
*attr
,
922 const char *buf
, size_t count
)
924 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
925 unsigned long start_addr
, end_addr
;
926 unsigned int add
= ADD_MANAGED_RESOURCE
;
929 ret
= sscanf (buf
, "+ 0x%lx - 0x%lx", &start_addr
, &end_addr
);
931 ret
= sscanf (buf
, "- 0x%lx - 0x%lx", &start_addr
, &end_addr
);
932 add
= REMOVE_MANAGED_RESOURCE
;
934 ret
= sscanf (buf
, "0x%lx - 0x%lx", &start_addr
, &end_addr
);
935 add
= ADD_MANAGED_RESOURCE
;
940 if (end_addr
< start_addr
)
943 ret
= adjust_io(s
, add
, start_addr
, end_addr
);
945 s
->resource_setup_new
= 1;
947 return ret
? ret
: count
;
949 static DEVICE_ATTR(available_resources_io
, 0600, show_io_db
, store_io_db
);
951 static ssize_t
show_mem_db(struct device
*dev
,
952 struct device_attribute
*attr
, char *buf
)
954 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
955 struct socket_data
*data
;
956 struct resource_map
*p
;
959 mutex_lock(&rsrc_mutex
);
960 data
= s
->resource_data
;
962 for (p
= data
->mem_db
.next
; p
!= &data
->mem_db
; p
= p
->next
) {
963 if (ret
> (PAGE_SIZE
- 10))
965 ret
+= snprintf (&buf
[ret
], (PAGE_SIZE
- ret
- 1),
966 "0x%08lx - 0x%08lx\n",
967 ((unsigned long) p
->base
),
968 ((unsigned long) p
->base
+ p
->num
- 1));
971 mutex_unlock(&rsrc_mutex
);
975 static ssize_t
store_mem_db(struct device
*dev
,
976 struct device_attribute
*attr
,
977 const char *buf
, size_t count
)
979 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
980 unsigned long start_addr
, end_addr
;
981 unsigned int add
= ADD_MANAGED_RESOURCE
;
984 ret
= sscanf (buf
, "+ 0x%lx - 0x%lx", &start_addr
, &end_addr
);
986 ret
= sscanf (buf
, "- 0x%lx - 0x%lx", &start_addr
, &end_addr
);
987 add
= REMOVE_MANAGED_RESOURCE
;
989 ret
= sscanf (buf
, "0x%lx - 0x%lx", &start_addr
, &end_addr
);
990 add
= ADD_MANAGED_RESOURCE
;
995 if (end_addr
< start_addr
)
998 ret
= adjust_memory(s
, add
, start_addr
, end_addr
);
1000 s
->resource_setup_new
= 1;
1002 return ret
? ret
: count
;
1004 static DEVICE_ATTR(available_resources_mem
, 0600, show_mem_db
, store_mem_db
);
1006 static struct attribute
*pccard_rsrc_attributes
[] = {
1007 &dev_attr_available_resources_io
.attr
,
1008 &dev_attr_available_resources_mem
.attr
,
1012 static const struct attribute_group rsrc_attributes
= {
1013 .attrs
= pccard_rsrc_attributes
,
1016 static int __devinit
pccard_sysfs_add_rsrc(struct device
*dev
,
1017 struct class_interface
*class_intf
)
1019 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1021 if (s
->resource_ops
!= &pccard_nonstatic_ops
)
1023 return sysfs_create_group(&dev
->kobj
, &rsrc_attributes
);
1026 static void __devexit
pccard_sysfs_remove_rsrc(struct device
*dev
,
1027 struct class_interface
*class_intf
)
1029 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1031 if (s
->resource_ops
!= &pccard_nonstatic_ops
)
1033 sysfs_remove_group(&dev
->kobj
, &rsrc_attributes
);
1036 static struct class_interface pccard_rsrc_interface __refdata
= {
1037 .class = &pcmcia_socket_class
,
1038 .add_dev
= &pccard_sysfs_add_rsrc
,
1039 .remove_dev
= __devexit_p(&pccard_sysfs_remove_rsrc
),
1042 static int __init
nonstatic_sysfs_init(void)
1044 return class_interface_register(&pccard_rsrc_interface
);
1047 static void __exit
nonstatic_sysfs_exit(void)
1049 class_interface_unregister(&pccard_rsrc_interface
);
1052 module_init(nonstatic_sysfs_init
);
1053 module_exit(nonstatic_sysfs_exit
);