aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/cistpl.c
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-03-30 12:07:50 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2010-05-10 04:23:23 -0400
commit059f667d9f81082e94dead14ff3fa7b3b42c98a0 (patch)
treeabd97312659c44cd05dc8b1bf5bc0bb6fba832c2 /drivers/pcmcia/cistpl.c
parenta60f22c4af3382b86301d64d6a9d68f30191d4c9 (diff)
pcmcia: call pcmcia_{read,write}_cis_mem with ops_mutex held
This avoids multiple lock takings in several codepaths. Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia/cistpl.c')
-rw-r--r--drivers/pcmcia/cistpl.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index e0b09e71d5c0..60d428be0b07 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -129,6 +129,8 @@ static void __iomem *set_cis_map(struct pcmcia_socket *s,
129 129
130/** 130/**
131 * pcmcia_read_cis_mem() - low-level function to read CIS memory 131 * pcmcia_read_cis_mem() - low-level function to read CIS memory
132 *
133 * must be called with ops_mutex held
132 */ 134 */
133int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, 135int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
134 u_int len, void *ptr) 136 u_int len, void *ptr)
@@ -138,7 +140,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
138 140
139 dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len); 141 dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
140 142
141 mutex_lock(&s->ops_mutex);
142 if (attr & IS_INDIRECT) { 143 if (attr & IS_INDIRECT) {
143 /* Indirect accesses use a bunch of special registers at fixed 144 /* Indirect accesses use a bunch of special registers at fixed
144 locations in common memory */ 145 locations in common memory */
@@ -153,7 +154,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
153 if (!sys) { 154 if (!sys) {
154 dev_dbg(&s->dev, "could not map memory\n"); 155 dev_dbg(&s->dev, "could not map memory\n");
155 memset(ptr, 0xff, len); 156 memset(ptr, 0xff, len);
156 mutex_unlock(&s->ops_mutex);
157 return -1; 157 return -1;
158 } 158 }
159 159
@@ -184,7 +184,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
184 if (!sys) { 184 if (!sys) {
185 dev_dbg(&s->dev, "could not map memory\n"); 185 dev_dbg(&s->dev, "could not map memory\n");
186 memset(ptr, 0xff, len); 186 memset(ptr, 0xff, len);
187 mutex_unlock(&s->ops_mutex);
188 return -1; 187 return -1;
189 } 188 }
190 end = sys + s->map_size; 189 end = sys + s->map_size;
@@ -198,7 +197,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
198 addr = 0; 197 addr = 0;
199 } 198 }
200 } 199 }
201 mutex_unlock(&s->ops_mutex);
202 dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", 200 dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
203 *(u_char *)(ptr+0), *(u_char *)(ptr+1), 201 *(u_char *)(ptr+0), *(u_char *)(ptr+1),
204 *(u_char *)(ptr+2), *(u_char *)(ptr+3)); 202 *(u_char *)(ptr+2), *(u_char *)(ptr+3));
@@ -209,7 +207,8 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
209/** 207/**
210 * pcmcia_write_cis_mem() - low-level function to write CIS memory 208 * pcmcia_write_cis_mem() - low-level function to write CIS memory
211 * 209 *
212 * Probably only useful for writing one-byte registers. 210 * Probably only useful for writing one-byte registers. Must be called
211 * with ops_mutex held.
213 */ 212 */
214void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, 213void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
215 u_int len, void *ptr) 214 u_int len, void *ptr)
@@ -220,7 +219,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
220 dev_dbg(&s->dev, 219 dev_dbg(&s->dev,
221 "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); 220 "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
222 221
223 mutex_lock(&s->ops_mutex);
224 if (attr & IS_INDIRECT) { 222 if (attr & IS_INDIRECT) {
225 /* Indirect accesses use a bunch of special registers at fixed 223 /* Indirect accesses use a bunch of special registers at fixed
226 locations in common memory */ 224 locations in common memory */
@@ -234,7 +232,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
234 ((cis_width) ? MAP_16BIT : 0)); 232 ((cis_width) ? MAP_16BIT : 0));
235 if (!sys) { 233 if (!sys) {
236 dev_dbg(&s->dev, "could not map memory\n"); 234 dev_dbg(&s->dev, "could not map memory\n");
237 mutex_unlock(&s->ops_mutex);
238 return; /* FIXME: Error */ 235 return; /* FIXME: Error */
239 } 236 }
240 237
@@ -260,7 +257,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
260 sys = set_cis_map(s, card_offset, flags); 257 sys = set_cis_map(s, card_offset, flags);
261 if (!sys) { 258 if (!sys) {
262 dev_dbg(&s->dev, "could not map memory\n"); 259 dev_dbg(&s->dev, "could not map memory\n");
263 mutex_unlock(&s->ops_mutex);
264 return; /* FIXME: error */ 260 return; /* FIXME: error */
265 } 261 }
266 262
@@ -275,7 +271,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
275 addr = 0; 271 addr = 0;
276 } 272 }
277 } 273 }
278 mutex_unlock(&s->ops_mutex);
279} 274}
280 275
281 276
@@ -314,7 +309,6 @@ static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
314 return 0; 309 return 0;
315 } 310 }
316 } 311 }
317 mutex_unlock(&s->ops_mutex);
318 312
319 ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr); 313 ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);
320 314
@@ -326,11 +320,11 @@ static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
326 cis->len = len; 320 cis->len = len;
327 cis->attr = attr; 321 cis->attr = attr;
328 memcpy(cis->cache, ptr, len); 322 memcpy(cis->cache, ptr, len);
329 mutex_lock(&s->ops_mutex);
330 list_add(&cis->node, &s->cis_cache); 323 list_add(&cis->node, &s->cis_cache);
331 mutex_unlock(&s->ops_mutex);
332 } 324 }
333 } 325 }
326 mutex_unlock(&s->ops_mutex);
327
334 return ret; 328 return ret;
335} 329}
336 330
@@ -386,6 +380,7 @@ int verify_cis_cache(struct pcmcia_socket *s)
386 "no memory for verifying CIS\n"); 380 "no memory for verifying CIS\n");
387 return -ENOMEM; 381 return -ENOMEM;
388 } 382 }
383 mutex_lock(&s->ops_mutex);
389 list_for_each_entry(cis, &s->cis_cache, node) { 384 list_for_each_entry(cis, &s->cis_cache, node) {
390 int len = cis->len; 385 int len = cis->len;
391 386
@@ -395,10 +390,12 @@ int verify_cis_cache(struct pcmcia_socket *s)
395 ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf); 390 ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
396 if (ret || memcmp(buf, cis->cache, len) != 0) { 391 if (ret || memcmp(buf, cis->cache, len) != 0) {
397 kfree(buf); 392 kfree(buf);
393 mutex_unlock(&s->ops_mutex);
398 return -1; 394 return -1;
399 } 395 }
400 } 396 }
401 kfree(buf); 397 kfree(buf);
398 mutex_unlock(&s->ops_mutex);
402 return 0; 399 return 0;
403} 400}
404 401