@@ -657,8 +657,10 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
struct mmc_async_req *data = host->areq;
/* Prepare a new request */
- if (areq)
+ if (areq && !areq->pre_req_done) {
+ areq->pre_req_done = true;
mmc_pre_req(host, areq->mrq, !host->areq);
+ }
if (host->areq) {
err = mmc_wait_for_data_req_done(host, host->areq->mrq, areq);
@@ -694,12 +696,16 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
if (!err && areq)
start_err = __mmc_start_data_req(host, areq->mrq);
- if (host->areq)
+ if (host->areq) {
+ host->areq->pre_req_done = false;
mmc_post_req(host, host->areq->mrq, 0);
+ }
/* Cancel a prepared request if it was not started. */
- if ((err || start_err) && areq)
+ if ((err || start_err) && areq) {
+ areq->pre_req_done = false;
mmc_post_req(host, areq->mrq, -EINVAL);
+ }
if (err)
host->areq = NULL;
@@ -174,6 +174,7 @@ struct mmc_async_req {
* Returns 0 if success otherwise non zero.
*/
int (*err_check) (struct mmc_card *, struct mmc_async_req *);
+ bool pre_req_done;
};
/**
mmc_start_req() assumes it is never called with the new request already prepared. That is true if the queue consists of only 2 requests, but is not true for a longer queue. e.g. mmc_start_req() has a current and previous request but still exits to queue a new request if the queue size is greater than 2. In that case, when mmc_start_req() is called again, the current request will have been prepared already. Fix by flagging if the request has been prepared. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> --- drivers/mmc/core/core.c | 12 +++++++++--- include/linux/mmc/host.h | 1 + 2 files changed, 10 insertions(+), 3 deletions(-)