Commit c49433fb authored by Ulf Hansson's avatar Ulf Hansson Committed by Chris Ball

mmc: block: Implement card_busy_detect() for busy detection

To complete a data write request we poll for the card's status register
by sending CMD13. The are other scenarios when this polling method are
needed, which is why we here moves this code to it's own function. No
functional change.
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Signed-off-by: default avatarChris Ball <chris@printf.net>
parent bcc3e172
...@@ -749,6 +749,49 @@ static int get_card_status(struct mmc_card *card, u32 *status, int retries) ...@@ -749,6 +749,49 @@ static int get_card_status(struct mmc_card *card, u32 *status, int retries)
return err; return err;
} }
static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms,
struct request *req, int *gen_err)
{
unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
int err = 0;
u32 status;
do {
err = get_card_status(card, &status, 5);
if (err) {
pr_err("%s: error %d requesting status\n",
req->rq_disk->disk_name, err);
return err;
}
if (status & R1_ERROR) {
pr_err("%s: %s: error sending status cmd, status %#x\n",
req->rq_disk->disk_name, __func__, status);
*gen_err = 1;
}
/*
* Timeout if the device never becomes ready for data and never
* leaves the program state.
*/
if (time_after(jiffies, timeout)) {
pr_err("%s: Card stuck in programming state! %s %s\n",
mmc_hostname(card->host),
req->rq_disk->disk_name, __func__);
return -ETIMEDOUT;
}
/*
* Some cards mishandle the status bits,
* so make sure to check both the busy
* indication and the card state.
*/
} while (!(status & R1_READY_FOR_DATA) ||
(R1_CURRENT_STATE(status) == R1_STATE_PRG));
return err;
}
#define ERR_NOMEDIUM 3 #define ERR_NOMEDIUM 3
#define ERR_RETRY 2 #define ERR_RETRY 2
#define ERR_ABORT 1 #define ERR_ABORT 1
...@@ -1156,8 +1199,7 @@ static int mmc_blk_err_check(struct mmc_card *card, ...@@ -1156,8 +1199,7 @@ static int mmc_blk_err_check(struct mmc_card *card,
* program mode, which we have to wait for it to complete. * program mode, which we have to wait for it to complete.
*/ */
if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
u32 status; int err;
unsigned long timeout;
/* Check stop command response */ /* Check stop command response */
if (brq->stop.resp[0] & R1_ERROR) { if (brq->stop.resp[0] & R1_ERROR) {
...@@ -1167,40 +1209,10 @@ static int mmc_blk_err_check(struct mmc_card *card, ...@@ -1167,40 +1209,10 @@ static int mmc_blk_err_check(struct mmc_card *card,
gen_err = 1; gen_err = 1;
} }
timeout = jiffies + msecs_to_jiffies(MMC_BLK_TIMEOUT_MS); err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, req, &gen_err);
do { if (err)
int err = get_card_status(card, &status, 5);
if (err) {
pr_err("%s: error %d requesting status\n",
req->rq_disk->disk_name, err);
return MMC_BLK_CMD_ERR;
}
if (status & R1_ERROR) {
pr_err("%s: %s: general error sending status command, card status %#x\n",
req->rq_disk->disk_name, __func__,
status);
gen_err = 1;
}
/* Timeout if the device never becomes ready for data
* and never leaves the program state.
*/
if (time_after(jiffies, timeout)) {
pr_err("%s: Card stuck in programming state!"\
" %s %s\n", mmc_hostname(card->host),
req->rq_disk->disk_name, __func__);
return MMC_BLK_CMD_ERR; return MMC_BLK_CMD_ERR;
} }
/*
* Some cards mishandle the status bits,
* so make sure to check both the busy
* indication and the card state.
*/
} while (!(status & R1_READY_FOR_DATA) ||
(R1_CURRENT_STATE(status) == R1_STATE_PRG));
}
/* if general error occurs, retry the write operation. */ /* if general error occurs, retry the write operation. */
if (gen_err) { if (gen_err) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment