Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4368d948 authored by Asutosh Das's avatar Asutosh Das Committed by Matt Wagantall
Browse files

mmc: queue: add timeout capability to requests



Individual requests can have timeouts defined. The default
timeout is set to 120 seconds. On a timeout, the block layer
notifies the driver and error can be handled thereafter.

Change-Id: Ifcd690411770ab266c12a01bb0993f92b0f18bc6
Signed-off-by: default avatarAsutosh Das <asutoshd@codeaurora.org>
Signed-off-by: default avatarVenkat Gopalakrishnan <venkatg@codeaurora.org>
parent 763480e5
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -2633,6 +2633,26 @@ reset:
	clear_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state);
}

static enum blk_eh_timer_return mmc_blk_cmdq_req_timed_out(struct request *req)
{
	struct mmc_queue *mq = req->q->queuedata;
	struct mmc_host *host = mq->card->host;
	struct mmc_queue_req *mq_rq = req->special;
	struct mmc_request *mrq = &mq_rq->cmdq_req.mrq;
	struct mmc_cmdq_req *cmdq_req = &mq_rq->cmdq_req;

	host->cmdq_ops->dumpstate(host);
	if (cmdq_req->cmdq_req_flags & DCMD)
		mrq->cmd->error = -ETIMEDOUT;
	else
		mrq->data->error = -ETIMEDOUT;

	host->err_mrq = mrq;
	mrq->done(mrq);

	return BLK_EH_NOT_HANDLED;
}

static void mmc_blk_cmdq_err(struct mmc_queue *mq)
{
	int err;
@@ -3230,6 +3250,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
		md->queue.cmdq_complete_fn = mmc_blk_cmdq_complete_rq;
		md->queue.cmdq_issue_fn = mmc_blk_cmdq_issue_rq;
		md->queue.cmdq_error_fn = mmc_blk_cmdq_err;
		md->queue.cmdq_req_timed_out = mmc_blk_cmdq_req_timed_out;
	}

	if (mmc_card_mmc(card) && !card->cmdq_init &&
+12 −0
Original line number Diff line number Diff line
@@ -571,6 +571,16 @@ static void mmc_cmdq_error_work(struct work_struct *work)
	mq->cmdq_error_fn(mq);
}

enum blk_eh_timer_return mmc_cmdq_rq_timed_out(struct request *req)
{
	struct mmc_queue *mq = req->q->queuedata;

	pr_err("%s: request with tag: %d flags: 0x%llx timed out\n",
	       mmc_hostname(mq->card->host), req->tag, req->cmd_flags);

	return mq->cmdq_req_timed_out(req);
}

int mmc_cmdq_init(struct mmc_queue *mq, struct mmc_card *card)
{
	int i, ret = 0;
@@ -613,6 +623,8 @@ int mmc_cmdq_init(struct mmc_queue *mq, struct mmc_card *card)
	blk_queue_softirq_done(mq->queue, mmc_cmdq_softirq_done);
	INIT_WORK(&mq->cmdq_err_work, mmc_cmdq_error_work);

	blk_queue_rq_timed_out(mq->queue, mmc_cmdq_rq_timed_out);
	blk_queue_rq_timeout(mq->queue, 120 * HZ);
	card->cmdq_init = true;

	goto out;
+1 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ struct mmc_queue {
			     struct request *);
	void (*cmdq_complete_fn)(struct request *);
	void (*cmdq_error_fn)(struct mmc_queue *);
	enum blk_eh_timer_return (*cmdq_req_timed_out)(struct request *);
	void			*data;
	struct request_queue	*queue;
	struct mmc_queue_req	mqrq[2];
+8 −0
Original line number Diff line number Diff line
@@ -715,6 +715,13 @@ static void cmdq_post_req(struct mmc_host *host, struct mmc_request *mrq,
	}
}

static void cmdq_dumpstate(struct mmc_host *mmc)
{
	struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc);

	cmdq_dumpregs(cq_host);
}

static const struct mmc_cmdq_host_ops cmdq_host_ops = {
	.enable = cmdq_enable,
	.disable = cmdq_disable,
@@ -722,6 +729,7 @@ static const struct mmc_cmdq_host_ops cmdq_host_ops = {
	.post_req = cmdq_post_req,
	.halt = cmdq_halt,
	.reset	= cmdq_reset,
	.dumpstate = cmdq_dumpstate,
};

struct cmdq_host *cmdq_pltfm_init(struct platform_device *pdev)
+1 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ struct mmc_cmdq_host_ops {
			 int err);
	int (*halt)(struct mmc_host *host, bool halt);
	void (*reset)(struct mmc_host *host, bool soft);
	void (*dumpstate)(struct mmc_host *host);
};

struct mmc_host_ops {