aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-02-17 12:00:07 -0500
committerDominik Brodowski <linux@dominikbrodowski.net>2010-02-17 12:00:07 -0500
commit7ab24855482fbc47712de46c05726d59cd0748e2 (patch)
tree0a2dfc014cd620eb6f9bdbc46ee58d63618a42ea /drivers/pcmcia
parent44961a03adbf16d872f0b83ec848d0759516d33f (diff)
pcmcia: add locking to pcmcia_{read,write}_cis_mem
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/cistpl.c27
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c5
2 files changed, 26 insertions, 6 deletions
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 17a5da32cce1..602f574898dc 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -83,6 +83,8 @@ void release_cis_mem(struct pcmcia_socket *s)
83 * Map the card memory at "card_offset" into virtual space. 83 * Map the card memory at "card_offset" into virtual space.
84 * If flags & MAP_ATTRIB, map the attribute space, otherwise 84 * If flags & MAP_ATTRIB, map the attribute space, otherwise
85 * map the memory space. 85 * map the memory space.
86 *
87 * Must be called with ops_mutex held.
86 */ 88 */
87static void __iomem * 89static void __iomem *
88set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) 90set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags)
@@ -90,13 +92,11 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag
90 pccard_mem_map *mem = &s->cis_mem; 92 pccard_mem_map *mem = &s->cis_mem;
91 int ret; 93 int ret;
92 94
93 mutex_lock(&s->ops_mutex);
94 if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) { 95 if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) {
95 mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); 96 mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s);
96 if (mem->res == NULL) { 97 if (mem->res == NULL) {
97 dev_printk(KERN_NOTICE, &s->dev, 98 dev_printk(KERN_NOTICE, &s->dev,
98 "cs: unable to map card memory!\n"); 99 "cs: unable to map card memory!\n");
99 mutex_unlock(&s->ops_mutex);
100 return NULL; 100 return NULL;
101 } 101 }
102 s->cis_virt = NULL; 102 s->cis_virt = NULL;
@@ -112,7 +112,6 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag
112 if (ret) { 112 if (ret) {
113 iounmap(s->cis_virt); 113 iounmap(s->cis_virt);
114 s->cis_virt = NULL; 114 s->cis_virt = NULL;
115 mutex_unlock(&s->ops_mutex);
116 return NULL; 115 return NULL;
117 } 116 }
118 117
@@ -122,7 +121,6 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag
122 s->cis_virt = ioremap(mem->static_start, s->map_size); 121 s->cis_virt = ioremap(mem->static_start, s->map_size);
123 } 122 }
124 123
125 mutex_unlock(&s->ops_mutex);
126 return s->cis_virt; 124 return s->cis_virt;
127} 125}
128 126
@@ -145,6 +143,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
145 143
146 dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len); 144 dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
147 145
146 mutex_lock(&s->ops_mutex);
148 if (attr & IS_INDIRECT) { 147 if (attr & IS_INDIRECT) {
149 /* Indirect accesses use a bunch of special registers at fixed 148 /* Indirect accesses use a bunch of special registers at fixed
150 locations in common memory */ 149 locations in common memory */
@@ -156,7 +155,9 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
156 155
157 sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0)); 156 sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0));
158 if (!sys) { 157 if (!sys) {
158 dev_dbg(&s->dev, "could not map memory\n");
159 memset(ptr, 0xff, len); 159 memset(ptr, 0xff, len);
160 mutex_unlock(&s->ops_mutex);
160 return -1; 161 return -1;
161 } 162 }
162 163
@@ -170,6 +171,9 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
170 } else { 171 } else {
171 u_int inc = 1, card_offset, flags; 172 u_int inc = 1, card_offset, flags;
172 173
174 if (addr > CISTPL_MAX_CIS_SIZE)
175 dev_dbg(&s->dev, "attempt to read CIS mem at addr %#x", addr);
176
173 flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0); 177 flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
174 if (attr) { 178 if (attr) {
175 flags |= MAP_ATTRIB; 179 flags |= MAP_ATTRIB;
@@ -181,7 +185,9 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
181 while (len) { 185 while (len) {
182 sys = set_cis_map(s, card_offset, flags); 186 sys = set_cis_map(s, card_offset, flags);
183 if (!sys) { 187 if (!sys) {
188 dev_dbg(&s->dev, "could not map memory\n");
184 memset(ptr, 0xff, len); 189 memset(ptr, 0xff, len);
190 mutex_unlock(&s->ops_mutex);
185 return -1; 191 return -1;
186 } 192 }
187 end = sys + s->map_size; 193 end = sys + s->map_size;
@@ -195,6 +201,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
195 addr = 0; 201 addr = 0;
196 } 202 }
197 } 203 }
204 mutex_unlock(&s->ops_mutex);
198 dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", 205 dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
199 *(u_char *)(ptr+0), *(u_char *)(ptr+1), 206 *(u_char *)(ptr+0), *(u_char *)(ptr+1),
200 *(u_char *)(ptr+2), *(u_char *)(ptr+3)); 207 *(u_char *)(ptr+2), *(u_char *)(ptr+3));
@@ -210,6 +217,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
210 217
211 dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); 218 dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
212 219
220 mutex_lock(&s->ops_mutex);
213 if (attr & IS_INDIRECT) { 221 if (attr & IS_INDIRECT) {
214 /* Indirect accesses use a bunch of special registers at fixed 222 /* Indirect accesses use a bunch of special registers at fixed
215 locations in common memory */ 223 locations in common memory */
@@ -220,8 +228,11 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
220 } 228 }
221 229
222 sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0)); 230 sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0));
223 if (!sys) 231 if (!sys) {
232 dev_dbg(&s->dev, "could not map memory\n");
233 mutex_unlock(&s->ops_mutex);
224 return; /* FIXME: Error */ 234 return; /* FIXME: Error */
235 }
225 236
226 writeb(flags, sys+CISREG_ICTRL0); 237 writeb(flags, sys+CISREG_ICTRL0);
227 writeb(addr & 0xff, sys+CISREG_IADDR0); 238 writeb(addr & 0xff, sys+CISREG_IADDR0);
@@ -243,8 +254,11 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
243 card_offset = addr & ~(s->map_size-1); 254 card_offset = addr & ~(s->map_size-1);
244 while (len) { 255 while (len) {
245 sys = set_cis_map(s, card_offset, flags); 256 sys = set_cis_map(s, card_offset, flags);
246 if (!sys) 257 if (!sys) {
258 dev_dbg(&s->dev, "could not map memory\n");
259 mutex_unlock(&s->ops_mutex);
247 return; /* FIXME: error */ 260 return; /* FIXME: error */
261 }
248 262
249 end = sys + s->map_size; 263 end = sys + s->map_size;
250 sys = sys + (addr & (s->map_size-1)); 264 sys = sys + (addr & (s->map_size-1));
@@ -257,6 +271,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
257 addr = 0; 271 addr = 0;
258 } 272 }
259 } 273 }
274 mutex_unlock(&s->ops_mutex);
260} 275}
261 276
262 277
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index c13424f7b479..19cecb539759 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -273,6 +273,11 @@ static int readable(struct pcmcia_socket *s, struct resource *res,
273{ 273{
274 int ret = -EINVAL; 274 int ret = -EINVAL;
275 275
276 if (s->fake_cis) {
277 dev_dbg(&s->dev, "fake CIS is being used: can't validate mem\n");
278 return 0;
279 }
280
276 s->cis_mem.res = res; 281 s->cis_mem.res = res;
277 s->cis_virt = ioremap(res->start, s->map_size); 282 s->cis_virt = ioremap(res->start, s->map_size);
278 if (s->cis_virt) { 283 if (s->cis_virt) {