mmc: core: Detect card removal on I/O error
[~shefty/rdma-dev.git] / drivers / mmc / core / core.c
index faa0af10d334dbb2cfc232187b25f0ec5ec354e7..436409f7f7bd926eee397829565ef1e92b89ac77 100644 (file)
@@ -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);