diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/block.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 8e1aa8d80e76..1761ab238483 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1598,20 +1598,27 @@ static void mmc_blk_rw_cmd_abort(struct mmc_card *card, struct request *req) blk_rq_cur_bytes(req)); } -static void mmc_blk_rw_start_new(struct mmc_queue *mq, struct mmc_card *card, - struct request *req) +/** + * mmc_blk_rw_try_restart() - tries to restart the current async request + * @mq: the queue with the card and host to restart + * @req: a new request that want to be started after the current one + */ +static void mmc_blk_rw_try_restart(struct mmc_queue *mq, struct request *req) { if (!req) return; - if (mmc_card_removed(card)) { + /* + * If the card was removed, just cancel everything and return. + */ + if (mmc_card_removed(mq->card)) { req->rq_flags |= RQF_QUIET; blk_end_request_all(req, -EIO); - } else { - mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); - mmc_start_areq(card->host, - &mq->mqrq_cur->mmc_active, NULL); + return; } + /* Else proceed and try to restart the current async request */ + mmc_blk_rw_rq_prep(mq->mqrq_cur, mq->card, 0, mq); + mmc_start_areq(mq->card->host, &mq->mqrq_cur->mmc_active, NULL); } static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) @@ -1698,11 +1705,11 @@ static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) ret = mmc_blk_cmd_err(md, card, brq, old_req, ret); if (mmc_blk_reset(md, card->host, type)) { mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_start_new(mq, card, new_req); + mmc_blk_rw_try_restart(mq, new_req); return; } if (!ret) { - mmc_blk_rw_start_new(mq, card, new_req); + mmc_blk_rw_try_restart(mq, new_req); return; } break; @@ -1715,7 +1722,7 @@ static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) if (!mmc_blk_reset(md, card->host, type)) break; mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_start_new(mq, card, new_req); + mmc_blk_rw_try_restart(mq, new_req); return; case MMC_BLK_DATA_ERR: { int err; @@ -1725,7 +1732,7 @@ static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) break; if (err == -ENODEV) { mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_start_new(mq, card, new_req); + mmc_blk_rw_try_restart(mq, new_req); return; } /* Fall through */ @@ -1746,19 +1753,19 @@ static void mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *new_req) ret = blk_end_request(old_req, -EIO, brq->data.blksz); if (!ret) { - mmc_blk_rw_start_new(mq, card, new_req); + mmc_blk_rw_try_restart(mq, new_req); return; } break; case MMC_BLK_NOMEDIUM: mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_start_new(mq, card, new_req); + mmc_blk_rw_try_restart(mq, new_req); return; default: pr_err("%s: Unhandled return value (%d)", old_req->rq_disk->disk_name, status); mmc_blk_rw_cmd_abort(card, old_req); - mmc_blk_rw_start_new(mq, card, new_req); + mmc_blk_rw_try_restart(mq, new_req); return; } |