Patchwork [U-Boot,1/2] mmc: Fix calculation of capacity for hc cards

login
register
mail settings
Submitter Oliver Metz
Date Oct. 1, 2013, 6:32 p.m.
Message ID <1380652327-8688-2-git-send-email-oliver@freetz.org>
Download mbox | patch
Permalink /patch/279556/
State Rejected
Delegated to: Pantelis Antoniou
Headers show

Comments

Oliver Metz - Oct. 1, 2013, 6:32 p.m.
When using a high capacity card with a density less than
 2 GB a wrong size is calculated. According to JEDEC 4.41 there is no
 differentiation for C_SIZE register between low and high capacity cards.
 Use ext_csd sector count to calculate capacity instead.

Signed-off-by: Oliver Metz <oliver@freetz.org>
---
 drivers/mmc/mmc.c | 20 ++++----------------
 1 file changed, 4 insertions(+), 16 deletions(-)
Pantelis Antoniou - Oct. 31, 2013, 7:30 a.m.
Hi Oliver,

On Oct 1, 2013, at 9:32 PM, Oliver Metz wrote:

> When using a high capacity card with a density less than
> 2 GB a wrong size is calculated. According to JEDEC 4.41 there is no
> differentiation for C_SIZE register between low and high capacity cards.
> Use ext_csd sector count to calculate capacity instead.
> 
> Signed-off-by: Oliver Metz <oliver@freetz.org>
> ---
> drivers/mmc/mmc.c | 20 ++++----------------
> 1 file changed, 4 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index 84dae4d..ff11ff9 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -884,15 +884,9 @@ static int mmc_startup(struct mmc *mmc)
> 	else
> 		mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
> 
> -	if (mmc->high_capacity) {
> -		csize = (mmc->csd[1] & 0x3f) << 16
> -			| (mmc->csd[2] & 0xffff0000) >> 16;
> -		cmult = 8;
> -	} else {
> -		csize = (mmc->csd[1] & 0x3ff) << 2
> -			| (mmc->csd[2] & 0xc0000000) >> 30;
> -		cmult = (mmc->csd[2] & 0x00038000) >> 15;
> -	}
> +	csize = (mmc->csd[1] & 0x3ff) << 2
> +		| (mmc->csd[2] & 0xc0000000) >> 30;
> +	cmult = (mmc->csd[2] & 0x00038000) >> 15;
> 
> 	mmc->capacity_user = (csize + 1) << (cmult + 2);
> 	mmc->capacity_user *= mmc->read_bl_len;
> @@ -927,18 +921,12 @@ static int mmc_startup(struct mmc *mmc)
> 		/* check  ext_csd version and capacity */
> 		err = mmc_send_ext_csd(mmc, ext_csd);
> 		if (!err && (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
> -			 * than 2GB
> -			 */
> 			capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
> 					| ext_csd[EXT_CSD_SEC_CNT + 1] << 8
> 					| ext_csd[EXT_CSD_SEC_CNT + 2] << 16
> 					| ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
> 			capacity *= MMC_MAX_BLOCK_LEN;
> -			if ((capacity >> 20) > 2 * 1024)
> -				mmc->capacity_user = capacity;
> +			mmc->capacity_user = capacity;
> 		}
> 
> 		switch (ext_csd[EXT_CSD_REV]) {
> -- 
> 1.8.4
> 

Something's not right with this:

> U-Boot SPL 2013.10-00105-g2ea5f3f (Oct 31 2013 - 09:24:02)
> reading args
> MMC: block number 0x15c exceeds max(0x100)
> spl: error reading image args, err - -1
> reading u-boot.img
> MMC: block number 0x15c exceeds max(0x100)
> spl: error reading image u-boot.img, err - -1
> ### ERROR ### Please RESET the board ###
> 

This happens on beaglebone black for both external MMC card (Kingston 4GB)
and the internal eMMC part.

When I have some free time I'll try to debug this, but for the moment
the patch is rejected.

Regards

-- Pantelis

Patch

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 84dae4d..ff11ff9 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -884,15 +884,9 @@  static int mmc_startup(struct mmc *mmc)
 	else
 		mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
 
-	if (mmc->high_capacity) {
-		csize = (mmc->csd[1] & 0x3f) << 16
-			| (mmc->csd[2] & 0xffff0000) >> 16;
-		cmult = 8;
-	} else {
-		csize = (mmc->csd[1] & 0x3ff) << 2
-			| (mmc->csd[2] & 0xc0000000) >> 30;
-		cmult = (mmc->csd[2] & 0x00038000) >> 15;
-	}
+	csize = (mmc->csd[1] & 0x3ff) << 2
+		| (mmc->csd[2] & 0xc0000000) >> 30;
+	cmult = (mmc->csd[2] & 0x00038000) >> 15;
 
 	mmc->capacity_user = (csize + 1) << (cmult + 2);
 	mmc->capacity_user *= mmc->read_bl_len;
@@ -927,18 +921,12 @@  static int mmc_startup(struct mmc *mmc)
 		/* check  ext_csd version and capacity */
 		err = mmc_send_ext_csd(mmc, ext_csd);
 		if (!err && (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
-			 * than 2GB
-			 */
 			capacity = ext_csd[EXT_CSD_SEC_CNT] << 0
 					| ext_csd[EXT_CSD_SEC_CNT + 1] << 8
 					| ext_csd[EXT_CSD_SEC_CNT + 2] << 16
 					| ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
 			capacity *= MMC_MAX_BLOCK_LEN;
-			if ((capacity >> 20) > 2 * 1024)
-				mmc->capacity_user = capacity;
+			mmc->capacity_user = capacity;
 		}
 
 		switch (ext_csd[EXT_CSD_REV]) {