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/ss.h>
32 #include <pcmcia/cistpl.h>
33 #include "cs_internal.h"
35 /* moved to rsrc_mgr.c
36 MODULE_AUTHOR("David A. Hinds, Dominik Brodowski");
37 MODULE_LICENSE("GPL");
40 /* Parameters that can be set with 'insmod' */
42 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
44 INT_MODULE_PARM(probe_mem
, 1); /* memory probe? */
45 #ifdef CONFIG_PCMCIA_PROBE
46 INT_MODULE_PARM(probe_io
, 1); /* IO port probe? */
47 INT_MODULE_PARM(mem_limit
, 0x10000);
50 /* for io_db and mem_db */
53 struct resource_map
*next
;
57 struct resource_map mem_db
;
58 struct resource_map mem_db_valid
;
59 struct resource_map io_db
;
62 #define MEM_PROBE_LOW (1 << 0)
63 #define MEM_PROBE_HIGH (1 << 1)
66 #define REMOVE_MANAGED_RESOURCE 1
67 #define ADD_MANAGED_RESOURCE 2
69 /*======================================================================
71 Linux resource management extensions
73 ======================================================================*/
75 static struct resource
*
76 claim_region(struct pcmcia_socket
*s
, resource_size_t base
,
77 resource_size_t size
, int type
, char *name
)
79 struct resource
*res
, *parent
;
81 parent
= type
& IORESOURCE_MEM
? &iomem_resource
: &ioport_resource
;
82 res
= pcmcia_make_resource(base
, size
, type
| IORESOURCE_BUSY
, name
);
87 parent
= pci_find_parent_resource(s
->cb_dev
, res
);
89 if (!parent
|| request_resource(parent
, res
)) {
97 static void free_region(struct resource
*res
)
100 release_resource(res
);
105 /*======================================================================
107 These manage the internal databases of available resources.
109 ======================================================================*/
111 static int add_interval(struct resource_map
*map
, u_long base
, u_long num
)
113 struct resource_map
*p
, *q
;
115 for (p
= map
; ; p
= p
->next
) {
116 if ((p
!= map
) && (p
->base
+p
->num
>= base
)) {
117 p
->num
= max(num
+ base
- p
->base
, p
->num
);
120 if ((p
->next
== map
) || (p
->next
->base
> base
+num
-1))
123 q
= kmalloc(sizeof(struct resource_map
), GFP_KERNEL
);
125 printk(KERN_WARNING
"out of memory to update resources\n");
128 q
->base
= base
; q
->num
= num
;
129 q
->next
= p
->next
; p
->next
= q
;
133 /*====================================================================*/
135 static int sub_interval(struct resource_map
*map
, u_long base
, u_long num
)
137 struct resource_map
*p
, *q
;
139 for (p
= map
; ; p
= q
) {
143 if ((q
->base
+q
->num
> base
) && (base
+num
> q
->base
)) {
144 if (q
->base
>= base
) {
145 if (q
->base
+q
->num
<= base
+num
) {
146 /* Delete whole block */
149 /* don't advance the pointer yet */
152 /* Cut off bit from the front */
153 q
->num
= q
->base
+ q
->num
- base
- num
;
154 q
->base
= base
+ num
;
156 } else if (q
->base
+q
->num
<= base
+num
) {
157 /* Cut off bit from the end */
158 q
->num
= base
- q
->base
;
160 /* Split the block into two pieces */
161 p
= kmalloc(sizeof(struct resource_map
),
164 printk(KERN_WARNING
"out of memory to update resources\n");
168 p
->num
= q
->base
+q
->num
- p
->base
;
169 q
->num
= base
- q
->base
;
170 p
->next
= q
->next
; q
->next
= p
;
177 /*======================================================================
179 These routines examine a region of IO or memory addresses to
180 determine what ranges might be genuinely available.
182 ======================================================================*/
184 #ifdef CONFIG_PCMCIA_PROBE
185 static void do_io_probe(struct pcmcia_socket
*s
, unsigned int base
,
188 struct resource
*res
;
189 struct socket_data
*s_data
= s
->resource_data
;
190 unsigned int i
, j
, bad
;
192 u_char
*b
, hole
, most
;
194 dev_printk(KERN_INFO
, &s
->dev
, "cs: IO port probe %#x-%#x:",
197 /* First, what does a floating port look like? */
198 b
= kzalloc(256, GFP_KERNEL
);
201 dev_printk(KERN_ERR
, &s
->dev
,
202 "do_io_probe: unable to kmalloc 256 bytes");
205 for (i
= base
, most
= 0; i
< base
+num
; i
+= 8) {
206 res
= claim_region(s
, i
, 8, IORESOURCE_IO
, "PCMCIA ioprobe");
210 for (j
= 1; j
< 8; j
++)
211 if (inb(i
+j
) != hole
)
214 if ((j
== 8) && (++b
[hole
] > b
[most
]))
222 for (i
= base
; i
< base
+num
; i
+= 8) {
223 res
= claim_region(s
, i
, 8, IORESOURCE_IO
, "PCMCIA ioprobe");
226 printk(" excluding");
231 for (j
= 0; j
< 8; j
++)
232 if (inb(i
+j
) != most
)
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 sub_interval(&s_data
->io_db
, bad
, i
-bad
);
251 printk(" nothing: probe failed.\n");
254 sub_interval(&s_data
->io_db
, bad
, i
-bad
);
255 printk(" %#x-%#x", bad
, i
-1);
259 printk(any
? "\n" : " clean.\n");
263 /*======================================================================*/
266 * readable() - iomem validation function for cards with a valid CIS
268 static int readable(struct pcmcia_socket
*s
, struct resource
*res
,
274 dev_dbg(&s
->dev
, "fake CIS is being used: can't validate mem\n");
278 s
->cis_mem
.res
= res
;
279 s
->cis_virt
= ioremap(res
->start
, s
->map_size
);
281 mutex_unlock(&s
->ops_mutex
);
282 /* as we're only called from pcmcia.c, we're safe */
283 if (s
->callback
->validate
)
284 ret
= s
->callback
->validate(s
, count
);
285 /* invalidate mapping */
286 mutex_lock(&s
->ops_mutex
);
287 iounmap(s
->cis_virt
);
290 s
->cis_mem
.res
= NULL
;
291 if ((ret
) || (*count
== 0))
297 * checksum() - iomem validation function for simple memory cards
299 static int checksum(struct pcmcia_socket
*s
, struct resource
*res
,
303 int i
, a
= 0, b
= -1, d
;
306 virt
= ioremap(res
->start
, s
->map_size
);
309 map
.flags
= MAP_ACTIVE
;
313 s
->ops
->set_mem_map(s
, &map
);
315 /* Don't bother checking every word... */
316 for (i
= 0; i
< s
->map_size
; i
+= 44) {
323 s
->ops
->set_mem_map(s
, &map
);
337 * do_validate_mem() - low level validate a memory region for PCMCIA use
338 * @s: PCMCIA socket to validate
339 * @base: start address of resource to check
340 * @size: size of resource to check
341 * @validate: validation function to use
343 * do_validate_mem() splits up the memory region which is to be checked
344 * into two parts. Both are passed to the @validate() function. If
345 * @validate() returns non-zero, or the value parameter to @validate()
346 * is zero, or the value parameter is different between both calls,
347 * the check fails, and -EINVAL is returned. Else, 0 is returned.
349 static int do_validate_mem(struct pcmcia_socket
*s
,
350 unsigned long base
, unsigned long size
,
351 int validate (struct pcmcia_socket
*s
,
352 struct resource
*res
,
353 unsigned int *value
))
355 struct socket_data
*s_data
= s
->resource_data
;
356 struct resource
*res1
, *res2
;
357 unsigned int info1
= 1, info2
= 1;
360 res1
= claim_region(s
, base
, size
/2, IORESOURCE_MEM
, "PCMCIA memprobe");
361 res2
= claim_region(s
, base
+ size
/2, size
/2, IORESOURCE_MEM
,
367 ret
= validate(s
, res1
, &info1
);
368 ret
+= validate(s
, res2
, &info2
);
372 dev_dbg(&s
->dev
, "cs: memory probe 0x%06lx-0x%06lx: %p %p %u %u %u",
373 base
, base
+size
-1, res1
, res2
, ret
, info1
, info2
);
378 if ((ret
) || (info1
!= info2
) || (info1
== 0))
381 if (validate
&& !s
->fake_cis
) {
382 /* move it to the validated data set */
383 add_interval(&s_data
->mem_db_valid
, base
, size
);
384 sub_interval(&s_data
->mem_db
, base
, size
);
392 * do_mem_probe() - validate a memory region for PCMCIA use
393 * @s: PCMCIA socket to validate
394 * @base: start address of resource to check
395 * @num: size of resource to check
396 * @validate: validation function to use
397 * @fallback: validation function to use if validate fails
399 * do_mem_probe() checks a memory region for use by the PCMCIA subsystem.
400 * To do so, the area is split up into sensible parts, and then passed
401 * into the @validate() function. Only if @validate() and @fallback() fail,
402 * the area is marked as unavaibale for use by the PCMCIA subsystem. The
403 * function returns the size of the usable memory area.
405 static int do_mem_probe(struct pcmcia_socket
*s
, u_long base
, u_long num
,
406 int validate (struct pcmcia_socket
*s
,
407 struct resource
*res
,
408 unsigned int *value
),
409 int fallback (struct pcmcia_socket
*s
,
410 struct resource
*res
,
411 unsigned int *value
))
413 struct socket_data
*s_data
= s
->resource_data
;
414 u_long i
, j
, bad
, fail
, step
;
416 dev_printk(KERN_INFO
, &s
->dev
, "cs: memory probe 0x%06lx-0x%06lx:",
419 step
= (num
< 0x20000) ? 0x2000 : ((num
>>4) & ~0x1fff);
420 /* don't allow too large steps */
423 /* cis_readable wants to map 2x map_size */
424 if (step
< 2 * s
->map_size
)
425 step
= 2 * s
->map_size
;
426 for (i
= j
= base
; i
< base
+num
; i
= j
+ step
) {
428 for (j
= i
; j
< base
+num
; j
+= step
) {
429 if (!do_validate_mem(s
, j
, step
, validate
))
432 fail
= ((i
== base
) && (j
== base
+num
));
434 if ((fail
) && (fallback
)) {
435 for (j
= i
; j
< base
+num
; j
+= step
)
436 if (!do_validate_mem(s
, j
, step
, fallback
))
441 printk(" excluding");
442 printk(" %#05lx-%#05lx", i
, j
-1);
443 sub_interval(&s_data
->mem_db
, i
, j
-i
);
447 printk(bad
? "\n" : " clean.\n");
452 #ifdef CONFIG_PCMCIA_PROBE
455 * inv_probe() - top-to-bottom search for one usuable high memory area
456 * @s: PCMCIA socket to validate
457 * @m: resource_map to check
459 static u_long
inv_probe(struct resource_map
*m
, struct pcmcia_socket
*s
)
461 struct socket_data
*s_data
= s
->resource_data
;
463 if (m
== &s_data
->mem_db
)
465 ok
= inv_probe(m
->next
, s
);
467 if (m
->base
>= 0x100000)
468 sub_interval(&s_data
->mem_db
, m
->base
, m
->num
);
471 if (m
->base
< 0x100000)
473 return do_mem_probe(s
, m
->base
, m
->num
, readable
, checksum
);
477 * validate_mem() - memory probe function
478 * @s: PCMCIA socket to validate
479 * @probe_mask: MEM_PROBE_LOW | MEM_PROBE_HIGH
481 * The memory probe. If the memory list includes a 64K-aligned block
482 * below 1MB, we probe in 64K chunks, and as soon as we accumulate at
483 * least mem_limit free space, we quit. Returns 0 on usuable ports.
485 static int validate_mem(struct pcmcia_socket
*s
, unsigned int probe_mask
)
487 struct resource_map
*m
, mm
;
488 static unsigned char order
[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
489 unsigned long b
, i
, ok
= 0;
490 struct socket_data
*s_data
= s
->resource_data
;
492 /* We do up to four passes through the list */
493 if (probe_mask
& MEM_PROBE_HIGH
) {
494 if (inv_probe(s_data
->mem_db
.next
, s
) > 0)
496 if (s_data
->mem_db_valid
.next
!= &s_data
->mem_db_valid
)
498 dev_printk(KERN_NOTICE
, &s
->dev
,
499 "cs: warning: no high memory space available!\n");
503 for (m
= s_data
->mem_db
.next
; m
!= &s_data
->mem_db
; m
= mm
.next
) {
505 /* Only probe < 1 MB */
506 if (mm
.base
>= 0x100000)
508 if ((mm
.base
| mm
.num
) & 0xffff) {
509 ok
+= do_mem_probe(s
, mm
.base
, mm
.num
, readable
,
513 /* Special probe for 64K-aligned block */
514 for (i
= 0; i
< 4; i
++) {
516 if ((b
>= mm
.base
) && (b
+0x10000 <= mm
.base
+mm
.num
)) {
518 sub_interval(&s_data
->mem_db
, b
, 0x10000);
520 ok
+= do_mem_probe(s
, b
, 0x10000,
532 #else /* CONFIG_PCMCIA_PROBE */
535 * validate_mem() - memory probe function
536 * @s: PCMCIA socket to validate
537 * @probe_mask: ignored
539 * Returns 0 on usuable ports.
541 static int validate_mem(struct pcmcia_socket
*s
, unsigned int probe_mask
)
543 struct resource_map
*m
, mm
;
544 struct socket_data
*s_data
= s
->resource_data
;
545 unsigned long ok
= 0;
547 for (m
= s_data
->mem_db
.next
; m
!= &s_data
->mem_db
; m
= mm
.next
) {
549 ok
+= do_mem_probe(s
, mm
.base
, mm
.num
, readable
, checksum
);
556 #endif /* CONFIG_PCMCIA_PROBE */
560 * pcmcia_nonstatic_validate_mem() - try to validate iomem for PCMCIA use
561 * @s: PCMCIA socket to validate
563 * This is tricky... when we set up CIS memory, we try to validate
564 * the memory window space allocations.
566 * Locking note: Must be called with skt_mutex held!
568 static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket
*s
)
570 struct socket_data
*s_data
= s
->resource_data
;
571 unsigned int probe_mask
= MEM_PROBE_LOW
;
574 if (!probe_mem
|| !(s
->state
& SOCKET_PRESENT
))
577 if (s
->features
& SS_CAP_PAGE_REGS
)
578 probe_mask
= MEM_PROBE_HIGH
;
580 ret
= validate_mem(s
, probe_mask
);
582 if (s_data
->mem_db_valid
.next
!= &s_data
->mem_db_valid
)
588 struct pcmcia_align_data
{
590 unsigned long offset
;
591 struct resource_map
*map
;
594 static resource_size_t
pcmcia_common_align(struct pcmcia_align_data
*align_data
,
595 resource_size_t start
)
599 * Ensure that we have the correct start address
601 ret
= (start
& ~align_data
->mask
) + align_data
->offset
;
603 ret
+= align_data
->mask
+ 1;
607 static resource_size_t
608 pcmcia_align(void *align_data
, const struct resource
*res
,
609 resource_size_t size
, resource_size_t align
)
611 struct pcmcia_align_data
*data
= align_data
;
612 struct resource_map
*m
;
613 resource_size_t start
;
615 start
= pcmcia_common_align(data
, res
->start
);
617 for (m
= data
->map
->next
; m
!= data
->map
; m
= m
->next
) {
618 unsigned long map_start
= m
->base
;
619 unsigned long map_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 (start
< map_start
)
627 start
= pcmcia_common_align(data
, map_start
);
630 * If we're above the area which was passed in, there's
631 * no point proceeding.
633 if (start
>= res
->end
)
636 if ((start
+ size
- 1) <= map_end
)
641 * If we failed to find something suitable, ensure we fail.
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 pcmcia_socket
*s
,
654 unsigned long r_start
,
657 struct resource_map
*m
;
658 struct socket_data
*s_data
= s
->resource_data
;
661 for (m
= s_data
->io_db
.next
; m
!= &s_data
->io_db
; m
= m
->next
) {
662 unsigned long start
= m
->base
;
663 unsigned long end
= m
->base
+ m
->num
- 1;
665 if (start
> r_start
|| r_end
> end
)
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(struct pcmcia_socket
*s
,
688 unsigned long base
, int num
,
691 struct resource
*res
= pcmcia_make_resource(0, num
, IORESOURCE_IO
,
693 struct socket_data
*s_data
= s
->resource_data
;
694 struct pcmcia_align_data data
;
695 unsigned long min
= base
;
698 data
.mask
= align
- 1;
699 data
.offset
= base
& data
.mask
;
700 data
.map
= &s_data
->io_db
;
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
);
718 static int nonstatic_find_io(struct pcmcia_socket
*s
, unsigned int attr
,
719 unsigned int *base
, unsigned int num
,
720 unsigned int align
, struct resource
**parent
)
724 /* Check for an already-allocated window that must conflict with
725 * what was asked for. It is a hack because it does not catch all
726 * potential conflicts, just the most obvious ones.
728 for (i
= 0; i
< MAX_IO_WIN
; i
++) {
735 if ((s
->io
[i
].res
->start
& (align
-1)) == *base
)
739 for (i
= 0; i
< MAX_IO_WIN
; i
++) {
740 struct resource
*res
= s
->io
[i
].res
;
743 if (res
&& (res
->flags
& IORESOURCE_BITS
) !=
744 (attr
& IORESOURCE_BITS
))
751 res
= s
->io
[i
].res
= __nonstatic_find_io_region(s
,
758 s
->io
[i
].res
->flags
=
759 ((res
->flags
& ~IORESOURCE_BITS
) |
760 (attr
& IORESOURCE_BITS
));
761 s
->io
[i
].InUse
= num
;
766 /* Try to extend top of window */
768 if ((*base
== 0) || (*base
== try)) {
769 ret
= __nonstatic_adjust_io_region(s
, res
->start
,
772 ret
= adjust_resource(s
->io
[i
].res
, res
->start
,
773 resource_size(res
) + num
);
777 s
->io
[i
].InUse
+= num
;
783 /* Try to extend bottom of window */
784 try = res
->start
- num
;
785 if ((*base
== 0) || (*base
== try)) {
786 ret
= __nonstatic_adjust_io_region(s
,
790 ret
= adjust_resource(s
->io
[i
].res
,
792 resource_size(res
) + num
);
796 s
->io
[i
].InUse
+= num
;
807 static struct resource
*nonstatic_find_mem_region(u_long base
, u_long num
,
808 u_long align
, int low
, struct pcmcia_socket
*s
)
810 struct resource
*res
= pcmcia_make_resource(0, num
, IORESOURCE_MEM
,
812 struct socket_data
*s_data
= s
->resource_data
;
813 struct pcmcia_align_data data
;
814 unsigned long min
, max
;
817 low
= low
|| !(s
->features
& SS_CAP_PAGE_REGS
);
819 data
.mask
= align
- 1;
820 data
.offset
= base
& data
.mask
;
822 for (i
= 0; i
< 2; i
++) {
823 data
.map
= &s_data
->mem_db_valid
;
826 min
= base
< max
? base
: 0;
829 min
= 0x100000UL
+ base
;
832 for (j
= 0; j
< 2; j
++) {
835 ret
= pci_bus_alloc_resource(s
->cb_dev
->bus
,
837 pcmcia_align
, &data
);
841 ret
= allocate_resource(&iomem_resource
,
842 res
, num
, min
, max
, 1,
843 pcmcia_align
, &data
);
847 data
.map
= &s_data
->mem_db
;
862 static int adjust_memory(struct pcmcia_socket
*s
, unsigned int action
, unsigned long start
, unsigned long end
)
864 struct socket_data
*data
= s
->resource_data
;
865 unsigned long size
= end
- start
+ 1;
872 case ADD_MANAGED_RESOURCE
:
873 ret
= add_interval(&data
->mem_db
, start
, size
);
875 do_mem_probe(s
, start
, size
, NULL
, NULL
);
877 case REMOVE_MANAGED_RESOURCE
:
878 ret
= sub_interval(&data
->mem_db
, start
, size
);
888 static int adjust_io(struct pcmcia_socket
*s
, unsigned int action
, unsigned long start
, unsigned long end
)
890 struct socket_data
*data
= s
->resource_data
;
894 #if defined(CONFIG_X86)
895 /* on x86, avoid anything < 0x100 for it is often used for
896 * legacy platform devices */
901 size
= end
- start
+ 1;
906 if (end
> IO_SPACE_LIMIT
)
910 case ADD_MANAGED_RESOURCE
:
911 if (add_interval(&data
->io_db
, start
, size
) != 0) {
915 #ifdef CONFIG_PCMCIA_PROBE
917 do_io_probe(s
, start
, size
);
920 case REMOVE_MANAGED_RESOURCE
:
921 sub_interval(&data
->io_db
, start
, size
);
933 static int nonstatic_autoadd_resources(struct pcmcia_socket
*s
)
935 struct resource
*res
;
938 if (!s
->cb_dev
|| !s
->cb_dev
->bus
)
941 #if defined(CONFIG_X86)
942 /* If this is the root bus, the risk of hitting some strange
943 * system devices is too high: If a driver isn't loaded, the
944 * resources are not claimed; even if a driver is loaded, it
945 * may not request all resources or even the wrong one. We
946 * can neither trust the rest of the kernel nor ACPI/PNP and
947 * CRS parsing to get it right. Therefore, use several
950 * - Do not auto-add resources if the CardBus bridge is on
953 * - Avoid any I/O ports < 0x100.
955 * - On PCI-PCI bridges, only use resources which are set up
956 * exclusively for the secondary PCI bus: the risk of hitting
957 * system devices is quite low, as they usually aren't
958 * connected to the secondary PCI bus.
960 if (s
->cb_dev
->bus
->number
== 0)
963 for (i
= 0; i
< PCI_BRIDGE_RESOURCE_NUM
; i
++) {
964 res
= s
->cb_dev
->bus
->resource
[i
];
966 pci_bus_for_each_resource(s
->cb_dev
->bus
, res
, i
) {
971 if (res
->flags
& IORESOURCE_IO
) {
972 /* safeguard against the root resource, where the
973 * risk of hitting any other device would be too
975 if (res
== &ioport_resource
)
978 dev_printk(KERN_INFO
, &s
->cb_dev
->dev
,
979 "pcmcia: parent PCI bridge window: %pR\n",
981 if (!adjust_io(s
, ADD_MANAGED_RESOURCE
, res
->start
, res
->end
))
982 done
|= IORESOURCE_IO
;
986 if (res
->flags
& IORESOURCE_MEM
) {
987 /* safeguard against the root resource, where the
988 * risk of hitting any other device would be too
990 if (res
== &iomem_resource
)
993 dev_printk(KERN_INFO
, &s
->cb_dev
->dev
,
994 "pcmcia: parent PCI bridge window: %pR\n",
996 if (!adjust_memory(s
, ADD_MANAGED_RESOURCE
, res
->start
, res
->end
))
997 done
|= IORESOURCE_MEM
;
1001 /* if we got at least one of IO, and one of MEM, we can be glad and
1002 * activate the PCMCIA subsystem */
1003 if (done
== (IORESOURCE_MEM
| IORESOURCE_IO
))
1004 s
->resource_setup_done
= 1;
1011 static inline int nonstatic_autoadd_resources(struct pcmcia_socket
*s
)
1019 static int nonstatic_init(struct pcmcia_socket
*s
)
1021 struct socket_data
*data
;
1023 data
= kzalloc(sizeof(struct socket_data
), GFP_KERNEL
);
1027 data
->mem_db
.next
= &data
->mem_db
;
1028 data
->mem_db_valid
.next
= &data
->mem_db_valid
;
1029 data
->io_db
.next
= &data
->io_db
;
1031 s
->resource_data
= (void *) data
;
1033 nonstatic_autoadd_resources(s
);
1038 static void nonstatic_release_resource_db(struct pcmcia_socket
*s
)
1040 struct socket_data
*data
= s
->resource_data
;
1041 struct resource_map
*p
, *q
;
1043 for (p
= data
->mem_db_valid
.next
; p
!= &data
->mem_db_valid
; p
= q
) {
1047 for (p
= data
->mem_db
.next
; p
!= &data
->mem_db
; p
= q
) {
1051 for (p
= data
->io_db
.next
; p
!= &data
->io_db
; p
= q
) {
1058 struct pccard_resource_ops pccard_nonstatic_ops
= {
1059 .validate_mem
= pcmcia_nonstatic_validate_mem
,
1060 .find_io
= nonstatic_find_io
,
1061 .find_mem
= nonstatic_find_mem_region
,
1062 .init
= nonstatic_init
,
1063 .exit
= nonstatic_release_resource_db
,
1065 EXPORT_SYMBOL(pccard_nonstatic_ops
);
1068 /* sysfs interface to the resource database */
1070 static ssize_t
show_io_db(struct device
*dev
,
1071 struct device_attribute
*attr
, char *buf
)
1073 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1074 struct socket_data
*data
;
1075 struct resource_map
*p
;
1078 mutex_lock(&s
->ops_mutex
);
1079 data
= s
->resource_data
;
1081 for (p
= data
->io_db
.next
; p
!= &data
->io_db
; p
= p
->next
) {
1082 if (ret
> (PAGE_SIZE
- 10))
1084 ret
+= snprintf(&buf
[ret
], (PAGE_SIZE
- ret
- 1),
1085 "0x%08lx - 0x%08lx\n",
1086 ((unsigned long) p
->base
),
1087 ((unsigned long) p
->base
+ p
->num
- 1));
1090 mutex_unlock(&s
->ops_mutex
);
1094 static ssize_t
store_io_db(struct device
*dev
,
1095 struct device_attribute
*attr
,
1096 const char *buf
, size_t count
)
1098 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1099 unsigned long start_addr
, end_addr
;
1100 unsigned int add
= ADD_MANAGED_RESOURCE
;
1103 ret
= sscanf(buf
, "+ 0x%lx - 0x%lx", &start_addr
, &end_addr
);
1105 ret
= sscanf(buf
, "- 0x%lx - 0x%lx", &start_addr
, &end_addr
);
1106 add
= REMOVE_MANAGED_RESOURCE
;
1108 ret
= sscanf(buf
, "0x%lx - 0x%lx", &start_addr
,
1110 add
= ADD_MANAGED_RESOURCE
;
1115 if (end_addr
< start_addr
)
1118 mutex_lock(&s
->ops_mutex
);
1119 ret
= adjust_io(s
, add
, start_addr
, end_addr
);
1120 mutex_unlock(&s
->ops_mutex
);
1122 return ret
? ret
: count
;
1124 static DEVICE_ATTR(available_resources_io
, 0600, show_io_db
, store_io_db
);
1126 static ssize_t
show_mem_db(struct device
*dev
,
1127 struct device_attribute
*attr
, char *buf
)
1129 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1130 struct socket_data
*data
;
1131 struct resource_map
*p
;
1134 mutex_lock(&s
->ops_mutex
);
1135 data
= s
->resource_data
;
1137 for (p
= data
->mem_db_valid
.next
; p
!= &data
->mem_db_valid
;
1139 if (ret
> (PAGE_SIZE
- 10))
1141 ret
+= snprintf(&buf
[ret
], (PAGE_SIZE
- ret
- 1),
1142 "0x%08lx - 0x%08lx\n",
1143 ((unsigned long) p
->base
),
1144 ((unsigned long) p
->base
+ p
->num
- 1));
1147 for (p
= data
->mem_db
.next
; p
!= &data
->mem_db
; p
= p
->next
) {
1148 if (ret
> (PAGE_SIZE
- 10))
1150 ret
+= snprintf(&buf
[ret
], (PAGE_SIZE
- ret
- 1),
1151 "0x%08lx - 0x%08lx\n",
1152 ((unsigned long) p
->base
),
1153 ((unsigned long) p
->base
+ p
->num
- 1));
1156 mutex_unlock(&s
->ops_mutex
);
1160 static ssize_t
store_mem_db(struct device
*dev
,
1161 struct device_attribute
*attr
,
1162 const char *buf
, size_t count
)
1164 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1165 unsigned long start_addr
, end_addr
;
1166 unsigned int add
= ADD_MANAGED_RESOURCE
;
1169 ret
= sscanf(buf
, "+ 0x%lx - 0x%lx", &start_addr
, &end_addr
);
1171 ret
= sscanf(buf
, "- 0x%lx - 0x%lx", &start_addr
, &end_addr
);
1172 add
= REMOVE_MANAGED_RESOURCE
;
1174 ret
= sscanf(buf
, "0x%lx - 0x%lx", &start_addr
,
1176 add
= ADD_MANAGED_RESOURCE
;
1181 if (end_addr
< start_addr
)
1184 mutex_lock(&s
->ops_mutex
);
1185 ret
= adjust_memory(s
, add
, start_addr
, end_addr
);
1186 mutex_unlock(&s
->ops_mutex
);
1188 return ret
? ret
: count
;
1190 static DEVICE_ATTR(available_resources_mem
, 0600, show_mem_db
, store_mem_db
);
1192 static struct attribute
*pccard_rsrc_attributes
[] = {
1193 &dev_attr_available_resources_io
.attr
,
1194 &dev_attr_available_resources_mem
.attr
,
1198 static const struct attribute_group rsrc_attributes
= {
1199 .attrs
= pccard_rsrc_attributes
,
1202 static int pccard_sysfs_add_rsrc(struct device
*dev
,
1203 struct class_interface
*class_intf
)
1205 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1207 if (s
->resource_ops
!= &pccard_nonstatic_ops
)
1209 return sysfs_create_group(&dev
->kobj
, &rsrc_attributes
);
1212 static void pccard_sysfs_remove_rsrc(struct device
*dev
,
1213 struct class_interface
*class_intf
)
1215 struct pcmcia_socket
*s
= dev_get_drvdata(dev
);
1217 if (s
->resource_ops
!= &pccard_nonstatic_ops
)
1219 sysfs_remove_group(&dev
->kobj
, &rsrc_attributes
);
1222 static struct class_interface pccard_rsrc_interface __refdata
= {
1223 .class = &pcmcia_socket_class
,
1224 .add_dev
= &pccard_sysfs_add_rsrc
,
1225 .remove_dev
= &pccard_sysfs_remove_rsrc
,
1228 static int __init
nonstatic_sysfs_init(void)
1230 return class_interface_register(&pccard_rsrc_interface
);
1233 static void __exit
nonstatic_sysfs_exit(void)
1235 class_interface_unregister(&pccard_rsrc_interface
);
1238 module_init(nonstatic_sysfs_init
);
1239 module_exit(nonstatic_sysfs_exit
);