summaryrefslogtreecommitdiff
path: root/drivers/mmc/core
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r--drivers/mmc/core/core.c19
-rw-r--r--drivers/mmc/core/mmc_ops.c2
2 files changed, 21 insertions, 0 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 6e4d04d..48b9fec 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -402,6 +402,7 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host,
context_info->is_done_rcv = false;
context_info->is_new_req = false;
cmd = mrq->cmd;
+
if (!cmd->error || !cmd->retries ||
mmc_card_removed(host->card)) {
err = host->areq->err_check(host->card,
@@ -436,6 +437,24 @@ static void mmc_wait_for_req_done(struct mmc_host *host,
wait_for_completion(&mrq->completion);
cmd = mrq->cmd;
+
+ /*
+ * If host has timed out waiting for the sanitize
+ * to complete, card might be still in programming state
+ * so let's try to bring the card out of programming
+ * state.
+ */
+ if (cmd->sanitize_busy && cmd->error == -ETIMEDOUT) {
+ if (!mmc_interrupt_hpi(host->card)) {
+ pr_warning("%s: %s: Interrupted sanitize\n",
+ mmc_hostname(host), __func__);
+ cmd->error = 0;
+ break;
+ } else {
+ pr_err("%s: %s: Failed to interrupt sanitize\n",
+ mmc_hostname(host), __func__);
+ }
+ }
if (!cmd->error || !cmd->retries ||
mmc_card_removed(host->card))
break;
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 49f04bc..124af52 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -431,6 +431,8 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
cmd.cmd_timeout_ms = timeout_ms;
+ if (index == EXT_CSD_SANITIZE_START)
+ cmd.sanitize_busy = true;
err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
if (err)