Skip to content

Commit 0d84c3e

Browse files
committed
mmc: core: Convert to mmc_poll_for_busy() for erase/trim/discard
Rather than open coding the polling loop in mmc_do_erase(), let's convert to use mmc_poll_for_busy(). To allow a slightly different error parsing during polling, compared to the __mmc_switch() case, a new in-parameter to mmc_poll_for_busy() is needed, but other than that the conversion is straight forward. Besides addressing the open coding issue, moving to mmc_poll_for_busy() for erase/trim/discard improves the behaviour according to below. - Adds support for polling via the optional ->card_busy() host ops. - Returns zero to indicate success when the final polling attempt finds the card non-busy, even if the timeout expired. - Exits the polling loop when state moves to R1_STATE_TRAN, rather than when leaving R1_STATE_PRG. - Decreases the starting range for throttling to 32-64us. Signed-off-by: Ulf Hansson <[email protected]> Tested-by: Baolin Wang <[email protected]> Tested-by: Ludovic Barre <[email protected]> Reviewed-by: Ludovic Barre <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 2a1c7cd commit 0d84c3e

File tree

3 files changed

+33
-40
lines changed

3 files changed

+33
-40
lines changed

drivers/mmc/core/core.c

+2-34
Original file line numberDiff line numberDiff line change
@@ -1658,8 +1658,6 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
16581658
struct mmc_command cmd = {};
16591659
unsigned int qty = 0, busy_timeout = 0;
16601660
bool use_r1b_resp = false;
1661-
unsigned long timeout;
1662-
int loop_udelay=64, udelay_max=32768;
16631661
int err;
16641662

16651663
mmc_retune_hold(card->host);
@@ -1763,38 +1761,8 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
17631761
if ((card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) && use_r1b_resp)
17641762
goto out;
17651763

1766-
timeout = jiffies + msecs_to_jiffies(busy_timeout);
1767-
do {
1768-
memset(&cmd, 0, sizeof(struct mmc_command));
1769-
cmd.opcode = MMC_SEND_STATUS;
1770-
cmd.arg = card->rca << 16;
1771-
cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
1772-
/* Do not retry else we can't see errors */
1773-
err = mmc_wait_for_cmd(card->host, &cmd, 0);
1774-
if (err || R1_STATUS(cmd.resp[0])) {
1775-
pr_err("error %d requesting status %#x\n",
1776-
err, cmd.resp[0]);
1777-
err = -EIO;
1778-
goto out;
1779-
}
1780-
1781-
/* Timeout if the device never becomes ready for data and
1782-
* never leaves the program state.
1783-
*/
1784-
if (time_after(jiffies, timeout)) {
1785-
pr_err("%s: Card stuck in programming state! %s\n",
1786-
mmc_hostname(card->host), __func__);
1787-
err = -EIO;
1788-
goto out;
1789-
}
1790-
if ((cmd.resp[0] & R1_READY_FOR_DATA) &&
1791-
R1_CURRENT_STATE(cmd.resp[0]) != R1_STATE_PRG)
1792-
break;
1793-
1794-
usleep_range(loop_udelay, loop_udelay*2);
1795-
if (loop_udelay < udelay_max)
1796-
loop_udelay *= 2;
1797-
} while (1);
1764+
/* Let's poll to find out when the erase operation completes. */
1765+
err = mmc_poll_for_busy(card, busy_timeout, MMC_BUSY_ERASE);
17981766

17991767
out:
18001768
mmc_retune_release(card->host);

drivers/mmc/core/mmc_ops.c

+24-6
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ int mmc_switch_status(struct mmc_card *card, bool crc_err_fatal)
445445
}
446446

447447
static int mmc_busy_status(struct mmc_card *card, bool retry_crc_err,
448-
bool *busy)
448+
enum mmc_busy_cmd busy_cmd, bool *busy)
449449
{
450450
struct mmc_host *host = card->host;
451451
u32 status = 0;
@@ -464,16 +464,27 @@ static int mmc_busy_status(struct mmc_card *card, bool retry_crc_err,
464464
if (err)
465465
return err;
466466

467-
err = mmc_switch_status_error(card->host, status);
467+
switch (busy_cmd) {
468+
case MMC_BUSY_CMD6:
469+
err = mmc_switch_status_error(card->host, status);
470+
break;
471+
case MMC_BUSY_ERASE:
472+
err = R1_STATUS(status) ? -EIO : 0;
473+
break;
474+
default:
475+
err = -EINVAL;
476+
}
477+
468478
if (err)
469479
return err;
470480

471481
*busy = !mmc_ready_for_data(status);
472482
return 0;
473483
}
474484

475-
static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
476-
bool send_status, bool retry_crc_err)
485+
static int __mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
486+
bool send_status, bool retry_crc_err,
487+
enum mmc_busy_cmd busy_cmd)
477488
{
478489
struct mmc_host *host = card->host;
479490
int err;
@@ -500,7 +511,7 @@ static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
500511
*/
501512
expired = time_after(jiffies, timeout);
502513

503-
err = mmc_busy_status(card, retry_crc_err, &busy);
514+
err = mmc_busy_status(card, retry_crc_err, busy_cmd, &busy);
504515
if (err)
505516
return err;
506517

@@ -522,6 +533,12 @@ static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
522533
return 0;
523534
}
524535

536+
int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
537+
enum mmc_busy_cmd busy_cmd)
538+
{
539+
return __mmc_poll_for_busy(card, timeout_ms, true, false, busy_cmd);
540+
}
541+
525542
/**
526543
* __mmc_switch - modify EXT_CSD register
527544
* @card: the MMC card associated with the data transfer
@@ -591,7 +608,8 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
591608
goto out_tim;
592609

593610
/* Let's try to poll to find out when the command is completed. */
594-
err = mmc_poll_for_busy(card, timeout_ms, send_status, retry_crc_err);
611+
err = __mmc_poll_for_busy(card, timeout_ms, send_status, retry_crc_err,
612+
MMC_BUSY_CMD6);
595613
if (err)
596614
goto out;
597615

drivers/mmc/core/mmc_ops.h

+7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010

1111
#include <linux/types.h>
1212

13+
enum mmc_busy_cmd {
14+
MMC_BUSY_CMD6,
15+
MMC_BUSY_ERASE,
16+
};
17+
1318
struct mmc_host;
1419
struct mmc_card;
1520

@@ -30,6 +35,8 @@ int mmc_interrupt_hpi(struct mmc_card *card);
3035
int mmc_can_ext_csd(struct mmc_card *card);
3136
int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd);
3237
int mmc_switch_status(struct mmc_card *card, bool crc_err_fatal);
38+
int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
39+
enum mmc_busy_cmd busy_cmd);
3340
int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
3441
unsigned int timeout_ms, unsigned char timing,
3542
bool send_status, bool retry_crc_err);

0 commit comments

Comments
 (0)