[12/12] mmc: core: Re-work the error path for the eMMC sanitize command

Message ID 20200204085449.32585-13-ulf.hansson@linaro.org
State New
Headers show
Series
  • mmc: core: Improve code for polling and HW busy detect
Related show

Commit Message

Ulf Hansson Feb. 4, 2020, 8:54 a.m.
The error path for sanitize operations that returns with a -ETIMEDOUT error
code, is for some reason very tightly coupled with the internal request
handling code of the mmc core. For example, mmc_wait_for_req_done() runs
code at completion of requests, to check specific sanitize errors. This is
inefficient, as at it affects all types of requests.

To improve the behaviour, let's move the error management for sanitize
requests into ioctl_do_sanitize(), as it's really there it belongs. Moving
the error handling requires retuning to be held, so let's do that.

While updating this code, let's also take the opportunity to clean it up a
bit.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

---
 drivers/mmc/core/block.c   | 33 +++++++++++++++++++--------------
 drivers/mmc/core/core.c    | 17 -----------------
 drivers/mmc/core/mmc_ops.c |  3 ---
 include/linux/mmc/core.h   |  3 ---
 4 files changed, 19 insertions(+), 37 deletions(-)

-- 
2.17.1

Patch

diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 8ac12e3fff27..db59c51052df 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -410,29 +410,34 @@  static int mmc_blk_ioctl_copy_to_user(struct mmc_ioc_cmd __user *ic_ptr,
 
 static int ioctl_do_sanitize(struct mmc_card *card)
 {
+	struct mmc_host *host = card->host;
 	int err;
 
 	if (!mmc_can_sanitize(card)) {
-			pr_warn("%s: %s - SANITIZE is not supported\n",
-				mmc_hostname(card->host), __func__);
-			err = -EOPNOTSUPP;
-			goto out;
+		pr_warn("%s: SANITIZE is not supported\n", mmc_hostname(host));
+		return -EOPNOTSUPP;
 	}
 
-	pr_debug("%s: %s - SANITIZE IN PROGRESS...\n",
-		mmc_hostname(card->host), __func__);
+	pr_debug("%s: SANITIZE IN PROGRESS...\n", mmc_hostname(host));
 
-	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-					EXT_CSD_SANITIZE_START, 1,
-					MMC_SANITIZE_REQ_TIMEOUT);
+	mmc_retune_hold(host);
 
+	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_SANITIZE_START,
+			 1, MMC_SANITIZE_REQ_TIMEOUT);
 	if (err)
-		pr_err("%s: %s - EXT_CSD_SANITIZE_START failed. err=%d\n",
-		       mmc_hostname(card->host), __func__, err);
+		pr_err("%s: SANITIZE failed err=%d\n", mmc_hostname(host), err);
 
-	pr_debug("%s: %s - SANITIZE COMPLETED\n", mmc_hostname(card->host),
-					     __func__);
-out:
+	/*
+	 * If the santize operation timed out, the card is probably still busy
+	 * in the R1_STATE_PRG. Rather than continue to wait, let's try to abort
+	 * it with a HPI command to get back into R1_STATE_TRAN.
+	 */
+	if (err == -ETIMEDOUT && !mmc_interrupt_hpi(card))
+		pr_warn("%s: Sanitize aborted\n", mmc_hostname(host));
+
+	mmc_retune_release(host);
+
+	pr_debug("%s: SANITIZE COMPLETED\n", mmc_hostname(host));
 	return err;
 }
 
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 6b38c194d74f..95db8ffbdd35 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -403,23 +403,6 @@  void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq)
 
 		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_warn("%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 aa0cab190cd8..c08f8b723a3b 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -595,9 +595,6 @@  int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
 		cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1;
 	}
 
-	if (index == EXT_CSD_SANITIZE_START)
-		cmd.sanitize_busy = true;
-
 	err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
 	if (err)
 		goto out;
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index b7ba8810a3b5..29aa50711626 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -107,9 +107,6 @@  struct mmc_command {
  */
 
 	unsigned int		busy_timeout;	/* busy detect timeout in ms */
-	/* Set this flag only for blocking sanitize request */
-	bool			sanitize_busy;
-
 	struct mmc_data		*data;		/* data segment associated with cmd */
 	struct mmc_request	*mrq;		/* associated request */
 };