aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2015-09-14 13:41:53 +0200
committerUlf Hansson <ulf.hansson@linaro.org>2015-09-15 13:30:03 +0200
commitea1b0baa065b1e8111c3aa79c5f64aa5d785f095 (patch)
tree10a2e0b45f66cfe8014dfe8f11804861f529d5df
parentd9db8ffccd1577378dd7dc33bf42f54d89dd02b5 (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.c67
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);
}