diff options
| author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-01-12 17:52:19 -0500 |
|---|---|---|
| committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-02-17 11:48:15 -0500 |
| commit | 8533ee31cdc08fc1f2533e5f21f8e4abf6a57dfc (patch) | |
| tree | 5f8e21433e945e482b3422eecd8a7a1f8e88897a | |
| parent | 8680c4b3faa298dc768c2a78a94a84d89854eca9 (diff) | |
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>
| -rw-r--r-- | drivers/pcmcia/pcmcia_resource.c | 10 |
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, | |||
| 306 | int i; | 306 | int i; |
| 307 | 307 | ||
| 308 | io_on.speed = io_speed; | 308 | io_on.speed = io_speed; |
| 309 | mutex_lock(&s->ops_mutex); | ||
| 309 | for (i = 0; i < MAX_IO_WIN; i++) { | 310 | for (i = 0; i < MAX_IO_WIN; i++) { |
| 310 | if (!s->io[i].res) | 311 | if (!s->io[i].res) |
| 311 | continue; | 312 | continue; |
| @@ -320,6 +321,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev, | |||
| 320 | mdelay(40); | 321 | mdelay(40); |
| 321 | s->ops->set_io_map(s, &io_on); | 322 | s->ops->set_io_map(s, &io_on); |
| 322 | } | 323 | } |
| 324 | mutex_unlock(&s->ops_mutex); | ||
| 323 | } | 325 | } |
| 324 | 326 | ||
| 325 | return 0; | 327 | return 0; |
| @@ -345,6 +347,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev) | |||
| 345 | } | 347 | } |
| 346 | if (c->state & CONFIG_LOCKED) { | 348 | if (c->state & CONFIG_LOCKED) { |
| 347 | c->state &= ~CONFIG_LOCKED; | 349 | c->state &= ~CONFIG_LOCKED; |
| 350 | mutex_lock(&s->ops_mutex); | ||
| 348 | if (c->state & CONFIG_IO_REQ) | 351 | if (c->state & CONFIG_IO_REQ) |
| 349 | for (i = 0; i < MAX_IO_WIN; i++) { | 352 | for (i = 0; i < MAX_IO_WIN; i++) { |
| 350 | if (!s->io[i].res) | 353 | if (!s->io[i].res) |
| @@ -355,6 +358,7 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev) | |||
| 355 | io.map = i; | 358 | io.map = i; |
| 356 | s->ops->set_io_map(s, &io); | 359 | s->ops->set_io_map(s, &io); |
| 357 | } | 360 | } |
| 361 | mutex_unlock(&s->ops_mutex); | ||
| 358 | } | 362 | } |
| 359 | 363 | ||
| 360 | return 0; | 364 | return 0; |
| @@ -562,6 +566,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
| 562 | 566 | ||
| 563 | /* Configure I/O windows */ | 567 | /* Configure I/O windows */ |
| 564 | if (c->state & CONFIG_IO_REQ) { | 568 | if (c->state & CONFIG_IO_REQ) { |
| 569 | mutex_lock(&s->ops_mutex); | ||
| 565 | iomap.speed = io_speed; | 570 | iomap.speed = io_speed; |
| 566 | for (i = 0; i < MAX_IO_WIN; i++) | 571 | for (i = 0; i < MAX_IO_WIN; i++) |
| 567 | if (s->io[i].res) { | 572 | if (s->io[i].res) { |
| @@ -580,6 +585,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
| 580 | s->ops->set_io_map(s, &iomap); | 585 | s->ops->set_io_map(s, &iomap); |
| 581 | s->io[i].Config++; | 586 | s->io[i].Config++; |
| 582 | } | 587 | } |
| 588 | mutex_unlock(&s->ops_mutex); | ||
| 583 | } | 589 | } |
| 584 | 590 | ||
| 585 | c->state |= CONFIG_LOCKED; | 591 | c->state |= CONFIG_LOCKED; |
| @@ -625,10 +631,12 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) | |||
| 625 | return -EINVAL; | 631 | return -EINVAL; |
| 626 | } | 632 | } |
| 627 | 633 | ||
| 634 | mutex_lock(&s->ops_mutex); | ||
| 628 | dev_dbg(&s->dev, "trying to allocate resource 1\n"); | 635 | dev_dbg(&s->dev, "trying to allocate resource 1\n"); |
| 629 | if (alloc_io_space(s, req->Attributes1, &req->BasePort1, | 636 | if (alloc_io_space(s, req->Attributes1, &req->BasePort1, |
| 630 | req->NumPorts1, req->IOAddrLines)) { | 637 | req->NumPorts1, req->IOAddrLines)) { |
| 631 | dev_dbg(&s->dev, "allocation of resource 1 failed\n"); | 638 | dev_dbg(&s->dev, "allocation of resource 1 failed\n"); |
| 639 | mutex_unlock(&s->ops_mutex); | ||
| 632 | return -EBUSY; | 640 | return -EBUSY; |
| 633 | } | 641 | } |
| 634 | 642 | ||
| @@ -638,9 +646,11 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) | |||
| 638 | req->NumPorts2, req->IOAddrLines)) { | 646 | req->NumPorts2, req->IOAddrLines)) { |
| 639 | dev_dbg(&s->dev, "allocation of resource 2 failed\n"); | 647 | dev_dbg(&s->dev, "allocation of resource 2 failed\n"); |
| 640 | release_io_space(s, req->BasePort1, req->NumPorts1); | 648 | release_io_space(s, req->BasePort1, req->NumPorts1); |
| 649 | mutex_unlock(&s->ops_mutex); | ||
| 641 | return -EBUSY; | 650 | return -EBUSY; |
| 642 | } | 651 | } |
| 643 | } | 652 | } |
| 653 | mutex_unlock(&s->ops_mutex); | ||
| 644 | 654 | ||
| 645 | c->io = *req; | 655 | c->io = *req; |
| 646 | c->state |= CONFIG_IO_REQ; | 656 | c->state |= CONFIG_IO_REQ; |
