All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/5] mmc:core: Add restrictions for data transfer and card ease
@ 2013-09-24  8:12 Haijun Zhang
  2013-09-24  8:12 ` [PATCH 2/5] mmc:sdhc: Calculate timeout_clk from actual sd clock Haijun Zhang
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Haijun Zhang @ 2013-09-24  8:12 UTC (permalink / raw)
  To: linux-mmc
  Cc: cbouatmailru, cjb, scottwood, X.Xie, ulf.hansson, Haijun Zhang,
	Haijun Zhang

At 50 Mhz SD_CLK period,
the max timeout value = 2^27 * SD_CLK period ~= 2.69 sec.

If max_discard_to was not designed, for mmc card preferred erase
size should be used, for sd card just return UINT_MAX. Also add
limit for data transfer, Use max_discard_to as max data timeout value
to avoid timeout error in case data timeout was larger than
2.69 sec.

For some crappy cards, the timeout value calculate from card was
larger than UINT_MAX, in this case the timeout value write into
register was not expected.

This patch can reduce I/O error due to large timeout value for
erase(CMD38) and write(CMD25) for some crappy cards.

Signed-off-by: Haijun Zhang <haijun.zhang@freescale.com>
---
 drivers/mmc/core/core.c | 45 ++++++++++++++++++++++++++++++---------------
 1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index bf18b6b..b429baa 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -757,6 +757,7 @@ EXPORT_SYMBOL(mmc_read_bkops_status);
  */
 void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
 {
+	struct mmc_host *host = card->host;
 	unsigned int mult;
 
 	/*
@@ -780,7 +781,12 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
 	if (data->flags & MMC_DATA_WRITE)
 		mult <<= card->csd.r2w_factor;
 
-	data->timeout_ns = card->csd.tacc_ns * mult;
+	/* Avoid over flow for some crappy cards. */
+	if ((UINT_MAX / mult) < card->csd.tacc_ns)
+		data->timeout_ns = UINT_MAX;
+	else
+		data->timeout_ns = card->csd.tacc_ns * mult;
+
 	data->timeout_clks = card->csd.tacc_clks * mult;
 
 	/*
@@ -842,6 +848,11 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
 				data->timeout_ns =  100000000;	/* 100ms */
 		}
 	}
+
+	if (host->max_discard_to &&
+			(host->max_discard_to <
+			 (data->timeout_ns / 1000000)))
+		data->timeout_ns = host->max_discard_to * 1000000;
 }
 EXPORT_SYMBOL(mmc_set_data_timeout);
 
@@ -1816,11 +1827,14 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
 		unsigned int timeout_clks = card->csd.tacc_clks * mult;
 		unsigned int timeout_us;
 
-		/* Avoid overflow: e.g. tacc_ns=80000000 mult=1280 */
-		if (card->csd.tacc_ns < 1000000)
-			timeout_us = (card->csd.tacc_ns * mult) / 1000;
-		else
+		/*
+		 * Avoid over flow for some crappy cards.
+		 * e.g. tacc_ns=80000000 mult=1280
+		 */
+		if ((UINT_MAX / mult) < card->csd.tacc_ns)
 			timeout_us = (card->csd.tacc_ns / 1000) * mult;
+		else
+			timeout_us = (card->csd.tacc_ns * mult) / 1000;
 
 		/*
 		 * ios.clock is only a target.  The real clock rate might be
@@ -2185,16 +2199,17 @@ unsigned int mmc_calc_max_discard(struct mmc_card *card)
 	struct mmc_host *host = card->host;
 	unsigned int max_discard, max_trim;
 
-	if (!host->max_discard_to)
-		return UINT_MAX;
-
-	/*
-	 * Without erase_group_def set, MMC erase timeout depends on clock
-	 * frequence which can change.  In that case, the best choice is
-	 * just the preferred erase size.
-	 */
-	if (mmc_card_mmc(card) && !(card->ext_csd.erase_group_def & 1))
-		return card->pref_erase;
+	if (!host->max_discard_to) {
+		/*
+		 * Without erase_group_def set, MMC erase timeout depends
+		 * on clock frequence which can change.  In that case, the
+		 * best choice is just the preferred erase size.
+		 */
+		if (mmc_card_mmc(card) && !(card->ext_csd.erase_group_def & 1))
+			return card->pref_erase;
+		else
+			return UINT_MAX;
+	}
 
 	max_discard = mmc_do_calc_max_discard(card, MMC_ERASE_ARG);
 	if (mmc_can_trim(card)) {
-- 
1.8.0



^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-10-21  9:21 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-24  8:12 [PATCH 1/5] mmc:core: Add restrictions for data transfer and card ease Haijun Zhang
2013-09-24  8:12 ` [PATCH 2/5] mmc:sdhc: Calculate timeout_clk from actual sd clock Haijun Zhang
2013-09-24  8:12 ` [PATCH 3/5] mmc:esdhc: Update timeout clock according to actual clock Haijun Zhang
2013-09-24  8:12 ` [PATCH 4/5] mmc:esdhc: Workaround about clock glitch issue on eSDHC host Haijun Zhang
2013-09-24  8:12 ` [PATCH 5/5] mmc:esdhc: Avoid writting to power register Haijun Zhang
2013-10-21  9:18 ` [PATCH 1/5] mmc:core: Add restrictions for data transfer and card ease Zhang Haijun

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.