X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fmmc%2Fcard%2Fblock.c;h=cc9b3abf4a3f7bc3ee99e0543c675b57e3e16d99;hb=504f191f25b1671802246bac06c9f59f94f0b7de;hp=3d067c35185db9704157d8bc4bddbecc20bf22c7;hpb=4d9c6a21befe6c73c35f2799c7e25a9eda82a95d;p=linux-2.6-omap-h63xx.git diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 3d067c35185..cc9b3abf4a3 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -145,7 +145,7 @@ struct mmc_blk_request { static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) { int err; - u32 blocks; + __be32 blocks; struct mmc_request mrq; struct mmc_command cmd; @@ -204,9 +204,24 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) if (cmd.error || data.error) return (u32)-1; - blocks = ntohl(blocks); + return ntohl(blocks); +} + +static u32 get_card_status(struct mmc_card *card, struct request *req) +{ + struct mmc_command cmd; + int err; - return blocks; + 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) @@ -220,7 +235,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 +290,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) {