mmc: core: Remove SD card upon recovery failure

In case of bad SD card recovery fails everytime.
Also some SD cards fail on Read/writes but can get initialized
successfully.

Mark card as removed and gracefully remove by calling
mmc_detect_change. Also mark the card as corrupted and return
to avoid reinitialization as sdhci_get_cd will return non zero as the
card is physically present and avoid mmc_rescan from proceeding ahead.

Change-Id: Id4c99d4608ef2b5f49cf5ac796a2aaf6d12a56c2
Signed-off-by: Sarthak Garg <sartgarg@codeaurora.org>
This commit is contained in:
Sarthak Garg 2020-09-21 10:02:48 +05:30
commit 48686b39b3
4 changed files with 22 additions and 1 deletions

View file

@ -1840,6 +1840,15 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)
err && mmc_blk_reset(md, card->host, type)) {
pr_err("%s: recovery failed!\n", req->rq_disk->disk_name);
mqrq->retries = MMC_NO_RETRIES;
#if defined(CONFIG_SDC_QTI)
/* Completely remove the non-recoverable card */
if (mmc_card_sd(card)) {
mmc_card_set_removed(card);
card->host->corrupted_card = true;
mmc_detect_change(card->host, msecs_to_jiffies(200));
}
#endif
return;
}

View file

@ -2997,6 +2997,11 @@ void mmc_rescan(struct work_struct *work)
if (host->bus_ops && !host->bus_dead)
host->bus_ops->detect(host);
#if defined(CONFIG_SDC_QTI)
if (host->corrupted_card)
return;
#endif
host->detect_change = 0;
/*

View file

@ -32,6 +32,11 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
struct mmc_host *host = dev_id;
struct mmc_gpio *ctx = host->slot.handler_priv;
#if defined(CONFIG_SDC_QTI)
/* New card is not corrupted */
host->corrupted_card = false;
#endif
host->trigger_card_event = true;
mmc_detect_change(host, msecs_to_jiffies(ctx->cd_debounce_delay_ms));

View file

@ -499,7 +499,9 @@ struct mmc_host {
int rescan_disable; /* disable card detection */
int rescan_entered; /* used with nonremovable devices */
#if defined(CONFIG_SDC_QTI)
bool corrupted_card; /* good/bad associated card */
#endif
int need_retune; /* re-tuning is needed */
int hold_retune; /* hold off re-tuning */
unsigned int retune_period; /* re-tuning period in secs */