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

Commit b80e1dfc authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "defconfig: msm: Enable CONFIG_FAIL_MMC_REQUEST for sdmsteppe"

parents debf4951 37bec372
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -714,6 +714,7 @@ CONFIG_DEBUG_CREDENTIALS=y
CONFIG_RCU_TORTURE_TEST=m
CONFIG_FAULT_INJECTION=y
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAIL_MMC_REQUEST=y
CONFIG_UFS_FAULT_INJECTION=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
+45 −24
Original line number Diff line number Diff line
@@ -2429,17 +2429,17 @@ static struct mmc_cmdq_req *mmc_blk_cmdq_prep_discard_req(struct mmc_queue *mq,
	struct mmc_cmdq_req *cmdq_req;
	struct mmc_queue_req *active_mqrq;

	BUG_ON(req->tag > card->ext_csd.cmdq_depth);
	BUG_ON(test_and_set_bit(req->tag, &host->cmdq_ctx.active_reqs));

	set_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx_info->curr_state);

	active_mqrq = req_to_mmc_queue_req(req);

	cmdq_req = mmc_cmdq_prep_dcmd(active_mqrq, mq);
	cmdq_req->cmdq_req_flags |= QBR;
	cmdq_req->mrq.cmd = &cmdq_req->cmd;
	cmdq_req->tag = req->tag;

	init_completion(&cmdq_req->mrq.completion);
	BUG_ON(req->tag > card->ext_csd.cmdq_depth);
	BUG_ON(test_and_set_bit(req->tag, &host->cmdq_ctx.active_reqs));
	set_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx_info->curr_state);
	return cmdq_req;
}

@@ -2483,8 +2483,13 @@ static int mmc_blk_cmdq_issue_discard_rq(struct mmc_queue *mq,
	}
	err = mmc_cmdq_erase(cmdq_req, card, from, nr, arg);
clear_dcmd:
	if (err != -EAGAIN) {
		mmc_host_clk_hold(card->host);
		blk_complete_request(req);
	} else {
		pr_err("%s: err(%d) handled by cmdq-error handler\n",
			__func__, err);
	}
out:
	return err ? 1 : 0;
}
@@ -2546,8 +2551,13 @@ static int mmc_blk_cmdq_issue_secdiscard_rq(struct mmc_queue *mq,
				MMC_SECURE_TRIM2_ARG);
	}
clear_dcmd:
	if (err != -EAGAIN) {
		mmc_host_clk_hold(card->host);
		blk_complete_request(req);
	} else {
		pr_err("%s: err(%d) handled by cmdq-error handler\n",
			__func__, err);
	}
out:
	return err ? 1 : 0;
}
@@ -2807,20 +2817,17 @@ static void mmc_blk_cmdq_reset(struct mmc_host *host, bool clear_all)
}

/**
 * is_cmdq_dcmd_req - Checks if tag belongs to DCMD request.
 * get_cmdq_req_by_tag - returns cmdq_rq based on tag.
 * @q:		request_queue pointer.
 * @tag:	tag number of request to check.
 *
 * This function checks if the request with tag number "tag"
 * is a DCMD request or not based on cmdq_req_flags set.
 *
 * returns true if DCMD req, otherwise false.
 */
static bool is_cmdq_dcmd_req(struct request_queue *q, int tag)
static struct mmc_cmdq_req *get_cmdq_req_by_tag(struct request_queue *q,
						int tag)
{
	struct request *req;
	struct mmc_queue_req *mq_rq;
	struct mmc_cmdq_req *cmdq_req;
	struct mmc_cmdq_req *cmdq_req = NULL;

	req = blk_queue_find_tag(q, tag);
	if (WARN_ON(!req))
@@ -2829,9 +2836,8 @@ static bool is_cmdq_dcmd_req(struct request_queue *q, int tag)
	if (WARN_ON(!mq_rq))
		goto out;
	cmdq_req = &(mq_rq->cmdq_req);
	return (cmdq_req->cmdq_req_flags & DCMD);
out:
	return -ENOENT;
	return cmdq_req;
}

