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
>= 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(NULL
, 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(NULL
, i
, 8, IORESOURCE_IO
, "PCMCIA ioprobe");
237 for (j
= 0; j
< 8; j
++)
238 if (inb(i
+j
) != most
)
243 printk(" excluding");
248 sub_interval(&s_data
->io_db
, bad
, i
-bad
);
249 printk(" %#x-%#x", bad
, i
-1);
255 if ((num
> 16) && (bad
== base
) && (i
== base
+num
)) {
256 printk(" nothing: probe failed.\n");
259 sub_interval(&s_data
->io_db
, bad
, i
-bad
);
260 printk(" %#x-%#x", bad
, i
-1);
264 printk(any
? "\n" : " clean.\n");
268 /*======================================================================*/
271 * readable() - iomem validation function for cards with a valid CIS
273 static int readable(struct pcmcia_socket
*s
, struct resource
*res
,
279 dev_dbg(&s
->dev
, "fake CIS is being used: can't validate mem\n");
283 s
->cis_mem
.res
= res
;
284 s
->cis_virt
= ioremap(res
->start
, s
->map_size
);
286 mutex_unlock(&s
->ops_mutex
);
287 /* as we're only called from pcmcia.c, we're safe */
288 if (s
->callback
->validate
)
289 ret
= s
->callback
->validate(s
, count
);
290 /* invalidate mapping */
291 mutex_lock(&s
->ops_mutex
);
292 iounmap(s
->cis_virt
);
295 s
->cis_mem
.res
= NULL
;
296 if ((ret
) || (*count
== 0))
302 * checksum() - iomem validation function for simple memory cards
304 static int checksum(struct pcmcia_socket
*s
, struct resource
*res
,
308 int i
, a
= 0, b
= -1, d
;
311 virt
= ioremap(res
->start
, s
->map_size
);
314 map
.flags
= MAP_ACTIVE
;
318 s
->ops
->set_mem_map(s
, &map
);
320 /* Don't bother checking every word... */
321 for (i
= 0; i
< s
->map_size
; i
+= 44) {
328 s
->ops
->set_mem_map(s
, &map
);
342 * do_validate_mem() - low level validate a memory region for PCMCIA use
343 * @s: PCMCIA socket to validate
344 * @base: start address of resource to check
345 * @size: size of resource to check
346 * @validate: validation function to use
348 * do_validate_mem() splits up the memory region which is to be checked
349 * into two parts. Both are passed to the @validate() function. If
350 * @validate() returns non-zero, or the value parameter to @validate()
351 * is zero, or the value parameter is different between both calls,
352 * the check fails, and -EINVAL is returned. Else, 0 is returned.
354 static int do_validate_mem(struct pcmcia_socket
*s
,
355 unsigned long base
, unsigned long size
,
356 int validate (struct pcmcia_socket
*s
,
357 struct resource
*res
,
358 unsigned int *value
))
360 struct resource
*res1
, *res2
;
361 unsigned int info1
= 1, info2
= 1;
364 res1
= claim_region(s
, base
, size
/2, IORESOURCE_MEM
, "PCMCIA memprobe");
365 res2
= claim_region(s
, base
+ size
/2, size
/2, IORESOURCE_MEM
,
371 ret
= validate(s
, res1
, &info1
);
372 ret
+= validate(s
, res2
, &info2
);
379 dev_dbg(&s
->dev
, "cs: memory probe 0x%06lx-0x%06lx: %p %p %u %u %u",
380 base
, base
+size
-1, res1
, res2
, ret
, info1
, info2
);
382 if ((ret
) || (info1
!= info2
) || (info1
== 0))
390 * do_mem_probe() - validate a memory region for PCMCIA use
391 * @s: PCMCIA socket to validate
392 * @base: start address of resource to check
393 * @num: size of resource to check
394 * @validate: validation function to use
395 * @fallback: validation function to use if validate fails
397 * do_mem_probe() checks a memory region for use by the PCMCIA subsystem.
398 * To do so, the area is split up into sensible parts, and then passed
399 * into the @validate() function. Only if @validate() and @fallback() fail,
400 * the area is marked as unavaibale for use by the PCMCIA subsystem. The
401 * function returns the size of the usable memory area.
403 static int do_mem_probe(struct pcmcia_socket
*s
, u_long base
, u_long num
,
404 int validate (struct pcmcia_socket
*s
,
405 struct resource
*res
,
406 unsigned int *value
),
407 int fallback (struct pcmcia_socket
*s
,
408 struct resource
*res
,
409 unsigned int *value
))
411 struct socket_data
*s_data
= s
->resource_data
;
412 u_long i
, j
, bad
, fail
, step
;
414 dev_printk(KERN_INFO
, &s
->dev
, "cs: memory probe 0x%06lx-0x%06lx:",
417 step
= (num
< 0x20000) ? 0x2000 : ((num
>>4) & ~0x1fff);
418 /* don't allow too large steps */
421 /* cis_readable wants to map 2x map_size */
422 if (step
< 2 * s
->map_size
)
423 step
= 2 * s
->map_size
;
424 for (i
= j
= base
; i
< base
+num
; i
= j
+ step
) {
426 for (j
= i
; j
< base
+num
; j
+= step
) {
427 if (!do_validate_mem(s
, j
, step
, validate
))
430 fail
= ((i
== base
) && (j
== base
+num
));
432 if ((fail
) && (fallback
)) {
433 for (j
= i
; j
< base
+num
; j
+= step
)
434 if (!do_validate_mem(s
, j
, step
, fallback
))
439 printk(" excluding");
440 printk(" %#05lx-%#05lx", i
, j
-1);
441 sub_interval(&s_data
->mem_db
, i
, j
-i
);
445 printk(bad
? "\n" : " clean.\n");
450 #ifdef CONFIG_PCMCIA_PROBE
453 * inv_probe() - top-to-bottom search for one usuable high memory area
454 * @s: PCMCIA socket to validate
455 * @m: resource_map to check
457 static u_long
inv_probe(struct resource_map
*m
, struct pcmcia_socket
*s
)
459 struct socket_data
*s_data
= s
->resource_data
;
461 if (m
== &s_data
->mem_db
)
463 ok
= inv_probe(m
->next
, s
);
465 if (m
->base
>= 0x100000)
466 sub_interval(&s_data
->mem_db
, m
->base
, m
->num
);
469 if (m
->base
< 0x100000)
471 return do_mem_probe(s
, m
->base
, m
->num
, readable
, checksum
);
475 * validate_mem() - memory probe function
476 * @s: PCMCIA socket to validate
477 * @probe_mask: MEM_PROBE_LOW | MEM_PROBE_HIGH
479 * The memory probe. If the memory list includes a 64K-aligned block
480 * below 1MB, we probe in 64K chunks, and as soon as we accumulate at
481 * least mem_limit free space, we quit. Returns 0 on usuable ports.
483 static int validate_mem(struct pcmcia_socket
*s
, unsigned int probe_mask
)
485 struct resource_map
*m
, mm
;
486 static unsigned char order
[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
487 unsigned long b
, i
, ok
= 0;
488 struct socket_data
*s_data
= s
->resource_data
;
490 /* We do up to four passes through the list */
491 if (probe_mask
& MEM_PROBE_HIGH
) {
492 if (inv_probe(s_data
->mem_db
.next
, s
) > 0)
494 dev_printk(KERN_NOTICE
, &s
->dev
,
495 "cs: warning: no high memory space available!\n");
499 for (m
= s_data
->mem_db
.next
; m
!= &s_data
->mem_db
; m
= mm
.next
) {
501 /* Only probe < 1 MB */
502 if (mm
.base
>= 0x100000)
504 if ((mm
.base
| mm
.num
) & 0xffff) {
505 ok
+= do_mem_probe(s
, mm
.base
, mm
.num
, readable
,
509 /* Special probe for 64K-aligned block */
510 for (i
= 0; i
< 4; i
++) {
512 if ((b
>= mm
.base
) && (b
+0x10000 <= mm
.base
+mm
.num
)) {
514 sub_interval(&s_data
->mem_db
, b
, 0x10000);
516 ok
+= do_mem_probe(s
, b
, 0x10000,
528 #else /* CONFIG_PCMCIA_PROBE */
531 * validate_mem() - memory probe function
532 * @s: PCMCIA socket to validate
533 * @probe_mask: ignored
535 * Returns 0 on usuable ports.
537 static int validate_mem(struct pcmcia_socket
*s
, unsigned int probe_mask
)
539 struct resource_map
*m
, mm
;
540 struct socket_data
*s_data
= s
->resource_data
;
541 unsigned long ok
= 0;
543 for (m
= s_data
->mem_db
.next
; m
!= &s_data
->mem_db
; m
= mm
.next
) {
545 ok
+= do_mem_probe(s
, mm
.base
, mm
.num
, readable
, checksum
);
552 #endif /* CONFIG_PCMCIA_PROBE */
556 * pcmcia_nonstatic_validate_mem() - try to validate iomem for PCMCIA use
557 * @s: PCMCIA socket to validate
559 * This is tricky... when we set up CIS memory, we try to validate
560 * the memory window space allocations.
562 * Locking note: Must be called with skt_mutex held!
564 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket
*s
)
566 struct socket_data
*s_data
= s
->resource_data
;
567 unsigned int probe_mask
= MEM_PROBE_LOW
;
573 if (s
->features
& SS_CAP_PAGE_REGS
)
574 probe_mask
= MEM_PROBE_HIGH
;
576 if (probe_mask
& ~s_data
->rsrc_mem_probe
) {
577 if (s
->state
& SOCKET_PRESENT
) {
578 ret
= validate_mem(s
, probe_mask
);
580 s_data
->rsrc_mem_probe
|= probe_mask
;
587 struct pcmcia_align_data
{
589 unsigned long offset
;
590 struct resource_map
*map
;
594 pcmcia_common_align(void *align_data
, struct resource
*res
,
595 resource_size_t size
, resource_size_t align
)
597 struct pcmcia_align_data
*data
= align_data
;
598 resource_size_t start
;
600 * Ensure that we have the correct start address
602 start
= (res
->start
& ~data
->mask
) + data
->offset
;
603 if (start
< res
->start
)
604 start
+= data
->mask
+ 1;
609 pcmcia_align(void *align_data
, struct resource
*res
, resource_size_t size
,
610 resource_size_t align
)
612 struct pcmcia_align_data
*data
= align_data
;
613 struct resource_map
*m
;
615 pcmcia_common_align(data
, res
, size
, align
);
617 for (m
= data
->map
->next
; m
!= data
->map
; m
= m
->next
) {
618 unsigned long start
= m
->base
;
619 unsigned long end
= m
->base
+ m
->num
- 1;
622 * If the lower resources are not available, try aligning
623 * to this entry of the resource database to see if it'll
626 if (res
->start
< start
) {
628 pcmcia_common_align(data
, res
, size
, align
);
632 * If we're above the area which was passed in, there's
633 * no point proceeding.
635 if (res
->start
>= res
->end
)
638 if ((res
->start
+ size
- 1) <= end
)
643 * If we failed to find something suitable, ensure we fail.
646 res
->start
= res
->end
;
650 * Adjust an existing IO region allocation, but making sure that we don't
651 * encroach outside the resources which the user supplied.
653 static int nonstatic_adjust_io_region(struct resource
*res
, unsigned long r_start
,
654 unsigned long r_end
, struct pcmcia_socket
*s
)
656 struct resource_map
*m
;
657 struct socket_data
*s_data
= s
->resource_data
;
660 for (m
= s_data
->io_db
.next
; m
!= &s_data
->io_db
; m
= m
->next
) {
661 unsigned long start
= m
->base
;
662 unsigned long end
= m
->base
+ m
->num
- 1;
664 if (start
> r_start
|| r_end
> end
)
667 ret
= adjust_resource(res
, r_start
, r_end
- r_start
+ 1);
674 /*======================================================================
676 These find ranges of I/O ports or memory addresses that are not
677 currently allocated by other devices.
679 The 'align' field should reflect the number of bits of address
680 that need to be preserved from the initial value of *base. It
681 should be a power of two, greater than or equal to 'num'. A value
682 of 0 means that all bits of *base are significant. *base should
683 also be strictly less than 'align'.
685 ======================================================================*/
687 static struct resource
*nonstatic_find_io_region(unsigned long base
, int num
,
688 unsigned long align
, struct pcmcia_socket
*s
)
690 struct resource
*res
= make_resource(0, num
, IORESOURCE_IO
, dev_name(&s
->dev
));
691 struct socket_data
*s_data
= s
->resource_data
;
692 struct pcmcia_align_data data
;
693 unsigned long min
= base
;
699 data
.mask
= align
- 1;
700 data
.offset
= base
& data
.mask
;
701 data
.map
= &s_data
->io_db
;
705 ret
= pci_bus_alloc_resource(s
->cb_dev
->bus
, res
, num
, 1,
706 min
, 0, pcmcia_align
, &data
);
709 ret
= allocate_resource(&ioport_resource
, res
, num
, min
, ~0UL,
710 1, pcmcia_align
, &data
);
719 static struct resource
*nonstatic_find_mem_region(u_long base
, u_long num
,
720 u_long align
, int low
, struct pcmcia_socket
*s
)
722 struct resource
*res
= make_resource(0, num
, IORESOURCE_MEM
, dev_name(&s
->dev
));
723 struct socket_data
*s_data
= s
->resource_data
;
724 struct pcmcia_align_data data
;
725 unsigned long min
, max
;
728 low
= low
|| !(s
->features
& SS_CAP_PAGE_REGS
);
730 data
.mask
= align
- 1;
731 data
.offset
= base
& data
.mask
;
732 data
.map
= &s_data
->mem_db
;
734 for (i
= 0; i
< 2; i
++) {
737 min
= base
< max
? base
: 0;
740 min
= 0x100000UL
+ base
;
745 ret
= pci_bus_alloc_resource(s
->cb_dev
->bus
, res
, num
,
747 pcmcia_align
, &data
);
750 ret
= allocate_resource(&iomem_resource
, res
, num
, min
,
751 max
, 1, pcmcia_align
, &data
);
765 static int adjust_memory(struct pcmcia_socket
*s
, unsigned int action
, unsigned long start
, unsigned long end
)
767 struct socket_data
*data
= s
->resource_data
;
768 unsigned long size
= end
- start
+ 1;
775 case ADD_MANAGED_RESOURCE
:
776 ret
= add_interval(&data
->mem_db
, start
, size
);
778 do_mem_probe(s
, start
, size
, NULL
, NULL
);
780 case REMOVE_MANAGED_RESOURCE
:
781 ret
= sub_interval(&data
->mem_db
, start
, size
);
791 static int adjust_io(struct pcmcia_socket
*s
, unsigned int action
, unsigned long start
, unsigned long end
)
793 struct socket_data
*data
= s
->resource_data
;
794 unsigned long size
= end
- start
+ 1;
800 if (end
> IO_SPACE_LIMIT
)
804 case ADD_MANAGED_RESOURCE
:
805 if (add_interval(&data
->io_db
, start
, size
) != 0) {
809 #ifdef CONFIG_PCMCIA_PROBE
811 do_io_probe(s
, start
, size
);
814 case REMOVE_MANAGED_RESOURCE
:
815 sub_interval(&data
->io_db
, start
, size
);
827 static int nonstatic_autoadd_resources(struct pcmcia_socket
*s
)
829 struct resource
*res
;
832 if (!s
->cb_dev
|| !s
->cb_dev
->bus
)
835 #if defined(CONFIG_X86)
836 /* If this is the root bus, the risk of hitting
837 * some strange system devices which aren't protected
838 * by either ACPI resource tables or properly requested
839 * resources is too big. Therefore, don't do auto-adding
840 * of resources at the moment.
842 if (s
->cb_dev
->bus
->number
== 0)
846 for (i
= 0; i
< PCI_BUS_NUM_RESOURCES
; i
++) {
847 res
= s
->cb_dev
->bus
->resource
[i
];
851 if (res
->flags
& IORESOURCE_IO
) {
852 if (res
== &ioport_resource
)
854 dev_printk(KERN_INFO
, &s
->cb_dev
->dev
,
855 "pcmcia: parent PCI bridge I/O "
856 "window: 0x%llx - 0x%llx\n",
857 (unsigned long long)res
->start
,
858 (unsigned long long)res
->end
);
859 if (!adjust_io(s
, ADD_MANAGED_RESOURCE
, res
->start
, res
->end
))
860 done
|= IORESOURCE_IO
;
864 if (res
->flags
& IORESOURCE_MEM
) {
865 if (res
== &iomem_resource
)
867 dev_printk(KERN_INFO
, &s
->cb_dev
->dev
,
868 "pcmcia: parent PCI bridge Memory "
869 "window: 0x%llx - 0x%llx\n",
870 (unsigned long long)res
->start
,
871 (unsigned long long)res
->end
);
872 if (!adjust_memory(s
, ADD_MANAGED_RESOURCE
, res
->start
, res
->end
))
873 done
|= IORESOURCE_MEM
;
877 /* if we got at least one of IO, and one of MEM, we can be glad and
878 * activate the PCMCIA subsystem */
879 if (done
== (IORESOURCE_MEM
| IORESOURCE_IO
))
880 s
->resource_setup_done
= 1;
887 static inline int nonstatic_autoadd_resources(struct pcmcia_socket
*s
)
895 static int nonstatic_init(struct pcmcia_socket
*s
)
897 struct socket_data
*data
;
899 data
= kzalloc(sizeof(struct socket_data
), GFP_KERNEL
);
903 data
->mem_db
.next
= &data
->mem_db
;
904 data
->io_db
.next
= &data
->io_db
;
906 s
->resource_data
= (void *) data
;
908 nonstatic_autoadd_resources(s
);
913 static void nonstatic_release_resource_db(struct pcmcia_socket
*s
)
915 struct socket_data
*data
= s
->resource_data
;
916 struct resource_map
*p
, *q
;
918 for (p
= data
->mem_db
.next
; p
!= &data
->mem_db
; p
= q
) {
922 for (p
= data
->io_db
.next
; p
!= &data
->io_db
; p
= q
) {
929 struct pccard_resource_ops pccard_nonstatic_ops
= {
930 .validate_mem
= pcmcia_nonstatic_validate_mem
,
931 .adjust_io_region
= nonstatic_adjust_io_region
,
932 .find_io
= nonstatic_find_io_region
,
933 .find_mem
= nonstatic_find_mem_region
,
935 .add_mem
= adjust_memory
,
936 .init
= nonstatic_init
,
937 .exit
= nonstatic_release_resource_db
,
939 EXPORT_SYMBOL(pccard_nonstatic_ops
);
942 /* sysfs interface to the resource database */
944 static ssize_t
show_io_db(struct device
*dev
,
945 struct device_attribute
*attr
, char *buf
)
947 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
948 struct socket_data
*data
;
949 struct resource_map
*p
;
952 mutex_lock(&s
->ops_mutex
);
953 data
= s
->resource_data
;
955 for (p
= data
->io_db
.next
; p
!= &data
->io_db
; p
= p
->next
) {
956 if (ret
> (PAGE_SIZE
- 10))
958 ret
+= snprintf(&buf
[ret
], (PAGE_SIZE
- ret
- 1),
959 "0x%08lx - 0x%08lx\n",
960 ((unsigned long) p
->base
),
961 ((unsigned long) p
->base
+ p
->num
- 1));
964 mutex_unlock(&s
->ops_mutex
);
968 static ssize_t
store_io_db(struct device
*dev
,
969 struct device_attribute
*attr
,
970 const char *buf
, size_t count
)
972 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
973 unsigned long start_addr
, end_addr
;
974 unsigned int add
= ADD_MANAGED_RESOURCE
;
977 ret
= sscanf(buf
, "+ 0x%lx - 0x%lx", &start_addr
, &end_addr
);
979 ret
= sscanf(buf
, "- 0x%lx - 0x%lx", &start_addr
, &end_addr
);
980 add
= REMOVE_MANAGED_RESOURCE
;
982 ret
= sscanf(buf
, "0x%lx - 0x%lx", &start_addr
,
984 add
= ADD_MANAGED_RESOURCE
;
989 if (end_addr
< start_addr
)
992 mutex_lock(&s
->ops_mutex
);
993 ret
= adjust_io(s
, add
, start_addr
, end_addr
);
995 s
->resource_setup_new
= 1;
996 mutex_unlock(&s
->ops_mutex
);
998 return ret
? ret
: count
;
1000 static DEVICE_ATTR(available_resources_io
, 0600, show_io_db
, store_io_db
);
1002 static ssize_t
show_mem_db(struct device
*dev
,
1003 struct device_attribute
*attr
, char *buf
)
1005 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1006 struct socket_data
*data
;
1007 struct resource_map
*p
;
1010 mutex_lock(&s
->ops_mutex
);
1011 data
= s
->resource_data
;
1013 for (p
= data
->mem_db
.next
; p
!= &data
->mem_db
; p
= p
->next
) {
1014 if (ret
> (PAGE_SIZE
- 10))
1016 ret
+= snprintf(&buf
[ret
], (PAGE_SIZE
- ret
- 1),
1017 "0x%08lx - 0x%08lx\n",
1018 ((unsigned long) p
->base
),
1019 ((unsigned long) p
->base
+ p
->num
- 1));
1022 mutex_unlock(&s
->ops_mutex
);
1026 static ssize_t
store_mem_db(struct device
*dev
,
1027 struct device_attribute
*attr
,
1028 const char *buf
, size_t count
)
1030 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1031 unsigned long start_addr
, end_addr
;
1032 unsigned int add
= ADD_MANAGED_RESOURCE
;
1035 ret
= sscanf(buf
, "+ 0x%lx - 0x%lx", &start_addr
, &end_addr
);
1037 ret
= sscanf(buf
, "- 0x%lx - 0x%lx", &start_addr
, &end_addr
);
1038 add
= REMOVE_MANAGED_RESOURCE
;
1040 ret
= sscanf(buf
, "0x%lx - 0x%lx", &start_addr
,
1042 add
= ADD_MANAGED_RESOURCE
;
1047 if (end_addr
< start_addr
)
1050 mutex_lock(&s
->ops_mutex
);
1051 ret
= adjust_memory(s
, add
, start_addr
, end_addr
);
1053 s
->resource_setup_new
= 1;
1054 mutex_unlock(&s
->ops_mutex
);
1056 return ret
? ret
: count
;
1058 static DEVICE_ATTR(available_resources_mem
, 0600, show_mem_db
, store_mem_db
);
1060 static struct attribute
*pccard_rsrc_attributes
[] = {
1061 &dev_attr_available_resources_io
.attr
,
1062 &dev_attr_available_resources_mem
.attr
,
1066 static const struct attribute_group rsrc_attributes
= {
1067 .attrs
= pccard_rsrc_attributes
,
1070 static int __devinit
pccard_sysfs_add_rsrc(struct device
*dev
,
1071 struct class_interface
*class_intf
)
1073 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1075 if (s
->resource_ops
!= &pccard_nonstatic_ops
)
1077 return sysfs_create_group(&dev
->kobj
, &rsrc_attributes
);
1080 static void __devexit
pccard_sysfs_remove_rsrc(struct device
*dev
,
1081 struct class_interface
*class_intf
)
1083 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1085 if (s
->resource_ops
!= &pccard_nonstatic_ops
)
1087 sysfs_remove_group(&dev
->kobj
, &rsrc_attributes
);
1090 static struct class_interface pccard_rsrc_interface __refdata
= {
1091 .class = &pcmcia_socket_class
,
1092 .add_dev
= &pccard_sysfs_add_rsrc
,
1093 .remove_dev
= __devexit_p(&pccard_sysfs_remove_rsrc
),
1096 static int __init
nonstatic_sysfs_init(void)
1098 return class_interface_register(&pccard_rsrc_interface
);
1101 static void __exit
nonstatic_sysfs_exit(void)
1103 class_interface_unregister(&pccard_rsrc_interface
);
1106 module_init(nonstatic_sysfs_init
);
1107 module_exit(nonstatic_sysfs_exit
);