diff options
-rw-r--r-- | drivers/pcmcia/Kconfig | 2 | ||||
-rw-r--r-- | drivers/pcmcia/Makefile | 7 | ||||
-rw-r--r-- | drivers/pcmcia/cs_internal.h | 8 | ||||
-rw-r--r-- | drivers/pcmcia/rsrc_iodyn.c | 107 | ||||
-rw-r--r-- | drivers/pcmcia/rsrc_mgr.c | 110 | ||||
-rw-r--r-- | drivers/pcmcia/rsrc_nonstatic.c | 24 |
6 files changed, 141 insertions, 117 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index d189e4743e69..4c5b53f62079 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig | |||
@@ -317,7 +317,7 @@ config ELECTRA_CF | |||
317 | PA Semi Electra eval board. | 317 | PA Semi Electra eval board. |
318 | 318 | ||
319 | config PCCARD_NONSTATIC | 319 | config PCCARD_NONSTATIC |
320 | tristate | 320 | bool |
321 | 321 | ||
322 | config PCCARD_IODYN | 322 | config PCCARD_IODYN |
323 | bool | 323 | bool |
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 8122b03e2ae5..7031d0a4f4b0 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the kernel pcmcia subsystem (c/o David Hinds) | 2 | # Makefile for the kernel pcmcia subsystem (c/o David Hinds) |
3 | # | 3 | # |
4 | 4 | ||
5 | pcmcia_core-y += cs.o rsrc_mgr.o socket_sysfs.o | 5 | pcmcia_core-y += cs.o socket_sysfs.o |
6 | pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o | 6 | pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o |
7 | obj-$(CONFIG_PCCARD) += pcmcia_core.o | 7 | obj-$(CONFIG_PCCARD) += pcmcia_core.o |
8 | 8 | ||
@@ -10,7 +10,10 @@ pcmcia-y += ds.o pcmcia_resource.o cistpl.o pcmcia_cis.o | |||
10 | pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o | 10 | pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o |
11 | obj-$(CONFIG_PCMCIA) += pcmcia.o | 11 | obj-$(CONFIG_PCMCIA) += pcmcia.o |
12 | 12 | ||
13 | obj-$(CONFIG_PCCARD_NONSTATIC) += rsrc_nonstatic.o | 13 | pcmcia_rsrc-y += rsrc_mgr.o |
14 | pcmcia_rsrc-$(CONFIG_PCCARD_NONSTATIC) += rsrc_nonstatic.o | ||
15 | pcmcia_rsrc-$(CONFIG_PCCARD_IODYN) += rsrc_iodyn.o | ||
16 | obj-$(CONFIG_PCCARD) += pcmcia_rsrc.o | ||
14 | 17 | ||
15 | 18 | ||
16 | # socket drivers | 19 | # socket drivers |
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 74d91c8849ba..ab000ea67296 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h | |||
@@ -89,6 +89,14 @@ struct pccard_resource_ops { | |||
89 | 89 | ||
90 | 90 | ||
91 | /* | 91 | /* |
92 | * Stuff internal to module "pcmcia_rsrc": | ||
93 | */ | ||
94 | extern int static_init(struct pcmcia_socket *s); | ||
95 | extern struct resource *pcmcia_make_resource(unsigned long start, | ||
96 | unsigned long end, | ||
97 | int flags, const char *name); | ||
98 | |||
99 | /* | ||
92 | * Stuff internal to module "pcmcia_core": | 100 | * Stuff internal to module "pcmcia_core": |
93 | */ | 101 | */ |
94 | 102 | ||
diff --git a/drivers/pcmcia/rsrc_iodyn.c b/drivers/pcmcia/rsrc_iodyn.c new file mode 100644 index 000000000000..3fa808b582f6 --- /dev/null +++ b/drivers/pcmcia/rsrc_iodyn.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * rsrc_iodyn.c -- Resource management routines for MEM-static sockets. | ||
3 | * | ||
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. | ||
7 | * | ||
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. | ||
11 | * | ||
12 | * (C) 1999 David A. Hinds | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/kernel.h> | ||
17 | |||
18 | #include <pcmcia/cs_types.h> | ||
19 | #include <pcmcia/ss.h> | ||
20 | #include <pcmcia/cs.h> | ||
21 | #include <pcmcia/cistpl.h> | ||
22 | #include "cs_internal.h" | ||
23 | |||
24 | |||
25 | struct pcmcia_align_data { | ||
26 | unsigned long mask; | ||
27 | unsigned long offset; | ||
28 | }; | ||
29 | |||
30 | static resource_size_t pcmcia_align(void *align_data, | ||
31 | const struct resource *res, | ||
32 | resource_size_t size, resource_size_t align) | ||
33 | { | ||
34 | struct pcmcia_align_data *data = align_data; | ||
35 | resource_size_t start; | ||
36 | |||
37 | start = (res->start & ~data->mask) + data->offset; | ||
38 | if (start < res->start) | ||
39 | start += data->mask + 1; | ||
40 | |||
41 | #ifdef CONFIG_X86 | ||
42 | if (res->flags & IORESOURCE_IO) { | ||
43 | if (start & 0x300) | ||
44 | start = (start + 0x3ff) & ~0x3ff; | ||
45 | } | ||
46 | #endif | ||
47 | |||
48 | #ifdef CONFIG_M68K | ||
49 | if (res->flags & IORESOURCE_IO) { | ||
50 | if ((res->start + size - 1) >= 1024) | ||
51 | start = res->end; | ||
52 | } | ||
53 | #endif | ||
54 | |||
55 | return start; | ||
56 | } | ||
57 | |||
58 | |||
59 | static int iodyn_adjust_io_region(struct resource *res, unsigned long r_start, | ||
60 | unsigned long r_end, struct pcmcia_socket *s) | ||
61 | { | ||
62 | return adjust_resource(res, r_start, r_end - r_start + 1); | ||
63 | } | ||
64 | |||
65 | |||
66 | static struct resource *iodyn_find_io_region(unsigned long base, int num, | ||
67 | unsigned long align, struct pcmcia_socket *s) | ||
68 | { | ||
69 | struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO, | ||
70 | dev_name(&s->dev)); | ||
71 | struct pcmcia_align_data data; | ||
72 | unsigned long min = base; | ||
73 | int ret; | ||
74 | |||
75 | if (align == 0) | ||
76 | align = 0x10000; | ||
77 | |||
78 | data.mask = align - 1; | ||
79 | data.offset = base & data.mask; | ||
80 | |||
81 | #ifdef CONFIG_PCI | ||
82 | if (s->cb_dev) { | ||
83 | ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, | ||
84 | min, 0, pcmcia_align, &data); | ||
85 | } else | ||
86 | #endif | ||
87 | ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, | ||
88 | 1, pcmcia_align, &data); | ||
89 | |||
90 | if (ret != 0) { | ||
91 | kfree(res); | ||
92 | res = NULL; | ||
93 | } | ||
94 | return res; | ||
95 | } | ||
96 | |||
97 | struct pccard_resource_ops pccard_iodyn_ops = { | ||
98 | .validate_mem = NULL, | ||
99 | .adjust_io_region = iodyn_adjust_io_region, | ||
100 | .find_io = iodyn_find_io_region, | ||
101 | .find_mem = NULL, | ||
102 | .add_io = NULL, | ||
103 | .add_mem = NULL, | ||
104 | .init = static_init, | ||
105 | .exit = NULL, | ||
106 | }; | ||
107 | EXPORT_SYMBOL(pccard_iodyn_ops); | ||
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index ffa5f3cae57b..71838cae890c 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <pcmcia/cistpl.h> | 22 | #include <pcmcia/cistpl.h> |
23 | #include "cs_internal.h" | 23 | #include "cs_internal.h" |
24 | 24 | ||
25 | static int static_init(struct pcmcia_socket *s) | 25 | int static_init(struct pcmcia_socket *s) |
26 | { | 26 | { |
27 | /* the good thing about SS_CAP_STATIC_MAP sockets is | 27 | /* the good thing about SS_CAP_STATIC_MAP sockets is |
28 | * that they don't need a resource database */ | 28 | * that they don't need a resource database */ |
@@ -32,118 +32,34 @@ static int static_init(struct pcmcia_socket *s) | |||
32 | return 0; | 32 | return 0; |
33 | } | 33 | } |
34 | 34 | ||
35 | 35 | struct resource *pcmcia_make_resource(unsigned long start, unsigned long end, | |
36 | struct pccard_resource_ops pccard_static_ops = { | 36 | int flags, const char *name) |
37 | .validate_mem = NULL, | ||
38 | .adjust_io_region = NULL, | ||
39 | .find_io = NULL, | ||
40 | .find_mem = NULL, | ||
41 | .add_io = NULL, | ||
42 | .add_mem = NULL, | ||
43 | .init = static_init, | ||
44 | .exit = NULL, | ||
45 | }; | ||
46 | EXPORT_SYMBOL(pccard_static_ops); | ||
47 | |||
48 | |||
49 | #ifdef CONFIG_PCCARD_IODYN | ||
50 | |||
51 | static struct resource * | ||
52 | make_resource(unsigned long b, unsigned long n, int flags, char *name) | ||
53 | { | 37 | { |
54 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); | 38 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); |
55 | 39 | ||
56 | if (res) { | 40 | if (res) { |
57 | res->name = name; | 41 | res->name = name; |
58 | res->start = b; | 42 | res->start = start; |
59 | res->end = b + n - 1; | 43 | res->end = start + end - 1; |
60 | res->flags = flags; | 44 | res->flags = flags; |
61 | } | 45 | } |
62 | return res; | 46 | return res; |
63 | } | 47 | } |
64 | 48 | ||
65 | struct pcmcia_align_data { | ||
66 | unsigned long mask; | ||
67 | unsigned long offset; | ||
68 | }; | ||
69 | |||
70 | static resource_size_t pcmcia_align(void *align_data, | ||
71 | const struct resource *res, | ||
72 | resource_size_t size, resource_size_t align) | ||
73 | { | ||
74 | struct pcmcia_align_data *data = align_data; | ||
75 | resource_size_t start; | ||
76 | |||
77 | start = (res->start & ~data->mask) + data->offset; | ||
78 | if (start < res->start) | ||
79 | start += data->mask + 1; | ||
80 | |||
81 | #ifdef CONFIG_X86 | ||
82 | if (res->flags & IORESOURCE_IO) { | ||
83 | if (start & 0x300) | ||
84 | start = (start + 0x3ff) & ~0x3ff; | ||
85 | } | ||
86 | #endif | ||
87 | |||
88 | #ifdef CONFIG_M68K | ||
89 | if (res->flags & IORESOURCE_IO) { | ||
90 | if ((res->start + size - 1) >= 1024) | ||
91 | start = res->end; | ||
92 | } | ||
93 | #endif | ||
94 | |||
95 | return start; | ||
96 | } | ||
97 | |||
98 | |||
99 | static int iodyn_adjust_io_region(struct resource *res, unsigned long r_start, | ||
100 | unsigned long r_end, struct pcmcia_socket *s) | ||
101 | { | ||
102 | return adjust_resource(res, r_start, r_end - r_start + 1); | ||
103 | } | ||
104 | |||
105 | |||
106 | static struct resource *iodyn_find_io_region(unsigned long base, int num, | ||
107 | unsigned long align, struct pcmcia_socket *s) | ||
108 | { | ||
109 | struct resource *res = make_resource(0, num, IORESOURCE_IO, | ||
110 | dev_name(&s->dev)); | ||
111 | struct pcmcia_align_data data; | ||
112 | unsigned long min = base; | ||
113 | int ret; | ||
114 | |||
115 | if (align == 0) | ||
116 | align = 0x10000; | ||
117 | 49 | ||
118 | data.mask = align - 1; | 50 | struct pccard_resource_ops pccard_static_ops = { |
119 | data.offset = base & data.mask; | ||
120 | |||
121 | #ifdef CONFIG_PCI | ||
122 | if (s->cb_dev) { | ||
123 | ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, | ||
124 | min, 0, pcmcia_align, &data); | ||
125 | } else | ||
126 | #endif | ||
127 | ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, | ||
128 | 1, pcmcia_align, &data); | ||
129 | |||
130 | if (ret != 0) { | ||
131 | kfree(res); | ||
132 | res = NULL; | ||
133 | } | ||
134 | return res; | ||
135 | } | ||
136 | |||
137 | struct pccard_resource_ops pccard_iodyn_ops = { | ||
138 | .validate_mem = NULL, | 51 | .validate_mem = NULL, |
139 | .adjust_io_region = iodyn_adjust_io_region, | 52 | .adjust_io_region = NULL, |
140 | .find_io = iodyn_find_io_region, | 53 | .find_io = NULL, |
141 | .find_mem = NULL, | 54 | .find_mem = NULL, |
142 | .add_io = NULL, | 55 | .add_io = NULL, |
143 | .add_mem = NULL, | 56 | .add_mem = NULL, |
144 | .init = static_init, | 57 | .init = static_init, |
145 | .exit = NULL, | 58 | .exit = NULL, |
146 | }; | 59 | }; |
147 | EXPORT_SYMBOL(pccard_iodyn_ops); | 60 | EXPORT_SYMBOL(pccard_static_ops); |
61 | |||
148 | 62 | ||
149 | #endif /* CONFIG_PCCARD_IODYN */ | 63 | MODULE_AUTHOR("David A. Hinds, Dominik Brodowski"); |
64 | MODULE_LICENSE("GPL"); | ||
65 | MODULE_ALIAS("rsrc_nonstatic"); | ||
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index a6eb7b59ba9f..c5ebc603b058 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -34,8 +34,10 @@ | |||
34 | #include <pcmcia/cistpl.h> | 34 | #include <pcmcia/cistpl.h> |
35 | #include "cs_internal.h" | 35 | #include "cs_internal.h" |
36 | 36 | ||
37 | /* moved to rsrc_mgr.c | ||
37 | MODULE_AUTHOR("David A. Hinds, Dominik Brodowski"); | 38 | MODULE_AUTHOR("David A. Hinds, Dominik Brodowski"); |
38 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
40 | */ | ||
39 | 41 | ||
40 | /* Parameters that can be set with 'insmod' */ | 42 | /* Parameters that can be set with 'insmod' */ |
41 | 43 | ||
@@ -70,27 +72,13 @@ struct socket_data { | |||
70 | ======================================================================*/ | 72 | ======================================================================*/ |
71 | 73 | ||
72 | static struct resource * | 74 | static struct resource * |
73 | make_resource(resource_size_t b, resource_size_t n, int flags, const char *name) | ||
74 | { | ||
75 | struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); | ||
76 | |||
77 | if (res) { | ||
78 | res->name = name; | ||
79 | res->start = b; | ||
80 | res->end = b + n - 1; | ||
81 | res->flags = flags; | ||
82 | } | ||
83 | return res; | ||
84 | } | ||
85 | |||
86 | static struct resource * | ||
87 | claim_region(struct pcmcia_socket *s, resource_size_t base, | 75 | claim_region(struct pcmcia_socket *s, resource_size_t base, |
88 | resource_size_t size, int type, char *name) | 76 | resource_size_t size, int type, char *name) |
89 | { | 77 | { |
90 | struct resource *res, *parent; | 78 | struct resource *res, *parent; |
91 | 79 | ||
92 | parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource; | 80 | parent = type & IORESOURCE_MEM ? &iomem_resource : &ioport_resource; |
93 | res = make_resource(base, size, type | IORESOURCE_BUSY, name); | 81 | res = pcmcia_make_resource(base, size, type | IORESOURCE_BUSY, name); |
94 | 82 | ||
95 | if (res) { | 83 | if (res) { |
96 | #ifdef CONFIG_PCI | 84 | #ifdef CONFIG_PCI |
@@ -698,7 +686,8 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star | |||
698 | static struct resource *nonstatic_find_io_region(unsigned long base, int num, | 686 | static struct resource *nonstatic_find_io_region(unsigned long base, int num, |
699 | unsigned long align, struct pcmcia_socket *s) | 687 | unsigned long align, struct pcmcia_socket *s) |
700 | { | 688 | { |
701 | struct resource *res = make_resource(0, num, IORESOURCE_IO, dev_name(&s->dev)); | 689 | struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO, |
690 | dev_name(&s->dev)); | ||
702 | struct socket_data *s_data = s->resource_data; | 691 | struct socket_data *s_data = s->resource_data; |
703 | struct pcmcia_align_data data; | 692 | struct pcmcia_align_data data; |
704 | unsigned long min = base; | 693 | unsigned long min = base; |
@@ -730,7 +719,8 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num, | |||
730 | static struct resource *nonstatic_find_mem_region(u_long base, u_long num, | 719 | static struct resource *nonstatic_find_mem_region(u_long base, u_long num, |
731 | u_long align, int low, struct pcmcia_socket *s) | 720 | u_long align, int low, struct pcmcia_socket *s) |
732 | { | 721 | { |
733 | struct resource *res = make_resource(0, num, IORESOURCE_MEM, dev_name(&s->dev)); | 722 | struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM, |
723 | dev_name(&s->dev)); | ||
734 | struct socket_data *s_data = s->resource_data; | 724 | struct socket_data *s_data = s->resource_data; |
735 | struct pcmcia_align_data data; | 725 | struct pcmcia_align_data data; |
736 | unsigned long min, max; | 726 | unsigned long min, max; |