Skip to content

Commit

Permalink
mmc: core: Align to common busy polling behaviour for mmc ioctls
Browse files Browse the repository at this point in the history
[ Upstream commit 51f5b30 ]

Let's align to the common busy polling behaviour for mmc ioctls, by
updating the below two corresponding parts, that comes into play when using
an R1B response for a command.

*) A command with an R1B response should be prepared by calling
mmc_prepare_busy_cmd(), which make us respects the host's busy timeout
constraints.
**) When an R1B response is being used and the host also supports HW busy
detection, we should skip to poll for busy completion.

Suggested-by: Christian Loehle <cloehle@hyperstone.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Christian Loehle <cloehle@hyperstone.com>
Link: https://lore.kernel.org/r/20230213133707.27857-1-ulf.hansson@linaro.org
Stable-dep-of: f19c5a7 ("mmc: core: Fix error propagation for some ioctl commands")
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
storulf authored and gregkh committed Nov 2, 2023
1 parent d3466ce commit 651e66d
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 8 deletions.
25 changes: 17 additions & 8 deletions drivers/mmc/core/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
struct mmc_data data = {};
struct mmc_request mrq = {};
struct scatterlist sg;
bool r1b_resp, use_r1b_resp = false;
unsigned int busy_timeout_ms;
int err;
unsigned int target_part;

Expand Down Expand Up @@ -559,6 +561,13 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
(cmd.opcode == MMC_SWITCH))
return mmc_sanitize(card, idata->ic.cmd_timeout_ms);

/* If it's an R1B response we need some more preparations. */
busy_timeout_ms = idata->ic.cmd_timeout_ms ? : MMC_BLK_TIMEOUT_MS;
r1b_resp = (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B;
if (r1b_resp)
use_r1b_resp = mmc_prepare_busy_cmd(card->host, &cmd,
busy_timeout_ms);

mmc_wait_for_req(card->host, &mrq);
memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp));

Expand Down Expand Up @@ -610,14 +619,14 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
if (idata->ic.postsleep_min_us)
usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us);

if (idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
/*
* Ensure RPMB/R1B command has completed by polling CMD13 "Send Status". Here we
* allow to override the default timeout value if a custom timeout is specified.
*/
err = mmc_poll_for_busy(card, idata->ic.cmd_timeout_ms ? : MMC_BLK_TIMEOUT_MS,
false, MMC_BUSY_IO);
}
/* No need to poll when using HW busy detection. */
if ((card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp)
return 0;

/* Ensure RPMB/R1B command has completed by polling with CMD13. */
if (idata->rpmb || r1b_resp)
err = mmc_poll_for_busy(card, busy_timeout_ms, false,
MMC_BUSY_IO);

return err;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/mmc/core/mmc_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ bool mmc_prepare_busy_cmd(struct mmc_host *host, struct mmc_command *cmd,
cmd->busy_timeout = timeout_ms;
return true;
}
EXPORT_SYMBOL_GPL(mmc_prepare_busy_cmd);

/**
* __mmc_switch - modify EXT_CSD register
Expand Down

0 comments on commit 651e66d

Please sign in to comment.