diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-01-02 14:14:23 +0100 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-01-17 18:30:12 +0100 |
commit | 88b060d6c03fcb9e4d2018b4349954c4242a5c7f (patch) | |
tree | 34954c1b7f1d4d978cae56ee40a9ab57829dccf2 /drivers/pcmcia/ds.c | |
parent | pcmcia: cleanup pccard_validate_cis() (diff) | |
download | linux-88b060d6c03fcb9e4d2018b4349954c4242a5c7f.tar.xz linux-88b060d6c03fcb9e4d2018b4349954c4242a5c7f.zip |
pcmcia: improve check for same card in slot after resume
During a suspend/resume cycle, an user may change the card in the
PCMCIA/CardBus slot. The pcmcia_core can at least look at the
socket state to check whether it is the same.
For PCMCIA devices, move the detection and handling of such a
change to ds.c.
For CardBus devices, the PCI hotplug interface doesn't offer a "rescan"
facility which also _removes_ devices no longer to be found behind a
bridge. Therefore, remove and re-add all devices unconditionally.
CC: Jesse Barnes <jbarnes@virtuousgeek.org>
CC: Linus Torvalds <torvalds@linux-foundation.org>
Tested-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia/ds.c')
-rw-r--r-- | drivers/pcmcia/ds.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index defa44c27b97..87e06395c129 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -1252,8 +1252,22 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) case CS_EVENT_EJECTION_REQUEST: break; - case CS_EVENT_PM_SUSPEND: case CS_EVENT_PM_RESUME: + if (verify_cis_cache(skt) != 0) { + dev_dbg(&skt->dev, "cis mismatch - different card\n"); + /* first, remove the card */ + ds_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); + destroy_cis_cache(skt); + kfree(skt->fake_cis); + skt->fake_cis = NULL; + /* now, add the new card */ + ds_event(skt, CS_EVENT_CARD_INSERTION, + CS_EVENT_PRI_LOW); + } + handle_event(skt, event); + break; + + case CS_EVENT_PM_SUSPEND: case CS_EVENT_RESET_PHYSICAL: case CS_EVENT_CARD_RESET: default: |