From f0cc9cf99326926fd76f77645c48d16d647802eb Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 6 Feb 2012 10:42:39 +0100 Subject: mmc: core: Detect card removal on I/O error To prevent I/O as soon as possible at card removal, a new detect work is re-scheduled without a delay to let a rescan remove the card device as soon as possible. Additionally, MMC_CAP2_DETECT_ON_ERR can now be used to handle "slowly" removed cards that a scheduled detect work did not detect as removed. To prevent further I/O requests for these lingering removed cards, check if card has been removed and then schedule a detect work to properly remove it. Signed-off-by: Ulf Hansson Reviewed-by: Namjae Jeon Acked-by: Linus Walleij Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'drivers/mmc/core') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index faa0af10d33..436409f7f7b 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2121,18 +2121,36 @@ int _mmc_detect_card_removed(struct mmc_host *host) int mmc_detect_card_removed(struct mmc_host *host) { struct mmc_card *card = host->card; + int ret; WARN_ON(!host->claimed); + + if (!card) + return 1; + + ret = mmc_card_removed(card); /* * The card will be considered unchanged unless we have been asked to * detect a change or host requires polling to provide card detection. */ - if (card && !host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL)) - return mmc_card_removed(card); + if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL) && + !(host->caps2 & MMC_CAP2_DETECT_ON_ERR)) + return ret; host->detect_change = 0; + if (!ret) { + ret = _mmc_detect_card_removed(host); + if (ret && (host->caps2 & MMC_CAP2_DETECT_ON_ERR)) { + /* + * Schedule a detect work as soon as possible to let a + * rescan handle the card removal. + */ + cancel_delayed_work(&host->detect); + mmc_detect_change(host, 0); + } + } - return _mmc_detect_card_removed(host); + return ret; } EXPORT_SYMBOL(mmc_detect_card_removed); -- cgit v1.2.3-70-g09d2