Skip to content

Commit 3bbb0de

Browse files
ChaotianJingstorulf
authored andcommitted
mmc: core: fix __mmc_switch timeout caused by preempt
there is a time window between __mmc_send_status() and time_afer(), on some eMMC chip, the timeout_ms is only 10ms, if this thread was scheduled out during this period, then, even card has already changes to transfer state by the result of CMD13, this part of code also treat it to timeout error. So, need calculate timeout first, then call __mmc_send_status(), if already timeout and card still in programing state, then treat it to the real timeout error. Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent 05caee9 commit 3bbb0de

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

drivers/mmc/core/mmc_ops.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
489489
unsigned long timeout;
490490
u32 status = 0;
491491
bool use_r1b_resp = use_busy_signal;
492+
bool expired = false;
492493

493494
mmc_retune_hold(host);
494495

@@ -545,6 +546,12 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
545546
timeout = jiffies + msecs_to_jiffies(timeout_ms);
546547
do {
547548
if (send_status) {
549+
/*
550+
* Due to the possibility of being preempted after
551+
* sending the status command, check the expiration
552+
* time first.
553+
*/
554+
expired = time_after(jiffies, timeout);
548555
err = __mmc_send_status(card, &status, ignore_crc);
549556
if (err)
550557
goto out;
@@ -565,7 +572,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
565572
}
566573

567574
/* Timeout if the device never leaves the program state. */
568-
if (time_after(jiffies, timeout)) {
575+
if (expired && R1_CURRENT_STATE(status) == R1_STATE_PRG) {
569576
pr_err("%s: Card stuck in programming state! %s\n",
570577
mmc_hostname(host), __func__);
571578
err = -ETIMEDOUT;

0 commit comments

Comments
 (0)