mmc_block: print better error messages
authorAdrian Hunter <ext-adrian.hunter@nokia.com>
Thu, 16 Oct 2008 09:55:25 +0000 (12:55 +0300)
committerGrazvydas Ignotas <notasas@gmail.com>
Mon, 31 Jan 2011 23:49:51 +0000 (01:49 +0200)
Add command response and card status to error
messages.

Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
drivers/mmc/card/block.c

index 1d1e469..fb3e40f 100644 (file)
@@ -209,6 +209,23 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
        return blocks;
 }
 
+static u32 get_card_status(struct mmc_card *card, struct request *req)
+{
+       struct mmc_command cmd;
+       int err;
+
+       memset(&cmd, 0, sizeof(struct mmc_command));
+       cmd.opcode = MMC_SEND_STATUS;
+       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 comand",
+                      req->rq_disk->disk_name, err);
+       return cmd.resp[0];
+}
+
 static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 {
        struct mmc_blk_data *md = mq->data;
@@ -220,7 +237,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 
        do {
                struct mmc_command cmd;
-               u32 readcmd, writecmd;
+               u32 readcmd, writecmd, status = 0;
 
                memset(&brq, 0, sizeof(struct mmc_blk_request));
                brq.mrq.cmd = &brq.cmd;
@@ -275,19 +292,32 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                 * until later as we need to wait for the card to leave
                 * programming mode even when things go wrong.
                 */
+               if (brq.cmd.error || brq.data.error || brq.stop.error)
+                       status = get_card_status(card, req);
+
                if (brq.cmd.error) {
-                       printk(KERN_ERR "%s: error %d sending read/write command\n",
-                              req->rq_disk->disk_name, brq.cmd.error);
+                       printk(KERN_ERR "%s: error %d sending read/write "
+                              "command, response %#x, card status %#x\n",
+                              req->rq_disk->disk_name, brq.cmd.error,
+                              brq.cmd.resp[0], status);
                }
 
                if (brq.data.error) {
-                       printk(KERN_ERR "%s: error %d transferring data\n",
-                              req->rq_disk->disk_name, brq.data.error);
+                       if (brq.data.error == -ETIMEDOUT && brq.mrq.stop)
+                               /* 'Stop' response contains card status */
+                               status = brq.mrq.stop->resp[0];
+                       printk(KERN_ERR "%s: error %d transferring data,"
+                              " sector %u, nr %u, card status %#x\n",
+                              req->rq_disk->disk_name, brq.data.error,
+                              (unsigned)req->sector,
+                              (unsigned)req->nr_sectors, status);
                }
 
                if (brq.stop.error) {
-                       printk(KERN_ERR "%s: error %d sending stop command\n",
-                              req->rq_disk->disk_name, brq.stop.error);
+                       printk(KERN_ERR "%s: error %d sending stop command, "
+                              "response %#x, card status %#x\n",
+                              req->rq_disk->disk_name, brq.stop.error,
+                              brq.stop.resp[0], status);
                }
 
                if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {