public inbox for linux-mmc@vger.kernel.org
 help / color / mirror / Atom feed
From: Mikko Vinni <mmvinni@yahoo.com>
To: linux-mmc@vger.kernel.org
Subject: [PATCH] sdhci: work around broken dma boundary behaviour
Date: Mon, 21 Feb 2011 21:23:32 +0000 (UTC)	[thread overview]
Message-ID: <loom.20110221T221815-772@post.gmane.org> (raw)
In-Reply-To: 403485.93468.qm@web161809.mail.bf1.yahoo.com

Some SD host controllers (noticed on an integrated JMicron SD reader
on an HP Pavilion dv5-1250eo laptop) don't update the dma address
register before signalling a dma interrupt due to a dma boundary.
Detect this and update the register to the next 512KB boundary,
at which the transfer presumably stopped. As long as each transfer
is at most 512KB in size (on this hardware the max seems to be
65536 bytes), this fix is neeeded at most once per transfer.

Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=28462

Signed-off-by: Mikko Vinni <mmvinni@yahoo.com>

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index a25db42..469cf74 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1537,9 +1537,27 @@ static void sdhci_data_irq(struct sdhci_host *host, u32
intmask)
 		 * boundaries, but as we can't disable the feature
 		 * we need to at least restart the transfer.
 		 */
-		if (intmask & SDHCI_INT_DMA_END)
-			sdhci_writel(host, sdhci_readl(host, SDHCI_DMA_ADDRESS),
-				SDHCI_DMA_ADDRESS);
+		if (intmask & SDHCI_INT_DMA_END) {
+			u32 dmastart, dmanow;
+			dmastart = sg_dma_address(host->data->sg);
+			dmanow = sdhci_readl(host, SDHCI_DMA_ADDRESS);
+			if (dmanow == dmastart) {
+				/*
+				 * HW failed to increase the address.
+				 * Update to the next 512KB block boundary.
+				 */
+				dmanow = (dmanow & ~0x7ffff) + 0x80000;
+				if (dmanow > dmastart + host->data->blksz *
+							host->data->blocks) {
+					WARN_ON(1);
+					dmanow = dmastart;
+				}
+				DBG("%s: next DMA address forced "
+				    "from 0x%08x to 0x%08x\n",
+				    mmc_hostname(host->mmc), dmastart, dmanow);
+			}
+			sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS);
+		}
 
 		if (intmask & SDHCI_INT_DATA_END) {
 			if (host->cmd) {



      reply	other threads:[~2011-02-21 21:30 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-20 21:04 SD card reads corrupted (JMicron card reader) Mikko Vinni
2011-02-21 21:23 ` Mikko Vinni [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=loom.20110221T221815-772@post.gmane.org \
    --to=mmvinni@yahoo.com \
    --cc=linux-mmc@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox