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>
This commit is contained in:
Dominik Brodowski 2010-01-12 23:52:19 +01:00
parent 8680c4b3fa
commit 8533ee31cd

View file

@ -306,6 +306,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
int i; int i;
io_on.speed = io_speed; io_on.speed = io_speed;
mutex_lock(&s->ops_mutex);
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)
continue; continue;
@ -320,6 +321,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
mdelay(40); mdelay(40);
s->ops->set_io_map(s, &io_on); s->ops->set_io_map(s, &io_on);
} }
mutex_unlock(&s->ops_mutex);
} }
return 0; return 0;
@ -345,6 +347,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
} }
if (c->state & CONFIG_LOCKED) { if (c->state & CONFIG_LOCKED) {
c->state &= ~CONFIG_LOCKED; c->state &= ~CONFIG_LOCKED;
mutex_lock(&s->ops_mutex);
if (c->state & CONFIG_IO_REQ) if (c->state & CONFIG_IO_REQ)
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)
@ -355,6 +358,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
io.map = i; io.map = i;
s->ops->set_io_map(s, &io); s->ops->set_io_map(s, &io);
} }
mutex_unlock(&s->ops_mutex);
} }
return 0; return 0;
@ -562,6 +566,7 @@ 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) {
@ -580,6 +585,7 @@ 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;
@ -625,10 +631,12 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
return -EINVAL; return -EINVAL;
} }
mutex_lock(&s->ops_mutex);
dev_dbg(&s->dev, "trying to allocate resource 1\n"); dev_dbg(&s->dev, "trying to allocate resource 1\n");
if (alloc_io_space(s, req->Attributes1, &req->BasePort1, if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
req->NumPorts1, req->IOAddrLines)) { req->NumPorts1, req->IOAddrLines)) {
dev_dbg(&s->dev, "allocation of resource 1 failed\n"); dev_dbg(&s->dev, "allocation of resource 1 failed\n");
mutex_unlock(&s->ops_mutex);
return -EBUSY; return -EBUSY;
} }
@ -638,9 +646,11 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
req->NumPorts2, req->IOAddrLines)) { req->NumPorts2, req->IOAddrLines)) {
dev_dbg(&s->dev, "allocation of resource 2 failed\n"); dev_dbg(&s->dev, "allocation of resource 2 failed\n");
release_io_space(s, req->BasePort1, req->NumPorts1); release_io_space(s, req->BasePort1, req->NumPorts1);
mutex_unlock(&s->ops_mutex);
return -EBUSY; return -EBUSY;
} }
} }
mutex_unlock(&s->ops_mutex);
c->io = *req; c->io = *req;
c->state |= CONFIG_IO_REQ; c->state |= CONFIG_IO_REQ;