diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2015-09-14 13:41:53 +0200 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2015-09-15 13:30:03 +0200 |
commit | ea1b0baa065b1e8111c3aa79c5f64aa5d785f095 (patch) | |
tree | 10a2e0b45f66cfe8014dfe8f11804861f529d5df | |
parent | d9db8ffccd1577378dd7dc33bf42f54d89dd02b5 (diff) |
mmc: core: Thoroughly initiate re-trying requestswip_retry_init
Only parts of the *re-trying* request structure is initiated, which means
some error code could be remaining from the original request while sending
the new one for re-trying.
Let's extract the code which deals with initiating the request structure
into a helper function. Call the new helper function also from the request
re-trying path, as this will address the issue described above.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r-- | drivers/mmc/core/core.c | 67 |
1 files changed, 36 insertions, 31 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index ed5f4ade9941..e38fcd8b6dd5 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -207,12 +207,44 @@ static void __mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) host->ops->request(host, mrq); } -static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) +static void mmc_init_request(struct mmc_host *host, struct mmc_request *mrq) { #ifdef CONFIG_MMC_DEBUG unsigned int i, sz; struct scatterlist *sg; #endif + mrq->cmd->error = 0; + mrq->cmd->mrq = mrq; + if (mrq->sbc) { + mrq->sbc->error = 0; + mrq->sbc->mrq = mrq; + } + if (mrq->data) { + BUG_ON(mrq->data->blksz > host->max_blk_size); + BUG_ON(mrq->data->blocks > host->max_blk_count); + BUG_ON(mrq->data->blocks * mrq->data->blksz > + host->max_req_size); + +#ifdef CONFIG_MMC_DEBUG + sz = 0; + for_each_sg(mrq->data->sg, sg, mrq->data->sg_len, i) + sz += sg->length; + BUG_ON(sz != mrq->data->blocks * mrq->data->blksz); +#endif + + mrq->cmd->data = mrq->data; + mrq->data->error = 0; + mrq->data->mrq = mrq; + if (mrq->stop) { + mrq->data->stop = mrq->stop; + mrq->stop->error = 0; + mrq->stop->mrq = mrq; + } + } +} + +static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) +{ mmc_retune_hold(host); if (mmc_card_removed(host->card)) @@ -245,34 +277,7 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) WARN_ON(!host->claimed); - mrq->cmd->error = 0; - mrq->cmd->mrq = mrq; - if (mrq->sbc) { - mrq->sbc->error = 0; - mrq->sbc->mrq = mrq; - } - if (mrq->data) { - BUG_ON(mrq->data->blksz > host->max_blk_size); - BUG_ON(mrq->data->blocks > host->max_blk_count); - BUG_ON(mrq->data->blocks * mrq->data->blksz > - host->max_req_size); - -#ifdef CONFIG_MMC_DEBUG - sz = 0; - for_each_sg(mrq->data->sg, sg, mrq->data->sg_len, i) - sz += sg->length; - BUG_ON(sz != mrq->data->blocks * mrq->data->blksz); -#endif - - mrq->cmd->data = mrq->data; - mrq->data->error = 0; - mrq->data->mrq = mrq; - if (mrq->stop) { - mrq->data->stop = mrq->stop; - mrq->stop->error = 0; - mrq->stop->mrq = mrq; - } - } + mmc_init_request(host, mrq); mmc_host_clk_hold(host); led_trigger_event(host->led, LED_FULL); __mmc_start_request(host, mrq); @@ -452,7 +457,7 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host, mmc_hostname(host), cmd->opcode, cmd->error); cmd->retries--; - cmd->error = 0; + mmc_init_request(host, mrq); __mmc_start_request(host, mrq); continue; /* wait for done/new event again */ } @@ -502,7 +507,7 @@ static void mmc_wait_for_req_done(struct mmc_host *host, pr_debug("%s: req failed (CMD%u): %d, retrying...\n", mmc_hostname(host), cmd->opcode, cmd->error); cmd->retries--; - cmd->error = 0; + mmc_init_request(host, mrq); __mmc_start_request(host, mrq); } |