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
, const 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
),
174 printk(KERN_WARNING
"out of memory to update resources\n");
178 p
->num
= q
->base
+q
->num
- p
->base
;
179 q
->num
= base
- q
->base
;
180 p
->next
= q
->next
; q
->next
= p
;
187 /*======================================================================
189 These routines examine a region of IO or memory addresses to
190 determine what ranges might be genuinely available.
192 ======================================================================*/
194 #ifdef CONFIG_PCMCIA_PROBE
195 static void do_io_probe(struct pcmcia_socket
*s
, unsigned int base
,
198 struct resource
*res
;
199 struct socket_data
*s_data
= s
->resource_data
;
200 unsigned int i
, j
, bad
;
202 u_char
*b
, hole
, most
;
204 dev_printk(KERN_INFO
, &s
->dev
, "cs: IO port probe %#x-%#x:",
207 /* First, what does a floating port look like? */
208 b
= kzalloc(256, GFP_KERNEL
);
211 dev_printk(KERN_ERR
, &s
->dev
,
212 "do_io_probe: unable to kmalloc 256 bytes");
215 for (i
= base
, most
= 0; i
< base
+num
; i
+= 8) {
216 res
= claim_region(NULL
, i
, 8, IORESOURCE_IO
, "PCMCIA ioprobe");
220 for (j
= 1; j
< 8; j
++)
221 if (inb(i
+j
) != hole
)
224 if ((j
== 8) && (++b
[hole
] > b
[most
]))
232 for (i
= base
; i
< base
+num
; i
+= 8) {
233 res
= claim_region(NULL
, i
, 8, IORESOURCE_IO
, "PCMCIA ioprobe");
236 for (j
= 0; j
< 8; j
++)
237 if (inb(i
+j
) != most
)
242 printk(" excluding");
247 sub_interval(&s_data
->io_db
, bad
, i
-bad
);
248 printk(" %#x-%#x", bad
, i
-1);
254 if ((num
> 16) && (bad
== base
) && (i
== base
+num
)) {
255 printk(" nothing: probe failed.\n");
258 sub_interval(&s_data
->io_db
, bad
, i
-bad
);
259 printk(" %#x-%#x", bad
, i
-1);
263 printk(any
? "\n" : " clean.\n");
267 /*======================================================================*/
270 * readable() - iomem validation function for cards with a valid CIS
272 static int readable(struct pcmcia_socket
*s
, struct resource
*res
,
277 s
->cis_mem
.res
= res
;
278 s
->cis_virt
= ioremap(res
->start
, s
->map_size
);
280 /* as we're only called from pcmcia.c, we're safe */
281 if (s
->callback
->validate
)
282 ret
= s
->callback
->validate(s
, count
);
283 /* invalidate mapping */
284 iounmap(s
->cis_virt
);
287 s
->cis_mem
.res
= NULL
;
288 if ((ret
) || (*count
== 0))
294 * checksum() - iomem validation function for simple memory cards
296 static int checksum(struct pcmcia_socket
*s
, struct resource
*res
,
300 int i
, a
= 0, b
= -1, d
;
303 virt
= ioremap(res
->start
, s
->map_size
);
306 map
.flags
= MAP_ACTIVE
;
310 s
->ops
->set_mem_map(s
, &map
);
312 /* Don't bother checking every word... */
313 for (i
= 0; i
< s
->map_size
; i
+= 44) {
320 s
->ops
->set_mem_map(s
, &map
);
334 * do_validate_mem() - low level validate a memory region for PCMCIA use
335 * @s: PCMCIA socket to validate
336 * @base: start address of resource to check
337 * @size: size of resource to check
338 * @validate: validation function to use
340 * do_validate_mem() splits up the memory region which is to be checked
341 * into two parts. Both are passed to the @validate() function. If
342 * @validate() returns non-zero, or the value parameter to @validate()
343 * is zero, or the value parameter is different between both calls,
344 * the check fails, and -EINVAL is returned. Else, 0 is returned.
346 static int do_validate_mem(struct pcmcia_socket
*s
,
347 unsigned long base
, unsigned long size
,
348 int validate (struct pcmcia_socket
*s
,
349 struct resource
*res
,
350 unsigned int *value
))
352 struct resource
*res1
, *res2
;
353 unsigned int info1
= 1, info2
= 1;
356 res1
= claim_region(s
, base
, size
/2, IORESOURCE_MEM
, "PCMCIA memprobe");
357 res2
= claim_region(s
, base
+ size
/2, size
/2, IORESOURCE_MEM
,
363 ret
= validate(s
, res1
, &info1
);
364 ret
+= validate(s
, res2
, &info2
);
371 dev_dbg(&s
->dev
, "cs: memory probe 0x%06lx-0x%06lx: %p %p %u %u %u",
372 base
, base
+size
-1, res1
, res2
, ret
, info1
, info2
);
374 if ((ret
) || (info1
!= info2
) || (info1
== 0))
382 * do_mem_probe() - validate a memory region for PCMCIA use
383 * @s: PCMCIA socket to validate
384 * @base: start address of resource to check
385 * @num: size of resource to check
386 * @validate: validation function to use
387 * @fallback: validation function to use if validate fails
389 * do_mem_probe() checks a memory region for use by the PCMCIA subsystem.
390 * To do so, the area is split up into sensible parts, and then passed
391 * into the @validate() function. Only if @validate() and @fallback() fail,
392 * the area is marked as unavaibale for use by the PCMCIA subsystem. The
393 * function returns the size of the usable memory area.
395 static int do_mem_probe(struct pcmcia_socket
*s
, u_long base
, u_long num
,
396 int validate (struct pcmcia_socket
*s
,
397 struct resource
*res
,
398 unsigned int *value
),
399 int fallback (struct pcmcia_socket
*s
,
400 struct resource
*res
,
401 unsigned int *value
))
403 struct socket_data
*s_data
= s
->resource_data
;
404 u_long i
, j
, bad
, fail
, step
;
406 dev_printk(KERN_INFO
, &s
->dev
, "cs: memory probe 0x%06lx-0x%06lx:",
409 step
= (num
< 0x20000) ? 0x2000 : ((num
>>4) & ~0x1fff);
410 /* don't allow too large steps */
413 /* cis_readable wants to map 2x map_size */
414 if (step
< 2 * s
->map_size
)
415 step
= 2 * s
->map_size
;
416 for (i
= j
= base
; i
< base
+num
; i
= j
+ step
) {
418 for (j
= i
; j
< base
+num
; j
+= step
) {
419 if (!do_validate_mem(s
, j
, step
, validate
))
422 fail
= ((i
== base
) && (j
== base
+num
));
424 if ((fail
) && (fallback
)) {
425 for (j
= i
; j
< base
+num
; j
+= step
)
426 if (!do_validate_mem(s
, j
, step
, fallback
))
431 printk(" excluding");
432 printk(" %#05lx-%#05lx", i
, j
-1);
433 sub_interval(&s_data
->mem_db
, i
, j
-i
);
437 printk(bad
? "\n" : " clean.\n");
442 #ifdef CONFIG_PCMCIA_PROBE
445 * inv_probe() - top-to-bottom search for one usuable high memory area
446 * @s: PCMCIA socket to validate
447 * @m: resource_map to check
449 static u_long
inv_probe(struct resource_map
*m
, struct pcmcia_socket
*s
)
451 struct socket_data
*s_data
= s
->resource_data
;
453 if (m
== &s_data
->mem_db
)
455 ok
= inv_probe(m
->next
, s
);
457 if (m
->base
>= 0x100000)
458 sub_interval(&s_data
->mem_db
, m
->base
, m
->num
);
461 if (m
->base
< 0x100000)
463 return do_mem_probe(s
, m
->base
, m
->num
, readable
, checksum
);
467 * validate_mem() - memory probe function
468 * @s: PCMCIA socket to validate
469 * @probe_mask: MEM_PROBE_LOW | MEM_PROBE_HIGH
471 * The memory probe. If the memory list includes a 64K-aligned block
472 * below 1MB, we probe in 64K chunks, and as soon as we accumulate at
473 * least mem_limit free space, we quit. Returns 0 on usuable ports.
475 static int validate_mem(struct pcmcia_socket
*s
, unsigned int probe_mask
)
477 struct resource_map
*m
, mm
;
478 static unsigned char order
[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
479 unsigned long b
, i
, ok
= 0;
480 struct socket_data
*s_data
= s
->resource_data
;
482 /* We do up to four passes through the list */
483 if (probe_mask
& MEM_PROBE_HIGH
) {
484 if (inv_probe(s_data
->mem_db
.next
, s
) > 0)
486 dev_printk(KERN_NOTICE
, &s
->dev
,
487 "cs: warning: no high memory space available!\n");
491 for (m
= s_data
->mem_db
.next
; m
!= &s_data
->mem_db
; m
= mm
.next
) {
493 /* Only probe < 1 MB */
494 if (mm
.base
>= 0x100000)
496 if ((mm
.base
| mm
.num
) & 0xffff) {
497 ok
+= do_mem_probe(s
, mm
.base
, mm
.num
, readable
,
501 /* Special probe for 64K-aligned block */
502 for (i
= 0; i
< 4; i
++) {
504 if ((b
>= mm
.base
) && (b
+0x10000 <= mm
.base
+mm
.num
)) {
506 sub_interval(&s_data
->mem_db
, b
, 0x10000);
508 ok
+= do_mem_probe(s
, b
, 0x10000,
520 #else /* CONFIG_PCMCIA_PROBE */
523 * validate_mem() - memory probe function
524 * @s: PCMCIA socket to validate
525 * @probe_mask: ignored
527 * Returns 0 on usuable ports.
529 static int validate_mem(struct pcmcia_socket
*s
, unsigned int probe_mask
)
531 struct resource_map
*m
, mm
;
532 struct socket_data
*s_data
= s
->resource_data
;
533 unsigned long ok
= 0;
535 for (m
= s_data
->mem_db
.next
; m
!= &s_data
->mem_db
; m
= mm
.next
) {
537 ok
+= do_mem_probe(s
, mm
.base
, mm
.num
, readable
, checksum
);
544 #endif /* CONFIG_PCMCIA_PROBE */
548 * pcmcia_nonstatic_validate_mem() - try to validate iomem for PCMCIA use
549 * @s: PCMCIA socket to validate
551 * This is tricky... when we set up CIS memory, we try to validate
552 * the memory window space allocations.
554 * Locking note: Must be called with skt_mutex held!
556 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket
*s
)
558 struct socket_data
*s_data
= s
->resource_data
;
559 unsigned int probe_mask
= MEM_PROBE_LOW
;
565 mutex_lock(&rsrc_mutex
);
567 if (s
->features
& SS_CAP_PAGE_REGS
)
568 probe_mask
= MEM_PROBE_HIGH
;
570 if (probe_mask
& ~s_data
->rsrc_mem_probe
) {
571 if (s
->state
& SOCKET_PRESENT
) {
572 ret
= validate_mem(s
, probe_mask
);
574 s_data
->rsrc_mem_probe
|= probe_mask
;
578 mutex_unlock(&rsrc_mutex
);
583 struct pcmcia_align_data
{
585 unsigned long offset
;
586 struct resource_map
*map
;
590 pcmcia_common_align(void *align_data
, struct resource
*res
,
591 resource_size_t size
, resource_size_t align
)
593 struct pcmcia_align_data
*data
= align_data
;
594 resource_size_t start
;
596 * Ensure that we have the correct start address
598 start
= (res
->start
& ~data
->mask
) + data
->offset
;
599 if (start
< res
->start
)
600 start
+= data
->mask
+ 1;
605 pcmcia_align(void *align_data
, struct resource
*res
, resource_size_t size
,
606 resource_size_t align
)
608 struct pcmcia_align_data
*data
= align_data
;
609 struct resource_map
*m
;
611 pcmcia_common_align(data
, res
, size
, align
);
613 for (m
= data
->map
->next
; m
!= data
->map
; m
= m
->next
) {
614 unsigned long start
= m
->base
;
615 unsigned long end
= m
->base
+ m
->num
- 1;
618 * If the lower resources are not available, try aligning
619 * to this entry of the resource database to see if it'll
622 if (res
->start
< start
) {
624 pcmcia_common_align(data
, res
, size
, align
);
628 * If we're above the area which was passed in, there's
629 * no point proceeding.
631 if (res
->start
>= res
->end
)
634 if ((res
->start
+ size
- 1) <= end
)
639 * If we failed to find something suitable, ensure we fail.
642 res
->start
= res
->end
;
646 * Adjust an existing IO region allocation, but making sure that we don't
647 * encroach outside the resources which the user supplied.
649 static int nonstatic_adjust_io_region(struct resource
*res
, unsigned long r_start
,
650 unsigned long r_end
, struct pcmcia_socket
*s
)
652 struct resource_map
*m
;
653 struct socket_data
*s_data
= s
->resource_data
;
656 mutex_lock(&rsrc_mutex
);
657 for (m
= s_data
->io_db
.next
; m
!= &s_data
->io_db
; m
= m
->next
) {
658 unsigned long start
= m
->base
;
659 unsigned long end
= m
->base
+ m
->num
- 1;
661 if (start
> r_start
|| r_end
> end
)
664 ret
= adjust_resource(res
, r_start
, r_end
- r_start
+ 1);
667 mutex_unlock(&rsrc_mutex
);
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
;
701 mutex_lock(&rsrc_mutex
);
704 ret
= pci_bus_alloc_resource(s
->cb_dev
->bus
, res
, num
, 1,
705 min
, 0, pcmcia_align
, &data
);
708 ret
= allocate_resource(&ioport_resource
, res
, num
, min
, ~0UL,
709 1, pcmcia_align
, &data
);
710 mutex_unlock(&rsrc_mutex
);
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
;
743 mutex_lock(&rsrc_mutex
);
746 ret
= pci_bus_alloc_resource(s
->cb_dev
->bus
, res
, num
,
748 pcmcia_align
, &data
);
751 ret
= allocate_resource(&iomem_resource
, res
, num
, min
,
752 max
, 1, pcmcia_align
, &data
);
753 mutex_unlock(&rsrc_mutex
);
767 static int adjust_memory(struct pcmcia_socket
*s
, unsigned int action
, unsigned long start
, unsigned long end
)
769 struct socket_data
*data
= s
->resource_data
;
770 unsigned long size
= end
- start
+ 1;
776 mutex_lock(&rsrc_mutex
);
778 case ADD_MANAGED_RESOURCE
:
779 ret
= add_interval(&data
->mem_db
, start
, size
);
781 do_mem_probe(s
, start
, size
, NULL
, NULL
);
783 case REMOVE_MANAGED_RESOURCE
:
784 ret
= sub_interval(&data
->mem_db
, start
, size
);
789 mutex_unlock(&rsrc_mutex
);
795 static int adjust_io(struct pcmcia_socket
*s
, unsigned int action
, unsigned long start
, unsigned long end
)
797 struct socket_data
*data
= s
->resource_data
;
798 unsigned long size
= end
- start
+ 1;
804 if (end
> IO_SPACE_LIMIT
)
807 mutex_lock(&rsrc_mutex
);
809 case ADD_MANAGED_RESOURCE
:
810 if (add_interval(&data
->io_db
, start
, size
) != 0) {
814 #ifdef CONFIG_PCMCIA_PROBE
816 do_io_probe(s
, start
, size
);
819 case REMOVE_MANAGED_RESOURCE
:
820 sub_interval(&data
->io_db
, start
, size
);
826 mutex_unlock(&rsrc_mutex
);
833 static int nonstatic_autoadd_resources(struct pcmcia_socket
*s
)
835 struct resource
*res
;
838 if (!s
->cb_dev
|| !s
->cb_dev
->bus
)
841 #if defined(CONFIG_X86)
842 /* If this is the root bus, the risk of hitting
843 * some strange system devices which aren't protected
844 * by either ACPI resource tables or properly requested
845 * resources is too big. Therefore, don't do auto-adding
846 * of resources at the moment.
848 if (s
->cb_dev
->bus
->number
== 0)
852 for (i
= 0; i
< PCI_BUS_NUM_RESOURCES
; i
++) {
853 res
= s
->cb_dev
->bus
->resource
[i
];
857 if (res
->flags
& IORESOURCE_IO
) {
858 if (res
== &ioport_resource
)
860 dev_printk(KERN_INFO
, &s
->cb_dev
->dev
,
861 "pcmcia: parent PCI bridge I/O "
862 "window: 0x%llx - 0x%llx\n",
863 (unsigned long long)res
->start
,
864 (unsigned long long)res
->end
);
865 if (!adjust_io(s
, ADD_MANAGED_RESOURCE
, res
->start
, res
->end
))
866 done
|= IORESOURCE_IO
;
870 if (res
->flags
& IORESOURCE_MEM
) {
871 if (res
== &iomem_resource
)
873 dev_printk(KERN_INFO
, &s
->cb_dev
->dev
,
874 "pcmcia: parent PCI bridge Memory "
875 "window: 0x%llx - 0x%llx\n",
876 (unsigned long long)res
->start
,
877 (unsigned long long)res
->end
);
878 if (!adjust_memory(s
, ADD_MANAGED_RESOURCE
, res
->start
, res
->end
))
879 done
|= IORESOURCE_MEM
;
883 /* if we got at least one of IO, and one of MEM, we can be glad and
884 * activate the PCMCIA subsystem */
885 if (done
== (IORESOURCE_MEM
| IORESOURCE_IO
))
886 s
->resource_setup_done
= 1;
893 static inline int nonstatic_autoadd_resources(struct pcmcia_socket
*s
)
901 static int nonstatic_init(struct pcmcia_socket
*s
)
903 struct socket_data
*data
;
905 data
= kzalloc(sizeof(struct socket_data
), GFP_KERNEL
);
909 data
->mem_db
.next
= &data
->mem_db
;
910 data
->io_db
.next
= &data
->io_db
;
912 s
->resource_data
= (void *) data
;
914 nonstatic_autoadd_resources(s
);
919 static void nonstatic_release_resource_db(struct pcmcia_socket
*s
)
921 struct socket_data
*data
= s
->resource_data
;
922 struct resource_map
*p
, *q
;
924 mutex_lock(&rsrc_mutex
);
925 for (p
= data
->mem_db
.next
; p
!= &data
->mem_db
; p
= q
) {
929 for (p
= data
->io_db
.next
; p
!= &data
->io_db
; p
= q
) {
933 mutex_unlock(&rsrc_mutex
);
937 struct pccard_resource_ops pccard_nonstatic_ops
= {
938 .validate_mem
= pcmcia_nonstatic_validate_mem
,
939 .adjust_io_region
= nonstatic_adjust_io_region
,
940 .find_io
= nonstatic_find_io_region
,
941 .find_mem
= nonstatic_find_mem_region
,
943 .add_mem
= adjust_memory
,
944 .init
= nonstatic_init
,
945 .exit
= nonstatic_release_resource_db
,
947 EXPORT_SYMBOL(pccard_nonstatic_ops
);
950 /* sysfs interface to the resource database */
952 static ssize_t
show_io_db(struct device
*dev
,
953 struct device_attribute
*attr
, char *buf
)
955 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
956 struct socket_data
*data
;
957 struct resource_map
*p
;
960 mutex_lock(&rsrc_mutex
);
961 data
= s
->resource_data
;
963 for (p
= data
->io_db
.next
; p
!= &data
->io_db
; p
= p
->next
) {
964 if (ret
> (PAGE_SIZE
- 10))
966 ret
+= snprintf(&buf
[ret
], (PAGE_SIZE
- ret
- 1),
967 "0x%08lx - 0x%08lx\n",
968 ((unsigned long) p
->base
),
969 ((unsigned long) p
->base
+ p
->num
- 1));
972 mutex_unlock(&rsrc_mutex
);
976 static ssize_t
store_io_db(struct device
*dev
,
977 struct device_attribute
*attr
,
978 const char *buf
, size_t count
)
980 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
981 unsigned long start_addr
, end_addr
;
982 unsigned int add
= ADD_MANAGED_RESOURCE
;
985 ret
= sscanf(buf
, "+ 0x%lx - 0x%lx", &start_addr
, &end_addr
);
987 ret
= sscanf(buf
, "- 0x%lx - 0x%lx", &start_addr
, &end_addr
);
988 add
= REMOVE_MANAGED_RESOURCE
;
990 ret
= sscanf(buf
, "0x%lx - 0x%lx", &start_addr
,
992 add
= ADD_MANAGED_RESOURCE
;
997 if (end_addr
< start_addr
)
1000 ret
= adjust_io(s
, add
, start_addr
, end_addr
);
1002 s
->resource_setup_new
= 1;
1004 return ret
? ret
: count
;
1006 static DEVICE_ATTR(available_resources_io
, 0600, show_io_db
, store_io_db
);
1008 static ssize_t
show_mem_db(struct device
*dev
,
1009 struct device_attribute
*attr
, char *buf
)
1011 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1012 struct socket_data
*data
;
1013 struct resource_map
*p
;
1016 mutex_lock(&rsrc_mutex
);
1017 data
= s
->resource_data
;
1019 for (p
= data
->mem_db
.next
; p
!= &data
->mem_db
; p
= p
->next
) {
1020 if (ret
> (PAGE_SIZE
- 10))
1022 ret
+= snprintf(&buf
[ret
], (PAGE_SIZE
- ret
- 1),
1023 "0x%08lx - 0x%08lx\n",
1024 ((unsigned long) p
->base
),
1025 ((unsigned long) p
->base
+ p
->num
- 1));
1028 mutex_unlock(&rsrc_mutex
);
1032 static ssize_t
store_mem_db(struct device
*dev
,
1033 struct device_attribute
*attr
,
1034 const char *buf
, size_t count
)
1036 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1037 unsigned long start_addr
, end_addr
;
1038 unsigned int add
= ADD_MANAGED_RESOURCE
;
1041 ret
= sscanf(buf
, "+ 0x%lx - 0x%lx", &start_addr
, &end_addr
);
1043 ret
= sscanf(buf
, "- 0x%lx - 0x%lx", &start_addr
, &end_addr
);
1044 add
= REMOVE_MANAGED_RESOURCE
;
1046 ret
= sscanf(buf
, "0x%lx - 0x%lx", &start_addr
,
1048 add
= ADD_MANAGED_RESOURCE
;
1053 if (end_addr
< start_addr
)
1056 ret
= adjust_memory(s
, add
, start_addr
, end_addr
);
1058 s
->resource_setup_new
= 1;
1060 return ret
? ret
: count
;
1062 static DEVICE_ATTR(available_resources_mem
, 0600, show_mem_db
, store_mem_db
);
1064 static struct attribute
*pccard_rsrc_attributes
[] = {
1065 &dev_attr_available_resources_io
.attr
,
1066 &dev_attr_available_resources_mem
.attr
,
1070 static const struct attribute_group rsrc_attributes
= {
1071 .attrs
= pccard_rsrc_attributes
,
1074 static int __devinit
pccard_sysfs_add_rsrc(struct device
*dev
,
1075 struct class_interface
*class_intf
)
1077 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1079 if (s
->resource_ops
!= &pccard_nonstatic_ops
)
1081 return sysfs_create_group(&dev
->kobj
, &rsrc_attributes
);
1084 static void __devexit
pccard_sysfs_remove_rsrc(struct device
*dev
,
1085 struct class_interface
*class_intf
)
1087 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1089 if (s
->resource_ops
!= &pccard_nonstatic_ops
)
1091 sysfs_remove_group(&dev
->kobj
, &rsrc_attributes
);
1094 static struct class_interface pccard_rsrc_interface __refdata
= {
1095 .class = &pcmcia_socket_class
,
1096 .add_dev
= &pccard_sysfs_add_rsrc
,
1097 .remove_dev
= __devexit_p(&pccard_sysfs_remove_rsrc
),
1100 static int __init
nonstatic_sysfs_init(void)
1102 return class_interface_register(&pccard_rsrc_interface
);
1105 static void __exit
nonstatic_sysfs_exit(void)
1107 class_interface_unregister(&pccard_rsrc_interface
);
1110 module_init(nonstatic_sysfs_init
);
1111 module_exit(nonstatic_sysfs_exit
);