lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Wed, 8 Dec 2010 19:44:52 +0800
From:	Chuanxiao Dong <chuanxiao.dong@...el.com>
To:	linux-mmc@...r.kernel.org, adrian.hunter@...ia.com
Cc:	linux-kernel@...r.kernel.org
Subject: [PATCH v1 1/2]move erase timeout calculation part to mmc.c and sd.c

Hi adrian,
   this 2 patches modify the erase timeout calculation part which added by
   you. Can you help to review that? Thanks.


Since mmc and sd erase timeout calculation only depends on
card registers and host clock, it can be done during card
initialization. No need to calculated the erase timeout value
for erase/trim command before each time sending.

Signed-off-by: Chuanxiao Dong <chuanxiao.dong@...el.com>
---
 drivers/mmc/core/mmc.c   |   50 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/mmc/core/sd.c    |   19 +++++++++++++++++
 include/linux/mmc/card.h |    4 +++
 3 files changed, 73 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 77f93c3..ee2f196 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -118,6 +118,54 @@ static void mmc_set_erase_size(struct mmc_card *card)
 	mmc_init_erase(card);
 }
 
+static void mmc_set_mmc_erase_timeout(struct mmc_card *card)
+{
+	unsigned int erase_timeout;
+
+	if (card->ext_csd.erase_group_def & 1) {
+		/* High Capacity Erase Group Size uses HC timeouts */
+		card->trim_timeout = card->ext_csd.trim_timeout;
+		card->erase_timeout = card->ext_csd.hc_erase_timeout;
+	} else {
+		/* CSD Erase Group Size uses write timeout */
+		unsigned int mult = (10 << card->csd.r2w_factor);
+		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
+			timeout_us = (card->csd.tacc_ns / 1000) * mult;
+
+		/*
+		 * ios.clock is only a target.  The real clock rate might be
+		 * less but not that much less, so fudge it by multiplying by 2.
+		 */
+		timeout_clks <<= 1;
+		timeout_us += (timeout_clks * 1000) /
+			      (card->host->ios.clock / 1000);
+
+		erase_timeout = timeout_us / 1000;
+
+		/*
+		 * Theoretically, the calculation could underflow so round up
+		 * to 1ms in that case.
+		 */
+		if (!erase_timeout)
+			erase_timeout = 1;
+
+		card->trim_timeout = erase_timeout;
+		card->erase_timeout = erase_timeout;
+	}
+
+	/* Multiplier for secure operations */
+	card->sec_trim_timeout = card->erase_timeout *
+		card->ext_csd.sec_trim_mult;
+	card->sec_erase_timeout = card->erase_timeout *
+		card->ext_csd.sec_erase_mult;
+}
+
 /*
  * Given a 128-bit response, decode to our card CSD structure.
  */
@@ -528,6 +576,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 			&& (host->caps & (MMC_CAP_1_2V_DDR)))
 				ddr = MMC_1_2V_DDR_MODE;
 	}
+	/* Erase/trim timeout depends on CSD, EXT_CSD and host clock */
+	mmc_set_mmc_erase_timeout(card);
 
 	/*
 	 * Activate wide bus and DDR (if supported).
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 49da4df..f9afff7 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -250,6 +250,20 @@ out:
 	return err;
 }
 
+static void mmc_set_sd_erase_timeout(struct mmc_card *card)
+{
+	if (card->ssr.erase_timeout)
+		/* Erase timeout specified in SD Status Register (SSR) */
+		card->erase_timeout = card->ssr.erase_timeout;
+	else
+		/*
+		 * Erase timeout not specified in SD Status Register (SSR) so
+		 * use 250ms per write block.
+		 */
+		card->erase_timeout = 250;
+}
+
+
 /*
  * Fetches and decodes switch information
  */
@@ -624,6 +638,11 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
 	mmc_set_clock(host, mmc_sd_get_max_clock(card));
 
 	/*
+	 * Set erase timeout
+	 * */
+	mmc_set_sd_erase_timeout(card);
+
+	/*
 	 * Switch to wider bus (if supported).
 	 */
 	if ((host->caps & MMC_CAP_4_BIT_DATA) &&
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 8ce0827..e95c770 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -126,6 +126,10 @@ struct mmc_card {
  	unsigned int		erase_shift;	/* if erase unit is power 2 */
  	unsigned int		pref_erase;	/* in sectors */
  	u8			erased_byte;	/* value of erased bytes */
+	unsigned int	erase_timeout; /* erase timeout value in ms per blk */
+	unsigned int	trim_timeout; /* trim timeout value in ms per blk */
+	unsigned int	sec_erase_timeout; /* sec erase timeout in ms per blk */
+	unsigned int	sec_trim_timeout; /* sec trim timeout in ms per blk */
 
 	u32			raw_cid[4];	/* raw card CID */
 	u32			raw_csd[4];	/* raw card CSD */
-- 
1.6.6.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