Skip to content

Commit 55c2b8b

Browse files
committed
mmc: core: Re-work the code for eMMC sanitize
The error path for sanitize operations that completes with -ETIMEDOUT, is tightly coupled with the internal request handling code of the core. More precisely, mmc_wait_for_req_done() checks for specific sanitize errors. This is not only inefficient as it affects all types of requests, but also hackish. Therefore, let's improve the behaviour by moving the error path out of the mmc core. To do that, retuning needs to be held while running the sanitize operation. Moreover, to avoid exporting unnecessary symbols to the mmc block module, let's move the code into the mmc_ops.c file. While updating the actual code, let's also take the opportunity to clean up some of the mess around it. Signed-off-by: Ulf Hansson <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent fa09101 commit 55c2b8b

File tree

5 files changed

+38
-63
lines changed

5 files changed

+38
-63
lines changed

drivers/mmc/core/block.c

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ MODULE_ALIAS("mmc:block");
7070
* ample.
7171
*/
7272
#define MMC_BLK_TIMEOUT_MS (10 * 1000)
73-
#define MMC_SANITIZE_REQ_TIMEOUT 240000
7473
#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16)
7574
#define MMC_EXTRACT_VALUE_FROM_ARG(x) ((x & 0x0000FF00) >> 8)
7675

@@ -413,34 +412,6 @@ static int mmc_blk_ioctl_copy_to_user(struct mmc_ioc_cmd __user *ic_ptr,
413412
return 0;
414413
}
415414

416-
static int ioctl_do_sanitize(struct mmc_card *card)
417-
{
418-
int err;
419-
420-
if (!mmc_can_sanitize(card)) {
421-
pr_warn("%s: %s - SANITIZE is not supported\n",
422-
mmc_hostname(card->host), __func__);
423-
err = -EOPNOTSUPP;
424-
goto out;
425-
}
426-
427-
pr_debug("%s: %s - SANITIZE IN PROGRESS...\n",
428-
mmc_hostname(card->host), __func__);
429-
430-
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
431-
EXT_CSD_SANITIZE_START, 1,
432-
MMC_SANITIZE_REQ_TIMEOUT);
433-
434-
if (err)
435-
pr_err("%s: %s - EXT_CSD_SANITIZE_START failed. err=%d\n",
436-
mmc_hostname(card->host), __func__, err);
437-
438-
pr_debug("%s: %s - SANITIZE COMPLETED\n", mmc_hostname(card->host),
439-
__func__);
440-
out:
441-
return err;
442-
}
443-
444415
static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms,
445416
u32 *resp_errs)
446417
{
@@ -569,15 +540,8 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
569540
}
570541

571542
if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_SANITIZE_START) &&
572-
(cmd.opcode == MMC_SWITCH)) {
573-
err = ioctl_do_sanitize(card);
574-
575-
if (err)
576-
pr_err("%s: ioctl_do_sanitize() failed. err = %d",
577-
__func__, err);
578-
579-
return err;
580-
}
543+
(cmd.opcode == MMC_SWITCH))
544+
return mmc_sanitize(card);
581545

582546
mmc_wait_for_req(card->host, &mrq);
583547

drivers/mmc/core/core.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -403,23 +403,6 @@ void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq)
403403

404404
cmd = mrq->cmd;
405405

406-
/*
407-
* If host has timed out waiting for the sanitize
408-
* to complete, card might be still in programming state
409-
* so let's try to bring the card out of programming
410-
* state.
411-
*/
412-
if (cmd->sanitize_busy && cmd->error == -ETIMEDOUT) {
413-
if (!mmc_interrupt_hpi(host->card)) {
414-
pr_warn("%s: %s: Interrupted sanitize\n",
415-
mmc_hostname(host), __func__);
416-
cmd->error = 0;
417-
break;
418-
} else {
419-
pr_err("%s: %s: Failed to interrupt sanitize\n",
420-
mmc_hostname(host), __func__);
421-
}
422-
}
423406
if (!cmd->error || !cmd->retries ||
424407
mmc_card_removed(host->card))
425408
break;
@@ -1925,7 +1908,6 @@ int mmc_can_sanitize(struct mmc_card *card)
19251908
return 1;
19261909
return 0;
19271910
}
1928-
EXPORT_SYMBOL(mmc_can_sanitize);
19291911

