[U-Boot] [PATCH 2/7 V5] mmc: Get secure erase information from card

Haijun Zhang haijun.zhang at freescale.com
Mon Dec 30 09:20:53 CET 2013


Read command class from csd register and secure erase
support bit from ext csd register. Also calculate the erase
timeout and secure erase timeout.

If read ext csd error, error status should be returned instead of
giving some incorrect information.

Error log:
=>
=> mmcinfo
Device: FSL_SDHC
Manufacturer ID: 0
OEM: 0
Name: Tran Speed: 0
Rd Block Len: 0
MMC version 0.0
High Capacity: No
Capacity: 0 Bytes
Bus Width: 1-bit
=>

Signed-off-by: Haijun Zhang <haijun.zhang at freescale.com>
---
changes for V5:
	- Exclude the judgement of EXT_CSD_REV in case of read EXT_CSD err

 drivers/mmc/mmc.c | 54 +++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 39 insertions(+), 15 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index e1461a9..da06990 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -871,6 +871,8 @@ static int mmc_startup(struct mmc *mmc)
 		}
 	}
 
+	mmc->cmdclass = (cmd.response[1] >> 20) & 0xfff;
+
 	/* divide frequency by 10, since the mults are 10x bigger */
 	freq = fbase[(cmd.response[0] & 0x7)];
 	mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
@@ -925,8 +927,10 @@ static int mmc_startup(struct mmc *mmc)
 	mmc->part_config = MMCPART_NOAVAILABLE;
 	if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
 		/* check  ext_csd version and capacity */
-		err = mmc_send_ext_csd(mmc, ext_csd);
-		if (!err && (ext_csd[EXT_CSD_REV] >= 2)) {
+		if (mmc_send_ext_csd(mmc, ext_csd))
+			return COMM_ERR;
+
+		if (ext_csd[EXT_CSD_REV] >= 2) {
 			/*
 			 * According to the JEDEC Standard, the value of
 			 * ext_csd's capacity is valid if the value is more
@@ -960,6 +964,39 @@ static int mmc_startup(struct mmc *mmc)
 		}
 
 		/*
+		 * The granularity of the erasable units is the Erase Group:The
+		 * smallest number of consecutive write blocks which can be
+		 * addressed for erase. The size of the Erase Group is card
+		 * specific and stored in the CSD when ERASE_GROUP_DEF is
+		 * disabled, and in the EXT_CSD when ERASE_GROUP_DEF is
+		 * enabled.
+		 */
+		if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) {
+			mmc->erase_grp_size =
+				ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 1024;
+
+			mmc->erase_timeout_mult = 300 *
+				ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];
+		} else {
+			/* Calculate the group size from the csd value. */
+			int erase_gsz, erase_gmul;
+			erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
+			erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
+			mmc->erase_grp_size = (erase_gsz + 1)
+				* (erase_gmul + 1);
+		}
+
+		if (ext_csd[EXT_CSD_REV] >= 4) {
+			mmc->sec_feature_support =
+				ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
+			mmc->sec_erase_mult =
+				ext_csd[EXT_CSD_SEC_ERASE_MULT];
+			mmc->sec_erase_timeout = 300 *
+				ext_csd[EXT_CSD_SEC_ERASE_MULT] *
+				ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];
+		}
+
+		/*
 		 * Host needs to enable ERASE_GRP_DEF bit if device is
 		 * partitioned. This bit will be lost every time after a reset
 		 * or power off. This will affect erase size.
@@ -971,20 +1008,7 @@ static int mmc_startup(struct mmc *mmc)
 
 			if (err)
 				return err;
-
-			/* Read out group size from ext_csd */
-			mmc->erase_grp_size =
-				ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
-					MMC_MAX_BLOCK_LEN * 1024;
-		} else {
-			/* Calculate the group size from the csd value. */
-			int erase_gsz, erase_gmul;
-			erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
-			erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
-			mmc->erase_grp_size = (erase_gsz + 1)
-				* (erase_gmul + 1);
 		}
-
 		/* store the partition info of emmc */
 		if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
 		    ext_csd[EXT_CSD_BOOT_MULT])
-- 
1.8.4.1




More information about the U-Boot mailing list