summaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/ds.c
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-01-02 14:14:23 +0100
committerDominik Brodowski <linux@dominikbrodowski.net>2010-01-17 18:30:12 +0100
commit88b060d6c03fcb9e4d2018b4349954c4242a5c7f (patch)
tree34954c1b7f1d4d978cae56ee40a9ab57829dccf2 /drivers/pcmcia/ds.c
parentpcmcia: cleanup pccard_validate_cis() (diff)
downloadlinux-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.c16
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: