summaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/pcmcia_resource.c
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-01-12 23:52:19 +0100
committerDominik Brodowski <linux@dominikbrodowski.net>2010-02-17 17:48:15 +0100
commit8533ee31cdc08fc1f2533e5f21f8e4abf6a57dfc (patch)
tree5f8e21433e945e482b3422eecd8a7a1f8e88897a /drivers/pcmcia/pcmcia_resource.c
parent8680c4b3faa298dc768c2a78a94a84d89854eca9 (diff)
downloadlinux-8533ee31cdc08fc1f2533e5f21f8e4abf6a57dfc.tar.gz
linux-8533ee31cdc08fc1f2533e5f21f8e4abf6a57dfc.tar.bz2
linux-8533ee31cdc08fc1f2533e5f21f8e4abf6a57dfc.zip
pcmcia: lock ops->set_io_map()
As a side effect, io_window_t io[MAX_IO_WIN]; is explicitely protected now. Tested-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia/pcmcia_resource.c')
-rw-r--r--drivers/pcmcia/pcmcia_resource.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index f31ba89e40d3..4e0aaec5cf99 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -306,6 +306,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
int i;
io_on.speed = io_speed;
+ mutex_lock(&s->ops_mutex);
for (i = 0; i < MAX_IO_WIN; i++) {
if (!s->io[i].res)
continue;
@@ -320,6 +321,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
mdelay(40);
s->ops->set_io_map(s, &io_on);
}
+ mutex_unlock(&s->ops_mutex);
}
return 0;
@@ -345,6 +347,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
}
if (c->state & CONFIG_LOCKED) {
c->state &= ~CONFIG_LOCKED;
+ mutex_lock(&s->ops_mutex);
if (c->state & CONFIG_IO_REQ)
for (i = 0; i < MAX_IO_WIN; i++) {
if (!s->io[i].res)
@@ -355,6 +358,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
io.map = i;
s->ops->set_io_map(s, &io);
}
+ mutex_unlock(&s->ops_mutex);
}
return 0;
@@ -562,6 +566,7 @@ 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) {
@@ -580,6 +585,7 @@ 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;
@@ -625,10 +631,12 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
return -EINVAL;
}
+ mutex_lock(&s->ops_mutex);
dev_dbg(&s->dev, "trying to allocate resource 1\n");
if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
req->NumPorts1, req->IOAddrLines)) {
dev_dbg(&s->dev, "allocation of resource 1 failed\n");
+ mutex_unlock(&s->ops_mutex);
return -EBUSY;
}
@@ -638,9 +646,11 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
req->NumPorts2, req->IOAddrLines)) {
dev_dbg(&s->dev, "allocation of resource 2 failed\n");
release_io_space(s, req->BasePort1, req->NumPorts1);
+ mutex_unlock(&s->ops_mutex);
return -EBUSY;
}
}
+ mutex_unlock(&s->ops_mutex);
c->io = *req;
c->state |= CONFIG_IO_REQ;