mmc: core: Align to common busy polling behaviour for mmc ioctls
[ Upstream commit 51f5b3056790bc0518e49587996f1e6f3058cca9 ] 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: f19c5a73e6f7 ("mmc: core: Fix error propagation for some ioctl commands") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
d3466ce4f4
commit
651e66d20b
@ -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;
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user