aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/card
diff options
context:
space:
mode:
authorSujit Reddy Thumma <sthumma@codeaurora.org>2011-12-08 03:35:50 -0500
committerChris Ball <cjb@laptop.org>2012-01-11 23:58:44 -0500
commita8ad82cc1b22d04916d9cdb1dc75052e80ac803c (patch)
tree57ebc4322ea4c2e269dd6b3ae599bdbca81528fe /drivers/mmc/card
parent4137e50494cb3496fbb6ccd27aa7b6d7c9634c1e (diff)
mmc: card: Kill block requests if card is removed
Kill block requests when the host realizes that the card is removed from the slot and is sure that subsequent requests are bound to fail. Do this silently so that the block layer doesn't output unnecessary error messages. Signed-off-by: Sujit Reddy Thumma <sthumma@codeaurora.org> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/card')
-rw-r--r--drivers/mmc/card/block.c17
-rw-r--r--drivers/mmc/card/queue.c5
2 files changed, 21 insertions, 1 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 0c959c96005e..0cad48a284a8 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -121,6 +121,7 @@ enum mmc_blk_status {
121 MMC_BLK_ABORT, 121 MMC_BLK_ABORT,
122 MMC_BLK_DATA_ERR, 122 MMC_BLK_DATA_ERR,
123 MMC_BLK_ECC_ERR, 123 MMC_BLK_ECC_ERR,
124 MMC_BLK_NOMEDIUM,
124}; 125};
125 126
126module_param(perdev_minors, int, 0444); 127module_param(perdev_minors, int, 0444);
@@ -639,6 +640,7 @@ static int get_card_status(struct mmc_card *card, u32 *status, int retries)
639 return err; 640 return err;
640} 641}
641 642
643#define ERR_NOMEDIUM 3
642#define ERR_RETRY 2 644#define ERR_RETRY 2
643#define ERR_ABORT 1 645#define ERR_ABORT 1
644#define ERR_CONTINUE 0 646#define ERR_CONTINUE 0
@@ -706,6 +708,9 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
706 u32 status, stop_status = 0; 708 u32 status, stop_status = 0;
707 int err, retry; 709 int err, retry;
708 710
711 if (mmc_card_removed(card))
712 return ERR_NOMEDIUM;
713
709 /* 714 /*
710 * Try to get card status which indicates both the card state 715 * Try to get card status which indicates both the card state
711 * and why there was no response. If the first attempt fails, 716 * and why there was no response. If the first attempt fails,
@@ -722,8 +727,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
722 } 727 }
723 728
724 /* We couldn't get a response from the card. Give up. */ 729 /* We couldn't get a response from the card. Give up. */
725 if (err) 730 if (err) {
731 /* Check if the card is removed */
732 if (mmc_detect_card_removed(card->host))
733 return ERR_NOMEDIUM;
726 return ERR_ABORT; 734 return ERR_ABORT;
735 }
727 736
728 /* Flag ECC errors */ 737 /* Flag ECC errors */
729 if ((status & R1_CARD_ECC_FAILED) || 738 if ((status & R1_CARD_ECC_FAILED) ||
@@ -996,6 +1005,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
996 return MMC_BLK_RETRY; 1005 return MMC_BLK_RETRY;
997 case ERR_ABORT: 1006 case ERR_ABORT:
998 return MMC_BLK_ABORT; 1007 return MMC_BLK_ABORT;
1008 case ERR_NOMEDIUM:
1009 return MMC_BLK_NOMEDIUM;
999 case ERR_CONTINUE: 1010 case ERR_CONTINUE:
1000 break; 1011 break;
1001 } 1012 }
@@ -1329,6 +1340,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
1329 if (!ret) 1340 if (!ret)
1330 goto start_new_req; 1341 goto start_new_req;
1331 break; 1342 break;
1343 case MMC_BLK_NOMEDIUM:
1344 goto cmd_abort;
1332 } 1345 }
1333 1346
1334 if (ret) { 1347 if (ret) {
@@ -1345,6 +1358,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
1345 1358
1346 cmd_abort: 1359 cmd_abort:
1347 spin_lock_irq(&md->lock); 1360 spin_lock_irq(&md->lock);
1361 if (mmc_card_removed(card))
1362 req->cmd_flags |= REQ_QUIET;
1348 while (ret) 1363 while (ret)
1349 ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req)); 1364 ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
1350 spin_unlock_irq(&md->lock); 1365 spin_unlock_irq(&md->lock);
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index dcad59cbfef1..2517547b4366 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -29,6 +29,8 @@
29 */ 29 */
30static int mmc_prep_request(struct request_queue *q, struct request *req) 30static int mmc_prep_request(struct request_queue *q, struct request *req)
31{ 31{
32 struct mmc_queue *mq = q->queuedata;
33
32 /* 34 /*
33 * We only like normal block requests and discards. 35 * We only like normal block requests and discards.
34 */ 36 */
@@ -37,6 +39,9 @@ static int mmc_prep_request(struct request_queue *q, struct request *req)
37 return BLKPREP_KILL; 39 return BLKPREP_KILL;
38 } 40 }
39 41
42 if (mq && mmc_card_removed(mq->card))
43 return BLKPREP_KILL;
44
40 req->cmd_flags |= REQ_DONTPREP; 45 req->cmd_flags |= REQ_DONTPREP;
41 46
42 return BLKPREP_OK; 47 return BLKPREP_OK;