/**
@@ -2851,7 +2857,9 @@ static void mmc_blk_cmdq_reset_all(struct mmc_host *host, int err)
	struct mmc_cmdq_context_info *ctx_info = &host->cmdq_ctx;
	struct request_queue *q;
	int itag = 0;
	int ret = 0;
	struct mmc_cmdq_req *cmdq_req = NULL;
	struct mmc_request *dcmd_mrq;
	bool is_err_mrq_dcmd = false;

	if (WARN_ON(!mrq))
		return;
@@ -2867,18 +2875,31 @@ static void mmc_blk_cmdq_reset_all(struct mmc_host *host, int err)

	mmc_blk_cmdq_reset(host, false);

	if (mrq->cmdq_req->cmdq_req_flags & DCMD)
		is_err_mrq_dcmd = true;

	for_each_set_bit(itag, &ctx_info->active_reqs,
			host->num_cq_slots) {
		ret = is_cmdq_dcmd_req(q, itag);
		if (WARN_ON(ret == -ENOENT))
		cmdq_req = get_cmdq_req_by_tag(q, itag);
		if (WARN_ON(!cmdq_req))
			continue;
		if (!ret) {
		if (!(cmdq_req->cmdq_req_flags & DCMD)) {
			WARN_ON(!test_and_clear_bit(itag,
				 &ctx_info->data_active_reqs));
			mmc_cmdq_post_req(host, itag, err);
		} else {
			clear_bit(CMDQ_STATE_DCMD_ACTIVE,
					&ctx_info->curr_state);
			dcmd_mrq = &cmdq_req->mrq;
			WARN_ON(!test_and_clear_bit(CMDQ_STATE_DCMD_ACTIVE,
					&ctx_info->curr_state));
			pr_debug("%s: cmd(%u), req_op(%llu)\n", __func__,
				 dcmd_mrq->cmd->opcode, req_op(dcmd_mrq->req));
			if (!is_err_mrq_dcmd && !dcmd_mrq->cmd->error &&
				(req_op(dcmd_mrq->req) == REQ_OP_SECURE_ERASE ||
				 req_op(dcmd_mrq->req) == REQ_OP_DISCARD)) {
				dcmd_mrq->cmd->error = -EAGAIN;
				complete(&dcmd_mrq->completion);
			}

		}
		WARN_ON(!test_and_clear_bit(itag,
					&ctx_info->active_reqs));
+1 −2
Original line number Diff line number Diff line
@@ -1854,7 +1854,6 @@ int mmc_cmdq_wait_for_dcmd(struct mmc_host *host,
	struct mmc_command *cmd = mrq->cmd;
	int err = 0;

	init_completion(&mrq->completion);
	mrq->done = mmc_cmdq_dcmd_req_done;
	err = mmc_cmdq_start_req(host, cmdq_req);
	if (err)
@@ -3553,7 +3552,7 @@ static int mmc_cmdq_send_erase_cmd(struct mmc_cmdq_req *cmdq_req,
	if (err) {
		pr_err("mmc_erase: group start error %d, status %#x\n",
				err, cmd->resp[0]);
		return -EIO;
		return err;
	}
	return 0;
}
+0 −14
Original line number Diff line number Diff line
@@ -2967,15 +2967,6 @@ static int mmc_reset(struct mmc_host *host)
		mmc_pwrseq_reset(host);
	}

	/* Suspend clk scaling to avoid switching frequencies intermittently */

	ret = mmc_suspend_clk_scaling(host);
	if (ret) {
		pr_err("%s: %s: fail to suspend clock scaling (%d)\n",
			mmc_hostname(host), __func__, ret);
		return ret;
	}

	ret = mmc_init_card(host, host->card->ocr, host->card);
	if (ret) {
		pr_err("%s: %s: mmc_init_card failed (%d)\n",
@@ -2983,11 +2974,6 @@ static int mmc_reset(struct mmc_host *host)
		return ret;
	}

	ret = mmc_resume_clk_scaling(host);
	if (ret)
		pr_err("%s: %s: fail to resume clock scaling (%d)\n",
			mmc_hostname(host), __func__, ret);

	return ret;
}

+46 −1
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@
#include <linux/mmc/card.h>
#include <linux/pm_runtime.h>
#include <linux/workqueue.h>
#include <linux/fault-inject.h>
#include <linux/random.h>

#include "cmdq_hci.h"
#include "sdhci.h"
@@ -899,6 +901,42 @@ static void cmdq_finish_data(struct mmc_host *mmc, unsigned int tag)
	mrq->done(mrq);
}

#ifdef CONFIG_FAIL_MMC_REQUEST
static int cmdq_should_inject_err(struct mmc_host *mmc, int *err,
				  unsigned int *dbr_set, unsigned int *status)
{
	struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc);
	static const int errors[] = {
		-ETIMEDOUT,
		-EILSEQ,
		-EIO,
	};

	*dbr_set = cmdq_readl(cq_host, CQTDBR);
	if (*dbr_set && should_fail(&mmc->fail_mmc_request,
				(prandom_u32() % 1024) * 512)) {
		pr_err("%s *** Before inducing force err, status (%d) error(%d) dbr(0x%x), active_reqs(0x%lx), data_active_reqs(0x%lx)\n",
			__func__, *status, *err, *dbr_set,
			mmc->cmdq_ctx.active_reqs,
			mmc->cmdq_ctx.data_active_reqs);
		*err = errors[prandom_u32() % ARRAY_SIZE(errors)];
		*status = 0;
		pr_err("%s *** After inducing force err, status (%d) error(%d) dbr(0x%x), active_reqs(0x%lx), data_active_reqs(0x%lx)\n",
			__func__, *status, *err, *dbr_set,
			mmc->cmdq_ctx.active_reqs,
			mmc->cmdq_ctx.data_active_reqs);
		return true;
	}
	return false;
}
#else
static int cmdq_should_inject_err(struct mmc_host *mmc, int *err,
				  unsigned int *dbr_set, unsigned int *status)
{
	return false;
}
#endif

irqreturn_t cmdq_irq(struct mmc_host *mmc, int err)
{
	u32 status;
@@ -910,9 +948,12 @@ irqreturn_t cmdq_irq(struct mmc_host *mmc, int err)
	u32 dbr_set = 0;
	u32 dev_pend_set = 0;
	int stat_err = 0;
	bool err_inject = false;

	status = cmdq_readl(cq_host, CQIS);

	err_inject = cmdq_should_inject_err(mmc, &err, &dbr_set, &status);

	if (!status && !err)
		return IRQ_NONE;
	MMC_TRACE(mmc, "%s: CQIS: 0x%x err: %d\n",
@@ -958,6 +999,7 @@ irqreturn_t cmdq_irq(struct mmc_host *mmc, int err)
			 *   have caused such error, so check for any first
			 *   bit set in doorbell and proceed with an error.
			 */
			if (!dbr_set)
				dbr_set = cmdq_readl(cq_host, CQTDBR);
			if (!dbr_set) {
				pr_err("%s: spurious/force error interrupt\n",
@@ -1099,6 +1141,9 @@ irqreturn_t cmdq_irq(struct mmc_host *mmc, int err)
				}
			}
		}

		if (err_inject && err == -ETIMEDOUT)
			goto out;
		cmdq_finish_data(mmc, tag);
		goto out;
	} else {