aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;