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 #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
-1 >= base
))
129 if ((p
->next
== map
) || (p
->next
->base
> base
+num
-1))
132 q
= kmalloc(sizeof(struct resource_map
), GFP_KERNEL
);
134 printk(KERN_WARNING
"out of memory to update resources\n");
137 q
->base
= base
; q
->num
= num
;
138 q
->next
= p
->next
; p
->next
= q
;
142 /*====================================================================*/
144 static int sub_interval(struct resource_map
*map
, u_long base
, u_long num
)
146 struct resource_map
*p
, *q
;
148 for (p
= map
; ; p
= q
) {
152 if ((q
->base
+q
->num
> base
) && (base
+num
> q
->base
)) {
153 if (q
->base
>= base
) {
154 if (q
->base
+q
->num
<= base
+num
) {
155 /* Delete whole block */
158 /* don't advance the pointer yet */
161 /* Cut off bit from the front */
162 q
->num
= q
->base
+ q
->num
- base
- num
;
163 q
->base
= base
+ num
;
165 } else if (q
->base
+q
->num
<= base
+num
) {
166 /* Cut off bit from the end */
167 q
->num
= base
- q
->base
;
169 /* Split the block into two pieces */
170 p
= kmalloc(sizeof(struct resource_map
),
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
);
210 dev_printk(KERN_ERR
, &s
->dev
,
211 "do_io_probe: unable to kmalloc 256 bytes");
214 for (i
= base
, most
= 0; i
< base
+num
; i
+= 8) {
215 res
= claim_region(NULL
, i
, 8, IORESOURCE_IO
, "PCMCIA ioprobe");
219 for (j
= 1; j
< 8; j
++)
220 if (inb(i
+j
) != hole
)
223 if ((j
== 8) && (++b
[hole
] > b
[most
]))
231 for (i
= base
; i
< base
+num
; i
+= 8) {
232 res
= claim_region(NULL
, i
, 8, IORESOURCE_IO
, "PCMCIA ioprobe");
235 for (j
= 0; j
< 8; j
++)
236 if (inb(i
+j
) != most
)
241 printk(" excluding");
246 sub_interval(&s_data
->io_db
, bad
, i
-bad
);
247 printk(" %#x-%#x", bad
, i
-1);
253 if ((num
> 16) && (bad
== base
) && (i
== base
+num
)) {
254 printk(" nothing: probe failed.\n");
257 sub_interval(&s_data
->io_db
, bad
, i
-bad
);
258 printk(" %#x-%#x", bad
, i
-1);
262 printk(any
? "\n" : " clean.\n");
266 /*======================================================================*/
269 * readable() - iomem validation function for cards with a valid CIS
271 static int readable(struct pcmcia_socket
*s
, struct resource
*res
,
277 dev_dbg(&s
->dev
, "fake CIS is being used: can't validate mem\n");
281 s
->cis_mem
.res
= res
;
282 s
->cis_virt
= ioremap(res
->start
, s
->map_size
);
284 mutex_unlock(&s
->ops_mutex
);
285 /* as we're only called from pcmcia.c, we're safe */
286 if (s
->callback
->validate
)
287 ret
= s
->callback
->validate(s
, count
);
288 /* invalidate mapping */
289 mutex_lock(&s
->ops_mutex
);
290 iounmap(s
->cis_virt
);
293 s
->cis_mem
.res
= NULL
;
294 if ((ret
) || (*count
== 0))
300 * checksum() - iomem validation function for simple memory cards
302 static int checksum(struct pcmcia_socket
*s
, struct resource
*res
,
306 int i
, a
= 0, b
= -1, d
;
309 virt
= ioremap(res
->start
, s
->map_size
);
312 map
.flags
= MAP_ACTIVE
;
316 s
->ops
->set_mem_map(s
, &map
);
318 /* Don't bother checking every word... */
319 for (i
= 0; i
< s
->map_size
; i
+= 44) {
326 s
->ops
->set_mem_map(s
, &map
);
340 * do_validate_mem() - low level validate a memory region for PCMCIA use
341 * @s: PCMCIA socket to validate
342 * @base: start address of resource to check
343 * @size: size of resource to check
344 * @validate: validation function to use
346 * do_validate_mem() splits up the memory region which is to be checked
347 * into two parts. Both are passed to the @validate() function. If
348 * @validate() returns non-zero, or the value parameter to @validate()
349 * is zero, or the value parameter is different between both calls,
350 * the check fails, and -EINVAL is returned. Else, 0 is returned.
352 static int do_validate_mem(struct pcmcia_socket
*s
,
353 unsigned long base
, unsigned long size
,
354 int validate (struct pcmcia_socket
*s
,
355 struct resource
*res
,
356 unsigned int *value
))
358 struct resource
*res1
, *res2
;
359 unsigned int info1
= 1, info2
= 1;
362 res1
= claim_region(s
, base
, size
/2, IORESOURCE_MEM
, "PCMCIA memprobe");
363 res2
= claim_region(s
, base
+ size
/2, size
/2, IORESOURCE_MEM
,
369 ret
= validate(s
, res1
, &info1
);
370 ret
+= validate(s
, res2
, &info2
);
377 dev_dbg(&s
->dev
, "cs: memory probe 0x%06lx-0x%06lx: %p %p %u %u %u",
378 base
, base
+size
-1, res1
, res2
, ret
, info1
, info2
);
380 if ((ret
) || (info1
!= info2
) || (info1
== 0))
388 * do_mem_probe() - validate a memory region for PCMCIA use
389 * @s: PCMCIA socket to validate
390 * @base: start address of resource to check
391 * @num: size of resource to check
392 * @validate: validation function to use
393 * @fallback: validation function to use if validate fails
395 * do_mem_probe() checks a memory region for use by the PCMCIA subsystem.
396 * To do so, the area is split up into sensible parts, and then passed
397 * into the @validate() function. Only if @validate() and @fallback() fail,
398 * the area is marked as unavaibale for use by the PCMCIA subsystem. The
399 * function returns the size of the usable memory area.
401 static int do_mem_probe(struct pcmcia_socket
*s
, u_long base
, u_long num
,
402 int validate (struct pcmcia_socket
*s
,
403 struct resource
*res
,
404 unsigned int *value
),
405 int fallback (struct pcmcia_socket
*s
,
406 struct resource
*res
,
407 unsigned int *value
))
409 struct socket_data
*s_data
= s
->resource_data
;
410 u_long i
, j
, bad
, fail
, step
;
412 dev_printk(KERN_INFO
, &s
->dev
, "cs: memory probe 0x%06lx-0x%06lx:",
415 step
= (num
< 0x20000) ? 0x2000 : ((num
>>4) & ~0x1fff);
416 /* don't allow too large steps */
419 /* cis_readable wants to map 2x map_size */
420 if (step
< 2 * s
->map_size
)
421 step
= 2 * s
->map_size
;
422 for (i
= j
= base
; i
< base
+num
; i
= j
+ step
) {
424 for (j
= i
; j
< base
+num
; j
+= step
) {
425 if (!do_validate_mem(s
, j
, step
, validate
))
428 fail
= ((i
== base
) && (j
== base
+num
));
430 if ((fail
) && (fallback
)) {
431 for (j
= i
; j
< base
+num
; j
+= step
)
432 if (!do_validate_mem(s
, j
, step
, fallback
))
437 printk(" excluding");
438 printk(" %#05lx-%#05lx", i
, j
-1);
439 sub_interval(&s_data
->mem_db
, i
, j
-i
);
443 printk(bad
? "\n" : " clean.\n");
448 #ifdef CONFIG_PCMCIA_PROBE
451 * inv_probe() - top-to-bottom search for one usuable high memory area
452 * @s: PCMCIA socket to validate
453 * @m: resource_map to check
455 static u_long
inv_probe(struct resource_map
*m
, struct pcmcia_socket
*s
)
457 struct socket_data
*s_data
= s
->resource_data
;
459 if (m
== &s_data
->mem_db
)
461 ok
= inv_probe(m
->next
, s
);
463 if (m
->base
>= 0x100000)
464 sub_interval(&s_data
->mem_db
, m
->base
, m
->num
);
467 if (m
->base
< 0x100000)
469 return do_mem_probe(s
, m
->base
, m
->num
, readable
, checksum
);
473 * validate_mem() - memory probe function
474 * @s: PCMCIA socket to validate
475 * @probe_mask: MEM_PROBE_LOW | MEM_PROBE_HIGH
477 * The memory probe. If the memory list includes a 64K-aligned block
478 * below 1MB, we probe in 64K chunks, and as soon as we accumulate at
479 * least mem_limit free space, we quit. Returns 0 on usuable ports.
481 static int validate_mem(struct pcmcia_socket
*s
, unsigned int probe_mask
)
483 struct resource_map
*m
, mm
;
484 static unsigned char order
[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
485 unsigned long b
, i
, ok
= 0;
486 struct socket_data
*s_data
= s
->resource_data
;
488 /* We do up to four passes through the list */
489 if (probe_mask
& MEM_PROBE_HIGH
) {
490 if (inv_probe(s_data
->mem_db
.next
, s
) > 0)
492 dev_printk(KERN_NOTICE
, &s
->dev
,
493 "cs: warning: no high memory space available!\n");
497 for (m
= s_data
->mem_db
.next
; m
!= &s_data
->mem_db
; m
= mm
.next
) {
499 /* Only probe < 1 MB */
500 if (mm
.base
>= 0x100000)
502 if ((mm
.base
| mm
.num
) & 0xffff) {
503 ok
+= do_mem_probe(s
, mm
.base
, mm
.num
, readable
,
507 /* Special probe for 64K-aligned block */
508 for (i
= 0; i
< 4; i
++) {
510 if ((b
>= mm
.base
) && (b
+0x10000 <= mm
.base
+mm
.num
)) {
512 sub_interval(&s_data
->mem_db
, b
, 0x10000);
514 ok
+= do_mem_probe(s
, b
, 0x10000,
526 #else /* CONFIG_PCMCIA_PROBE */
529 * validate_mem() - memory probe function
530 * @s: PCMCIA socket to validate
531 * @probe_mask: ignored
533 * Returns 0 on usuable ports.
535 static int validate_mem(struct pcmcia_socket
*s
, unsigned int probe_mask
)
537 struct resource_map
*m
, mm
;
538 struct socket_data
*s_data
= s
->resource_data
;
539 unsigned long ok
= 0;
541 for (m
= s_data
->mem_db
.next
; m
!= &s_data
->mem_db
; m
= mm
.next
) {
543 ok
+= do_mem_probe(s
, mm
.base
, mm
.num
, readable
, checksum
);
550 #endif /* CONFIG_PCMCIA_PROBE */
554 * pcmcia_nonstatic_validate_mem() - try to validate iomem for PCMCIA use
555 * @s: PCMCIA socket to validate
557 * This is tricky... when we set up CIS memory, we try to validate
558 * the memory window space allocations.
560 * Locking note: Must be called with skt_mutex held!
562 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket
*s
)
564 struct socket_data
*s_data
= s
->resource_data
;
565 unsigned int probe_mask
= MEM_PROBE_LOW
;
571 if (s
->features
& SS_CAP_PAGE_REGS
)
572 probe_mask
= MEM_PROBE_HIGH
;
574 if (probe_mask
& ~s_data
->rsrc_mem_probe
) {
575 if (s
->state
& SOCKET_PRESENT
) {
576 ret
= validate_mem(s
, probe_mask
);
578 s_data
->rsrc_mem_probe
|= probe_mask
;
585 struct pcmcia_align_data
{
587 unsigned long offset
;
588 struct resource_map
*map
;
592 pcmcia_common_align(void *align_data
, struct resource
*res
,
593 resource_size_t size
, resource_size_t align
)
595 struct pcmcia_align_data
*data
= align_data
;
596 resource_size_t start
;
598 * Ensure that we have the correct start address
600 start
= (res
->start
& ~data
->mask
) + data
->offset
;
601 if (start
< res
->start
)
602 start
+= data
->mask
+ 1;
607 pcmcia_align(void *align_data
, struct resource
*res
, resource_size_t size
,
608 resource_size_t align
)
610 struct pcmcia_align_data
*data
= align_data
;
611 struct resource_map
*m
;
613 pcmcia_common_align(data
, res
, size
, align
);
615 for (m
= data
->map
->next
; m
!= data
->map
; m
= m
->next
) {
616 unsigned long start
= m
->base
;
617 unsigned long end
= m
->base
+ m
->num
- 1;
620 * If the lower resources are not available, try aligning
621 * to this entry of the resource database to see if it'll
624 if (res
->start
< start
) {
626 pcmcia_common_align(data
, res
, size
, align
);
630 * If we're above the area which was passed in, there's
631 * no point proceeding.
633 if (res
->start
>= res
->end
)
636 if ((res
->start
+ size
- 1) <= end
)
641 * If we failed to find something suitable, ensure we fail.
644 res
->start
= res
->end
;
648 * Adjust an existing IO region allocation, but making sure that we don't
649 * encroach outside the resources which the user supplied.
651 static int nonstatic_adjust_io_region(struct resource
*res
, unsigned long r_start
,
652 unsigned long r_end
, struct pcmcia_socket
*s
)
654 struct resource_map
*m
;
655 struct socket_data
*s_data
= s
->resource_data
;
658 for (m
= s_data
->io_db
.next
; m
!= &s_data
->io_db
; m
= m
->next
) {
659 unsigned long start
= m
->base
;
660 unsigned long end
= m
->base
+ m
->num
- 1;
662 if (start
> r_start
|| r_end
> end
)
665 ret
= adjust_resource(res
, r_start
, r_end
- r_start
+ 1);
672 /*======================================================================
674 These find ranges of I/O ports or memory addresses that are not
675 currently allocated by other devices.
677 The 'align' field should reflect the number of bits of address
678 that need to be preserved from the initial value of *base. It
679 should be a power of two, greater than or equal to 'num'. A value
680 of 0 means that all bits of *base are significant. *base should
681 also be strictly less than 'align'.
683 ======================================================================*/
685 static struct resource
*nonstatic_find_io_region(unsigned long base
, int num
,
686 unsigned long align
, struct pcmcia_socket
*s
)
688 struct resource
*res
= make_resource(0, num
, IORESOURCE_IO
, dev_name(&s
->dev
));
689 struct socket_data
*s_data
= s
->resource_data
;
690 struct pcmcia_align_data data
;
691 unsigned long min
= base
;
697 data
.mask
= align
- 1;
698 data
.offset
= base
& data
.mask
;
699 data
.map
= &s_data
->io_db
;
703 ret
= pci_bus_alloc_resource(s
->cb_dev
->bus
, res
, num
, 1,
704 min
, 0, pcmcia_align
, &data
);
707 ret
= allocate_resource(&ioport_resource
, res
, num
, min
, ~0UL,
708 1, pcmcia_align
, &data
);
717 static struct resource
*nonstatic_find_mem_region(u_long base
, u_long num
,
718 u_long align
, int low
, struct pcmcia_socket
*s
)
720 struct resource
*res
= make_resource(0, num
, IORESOURCE_MEM
, dev_name(&s
->dev
));
721 struct socket_data
*s_data
= s
->resource_data
;
722 struct pcmcia_align_data data
;
723 unsigned long min
, max
;
726 low
= low
|| !(s
->features
& SS_CAP_PAGE_REGS
);
728 data
.mask
= align
- 1;
729 data
.offset
= base
& data
.mask
;
730 data
.map
= &s_data
->mem_db
;
732 for (i
= 0; i
< 2; i
++) {
735 min
= base
< max
? base
: 0;
738 min
= 0x100000UL
+ base
;
743 ret
= pci_bus_alloc_resource(s
->cb_dev
->bus
, res
, num
,
745 pcmcia_align
, &data
);
748 ret
= allocate_resource(&iomem_resource
, res
, num
, min
,
749 max
, 1, pcmcia_align
, &data
);
763 static int adjust_memory(struct pcmcia_socket
*s
, unsigned int action
, unsigned long start
, unsigned long end
)
765 struct socket_data
*data
= s
->resource_data
;
766 unsigned long size
= end
- start
+ 1;
773 case ADD_MANAGED_RESOURCE
:
774 ret
= add_interval(&data
->mem_db
, start
, size
);
776 do_mem_probe(s
, start
, size
, NULL
, NULL
);
778 case REMOVE_MANAGED_RESOURCE
:
779 ret
= sub_interval(&data
->mem_db
, start
, size
);
789 static int adjust_io(struct pcmcia_socket
*s
, unsigned int action
, unsigned long start
, unsigned long end
)
791 struct socket_data
*data
= s
->resource_data
;
792 unsigned long size
= end
- start
+ 1;
798 if (end
> IO_SPACE_LIMIT
)
802 case ADD_MANAGED_RESOURCE
:
803 if (add_interval(&data
->io_db
, start
, size
) != 0) {
807 #ifdef CONFIG_PCMCIA_PROBE
809 do_io_probe(s
, start
, size
);
812 case REMOVE_MANAGED_RESOURCE
:
813 sub_interval(&data
->io_db
, start
, size
);
825 static int nonstatic_autoadd_resources(struct pcmcia_socket
*s
)
827 struct resource
*res
;
830 if (!s
->cb_dev
|| !s
->cb_dev
->bus
)
833 #if defined(CONFIG_X86)
834 /* If this is the root bus, the risk of hitting
835 * some strange system devices which aren't protected
836 * by either ACPI resource tables or properly requested
837 * resources is too big. Therefore, don't do auto-adding
838 * of resources at the moment.
840 if (s
->cb_dev
->bus
->number
== 0)
844 for (i
= 0; i
< PCI_BUS_NUM_RESOURCES
; i
++) {
845 res
= s
->cb_dev
->bus
->resource
[i
];
849 if (res
->flags
& IORESOURCE_IO
) {
850 if (res
== &ioport_resource
)
852 dev_printk(KERN_INFO
, &s
->cb_dev
->dev
,
853 "pcmcia: parent PCI bridge I/O "
854 "window: 0x%llx - 0x%llx\n",
855 (unsigned long long)res
->start
,
856 (unsigned long long)res
->end
);
857 if (!adjust_io(s
, ADD_MANAGED_RESOURCE
, res
->start
, res
->end
))
858 done
|= IORESOURCE_IO
;
862 if (res
->flags
& IORESOURCE_MEM
) {
863 if (res
== &iomem_resource
)
865 dev_printk(KERN_INFO
, &s
->cb_dev
->dev
,
866 "pcmcia: parent PCI bridge Memory "
867 "window: 0x%llx - 0x%llx\n",
868 (unsigned long long)res
->start
,
869 (unsigned long long)res
->end
);
870 if (!adjust_memory(s
, ADD_MANAGED_RESOURCE
, res
->start
, res
->end
))
871 done
|= IORESOURCE_MEM
;
875 /* if we got at least one of IO, and one of MEM, we can be glad and
876 * activate the PCMCIA subsystem */
877 if (done
== (IORESOURCE_MEM
| IORESOURCE_IO
))
878 s
->resource_setup_done
= 1;
885 static inline int nonstatic_autoadd_resources(struct pcmcia_socket
*s
)
893 static int nonstatic_init(struct pcmcia_socket
*s
)
895 struct socket_data
*data
;
897 data
= kzalloc(sizeof(struct socket_data
), GFP_KERNEL
);
901 data
->mem_db
.next
= &data
->mem_db
;
902 data
->io_db
.next
= &data
->io_db
;
904 s
->resource_data
= (void *) data
;
906 nonstatic_autoadd_resources(s
);
911 static void nonstatic_release_resource_db(struct pcmcia_socket
*s
)
913 struct socket_data
*data
= s
->resource_data
;
914 struct resource_map
*p
, *q
;
916 for (p
= data
->mem_db
.next
; p
!= &data
->mem_db
; p
= q
) {
920 for (p
= data
->io_db
.next
; p
!= &data
->io_db
; p
= q
) {
927 struct pccard_resource_ops pccard_nonstatic_ops
= {
928 .validate_mem
= pcmcia_nonstatic_validate_mem
,
929 .adjust_io_region
= nonstatic_adjust_io_region
,
930 .find_io
= nonstatic_find_io_region
,
931 .find_mem
= nonstatic_find_mem_region
,
933 .add_mem
= adjust_memory
,
934 .init
= nonstatic_init
,
935 .exit
= nonstatic_release_resource_db
,
937 EXPORT_SYMBOL(pccard_nonstatic_ops
);
940 /* sysfs interface to the resource database */
942 static ssize_t
show_io_db(struct device
*dev
,
943 struct device_attribute
*attr
, char *buf
)
945 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
946 struct socket_data
*data
;
947 struct resource_map
*p
;
950 mutex_lock(&s
->ops_mutex
);
951 data
= s
->resource_data
;
953 for (p
= data
->io_db
.next
; p
!= &data
->io_db
; p
= p
->next
) {
954 if (ret
> (PAGE_SIZE
- 10))
956 ret
+= snprintf(&buf
[ret
], (PAGE_SIZE
- ret
- 1),
957 "0x%08lx - 0x%08lx\n",
958 ((unsigned long) p
->base
),
959 ((unsigned long) p
->base
+ p
->num
- 1));
962 mutex_unlock(&s
->ops_mutex
);
966 static ssize_t
store_io_db(struct device
*dev
,
967 struct device_attribute
*attr
,
968 const char *buf
, size_t count
)
970 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
971 unsigned long start_addr
, end_addr
;
972 unsigned int add
= ADD_MANAGED_RESOURCE
;
975 ret
= sscanf(buf
, "+ 0x%lx - 0x%lx", &start_addr
, &end_addr
);
977 ret
= sscanf(buf
, "- 0x%lx - 0x%lx", &start_addr
, &end_addr
);
978 add
= REMOVE_MANAGED_RESOURCE
;
980 ret
= sscanf(buf
, "0x%lx - 0x%lx", &start_addr
,
982 add
= ADD_MANAGED_RESOURCE
;
987 if (end_addr
< start_addr
)
990 mutex_lock(&s
->ops_mutex
);
991 ret
= adjust_io(s
, add
, start_addr
, end_addr
);
993 s
->resource_setup_new
= 1;
994 mutex_unlock(&s
->ops_mutex
);
996 return ret
? ret
: count
;
998 static DEVICE_ATTR(available_resources_io
, 0600, show_io_db
, store_io_db
);
1000 static ssize_t
show_mem_db(struct device
*dev
,
1001 struct device_attribute
*attr
, char *buf
)
1003 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1004 struct socket_data
*data
;
1005 struct resource_map
*p
;
1008 mutex_lock(&s
->ops_mutex
);
1009 data
= s
->resource_data
;
1011 for (p
= data
->mem_db
.next
; p
!= &data
->mem_db
; p
= p
->next
) {
1012 if (ret
> (PAGE_SIZE
- 10))
1014 ret
+= snprintf(&buf
[ret
], (PAGE_SIZE
- ret
- 1),
1015 "0x%08lx - 0x%08lx\n",
1016 ((unsigned long) p
->base
),
1017 ((unsigned long) p
->base
+ p
->num
- 1));
1020 mutex_unlock(&s
->ops_mutex
);
1024 static ssize_t
store_mem_db(struct device
*dev
,
1025 struct device_attribute
*attr
,
1026 const char *buf
, size_t count
)
1028 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1029 unsigned long start_addr
, end_addr
;
1030 unsigned int add
= ADD_MANAGED_RESOURCE
;
1033 ret
= sscanf(buf
, "+ 0x%lx - 0x%lx", &start_addr
, &end_addr
);
1035 ret
= sscanf(buf
, "- 0x%lx - 0x%lx", &start_addr
, &end_addr
);
1036 add
= REMOVE_MANAGED_RESOURCE
;
1038 ret
= sscanf(buf
, "0x%lx - 0x%lx", &start_addr
,
1040 add
= ADD_MANAGED_RESOURCE
;
1045 if (end_addr
< start_addr
)
1048 mutex_lock(&s
->ops_mutex
);
1049 ret
= adjust_memory(s
, add
, start_addr
, end_addr
);
1051 s
->resource_setup_new
= 1;
1052 mutex_unlock(&s
->ops_mutex
);
1054 return ret
? ret
: count
;
1056 static DEVICE_ATTR(available_resources_mem
, 0600, show_mem_db
, store_mem_db
);
1058 static struct attribute
*pccard_rsrc_attributes
[] = {
1059 &dev_attr_available_resources_io
.attr
,
1060 &dev_attr_available_resources_mem
.attr
,
1064 static const struct attribute_group rsrc_attributes
= {
1065 .attrs
= pccard_rsrc_attributes
,
1068 static int __devinit
pccard_sysfs_add_rsrc(struct device
*dev
,
1069 struct class_interface
*class_intf
)
1071 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1073 if (s
->resource_ops
!= &pccard_nonstatic_ops
)
1075 return sysfs_create_group(&dev
->kobj
, &rsrc_attributes
);
1078 static void __devexit
pccard_sysfs_remove_rsrc(struct device
*dev
,
1079 struct class_interface
*class_intf
)
1081 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1083 if (s
->resource_ops
!= &pccard_nonstatic_ops
)
1085 sysfs_remove_group(&dev
->kobj
, &rsrc_attributes
);
1088 static struct class_interface pccard_rsrc_interface __refdata
= {
1089 .class = &pcmcia_socket_class
,
1090 .add_dev
= &pccard_sysfs_add_rsrc
,
1091 .remove_dev
= __devexit_p(&pccard_sysfs_remove_rsrc
),
1094 static int __init
nonstatic_sysfs_init(void)
1096 return class_interface_register(&pccard_rsrc_interface
);
1099 static void __exit
nonstatic_sysfs_exit(void)
1101 class_interface_unregister(&pccard_rsrc_interface
);
1104 module_init(nonstatic_sysfs_init
);
1105 module_exit(nonstatic_sysfs_exit
);