diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-01-12 15:42:51 -0500 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-02-17 11:48:13 -0500 |
commit | 6b8e087b86c59c3941e125738d30cf38014089e0 (patch) | |
tree | 08f77e50e5237e3bbe5e4c8f114fddc09f242628 /drivers/pcmcia/rsrc_nonstatic.c | |
parent | c6958fdb041db6ed77f24e871dd4af5f059d1a2b (diff) |
pcmcia: add locking to set_mem_map()
Protect the pccard_operations callback "set_mem_map" by a new
mutex ops_mutex. This mutex also protects the following values
in struct pcmcia_socket:
pccard_mem_map win[]
pccard_mem_map cis_mem
void __iomem *cis_virt
Tested-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia/rsrc_nonstatic.c')
-rw-r--r-- | drivers/pcmcia/rsrc_nonstatic.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 91626c17f97b..1de46cf2772f 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -274,17 +274,21 @@ static int readable(struct pcmcia_socket *s, struct resource *res, | |||
274 | { | 274 | { |
275 | int ret = -EINVAL; | 275 | int ret = -EINVAL; |
276 | 276 | ||
277 | mutex_lock(&s->ops_mutex); | ||
277 | s->cis_mem.res = res; | 278 | s->cis_mem.res = res; |
278 | s->cis_virt = ioremap(res->start, s->map_size); | 279 | s->cis_virt = ioremap(res->start, s->map_size); |
279 | if (s->cis_virt) { | 280 | if (s->cis_virt) { |
281 | mutex_unlock(&s->ops_mutex); | ||
280 | /* as we're only called from pcmcia.c, we're safe */ | 282 | /* as we're only called from pcmcia.c, we're safe */ |
281 | if (s->callback->validate) | 283 | if (s->callback->validate) |
282 | ret = s->callback->validate(s, count); | 284 | ret = s->callback->validate(s, count); |
283 | /* invalidate mapping */ | 285 | /* invalidate mapping */ |
286 | mutex_lock(&s->ops_mutex); | ||
284 | iounmap(s->cis_virt); | 287 | iounmap(s->cis_virt); |
285 | s->cis_virt = NULL; | 288 | s->cis_virt = NULL; |
286 | } | 289 | } |
287 | s->cis_mem.res = NULL; | 290 | s->cis_mem.res = NULL; |
291 | mutex_unlock(&s->ops_mutex); | ||
288 | if ((ret) || (*count == 0)) | 292 | if ((ret) || (*count == 0)) |
289 | return -EINVAL; | 293 | return -EINVAL; |
290 | return 0; | 294 | return 0; |
@@ -300,6 +304,8 @@ static int checksum(struct pcmcia_socket *s, struct resource *res, | |||
300 | int i, a = 0, b = -1, d; | 304 | int i, a = 0, b = -1, d; |
301 | void __iomem *virt; | 305 | void __iomem *virt; |
302 | 306 | ||
307 | mutex_lock(&s->ops_mutex); | ||
308 | |||
303 | virt = ioremap(res->start, s->map_size); | 309 | virt = ioremap(res->start, s->map_size); |
304 | if (virt) { | 310 | if (virt) { |
305 | map.map = 0; | 311 | map.map = 0; |
@@ -322,6 +328,8 @@ static int checksum(struct pcmcia_socket *s, struct resource *res, | |||
322 | iounmap(virt); | 328 | iounmap(virt); |
323 | } | 329 | } |
324 | 330 | ||
331 | mutex_unlock(&s->ops_mutex); | ||
332 | |||
325 | if (b == -1) | 333 | if (b == -1) |
326 | return -EINVAL; | 334 | return -EINVAL; |
327 | 335 | ||