diff options
Diffstat (limited to 'drivers/pcmcia/rsrc_mgr.c')
-rw-r--r-- | drivers/pcmcia/rsrc_mgr.c | 112 |
1 files changed, 19 insertions, 93 deletions
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index ffa5f3cae57b..142efac3c387 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,44 @@ 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 { | 49 | static int static_find_io(struct pcmcia_socket *s, unsigned int attr, |
66 | unsigned long mask; | 50 | unsigned int *base, unsigned int num, |
67 | unsigned long offset; | 51 | unsigned int align) |
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 | { | 52 | { |
74 | struct pcmcia_align_data *data = align_data; | 53 | if (!s->io_offset) |
75 | resource_size_t start; | 54 | return -EINVAL; |
55 | *base = s->io_offset | (*base & 0x0fff); | ||
76 | 56 | ||
77 | start = (res->start & ~data->mask) + data->offset; | 57 | return 0; |
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 | } | 58 | } |
104 | 59 | ||
105 | 60 | ||
106 | static struct resource *iodyn_find_io_region(unsigned long base, int num, | 61 | struct pccard_resource_ops pccard_static_ops = { |
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 | |||
118 | data.mask = align - 1; | ||
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, | 62 | .validate_mem = NULL, |
139 | .adjust_io_region = iodyn_adjust_io_region, | 63 | .find_io = static_find_io, |
140 | .find_io = iodyn_find_io_region, | ||
141 | .find_mem = NULL, | 64 | .find_mem = NULL, |
142 | .add_io = NULL, | 65 | .add_io = NULL, |
143 | .add_mem = NULL, | 66 | .add_mem = NULL, |
144 | .init = static_init, | 67 | .init = static_init, |
145 | .exit = NULL, | 68 | .exit = NULL, |
146 | }; | 69 | }; |
147 | EXPORT_SYMBOL(pccard_iodyn_ops); | 70 | EXPORT_SYMBOL(pccard_static_ops); |
71 | |||
148 | 72 | ||
149 | #endif /* CONFIG_PCCARD_IODYN */ | 73 | MODULE_AUTHOR("David A. Hinds, Dominik Brodowski"); |
74 | MODULE_LICENSE("GPL"); | ||
75 | MODULE_ALIAS("rsrc_nonstatic"); | ||