All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pierre Ossman <drzeus-list@drzeus.cx>
To: Alex Dubov <oakad@yahoo.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: Support for TI FlashMedia (pci id 104c:8033, 104c:803b) flash card readers
Date: Tue, 05 Sep 2006 07:35:38 +0200	[thread overview]
Message-ID: <44FD0CAA.6020706@drzeus.cx> (raw)
In-Reply-To: <20060905021828.13099.qmail@web36706.mail.mud.yahoo.com>

[-- Attachment #1: Type: text/plain, Size: 467 bytes --]

Alex Dubov wrote:
> I also got a bug report from one of my users. Formerly, I used fixed timeout for data transfer,
> but now I'm setting a timeout from data->timeout_clks. This causes recurrent timeouts with some
> cards. Have you encountered this problem before? If yes, what will be the preferred solution?
>
>   

Yup. The timeout calculation we currently have is broken with regard to
SD cards. Only some cards are affected though. Patch included.

Rgds
Pierre


[-- Attachment #2: sd-timeout.patch --]
[-- Type: text/x-patch, Size: 3566 bytes --]

[MMC] Fix SD timeout calculation

Secure Digital cards use a different algorithm to calculate the timeout
for data transfers. Using the MMC one works often, but not always.

Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
---

 drivers/mmc/mmc.c       |   15 +++++++++++++--
 drivers/mmc/mmc_block.c |   44 ++++++++++++++++++++++++++++++++++++--------
 2 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 33525bd..c0c7ef2 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -912,6 +912,7 @@ static void mmc_read_scrs(struct mmc_hos
 	struct mmc_request mrq;
 	struct mmc_command cmd;
 	struct mmc_data data;
+	unsigned int timeout_us;
 
 	struct scatterlist sg;
 
@@ -947,8 +948,18 @@ static void mmc_read_scrs(struct mmc_hos
 
 		memset(&data, 0, sizeof(struct mmc_data));
 
-		data.timeout_ns = card->csd.tacc_ns * 10;
-		data.timeout_clks = card->csd.tacc_clks * 10;
+		data.timeout_ns = card->csd.tacc_ns * 100;
+		data.timeout_clks = card->csd.tacc_clks * 100;
+
+		timeout_us = data.timeout_ns / 1000;
+		timeout_us += data.timeout_clks * 1000 /
+			(host->ios.clock / 1000);
+
+		if (timeout_us > 100000) {
+			data.timeout_ns = 100000000;
+			data.timeout_clks = 0;
+		}
+
 		data.blksz_bits = 3;
 		data.blksz = 1 << 3;
 		data.blocks = 1;
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index e033424..cb7fc8d 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -30,6 +30,7 @@ #include <linux/blkdev.h>
 #include <linux/mutex.h>
 
 #include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
 #include <linux/mmc/protocol.h>
 
 #include <asm/system.h>
@@ -171,8 +172,6 @@ static int mmc_blk_issue_rq(struct mmc_q
 
 		brq.cmd.arg = req->sector << 9;
 		brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
-		brq.data.timeout_ns = card->csd.tacc_ns * 10;
-		brq.data.timeout_clks = card->csd.tacc_clks * 10;
 		brq.data.blksz_bits = md->block_bits;
 		brq.data.blksz = 1 << md->block_bits;
 		brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
@@ -180,6 +179,41 @@ static int mmc_blk_issue_rq(struct mmc_q
 		brq.stop.arg = 0;
 		brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC;
 
+		brq.data.timeout_ns = card->csd.tacc_ns * 10;
+		brq.data.timeout_clks = card->csd.tacc_clks * 10;
+
+		/*
+		 * Scale up the timeout by the r2w factor
+		 */
+		if (rq_data_dir(req) == WRITE) {
+			brq.data.timeout_ns <<= card->csd.r2w_factor;
+			brq.data.timeout_clks <<= card->csd.r2w_factor;
+		}
+
+		/*
+		 * SD cards use a 100 multiplier and has a upper limit
+		 */
+		if (mmc_card_sd(card)) {
+			unsigned int limit_us, timeout_us;
+
+			brq.data.timeout_ns *= 10;
+			brq.data.timeout_clks *= 10;
+
+			if (rq_data_dir(req) == READ)
+				limit_us = 100000;
+			else
+				limit_us = 250000;
+
+			timeout_us = brq.data.timeout_ns / 1000;
+			timeout_us += brq.data.timeout_clks * 1000 /
+				(card->host->ios.clock / 1000);
+
+			if (timeout_us > limit_us) {
+				brq.data.timeout_ns = limit_us * 1000;
+				brq.data.timeout_clks = 0;
+			}
+		}
+
 		if (rq_data_dir(req) == READ) {
 			brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK;
 			brq.data.flags |= MMC_DATA_READ;
@@ -187,12 +221,6 @@ static int mmc_blk_issue_rq(struct mmc_q
 			brq.cmd.opcode = MMC_WRITE_BLOCK;
 			brq.data.flags |= MMC_DATA_WRITE;
 			brq.data.blocks = 1;
-
-			/*
-			 * Scale up the timeout by the r2w factor
-			 */
-			brq.data.timeout_ns <<= card->csd.r2w_factor;
-			brq.data.timeout_clks <<= card->csd.r2w_factor;
 		}
 
 		if (brq.data.blocks > 1) {

  reply	other threads:[~2006-09-05  5:35 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-07-28  3:34 Support for TI FlashMedia (pci id 104c:8033, 104c:803b) flash card readers Alex Dubov
2006-07-28  4:04 ` Alexey Dobriyan
2006-07-29 15:11   ` Alex Dubov
2006-07-28 11:46 ` Andrey Panin
2006-07-28 13:02   ` Alex Dubov
2006-07-29 20:02 ` Pierre Ossman
2006-07-30  6:29   ` Alex Dubov
2006-07-30 10:12     ` Pierre Ossman
2006-07-31 15:11       ` Alex Dubov
2006-07-31 17:37         ` Pierre Ossman
2006-08-02  2:12           ` Alex Dubov
2006-08-02  9:31             ` Pierre Ossman
2006-09-02  8:53               ` Alex Dubov
2006-09-02 11:15                 ` Pierre Ossman
2006-09-02 16:48                   ` Andrew Morton
2006-09-02 20:50                     ` Pierre Ossman
2006-09-03  3:48                       ` Greg KH
2006-09-03  9:53                         ` Pierre Ossman
2006-09-05 19:12                           ` Greg KH
2006-09-05 20:08                             ` Pierre Ossman
2006-09-06  3:33                               ` Greg KH
2006-09-06  5:02                                 ` Pierre Ossman
2006-09-07  3:00                                   ` Alex Dubov
2006-09-15  2:17                                   ` Alex Dubov
2006-09-15  6:43                                     ` Pierre Ossman
2006-09-19  3:20                                       ` Alex Dubov
2006-09-19  6:03                                         ` Pierre Ossman
2006-09-03  7:41                   ` Alex Dubov
2006-09-03 10:03                     ` Pierre Ossman
2006-09-04 14:12                       ` Alex Dubov
2006-09-04 14:49                         ` Pierre Ossman
2006-09-03 10:20                     ` Russell King
2006-09-03 10:32                       ` Pierre Ossman
2006-09-04 14:28                         ` Alex Dubov
2006-09-04 14:41                           ` Pierre Ossman
2006-09-05  2:18                             ` Alex Dubov
2006-09-05  5:35                               ` Pierre Ossman [this message]
  -- strict thread matches above, loose matches on Subject: below --
2006-07-28 16:04 Mikael Pettersson
2006-07-29  6:43 ` Alex Dubov

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=44FD0CAA.6020706@drzeus.cx \
    --to=drzeus-list@drzeus.cx \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oakad@yahoo.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.