mmc: block: allow get_card_status() to return error status
authorRussell King - ARM Linux <linux@arm.linux.org.uk>
Mon, 20 Jun 2011 19:10:08 +0000 (20:10 +0100)
committerKen Sumrall <ksumrall@android.com>
Thu, 27 Oct 2011 00:11:38 +0000 (17:11 -0700)
If the MMC_SEND_STATUS command is not successful, we should not return
a zero status word, but instead allow the caller to know positively
that an error occurred.

Convert the open-coded get_card_status() to use the helper function,
and provide definitions for the card state field.

Change-Id: Icfd6258af78a89c21abac386c556153fa3fac364
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Pawel Moll <pawel.moll@arm.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
drivers/mmc/card/block.c
include/linux/mmc/mmc.h

index c779503e75784c6815a1fe3fe1981b5e19fbd432..6d38d2ceb27a32f93860c1982de540c0ba457b78 100644 (file)
@@ -521,7 +521,7 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
        return result;
 }
 
-static u32 get_card_status(struct mmc_card *card, struct request *req)
+static int get_card_status(struct mmc_card *card, u32 *status, int retries)
 {
        struct mmc_command cmd = {0};
        int err;
@@ -530,11 +530,10 @@ static u32 get_card_status(struct mmc_card *card, struct request *req)
        if (!mmc_host_is_spi(card->host))
                cmd.arg = card->rca << 16;
        cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;
-       err = mmc_wait_for_cmd(card->host, &cmd, 0);
-       if (err)
-               printk(KERN_ERR "%s: error %d sending status command",
-                      req->rq_disk->disk_name, err);
-       return cmd.resp[0];
+       err = mmc_wait_for_cmd(card->host, &cmd, retries);
+       if (err == 0)
+               *status = cmd.resp[0];
+       return err;
 }
 
 static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
@@ -682,7 +681,6 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req)
                (md->flags & MMC_BLK_REL_WR);
 
        do {
-               struct mmc_command cmd = {0};
                u32 readcmd, writecmd, status = 0;
 
                memset(&brq, 0, sizeof(struct mmc_blk_request));
@@ -813,7 +811,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req)
                                disable_multi = 1;
                                continue;
                        }
-                       status = get_card_status(card, req);
+                       get_card_status(card, &status, 0);
                } else if (disable_multi == 1) {
                        disable_multi = 0;
                }
@@ -852,12 +850,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req)
 
                if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
                        do {
-                               int err;
-
-                               cmd.opcode = MMC_SEND_STATUS;
-                               cmd.arg = card->rca << 16;
-                               cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
-                               err = mmc_wait_for_cmd(card->host, &cmd, 5);
+                               int err = get_card_status(card, &status, 5);
                                if (err) {
                                        printk(KERN_ERR "%s: error %d requesting status\n",
                                               req->rq_disk->disk_name, err);
@@ -868,16 +861,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req)
                                 * so make sure to check both the busy
                                 * indication and the card state.
                                 */
-                       } while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
-                               (R1_CURRENT_STATE(cmd.resp[0]) == 7));
-
-#if 0
-                       if (cmd.resp[0] & ~0x00000900)
-                               printk(KERN_ERR "%s: status = %08x\n",
-                                      req->rq_disk->disk_name, cmd.resp[0]);
-                       if (mmc_decode_status(cmd.resp))
-                               goto cmd_err;
-#endif
+                       } while (!(status & R1_READY_FOR_DATA) ||
+                                (R1_CURRENT_STATE(status) == R1_STATE_PRG));
                }
 
                if (brq.cmd.error || brq.stop.error || brq.data.error) {
index ac26a685cca8a82e55f2b6eba31ee1321ff70727..8e425ab761f073809b8fcc66701c34447f08e915 100644 (file)
@@ -140,6 +140,16 @@ static inline bool mmc_op_multi(u32 opcode)
 #define R1_SWITCH_ERROR                (1 << 7)        /* sx, c */
 #define R1_APP_CMD             (1 << 5)        /* sr, c */
 
+#define R1_STATE_IDLE  0
+#define R1_STATE_READY 1
+#define R1_STATE_IDENT 2
+#define R1_STATE_STBY  3
+#define R1_STATE_TRAN  4
+#define R1_STATE_DATA  5
+#define R1_STATE_RCV   6
+#define R1_STATE_PRG   7
+#define R1_STATE_DIS   8
+
 /*
  * MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
  * R1 is the low order byte; R2 is the next highest byte, when present.