19301912
int mmc_can_secure_erase_trim(struct mmc_card *card)
19311913
{

drivers/mmc/core/mmc_ops.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#define MMC_BKOPS_TIMEOUT_MS (120 * 1000) /* 120s */
2323
#define MMC_CACHE_FLUSH_TIMEOUT_MS (30 * 1000) /* 30s */
24+
#define MMC_SANITIZE_TIMEOUT_MS (240 * 1000) /* 240s */
2425

2526
static const u8 tuning_blk_pattern_4bit[] = {
2627
0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
@@ -597,9 +598,6 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
597598
cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1;
598599
}
599600

600-
if (index == EXT_CSD_SANITIZE_START)
601-
cmd.sanitize_busy = true;
602-
603601
err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
604602
if (err)
605603
goto out;
@@ -1032,3 +1030,37 @@ int mmc_cmdq_disable(struct mmc_card *card)
10321030
return mmc_cmdq_switch(card, false);
10331031
}
10341032
EXPORT_SYMBOL_GPL(mmc_cmdq_disable);
1033+
1034+
int mmc_sanitize(struct mmc_card *card)
1035+
{
1036+
struct mmc_host *host = card->host;
1037+
int err;
1038+
1039+
if (!mmc_can_sanitize(card)) {
1040+
pr_warn("%s: Sanitize not supported\n", mmc_hostname(host));
1041+
return -EOPNOTSUPP;
1042+
}
1043+
1044+
pr_debug("%s: Sanitize in progress...\n", mmc_hostname(host));
1045+
1046+
mmc_retune_hold(host);
1047+
1048+
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_SANITIZE_START,
1049+
1, MMC_SANITIZE_TIMEOUT_MS);
1050+
if (err)
1051+
pr_err("%s: Sanitize failed err=%d\n", mmc_hostname(host), err);
1052+
1053+
/*
1054+
* If the sanitize operation timed out, the card is probably still busy
1055+
* in the R1_STATE_PRG. Rather than continue to wait, let's try to abort
1056+
* it with a HPI command to get back into R1_STATE_TRAN.
1057+
*/
1058+
if (err == -ETIMEDOUT && !mmc_interrupt_hpi(card))
1059+
pr_warn("%s: Sanitize aborted\n", mmc_hostname(host));
1060+
1061+
mmc_retune_release(host);
1062+
1063+
pr_debug("%s: Sanitize completed\n", mmc_hostname(host));
1064+
return err;
1065+
}
1066+
EXPORT_SYMBOL_GPL(mmc_sanitize);

drivers/mmc/core/mmc_ops.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ int mmc_send_cid(struct mmc_host *host, u32 *cid);
3232
int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp);
3333
int mmc_spi_set_crc(struct mmc_host *host, int use_crc);
3434
int mmc_bus_test(struct mmc_card *card, u8 bus_width);
35-
int mmc_interrupt_hpi(struct mmc_card *card);
3635
int mmc_can_ext_csd(struct mmc_card *card);
3736
int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd);
3837
int mmc_switch_status(struct mmc_card *card, bool crc_err_fatal);
@@ -47,6 +46,7 @@ void mmc_run_bkops(struct mmc_card *card);
4746
int mmc_flush_cache(struct mmc_card *card);
4847
int mmc_cmdq_enable(struct mmc_card *card);
4948
int mmc_cmdq_disable(struct mmc_card *card);
49+
int mmc_sanitize(struct mmc_card *card);
5050

5151
#endif
5252

include/linux/mmc/core.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,6 @@ struct mmc_command {
107107
*/
108108

109109
unsigned int busy_timeout; /* busy detect timeout in ms */
110-
/* Set this flag only for blocking sanitize request */
111-
bool sanitize_busy;
112-
113110
struct mmc_data *data; /* data segment associated with cmd */
114111
struct mmc_request *mrq; /* associated request */
115112
};

0 commit comments

Comments
 (0)