Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: core: Don't use ->card_busy() and CMD13 in combination when polling

When polling for busy after sending a MMC_SWITCH command, both the optional
->card_busy() callback and CMD13 are being used in conjunction.

This doesn't make sense. Instead it's more reasonable to rely solely on the
->card_busy() callback when it exists. Let's change that and instead use
the CMD13 as a fall-back. In this way we avoid sending CMD13, unless it's
really needed.

Within this context, let's also take the opportunity to make some
additional clean-ups and clarifications to the related code.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Jaehoon Chung <jh80.chung@samsung.com>
Tested-by: Jaehoon Chung <jh80.chung@samsung.com>

+14 -16
+14 -16
drivers/mmc/core/mmc_ops.c
··· 495 495 timeout = jiffies + msecs_to_jiffies(timeout_ms) + 1; 496 496 do { 497 497 /* 498 - * Due to the possibility of being preempted after 499 - * sending the status command, check the expiration 500 - * time first. 498 + * Due to the possibility of being preempted while polling, 499 + * check the expiration time first. 501 500 */ 502 501 expired = time_after(jiffies, timeout); 503 - if (send_status) { 502 + 503 + if (host->ops->card_busy) { 504 + busy = host->ops->card_busy(host); 505 + } else { 504 506 err = __mmc_send_status(card, &status, ignore_crc); 505 507 if (err) 506 508 return err; 507 - } 508 - if (host->ops->card_busy) { 509 - if (!host->ops->card_busy(host)) 510 - break; 511 - busy = true; 509 + busy = R1_CURRENT_STATE(status) == R1_STATE_PRG; 512 510 } 513 511 514 - /* Timeout if the device never leaves the program state. */ 515 - if (expired && 516 - (R1_CURRENT_STATE(status) == R1_STATE_PRG || busy)) { 517 - pr_err("%s: Card stuck in programming state! %s\n", 512 + /* Timeout if the device still remains busy. */ 513 + if (expired && busy) { 514 + pr_err("%s: Card stuck being busy! %s\n", 518 515 mmc_hostname(host), __func__); 519 516 return -ETIMEDOUT; 520 517 } 521 - } while (R1_CURRENT_STATE(status) == R1_STATE_PRG || busy); 518 + } while (busy); 522 519 523 - err = mmc_switch_status_error(host, status); 520 + if (host->ops->card_busy && send_status) 521 + return mmc_switch_status(card); 524 522 525 - return err; 523 + return mmc_switch_status_error(host, status); 526 524 } 527 525 528 526 /**