Skip to content

Commit f19c5a7

Browse files
committed
mmc: core: Fix error propagation for some ioctl commands
Userspace has currently no way of checking the internal R1 response error bits for some commands. This is a problem for some commands, like RPMB for example. Typically, we may detect that the busy completion has successfully ended, while in fact the card did not complete the requested operation. To fix the problem, let's always poll with CMD13 for these commands and during the polling, let's also aggregate the R1 response bits. Before completing the ioctl request, let's propagate the R1 response bits too. Reviewed-by: Avri Altman <[email protected]> Co-developed-by: Christian Loehle <[email protected]> Signed-off-by: Christian Loehle <[email protected]> Signed-off-by: Ulf Hansson <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected]
1 parent 168054c commit f19c5a7

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

drivers/mmc/core/block.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
179179
struct mmc_queue *mq);
180180
static void mmc_blk_hsq_req_done(struct mmc_request *mrq);
181181
static int mmc_spi_err_check(struct mmc_card *card);
182+
static int mmc_blk_busy_cb(void *cb_data, bool *busy);
182183

183184
static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
184185
{
@@ -470,7 +471,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
470471
struct mmc_data data = {};
471472
struct mmc_request mrq = {};
472473
struct scatterlist sg;
473-
bool r1b_resp, use_r1b_resp = false;
474+
bool r1b_resp;
474475
unsigned int busy_timeout_ms;
475476
int err;
476477
unsigned int target_part;
@@ -551,8 +552,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
551552
busy_timeout_ms = idata->ic.cmd_timeout_ms ? : MMC_BLK_TIMEOUT_MS;
552553
r1b_resp = (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B;
553554
if (r1b_resp)
554-
use_r1b_resp = mmc_prepare_busy_cmd(card->host, &cmd,
555-
busy_timeout_ms);
555+
mmc_prepare_busy_cmd(card->host, &cmd, busy_timeout_ms);
556556

557557
mmc_wait_for_req(card->host, &mrq);
558558
memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp));
@@ -605,19 +605,28 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
605605
if (idata->ic.postsleep_min_us)
606606
usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us);
607607

608-
/* No need to poll when using HW busy detection. */
609-
if ((card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp)
610-
return 0;
611-
612608
if (mmc_host_is_spi(card->host)) {
613609
if (idata->ic.write_flag || r1b_resp || cmd.flags & MMC_RSP_SPI_BUSY)
614610
return mmc_spi_err_check(card);
615611
return err;
616612
}
617-
/* Ensure RPMB/R1B command has completed by polling with CMD13. */
618-
if (idata->rpmb || r1b_resp)
619-
err = mmc_poll_for_busy(card, busy_timeout_ms, false,
620-
MMC_BUSY_IO);
613+
614+
/*
615+
* Ensure RPMB, writes and R1B responses are completed by polling with
616+
* CMD13. Note that, usually we don't need to poll when using HW busy
617+
* detection, but here it's needed since some commands may indicate the
618+
* error through the R1 status bits.
619+
*/
620+
if (idata->rpmb || idata->ic.write_flag || r1b_resp) {
621+
struct mmc_blk_busy_data cb_data = {
622+
.card = card,
623+
};
624+
625+
err = __mmc_poll_for_busy(card->host, 0, busy_timeout_ms,
626+
&mmc_blk_busy_cb, &cb_data);
627+
628+
idata->ic.response[0] = cb_data.status;
629+
}
621630

622631
return err;
623632
}

0 commit comments

Comments
 (0)