forked from luck/tmp_suning_uos_patched
mmc: core: Clean up after mmc_pre_req if card was removed
Make sure mmc_start_req cancels the prepared job, if the request was prevented to be started due to the card has been removed. This bug was introduced in commit: mmc: allow upper layers to know immediately if card has been removed Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com> Reviewed-by: Per Forlin <per.forlin@stericsson.com> Tested-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Chris Ball <cjb@laptop.org>
This commit is contained in:
parent
907d2e7cc7
commit
956d9fd5eb
|
@ -249,16 +249,17 @@ static void mmc_wait_done(struct mmc_request *mrq)
|
|||
complete(&mrq->completion);
|
||||
}
|
||||
|
||||
static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
|
||||
static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
|
||||
{
|
||||
init_completion(&mrq->completion);
|
||||
mrq->done = mmc_wait_done;
|
||||
if (mmc_card_removed(host->card)) {
|
||||
mrq->cmd->error = -ENOMEDIUM;
|
||||
complete(&mrq->completion);
|
||||
return;
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
mmc_start_request(host, mrq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mmc_wait_for_req_done(struct mmc_host *host,
|
||||
|
@ -342,6 +343,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
|
|||
struct mmc_async_req *areq, int *error)
|
||||
{
|
||||
int err = 0;
|
||||
int start_err = 0;
|
||||
struct mmc_async_req *data = host->areq;
|
||||
|
||||
/* Prepare a new request */
|
||||
|
@ -351,30 +353,23 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
|
|||
if (host->areq) {
|
||||
mmc_wait_for_req_done(host, host->areq->mrq);
|
||||
err = host->areq->err_check(host->card, host->areq);
|
||||
if (err) {
|
||||
/* post process the completed failed request */
|
||||
mmc_post_req(host, host->areq->mrq, 0);
|
||||
if (areq)
|
||||
/*
|
||||
* Cancel the new prepared request, because
|
||||
* it can't run until the failed
|
||||
* request has been properly handled.
|
||||
*/
|
||||
mmc_post_req(host, areq->mrq, -EINVAL);
|
||||
|
||||
host->areq = NULL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (areq)
|
||||
__mmc_start_req(host, areq->mrq);
|
||||
if (!err && areq)
|
||||
start_err = __mmc_start_req(host, areq->mrq);
|
||||
|
||||
if (host->areq)
|
||||
mmc_post_req(host, host->areq->mrq, 0);
|
||||
|
||||
host->areq = areq;
|
||||
out:
|
||||
/* Cancel a prepared request if it was not started. */
|
||||
if ((err || start_err) && areq)
|
||||
mmc_post_req(host, areq->mrq, -EINVAL);
|
||||
|
||||
if (err)
|
||||
host->areq = NULL;
|
||||
else
|
||||
host->areq = areq;
|
||||
|
||||
if (error)
|
||||
*error = err;
|
||||
return data;
|
||||
|
|
Loading…
Reference in New Issue
Block a user