@@ -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;
}
@@ -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;
@@ -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;
@@ -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 */
};
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