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>
This commit is contained in:
parent
a60f22c4af
commit
059f667d9f
3 changed files with 19 additions and 19 deletions
|
@ -129,6 +129,8 @@ static void __iomem *set_cis_map(struct pcmcia_socket *s,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pcmcia_read_cis_mem() - low-level function to read CIS memory
|
* pcmcia_read_cis_mem() - low-level function to read CIS memory
|
||||||
|
*
|
||||||
|
* must be called with ops_mutex held
|
||||||
*/
|
*/
|
||||||
int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
||||||
u_int len, void *ptr)
|
u_int len, void *ptr)
|
||||||
|
@ -138,7 +140,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
||||||
|
|
||||||
dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
|
dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
|
||||||
|
|
||||||
mutex_lock(&s->ops_mutex);
|
|
||||||
if (attr & IS_INDIRECT) {
|
if (attr & IS_INDIRECT) {
|
||||||
/* Indirect accesses use a bunch of special registers at fixed
|
/* Indirect accesses use a bunch of special registers at fixed
|
||||||
locations in common memory */
|
locations in common memory */
|
||||||
|
@ -153,7 +154,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
||||||
if (!sys) {
|
if (!sys) {
|
||||||
dev_dbg(&s->dev, "could not map memory\n");
|
dev_dbg(&s->dev, "could not map memory\n");
|
||||||
memset(ptr, 0xff, len);
|
memset(ptr, 0xff, len);
|
||||||
mutex_unlock(&s->ops_mutex);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +184,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
||||||
if (!sys) {
|
if (!sys) {
|
||||||
dev_dbg(&s->dev, "could not map memory\n");
|
dev_dbg(&s->dev, "could not map memory\n");
|
||||||
memset(ptr, 0xff, len);
|
memset(ptr, 0xff, len);
|
||||||
mutex_unlock(&s->ops_mutex);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
end = sys + s->map_size;
|
end = sys + s->map_size;
|
||||||
|
@ -198,7 +197,6 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
||||||
addr = 0;
|
addr = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&s->ops_mutex);
|
|
||||||
dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
|
dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
|
||||||
*(u_char *)(ptr+0), *(u_char *)(ptr+1),
|
*(u_char *)(ptr+0), *(u_char *)(ptr+1),
|
||||||
*(u_char *)(ptr+2), *(u_char *)(ptr+3));
|
*(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,
|
||||||
/**
|
/**
|
||||||
* pcmcia_write_cis_mem() - low-level function to write CIS memory
|
* pcmcia_write_cis_mem() - low-level function to write CIS memory
|
||||||
*
|
*
|
||||||
* Probably only useful for writing one-byte registers.
|
* Probably only useful for writing one-byte registers. Must be called
|
||||||
|
* with ops_mutex held.
|
||||||
*/
|
*/
|
||||||
void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
||||||
u_int len, void *ptr)
|
u_int len, void *ptr)
|
||||||
|
@ -220,7 +219,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
||||||
dev_dbg(&s->dev,
|
dev_dbg(&s->dev,
|
||||||
"pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
|
"pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
|
||||||
|
|
||||||
mutex_lock(&s->ops_mutex);
|
|
||||||
if (attr & IS_INDIRECT) {
|
if (attr & IS_INDIRECT) {
|
||||||
/* Indirect accesses use a bunch of special registers at fixed
|
/* Indirect accesses use a bunch of special registers at fixed
|
||||||
locations in common memory */
|
locations in common memory */
|
||||||
|
@ -234,7 +232,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
||||||
((cis_width) ? MAP_16BIT : 0));
|
((cis_width) ? MAP_16BIT : 0));
|
||||||
if (!sys) {
|
if (!sys) {
|
||||||
dev_dbg(&s->dev, "could not map memory\n");
|
dev_dbg(&s->dev, "could not map memory\n");
|
||||||
mutex_unlock(&s->ops_mutex);
|
|
||||||
return; /* FIXME: Error */
|
return; /* FIXME: Error */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +257,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
||||||
sys = set_cis_map(s, card_offset, flags);
|
sys = set_cis_map(s, card_offset, flags);
|
||||||
if (!sys) {
|
if (!sys) {
|
||||||
dev_dbg(&s->dev, "could not map memory\n");
|
dev_dbg(&s->dev, "could not map memory\n");
|
||||||
mutex_unlock(&s->ops_mutex);
|
|
||||||
return; /* FIXME: error */
|
return; /* FIXME: error */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +271,6 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
||||||
addr = 0;
|
addr = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&s->ops_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -314,7 +309,6 @@ static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&s->ops_mutex);
|
|
||||||
|
|
||||||
ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);
|
ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);
|
||||||
|
|
||||||
|
@ -326,11 +320,11 @@ static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
|
||||||
cis->len = len;
|
cis->len = len;
|
||||||
cis->attr = attr;
|
cis->attr = attr;
|
||||||
memcpy(cis->cache, ptr, len);
|
memcpy(cis->cache, ptr, len);
|
||||||
mutex_lock(&s->ops_mutex);
|
|
||||||
list_add(&cis->node, &s->cis_cache);
|
list_add(&cis->node, &s->cis_cache);
|
||||||
mutex_unlock(&s->ops_mutex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&s->ops_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,6 +380,7 @@ int verify_cis_cache(struct pcmcia_socket *s)
|
||||||
"no memory for verifying CIS\n");
|
"no memory for verifying CIS\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
mutex_lock(&s->ops_mutex);
|
||||||
list_for_each_entry(cis, &s->cis_cache, node) {
|
list_for_each_entry(cis, &s->cis_cache, node) {
|
||||||
int len = cis->len;
|
int len = cis->len;
|
||||||
|
|
||||||
|
@ -395,10 +390,12 @@ int verify_cis_cache(struct pcmcia_socket *s)
|
||||||
ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
|
ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
|
||||||
if (ret || memcmp(buf, cis->cache, len) != 0) {
|
if (ret || memcmp(buf, cis->cache, len) != 0) {
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
|
mutex_unlock(&s->ops_mutex);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
|
mutex_unlock(&s->ops_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -301,7 +301,9 @@ static int pccard_get_status(struct pcmcia_socket *s,
|
||||||
(c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
|
(c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
|
||||||
u_char reg;
|
u_char reg;
|
||||||
if (c->CardValues & PRESENT_PIN_REPLACE) {
|
if (c->CardValues & PRESENT_PIN_REPLACE) {
|
||||||
|
mutex_lock(&s->ops_mutex);
|
||||||
pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®);
|
pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®);
|
||||||
|
mutex_unlock(&s->ops_mutex);
|
||||||
status->CardState |=
|
status->CardState |=
|
||||||
(reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
|
(reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
|
||||||
status->CardState |=
|
status->CardState |=
|
||||||
|
@ -315,7 +317,9 @@ static int pccard_get_status(struct pcmcia_socket *s,
|
||||||
status->CardState |= CS_EVENT_READY_CHANGE;
|
status->CardState |= CS_EVENT_READY_CHANGE;
|
||||||
}
|
}
|
||||||
if (c->CardValues & PRESENT_EXT_STATUS) {
|
if (c->CardValues & PRESENT_EXT_STATUS) {
|
||||||
|
mutex_lock(&s->ops_mutex);
|
||||||
pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®);
|
pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®);
|
||||||
|
mutex_unlock(&s->ops_mutex);
|
||||||
status->CardState |=
|
status->CardState |=
|
||||||
(reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
|
(reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,7 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
|
||||||
config_t *c;
|
config_t *c;
|
||||||
int addr;
|
int addr;
|
||||||
u_char val;
|
u_char val;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (!p_dev || !p_dev->function_config)
|
if (!p_dev || !p_dev->function_config)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -139,11 +140,10 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = (c->ConfigBase + reg->Offset) >> 1;
|
addr = (c->ConfigBase + reg->Offset) >> 1;
|
||||||
mutex_unlock(&s->ops_mutex);
|
|
||||||
|
|
||||||
switch (reg->Action) {
|
switch (reg->Action) {
|
||||||
case CS_READ:
|
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;
|
reg->Value = val;
|
||||||
break;
|
break;
|
||||||
case CS_WRITE:
|
case CS_WRITE:
|
||||||
|
@ -152,10 +152,11 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_dbg(&s->dev, "Invalid conf register request\n");
|
dev_dbg(&s->dev, "Invalid conf register request\n");
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
mutex_unlock(&s->ops_mutex);
|
||||||
|
return ret;
|
||||||
} /* pcmcia_access_configuration_register */
|
} /* pcmcia_access_configuration_register */
|
||||||
EXPORT_SYMBOL(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->socket.io_irq = 0;
|
||||||
s->ops->set_socket(s, &s->socket);
|
s->ops->set_socket(s, &s->socket);
|
||||||
s->lock_count++;
|
s->lock_count++;
|
||||||
mutex_unlock(&s->ops_mutex);
|
|
||||||
|
|
||||||
/* Set up CIS configuration registers */
|
/* Set up CIS configuration registers */
|
||||||
base = c->ConfigBase = req->ConfigBase;
|
base = c->ConfigBase = req->ConfigBase;
|
||||||
|
@ -485,7 +485,6 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
|
||||||
|
|
||||||
/* Configure I/O windows */
|
/* Configure I/O windows */
|
||||||
if (c->state & CONFIG_IO_REQ) {
|
if (c->state & CONFIG_IO_REQ) {
|
||||||
mutex_lock(&s->ops_mutex);
|
|
||||||
iomap.speed = io_speed;
|
iomap.speed = io_speed;
|
||||||
for (i = 0; i < MAX_IO_WIN; i++)
|
for (i = 0; i < MAX_IO_WIN; i++)
|
||||||
if (s->io[i].res) {
|
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->ops->set_io_map(s, &iomap);
|
||||||
s->io[i].Config++;
|
s->io[i].Config++;
|
||||||
}
|
}
|
||||||
mutex_unlock(&s->ops_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c->state |= CONFIG_LOCKED;
|
c->state |= CONFIG_LOCKED;
|
||||||
p_dev->_locked = 1;
|
p_dev->_locked = 1;
|
||||||
|
mutex_unlock(&s->ops_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
} /* pcmcia_request_configuration */
|
} /* pcmcia_request_configuration */
|
||||||
EXPORT_SYMBOL(pcmcia_request_configuration);
|
EXPORT_SYMBOL(pcmcia_request_configuration);
|
||||||
|
|
Loading…
Reference in a new issue