diff mbox

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

Message ID 1386653960-4511-2-git-send-email-haijun.zhang@freescale.com
State Superseded
Delegated to: Pantelis Antoniou
Headers show

Commit Message

Haijun.Zhang Dec. 10, 2013, 5:39 a.m. UTC
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
give 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@freescale.com>
---
changes for V3:
	- Change the erase group size to be block aligned.

 drivers/mmc/mmc.c | 52 ++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 38 insertions(+), 14 deletions(-)

Comments

Pantelis Antoniou Dec. 10, 2013, 8:23 a.m. UTC | #1
Hi Haijun,

On Dec 10, 2013, at 7:39 AM, Haijun Zhang wrote:

> 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
> give some incorrect information.
> 

s/give some/giving/

> 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@freescale.com>
> ---
> changes for V3:
> 	- Change the erase group size to be block aligned.
> 
> drivers/mmc/mmc.c | 52 ++++++++++++++++++++++++++++++++++++++--------------
> 1 file changed, 38 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index e1461a9..e8dbb8c 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;
> +

^ use mask of cmd class maximum width (even if class is 12 bit wide)

> 	/* divide frequency by 10, since the mults are 10x bigger */
> 	freq = fbase[(cmd.response[0] & 0x7)];
> 	mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
> @@ -939,7 +941,8 @@ static int mmc_startup(struct mmc *mmc)
> 			capacity *= MMC_MAX_BLOCK_LEN;
> 			if ((capacity >> 20) > 2 * 1024)
> 				mmc->capacity_user = capacity;
> -		}
> +		} else
> +			return COMM_ERR;
> 
> 		switch (ext_csd[EXT_CSD_REV]) {
> 		case 1:
> @@ -960,6 +963,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.
> @@ -968,23 +1004,11 @@ static int mmc_startup(struct mmc *mmc)
> 		    (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
> 			err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
> 				EXT_CSD_ERASE_GROUP_DEF, 1);
> -

^ removed line for no reason

> 			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);
> 		}
> 
> +

^ extra line
> 		/* 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
> 
>
Jaehoon Chung Dec. 27, 2013, 11:13 a.m. UTC | #2
Hi, Haijun.

On 12/10/2013 02:39 PM, Haijun Zhang wrote:
> 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
> give 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@freescale.com>
> ---
> changes for V3:
> 	- Change the erase group size to be block aligned.
> 
>  drivers/mmc/mmc.c | 52 ++++++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 38 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index e1461a9..e8dbb8c 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;
> +
>  	/* divide frequency by 10, since the mults are 10x bigger */
>  	freq = fbase[(cmd.response[0] & 0x7)];
>  	mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
> @@ -939,7 +941,8 @@ static int mmc_startup(struct mmc *mmc)
>  			capacity *= MMC_MAX_BLOCK_LEN;
>  			if ((capacity >> 20) > 2 * 1024)
>  				mmc->capacity_user = capacity;
> -		}
> +		} else
> +			return COMM_ERR;

Well, I think this point need to consider more.
When error is returned, then this return is right. but it's also satisfied "ext_csd[EXT_CSD_REV] >= 2".

>  
>  		switch (ext_csd[EXT_CSD_REV]) {
>  		case 1:
> @@ -960,6 +963,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.
> @@ -968,23 +1004,11 @@ static int mmc_startup(struct mmc *mmc)
>  		    (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
>  			err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
>  				EXT_CSD_ERASE_GROUP_DEF, 1);
> -
>  			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);
>  		}
>  
> +

remove the blank.

Best Regards,
Jaehoon Chung

>  		/* store the partition info of emmc */
>  		if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) ||
>  		    ext_csd[EXT_CSD_BOOT_MULT])
>
diff mbox

Patch

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index e1461a9..e8dbb8c 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;
+
 	/* divide frequency by 10, since the mults are 10x bigger */
 	freq = fbase[(cmd.response[0] & 0x7)];
 	mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
@@ -939,7 +941,8 @@  static int mmc_startup(struct mmc *mmc)
 			capacity *= MMC_MAX_BLOCK_LEN;
 			if ((capacity >> 20) > 2 * 1024)
 				mmc->capacity_user = capacity;
-		}
+		} else
+			return COMM_ERR;
 
 		switch (ext_csd[EXT_CSD_REV]) {
 		case 1:
@@ -960,6 +963,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.
@@ -968,23 +1004,11 @@  static int mmc_startup(struct mmc *mmc)
 		    (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) {
 			err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
 				EXT_CSD_ERASE_GROUP_DEF, 1);
-
 			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])