diff options
author | Wolfram Sang <w.sang@pengutronix.de> | 2010-01-15 04:33:08 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-15 04:33:08 -0500 |
commit | d4ae5415c6f2dd8f14e027c24f09d708f11a8d60 (patch) | |
tree | a98f778fe54edfa81a3dbff6736e212e8a2b7005 /drivers/ide/ide-cs.c | |
parent | c3be57b6f35ef96a980ce84e59d6a5a8ca6184ad (diff) |
ide/ide-cs: fix order of releasing resources
ide_detach() called first ide_release() and then release_region(). This
produced the following warnings:
Trying to free nonexistent resource <000000000000c10e-000000000000c10e>
Trying to free nonexistent resource <000000000000c100-000000000000c107>
This is true, because the callchain inside ide_release() is:
ide_release -> pcmcia_disable_device -> pcmcia_release_io
So, the whole io-block is already gone for release_region(). To fix
this, just swap the order of releasing (and remove the now obsolete
shadowing).
bzolnier:
- release resources in ide_release() to fix ordering of events
- remove stale FIXME note while at it
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/ide/ide-cs.c')
-rw-r--r-- | drivers/ide/ide-cs.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c index dd6396384c25..ab87e4f7cec9 100644 --- a/drivers/ide/ide-cs.c +++ b/drivers/ide/ide-cs.c | |||
@@ -121,19 +121,11 @@ static int ide_probe(struct pcmcia_device *link) | |||
121 | static void ide_detach(struct pcmcia_device *link) | 121 | static void ide_detach(struct pcmcia_device *link) |
122 | { | 122 | { |
123 | ide_info_t *info = link->priv; | 123 | ide_info_t *info = link->priv; |
124 | ide_hwif_t *hwif = info->host->ports[0]; | ||
125 | unsigned long data_addr, ctl_addr; | ||
126 | 124 | ||
127 | dev_dbg(&link->dev, "ide_detach(0x%p)\n", link); | 125 | dev_dbg(&link->dev, "ide_detach(0x%p)\n", link); |
128 | 126 | ||
129 | data_addr = hwif->io_ports.data_addr; | ||
130 | ctl_addr = hwif->io_ports.ctl_addr; | ||
131 | |||
132 | ide_release(link); | 127 | ide_release(link); |
133 | 128 | ||
134 | release_region(ctl_addr, 1); | ||
135 | release_region(data_addr, 8); | ||
136 | |||
137 | kfree(info); | 129 | kfree(info); |
138 | } /* ide_detach */ | 130 | } /* ide_detach */ |
139 | 131 | ||
@@ -354,12 +346,19 @@ static void ide_release(struct pcmcia_device *link) | |||
354 | 346 | ||
355 | dev_dbg(&link->dev, "ide_release(0x%p)\n", link); | 347 | dev_dbg(&link->dev, "ide_release(0x%p)\n", link); |
356 | 348 | ||
357 | if (info->ndev) | 349 | if (info->ndev) { |
358 | /* FIXME: if this fails we need to queue the cleanup somehow | 350 | ide_hwif_t *hwif = host->ports[0]; |
359 | -- need to investigate the required PCMCIA magic */ | 351 | unsigned long data_addr, ctl_addr; |
352 | |||
353 | data_addr = hwif->io_ports.data_addr; | ||
354 | ctl_addr = hwif->io_ports.ctl_addr; | ||
355 | |||
360 | ide_host_remove(host); | 356 | ide_host_remove(host); |
357 | info->ndev = 0; | ||
361 | 358 | ||
362 | info->ndev = 0; | 359 | release_region(ctl_addr, 1); |
360 | release_region(data_addr, 8); | ||
361 | } | ||
363 | 362 | ||
364 | pcmcia_disable_device(link); | 363 | pcmcia_disable_device(link); |
365 | } /* ide_release */ | 364 | } /* ide_release */ |