> Poll for TRAN state if the ioctl command will eventually return to TRAN > > The ioctl submitted command should not be considered completed until > the card has returned back to TRAN state. Waiting just for the card > to no longer signal busy is not enough as they might remain in a > non-busy PROG state for a while after the command. > Further commands requiring TRAN will fail then. > It should not be the responsibility of the user to check if their command > has completed until sending the next via ioctl, > instead the check should be made here. > So now, in doubt, wait for TRAN except for the few commands that will > never return to TRAN state. > > Signed-off-by: Christian Loehle <cloehle@xxxxxxxxxxxxxx> > --- > drivers/mmc/core/block.c | 27 ++++++++++++++++++++++----- > 1 file changed, 22 insertions(+), 5 deletions(-) > > diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c > index 689eb9afeeed..a02187e4fad7 100644 > --- a/drivers/mmc/core/block.c > +++ b/drivers/mmc/core/block.c > @@ -410,7 +410,23 @@ static int mmc_blk_ioctl_copy_to_user(struct > mmc_ioc_cmd __user *ic_ptr, > return 0; > } > > -static int card_busy_detect(struct mmc_card *card, unsigned int > timeout_ms, > +static int is_return_to_tran_cmd(struct mmc_command *cmd) > +{ > + /* Cards will never return to TRAN after completing Multi-line comment style > + * identification commands or MMC_SEND_STATUS if they are not > selected. > + */ > + return !(cmd->opcode == MMC_SEND_CID > + || cmd->opcode == MMC_ALL_SEND_CID > + || cmd->opcode == MMC_SEND_CSD > + || cmd->opcode == MMC_SEND_STATUS > + || cmd->opcode == MMC_SELECT_CARD > + || cmd->opcode == MMC_APP_CMD > + || cmd->opcode == MMC_GO_INACTIVE_STATE > + || cmd->opcode == MMC_GO_IDLE_STATE); > + Aren’t you only interested in cmds that move to tran state from other state? According to the Device state transitions (table 61 in eMMC5.1) it only concern cmd7 (stby->tran), cmd12 (data->tran), and cmd14 (btst->tran). Thanks, Avri > +} > + > +static int card_poll_until_tran(struct mmc_card *card, unsigned int > timeout_ms, > u32 *resp_errs) > { > unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); > @@ -593,12 +609,13 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card > *card, struct mmc_blk_data *md, > > memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp)); > > - if (idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { > + if (idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B > + || is_return_to_tran_cmd(&cmd)) { > /* > * Ensure RPMB/R1B command has completed by polling CMD13 > * "Send Status". > */ > - err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, NULL); > + err = card_poll_until_tran(card, MMC_BLK_TIMEOUT_MS, NULL); > } > > return err; > @@ -1621,7 +1638,7 @@ static int mmc_blk_fix_state(struct mmc_card > *card, struct request *req) > > mmc_blk_send_stop(card, timeout); > > - err = card_busy_detect(card, timeout, NULL); > + err = card_poll_until_tran(card, timeout, NULL); > > mmc_retune_release(card->host); > > @@ -1845,7 +1862,7 @@ static int mmc_blk_card_busy(struct mmc_card > *card, struct request *req) > if (mmc_host_is_spi(card->host) || rq_data_dir(req) == READ) > return 0; > > - err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, &status); > + err = card_poll_until_tran(card, MMC_BLK_TIMEOUT_MS, &status); > > /* > * Do not assume data transferred correctly if there are any error bits > -- > 2.31.1 > Hyperstone GmbH | Line-Eid-Strasse 3 | 78467 Konstanz > Managing Directors: Dr. Jan Peter Berns. > Commercial register of local courts: Freiburg HRB381782