Skip to content

Commit

Permalink
mmc: sdhci: improve ADMA error reporting
Browse files Browse the repository at this point in the history
ADMA errors are potentially data corrupting events; although we print
the register state, we do not usefully print the ADMA descriptors.
Worse than that, we print them by referencing their virtual address
which is meaningless when the register state gives us the DMA address
of the failing descriptor.

Print the ADMA descriptors giving their DMA addresses rather than their
virtual addresses, and print them using SDHCI_DUMP() rather than DBG().

We also do not show the correct value of the interrupt status register;
the register dump shows the current value, after we have cleared the
pending interrupts we are going to service.  What is more useful is to
print the interrupts that _were_ pending at the time the ADMA error was
encountered.  Fix that too.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
  • Loading branch information
Russell King authored and Ulf Hansson committed Sep 27, 2019
1 parent 3c6a691 commit d1c536e
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions drivers/mmc/host/sdhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2874,25 +2874,29 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p)
static void sdhci_adma_show_error(struct sdhci_host *host)
{
void *desc = host->adma_table;
dma_addr_t dma = host->adma_addr;

sdhci_dumpregs(host);

while (true) {
struct sdhci_adma2_64_desc *dma_desc = desc;

if (host->flags & SDHCI_USE_64_BIT_DMA)
DBG("%p: DMA 0x%08x%08x, LEN 0x%04x, Attr=0x%02x\n",
desc, le32_to_cpu(dma_desc->addr_hi),
SDHCI_DUMP("%08llx: DMA 0x%08x%08x, LEN 0x%04x, Attr=0x%02x\n",
(unsigned long long)dma,
le32_to_cpu(dma_desc->addr_hi),
le32_to_cpu(dma_desc->addr_lo),
le16_to_cpu(dma_desc->len),
le16_to_cpu(dma_desc->cmd));
else
DBG("%p: DMA 0x%08x, LEN 0x%04x, Attr=0x%02x\n",
desc, le32_to_cpu(dma_desc->addr_lo),
SDHCI_DUMP("%08llx: DMA 0x%08x, LEN 0x%04x, Attr=0x%02x\n",
(unsigned long long)dma,
le32_to_cpu(dma_desc->addr_lo),
le16_to_cpu(dma_desc->len),
le16_to_cpu(dma_desc->cmd));

desc += host->desc_sz;
dma += host->desc_sz;

if (dma_desc->cmd & cpu_to_le16(ADMA2_END))
break;
Expand Down Expand Up @@ -2968,7 +2972,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
!= MMC_BUS_TEST_R)
host->data->error = -EILSEQ;
else if (intmask & SDHCI_INT_ADMA_ERROR) {
pr_err("%s: ADMA error\n", mmc_hostname(host->mmc));
pr_err("%s: ADMA error: 0x%08x\n", mmc_hostname(host->mmc),
intmask);
sdhci_adma_show_error(host);
host->data->error = -EIO;
if (host->ops->adma_workaround)
Expand Down

0 comments on commit d1c536e

Please sign in to comment.