diff options
| author | Ulf Hansson <ulf.hansson@stericsson.com> | 2012-02-06 04:42:39 -0500 |
|---|---|---|
| committer | Chris Ball <cjb@laptop.org> | 2012-03-27 12:19:58 -0400 |
| commit | f0cc9cf99326926fd76f77645c48d16d647802eb (patch) | |
| tree | 62ad1c9e51cb27c797acaa5481d93a4306125bcd /drivers/mmc/core | |
| parent | 885c3e800cf99db3391247776bfa2d262b21a72b (diff) | |
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 <ulf.hansson@stericsson.com>
Reviewed-by: Namjae Jeon <linkinjeon@gmail.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/core')
| -rw-r--r-- | drivers/mmc/core/core.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index faa0af10d334..436409f7f7bd 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) | |||
| 2121 | int mmc_detect_card_removed(struct mmc_host *host) | 2121 | int mmc_detect_card_removed(struct mmc_host *host) |
| 2122 | { | 2122 | { |
| 2123 | struct mmc_card *card = host->card; | 2123 | struct mmc_card *card = host->card; |
| 2124 | int ret; | ||
| 2124 | 2125 | ||
| 2125 | WARN_ON(!host->claimed); | 2126 | WARN_ON(!host->claimed); |
| 2127 | |||
| 2128 | if (!card) | ||
| 2129 | return 1; | ||
| 2130 | |||
| 2131 | ret = mmc_card_removed(card); | ||
| 2126 | /* | 2132 | /* |
| 2127 | * The card will be considered unchanged unless we have been asked to | 2133 | * The card will be considered unchanged unless we have been asked to |
| 2128 | * detect a change or host requires polling to provide card detection. | 2134 | * detect a change or host requires polling to provide card detection. |
| 2129 | */ | 2135 | */ |
| 2130 | if (card && !host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL)) | 2136 | if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL) && |
| 2131 | return mmc_card_removed(card); | 2137 | !(host->caps2 & MMC_CAP2_DETECT_ON_ERR)) |
| 2138 | return ret; | ||
| 2132 | 2139 | ||
| 2133 | host->detect_change = 0; | 2140 | host->detect_change = 0; |
| 2141 | if (!ret) { | ||
| 2142 | ret = _mmc_detect_card_removed(host); | ||
| 2143 | if (ret && (host->caps2 & MMC_CAP2_DETECT_ON_ERR)) { | ||
| 2144 | /* | ||
| 2145 | * Schedule a detect work as soon as possible to let a | ||
| 2146 | * rescan handle the card removal. | ||
| 2147 | */ | ||
| 2148 | cancel_delayed_work(&host->detect); | ||
| 2149 | mmc_detect_change(host, 0); | ||
| 2150 | } | ||
| 2151 | } | ||
| 2134 | 2152 | ||
| 2135 | return _mmc_detect_card_removed(host); | 2153 | return ret; |
| 2136 | } | 2154 | } |
| 2137 | EXPORT_SYMBOL(mmc_detect_card_removed); | 2155 | EXPORT_SYMBOL(mmc_detect_card_removed); |
| 2138 | 2156 | ||
