mmc: block: Implement card_busy_detect() for busy detection
authorUlf Hansson <ulf.hansson@linaro.org>
Wed, 29 Jan 2014 10:01:55 +0000 (11:01 +0100)
committerChris Ball <chris@printf.net>
Sun, 23 Feb 2014 15:40:58 +0000 (10:40 -0500)
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: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Chris Ball <chris@printf.net>
drivers/mmc/card/block.c

index 156cabfa61c37e8034a5fe3b0efee75fbdb0b131..fffa83359c677e35827da326e6cf749eea462b63 100644 (file)
@@ -749,6 +749,49 @@ static int get_card_status(struct mmc_card *card, u32 *status, int retries)
        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_RETRY      2
 #define ERR_ABORT      1
@@ -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.
         */
        if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
-               u32 status;
-               unsigned long timeout;
+               int err;
 
                /* Check stop command response */
                if (brq->stop.resp[0] & R1_ERROR) {
@@ -1167,39 +1209,9 @@ static int mmc_blk_err_check(struct mmc_card *card,
                        gen_err = 1;
                }
 
-               timeout = jiffies + msecs_to_jiffies(MMC_BLK_TIMEOUT_MS);
-               do {
-                       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;
-                       }
-                       /*
-                        * 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));
+               err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, req, &gen_err);
+               if (err)
+                       return MMC_BLK_CMD_ERR;
        }
 
        /* if general error occurs, retry the write operation. */