diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-03-30 18:07:50 +0200 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-05-10 10:23:23 +0200 |
commit | 059f667d9f81082e94dead14ff3fa7b3b42c98a0 (patch) | |
tree | abd97312659c44cd05dc8b1bf5bc0bb6fba832c2 /drivers/pcmcia/pcmcia_resource.c | |
parent | pcmcia: remove pcmcia_add_device_lock (diff) | |
download | linux-059f667d9f81082e94dead14ff3fa7b3b42c98a0.tar.xz linux-059f667d9f81082e94dead14ff3fa7b3b42c98a0.zip |
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/pcmcia_resource.c')
-rw-r--r-- | drivers/pcmcia/pcmcia_resource.c | 13 |
1 files changed, 6 insertions, 7 deletions
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, config_t *c; int addr; u_char val; + int ret = 0; if (!p_dev || !p_dev->function_config) return -EINVAL; @@ -139,11 +140,10 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, } addr = (c->ConfigBase + reg->Offset) >> 1; - mutex_unlock(&s->ops_mutex); switch (reg->Action) { case CS_READ: - pcmcia_read_cis_mem(s, 1, addr, 1, &val); + ret = pcmcia_read_cis_mem(s, 1, addr, 1, &val); reg->Value = val; break; case CS_WRITE: @@ -152,10 +152,11 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, break; default: dev_dbg(&s->dev, "Invalid conf register request\n"); - return -EINVAL; + ret = -EINVAL; break; } - return 0; + mutex_unlock(&s->ops_mutex); + return ret; } /* pcmcia_access_configuration_register */ EXPORT_SYMBOL(pcmcia_access_configuration_register); @@ -436,7 +437,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, s->socket.io_irq = 0; s->ops->set_socket(s, &s->socket); s->lock_count++; - mutex_unlock(&s->ops_mutex); /* Set up CIS configuration registers */ base = c->ConfigBase = req->ConfigBase; @@ -485,7 +485,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, /* Configure I/O windows */ if (c->state & CONFIG_IO_REQ) { - mutex_lock(&s->ops_mutex); iomap.speed = io_speed; for (i = 0; i < MAX_IO_WIN; i++) if (s->io[i].res) { @@ -504,11 +503,11 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, s->ops->set_io_map(s, &iomap); s->io[i].Config++; } - mutex_unlock(&s->ops_mutex); } c->state |= CONFIG_LOCKED; p_dev->_locked = 1; + mutex_unlock(&s->ops_mutex); return 0; } /* pcmcia_request_configuration */ EXPORT_SYMBOL(pcmcia_request_configuration); |