Patchwork [U-Boot] generic mmc bug in reading sd card capacity

login
register
mail settings
Submitter Romain Izard
Date Nov. 6, 2012, 8:41 a.m.
Message ID <k7aif2$r2o$1@ger.gmane.org>
Download mbox | patch
Permalink /patch/197432/
State RFC
Delegated to: Andy Fleming
Headers show

Comments

Romain Izard - Nov. 6, 2012, 8:41 a.m.
On 2012-11-02, victor <victor@keyasic.com> wrote:
> Hi All,
>
> Accord to SD spec 2.0, the formula to find out sd card capacity is:
>
> memory capacity = (C_SIZE+1) * 512K byte 
>  	and
> C_SIZE  is from CSD [69:48]
>
> Thus, the code in generic mmc is wrong for the high capacity sd card. My
> patch is below.
>

We should be careful about the fact that this only works for SD cards.
The size parameter is handled differently on MMC devices larger than
2 GiB. What do you think of the following patch:

(Compile tested only, I do not have a board available for testing right now)

8<----------------------------------------------------------------------

From 206b32c0bc90972b3dab2fe7ef902a451fc8e7b6 Mon Sep 17 00:00:00 2001
From: Romain Izard <romain.izard.pro@gmail.com>
Date: Mon, 5 Nov 2012 10:52:56 +0100
Subject: [PATCH] mmc: Correct computing the SD capacity

For high-capacity SD cards, the block size is not used to compute the
effective card capacity. Since high capacity MMC cards do not use the
same method, high-capacity SD cards must be adressed separately.

Signed-off-by: Romain Izard <romain.izard.pro@gmail.com>
---
 drivers/mmc/mmc.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

Patch

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 5ffd8c5..209a200 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -976,19 +976,18 @@  static int mmc_startup(struct mmc *mmc)
 	else
 		mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf);
 
-	if (mmc->high_capacity) {
+	if (IS_SD(mmc) && mmc->high_capacity) {
 		csize = (mmc->csd[1] & 0x3f) << 16
 			| (mmc->csd[2] & 0xffff0000) >> 16;
-		cmult = 8;
+		mmc->capacity = (csize + 1) << 19;
 	} else {
 		csize = (mmc->csd[1] & 0x3ff) << 2
 			| (mmc->csd[2] & 0xc0000000) >> 30;
 		cmult = (mmc->csd[2] & 0x00038000) >> 15;
+		mmc->capacity = (csize + 1) << (cmult + 2);
+		mmc->capacity *= mmc->read_bl_len;
 	}
 
-	mmc->capacity = (csize + 1) << (cmult + 2);
-	mmc->capacity *= mmc->read_bl_len;
-
 	if (mmc->read_bl_len > 512)
 		mmc->read_bl_len = 512;