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

Commit cd78bbb1 authored by Veerabhadrarao Badiganti's avatar Veerabhadrarao Badiganti
Browse files

mmc: host: Update error stats to track different mmc errors



Updates the error stats list to capture number of occurrences of
different type of errors that mmc driver can encounter.
These error stats can be read out from debugfs.

Change-Id: I9cb5c24caecfe7af06888ba120e188491e2a8472
Signed-off-by: default avatarVeerabhadrarao Badiganti <vbadigan@codeaurora.org>
parent b14535cc
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -803,6 +803,7 @@ static int cmdq_request(struct mmc_host *mmc, struct mmc_request *mrq)
	if (cq_host->ops->crypto_cfg) {
		err = cq_host->ops->crypto_cfg(mmc, mrq, tag, &ice_ctx);
		if (err) {
			mmc->err_stats[MMC_ERR_ICE_CFG]++;
			pr_err("%s: failed to configure crypto: err %d tag %d\n",
					mmc_hostname(mmc), err, tag);
			goto out;
@@ -1015,6 +1016,7 @@ irqreturn_t cmdq_irq(struct mmc_host *mmc, int err)
				mmc->card->bkops.needs_check = true;

			mrq->cmdq_req->resp_err = true;
			mmc->err_stats[MMC_ERR_CMDQ_RED]++;
			pr_err("%s: Response error (0x%08x) from card !!!",
				mmc_hostname(mmc), cmdq_readl(cq_host, CQCRA));

@@ -1030,6 +1032,7 @@ irqreturn_t cmdq_irq(struct mmc_host *mmc, int err)
		if (stat_err & CQIS_GCE) {
			if (mrq->data)
				mrq->data->error = -EIO;
			mmc->err_stats[MMC_ERR_CMDQ_GCE]++;
			pr_err("%s: Crypto generic error while processing task %lu!",
				mmc_hostname(mmc), tag);
			MMC_TRACE(mmc, "%s: GCE error detected with tag %lu\n",
@@ -1054,6 +1057,7 @@ irqreturn_t cmdq_irq(struct mmc_host *mmc, int err)
			if (dbr_set ^ dev_pend_set)
				tag = ffs(dbr_set ^ dev_pend_set) - 1;
			mrq = get_req_by_tag(cq_host, tag);
			mmc->err_stats[MMC_ERR_CMDQ_ICCE]++;
			pr_err("%s: Crypto config error while processing task %lu!",
				mmc_hostname(mmc), tag);
			MMC_TRACE(mmc, "%s: ICCE error with tag %lu\n",
+5 −0
Original line number Diff line number Diff line
@@ -1281,6 +1281,11 @@ int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode)
			pr_debug("%s: %s: found *** good *** phase = %d\n",
				mmc_hostname(mmc), __func__, phase);
		} else {
			/* Ignore crc errors occurred during tuning */
			if (cmd.error)
				mmc->err_stats[MMC_ERR_CMD_CRC]--;
			else if (data.error)
				mmc->err_stats[MMC_ERR_DAT_CRC]--;
			pr_debug("%s: %s: found ## bad ## phase = %d\n",
				mmc_hostname(mmc), __func__, phase);
		}
+36 −14
Original line number Diff line number Diff line
@@ -2491,6 +2491,8 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
		 */
		mmc_retune_disable(mmc);
		err = host->ops->platform_execute_tuning(host, opcode);
		if (err)
			host->mmc->err_stats[MMC_ERR_TUNING]++;
		mmc_retune_enable(mmc);
		return err;
	}
@@ -2919,8 +2921,10 @@ static void sdhci_timeout_timer(unsigned long data)
	spin_lock_irqsave(&host->lock, flags);

	if (host->cmd && !sdhci_data_line_cmd(host->cmd)) {
		host->mmc->err_stats[MMC_ERR_REQ_TIMEOUT]++;
		pr_err("%s: Timeout waiting for hardware cmd interrupt.\n",
		       mmc_hostname(host->mmc));
		MMC_TRACE(host->mmc, "Timeout waiting for h/w interrupt\n");
		sdhci_dumpregs(host);

		host->cmd->error = -ETIMEDOUT;
@@ -2942,6 +2946,7 @@ static void sdhci_timeout_data_timer(unsigned long data)

	if (host->data || host->data_cmd ||
	    (host->cmd && sdhci_data_line_cmd(host->cmd))) {
		host->mmc->err_stats[MMC_ERR_REQ_TIMEOUT]++;
		pr_err("%s: Timeout waiting for hardware interrupt.\n",
		       mmc_hostname(host->mmc));
		MMC_TRACE(host->mmc, "Timeout waiting for h/w interrupt\n");
@@ -3000,13 +3005,17 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
	if (intmask & (SDHCI_INT_TIMEOUT | SDHCI_INT_CRC |
		       SDHCI_INT_END_BIT | SDHCI_INT_INDEX |
		       SDHCI_INT_AUTO_CMD_ERR)) {
		if (intmask & SDHCI_INT_TIMEOUT)
		if (intmask & SDHCI_INT_TIMEOUT) {
			host->cmd->error = -ETIMEDOUT;
		else
			host->mmc->err_stats[MMC_ERR_CMD_TIMEOUT]++;
		} else {
			host->cmd->error = -EILSEQ;
			host->mmc->err_stats[MMC_ERR_CMD_CRC]++;
		}

		if (intmask & SDHCI_INT_AUTO_CMD_ERR) {
			auto_cmd_status = host->auto_cmd_err_sts;
			host->mmc->err_stats[MMC_ERR_AUTO_CMD]++;
			pr_err_ratelimited("%s: %s: AUTO CMD err sts 0x%08x\n",
				mmc_hostname(host->mmc), __func__, auto_cmd_status);
			if (auto_cmd_status & (SDHCI_AUTO_CMD12_NOT_EXEC |
@@ -3134,6 +3143,7 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
			if (intmask & SDHCI_INT_DATA_TIMEOUT) {
				host->data_cmd = NULL;
				data_cmd->error = -ETIMEDOUT;
				host->mmc->err_stats[MMC_ERR_CMD_TIMEOUT]++;
				sdhci_finish_mrq(host, data_cmd->mrq);
				return;
			}
@@ -3157,16 +3167,21 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
		return;
	}

	if (intmask & SDHCI_INT_DATA_TIMEOUT)
	if (intmask & SDHCI_INT_DATA_TIMEOUT) {
		host->data->error = -ETIMEDOUT;
		host->mmc->err_stats[MMC_ERR_DAT_TIMEOUT]++;
	}
	else if (intmask & SDHCI_INT_DATA_END_BIT)
		host->data->error = -EILSEQ;
	else if ((intmask & SDHCI_INT_DATA_CRC) &&
		(command != MMC_BUS_TEST_R))
		(command != MMC_BUS_TEST_R)) {
		host->data->error = -EILSEQ;
		host->mmc->err_stats[MMC_ERR_DAT_CRC]++;
	}
	else if (intmask & SDHCI_INT_ADMA_ERROR) {
		pr_err("%s: ADMA error\n", mmc_hostname(host->mmc));
		sdhci_adma_show_error(host);
		host->mmc->err_stats[MMC_ERR_ADMA]++;
		host->data->error = -EIO;
		if (host->ops->adma_workaround)
			host->ops->adma_workaround(host, intmask);
@@ -3245,24 +3260,31 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
}

#ifdef CONFIG_MMC_CQ_HCI
static int sdhci_get_cmd_err(u32 intmask)
static int sdhci_get_cmd_err(struct sdhci_host *host, u32 intmask)
{
	if (intmask & SDHCI_INT_TIMEOUT)
	if (intmask & SDHCI_INT_TIMEOUT) {
		host->mmc->err_stats[MMC_ERR_CMD_TIMEOUT]++;
		return -ETIMEDOUT;
	else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT |
			    SDHCI_INT_INDEX))
	} else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT |
			    SDHCI_INT_INDEX)) {
		host->mmc->err_stats[MMC_ERR_CMD_CRC]++;
		return -EILSEQ;
	}
	return 0;
}

static int sdhci_get_data_err(u32 intmask)
static int sdhci_get_data_err(struct sdhci_host *host, u32 intmask)
{
	if (intmask & SDHCI_INT_DATA_TIMEOUT)
	if (intmask & SDHCI_INT_DATA_TIMEOUT) {
		host->mmc->err_stats[MMC_ERR_DAT_TIMEOUT]++;
		return -ETIMEDOUT;
	else if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC))
	} else if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC)) {
		host->mmc->err_stats[MMC_ERR_DAT_CRC]++;
		return -EILSEQ;
	else if (intmask & SDHCI_INT_ADMA_ERROR)
	} else if (intmask & MMC_ERR_ADMA) {
		host->mmc->err_stats[MMC_ERR_ADMA]++;
		return -EIO;
	}
	return 0;
}

@@ -3273,9 +3295,9 @@ static irqreturn_t sdhci_cmdq_irq(struct sdhci_host *host, u32 intmask)
	irqreturn_t ret;

	if (intmask & SDHCI_INT_CMD_MASK)
		err = sdhci_get_cmd_err(intmask);
		err = sdhci_get_cmd_err(host, intmask);
	else if (intmask & SDHCI_INT_DATA_MASK)
		err = sdhci_get_data_err(intmask);
		err = sdhci_get_data_err(host, intmask);

	ret = cmdq_irq(host->mmc, err);
	if (err) {