diff options
| author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-03-30 12:07:50 -0400 |
|---|---|---|
| committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-05-10 04:23:23 -0400 |
| commit | 059f667d9f81082e94dead14ff3fa7b3b42c98a0 (patch) | |
| tree | abd97312659c44cd05dc8b1bf5bc0bb6fba832c2 | |
| parent | a60f22c4af3382b86301d64d6a9d68f30191d4c9 (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>
| -rw-r--r-- | drivers/pcmcia/cistpl.c | 21 | ||||
| -rw-r--r-- | drivers/pcmcia/pcmcia_ioctl.c | 4 | ||||
| -rw-r--r-- | drivers/pcmcia/pcmcia_resource.c | 13 |
3 files changed, 19 insertions, 19 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 | */ |
| 133 | int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | 135 | int 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 | */ |
| 214 | void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | 213 | void 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 | ||
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index a42a6c7be10a..ef0c5f133691 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c | |||
| @@ -301,7 +301,9 @@ static int pccard_get_status(struct pcmcia_socket *s, | |||
| 301 | (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) { | 301 | (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) { |
| 302 | u_char reg; | 302 | u_char reg; |
| 303 | if (c->CardValues & PRESENT_PIN_REPLACE) { | 303 | if (c->CardValues & PRESENT_PIN_REPLACE) { |
| 304 | mutex_lock(&s->ops_mutex); | ||
| 304 | pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®); | 305 | pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®); |
| 306 | mutex_unlock(&s->ops_mutex); | ||
| 305 | status->CardState |= | 307 | status->CardState |= |
| 306 | (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0; | 308 | (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0; |
| 307 | status->CardState |= | 309 | status->CardState |= |
| @@ -315,7 +317,9 @@ static int pccard_get_status(struct pcmcia_socket *s, | |||
| 315 | status->CardState |= CS_EVENT_READY_CHANGE; | 317 | status->CardState |= CS_EVENT_READY_CHANGE; |
| 316 | } | 318 | } |
| 317 | if (c->CardValues & PRESENT_EXT_STATUS) { | 319 | if (c->CardValues & PRESENT_EXT_STATUS) { |
| 320 | mutex_lock(&s->ops_mutex); | ||
| 318 | pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®); | 321 | pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®); |
| 322 | mutex_unlock(&s->ops_mutex); | ||
| 319 | status->CardState |= | 323 | status->CardState |= |
| 320 | (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; | 324 | (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; |
| 321 | } | 325 | } |
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index c6419c18a6c8..29f91fac1dff 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
| @@ -123,6 +123,7 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, | |||
| 123 | config_t *c; | 123 | config_t *c; |
| 124 | int addr; | 124 | int addr; |
| 125 | u_char val; | 125 | u_char val; |
| 126 | int ret = 0; | ||
| 126 | 127 | ||
| 127 | if (!p_dev || !p_dev->function_config) | 128 | if (!p_dev || !p_dev->function_config) |
| 128 | return -EINVAL; | 129 | return -EINVAL; |
| @@ -139,11 +140,10 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, | |||
| 139 | } | 140 | } |
| 140 | 141 | ||
| 141 | addr = (c->ConfigBase + reg->Offset) >> 1; | 142 | addr = (c->ConfigBase + reg->Offset) >> 1; |
| 142 | mutex_unlock(&s->ops_mutex); | ||
| 143 | 143 | ||
| 144 | switch (reg->Action) { | 144 | switch (reg->Action) { |
| 145 | case CS_READ: | 145 | case CS_READ: |
| 146 | pcmcia_read_cis_mem(s, 1, addr, 1, &val); | 146 | ret = pcmcia_read_cis_mem(s, 1, addr, 1, &val); |
| 147 | reg->Value = val; | 147 | reg->Value = val; |
| 148 | break; | 148 | break; |
| 149 | case CS_WRITE: | 149 | case CS_WRITE: |
| @@ -152,10 +152,11 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, | |||
| 152 | break; | 152 | break; |
| 153 | default: | 153 | default: |
| 154 | dev_dbg(&s->dev, "Invalid conf register request\n"); | 154 | dev_dbg(&s->dev, "Invalid conf register request\n"); |
| 155 | return -EINVAL; | 155 | ret = -EINVAL; |
| 156 | break; | 156 | break; |
| 157 | } | 157 | } |
| 158 | return 0; | 158 | mutex_unlock(&s->ops_mutex); |
| 159 | return ret; | ||
| 159 | } /* pcmcia_access_configuration_register */ | 160 | } /* pcmcia_access_configuration_register */ |
| 160 | EXPORT_SYMBOL(pcmcia_access_configuration_register); | 161 | EXPORT_SYMBOL(pcmcia_access_configuration_register); |
| 161 | 162 | ||
| @@ -436,7 +437,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
| 436 | s->socket.io_irq = 0; | 437 | s->socket.io_irq = 0; |
| 437 | s->ops->set_socket(s, &s->socket); | 438 | s->ops->set_socket(s, &s->socket); |
| 438 | s->lock_count++; | 439 | s->lock_count++; |
| 439 | mutex_unlock(&s->ops_mutex); | ||
| 440 | 440 | ||
| 441 | /* Set up CIS configuration registers */ | 441 | /* Set up CIS configuration registers */ |
| 442 | base = c->ConfigBase = req->ConfigBase; | 442 | base = c->ConfigBase = req->ConfigBase; |
| @@ -485,7 +485,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
| 485 | 485 | ||
| 486 | /* Configure I/O windows */ | 486 | /* Configure I/O windows */ |
| 487 | if (c->state & CONFIG_IO_REQ) { | 487 | if (c->state & CONFIG_IO_REQ) { |
| 488 | mutex_lock(&s->ops_mutex); | ||
| 489 | iomap.speed = io_speed; | 488 | iomap.speed = io_speed; |
| 490 | for (i = 0; i < MAX_IO_WIN; i++) | 489 | for (i = 0; i < MAX_IO_WIN; i++) |
| 491 | if (s->io[i].res) { | 490 | if (s->io[i].res) { |
| @@ -504,11 +503,11 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
| 504 | s->ops->set_io_map(s, &iomap); | 503 | s->ops->set_io_map(s, &iomap); |
| 505 | s->io[i].Config++; | 504 | s->io[i].Config++; |
| 506 | } | 505 | } |
| 507 | mutex_unlock(&s->ops_mutex); | ||
| 508 | } | 506 | } |
| 509 | 507 | ||
| 510 | c->state |= CONFIG_LOCKED; | 508 | c->state |= CONFIG_LOCKED; |
| 511 | p_dev->_locked = 1; | 509 | p_dev->_locked = 1; |
| 510 | mutex_unlock(&s->ops_mutex); | ||
| 512 | return 0; | 511 | return 0; |
| 513 | } /* pcmcia_request_configuration */ | 512 | } /* pcmcia_request_configuration */ |
| 514 | EXPORT_SYMBOL(pcmcia_request_configuration); | 513 | EXPORT_SYMBOL(pcmcia_request_configuration); |
