Read mmc device memory capacity from EXT_CSD if memory is addressed by sector
RFC PATCH 1/1 Read mmc device memory capacity from EXT_CSD if memory is addressed by sector
Hello Everyone,
I believe, there is a bug in the mmc driver code pertaining to how u-boot detects memory size of an mmc device. However, I am not 100% sure, my solution conforms to the JEDEC standard. So I am putting it up for discussion.
Previously, sector count indicated by mmc devices in the EXT_CSD would only be used in u-boot if the size indicated is greater than 2 GB. This seems to be incorrect. I am working with a 4 GB Micron eMMC device that after partition configuration and setting the user data area to enhanced mode has a remaining capacity of less than 2 GB for the user data area. JESD84-B50 explicitly states in 6.2.4 that for these devices SEC_CNT from the EXT_CSD is still valid even if the memory size for that device has dropped below 2 GB by the partition configuration applied. The access mode bits from the OCR register seem to provide a better way to decide whether to use the CSD-based C_SIZE & C_MULT or the EXT_CSD-based SEC_CNT information when determining the device's capacity.
In particular, this fixes a bug where u-boot SPL would assign 0 to mmc->block_dev.lba later on in the mmc_startup() function and subsequently fail to load u-boot from that mmc due to the original C_SIZE & C_MULT code assigning a 4 TB size to mmc->capacity, that incorrect capacity never being overwritten by the SEC_CNT capacity calculation (due to its size being less than 2 GB) and then finally lldiv(mmc->capacity, mmc->read_bl_len) exceeding the 32-bit result data type of mmc->block_dev.lba.
--- drivers/mmc/mmc.c | 10 +++++----- include/mmc.h | 1 + 2 files changed, 6 insertions(+), 5 deletions(-)
drivers/mmc/mmc.c +5 -5
@@ -935,19 +935,19 @@ static int mmc_startup(struct mmc *mmc)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 (!err && (ext_csd[EXT_CSD_REV ] >=2 ) && + (mmc->ocr &OCR_ACCESS_MODE ) ==OCR_ACCESS_BY_SECTOR ) {/* * According to the JEDEC Standard, the value of -* ext_csd's capacity is valid if the value is more -* than 2GB +* ext_csd's capacity is valid if the device addresses +* its memory by sector */ 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 ]) {
include/mmc.h +1 -0
@@ -104,6 +104,7 @@#define OCR_HCS 0x40000000#define OCR_VOLTAGE_MASK 0x007FFF80#define OCR_ACCESS_MODE 0x60000000 +#define OCR_ACCESS_BY_SECTOR (1 << 30)#define SECURE_ERASE 0x80000000
PATCH 1/1 Read mmc device memory capacity from EXT_CSD if memory is addressed by sector
Hi Pantos, hi Tom,
I sent this a couple of months ago to the mailing list, never really received a response. We are testing 2014.04-rc3 right now and the issue is still there. Would you still consider bringing this fix in for the upcoming release?
This is for an eMMC chip with an initial memory size > 2GB whose memory size drops below 2GB when turning enhanced (pseudo-SLC) mode on for the user partition. u-boot would then fail memory size detection and assume memory size if zero. You'd see error messages like:
MMC: block number 0x1 exceeds max(0x0)
MMC: block number 0x800 exceeds max(0x0)
MMC: block number 0x900 exceeds max(0x0)
Thanks,
Frank
Quoted 79 lines · Frank Bormann
Hello Everyone,
I believe, there is a bug in the mmc driver code pertaining to how u-boot detects memory size of an mmc device. However, I am not 100% sure, my solution conforms to the JEDEC standard. So I am putting it up for discussion.
Previously, sector count indicated by mmc devices in the
EXT_CSDwould only be used in u-boot if the size indicated is greater than 2 GB. This seems to be incorrect. I am working with a 4 GB Micron eMMC device that after partition configuration and setting the user data area to enhanced mode has a remaining capacity of less than 2 GB for the user data area. JESD84-B50 explicitly states in 6.2.4 that for these devicesSEC_CNTfrom theEXT_CSDis still valid even if the memory size for that device has dropped below 2 GB by the partition configuration applied. The access mode bits from the OCR register seem to provide a better way to decide whether to use the CSD-basedC_SIZE&C_MULTor the EXT_CSD-basedSEC_CNTinformation when determining the device's capacity.In particular, this fixes a bug where u-boot SPL would assign 0 to
mmc->block_dev.lbalater on in themmc_startup()function and subsequently fail to load u-boot from that mmc due to the originalC_SIZE&C_MULTcode assigning a 4 TB size tommc->capacity, that incorrect capacity never being overwritten by theSEC_CNTcapacity calculation (due to its size being less than 2 GB) and then finallylldiv(mmc->capacity, mmc->read_bl_len)exceeding the 32-bit result data type ofmmc->block_dev.lba.Signed-off-by Frank Bormann <[email protected]>--- drivers/mmc/mmc.c | 10 +++++----- include/mmc.h | 1 + 2 files changed, 6 insertions(+), 5 deletions(-)drivers/mmc/mmc.c +5
-5@@ -935,19 +935,19 @@ static int mmc_startup(struct mmc *mmc)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 (!err && (ext_csd[EXT_CSD_REV ] >=2 ) && + (mmc->ocr &OCR_ACCESS_MODE ) ==OCR_ACCESS_BY_SECTOR ) {/* * According to the JEDEC Standard, the value of -* ext_csd's capacity is valid if the value is more -* than 2GB +* ext_csd's capacity is valid if the device addresses +* its memory by sector */ 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 ]) {include/mmc.h +1
-0@@ -104,6 +104,7 @@#define OCR_HCS 0x40000000#define OCR_VOLTAGE_MASK 0x007FFF80#define OCR_ACCESS_MODE 0x60000000 +#define OCR_ACCESS_BY_SECTOR (1 << 30)#define SECURE_ERASE 0x80000000_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot
PATCH 1/1 Read mmc device memory capacity from EXT_CSD if memory is addressed by sector
Hi Frank,
Quoted 4 lines · Frank Bormann
Hi Pantos, hi Tom,
I sent this a couple of months ago to the mailing list, never really received a response. We are testing 2014.04-rc3 right now and the issue is still there. Would you still consider bringing this fix in for the upcoming release?
Quoted 9 lines
This is for an eMMC chip with an initial memory size > 2GB whose memory size drops below 2GB when turning enhanced (pseudo-SLC) mode on for the user partition. u-boot would then fail memory size detection and assume memory size if zero. You'd see error messages like:
MMC: block number
0x1exceeds max(0x0)
MMC: block number0x800exceeds max(0x0)
MMC: block number0x900exceeds max(0x0)Thanks,
Frank
Your patch is corrupted; can you please resend and make sure it applies using git am?
Quoted 12 lines
panto at sles11esa:~/u-boot-mmc.git (master)$ git am -3 U-Boot-RFC-1-1-Read-mmc-device-memory-capacity-from-EXT_CSD-if-memory-is-addressed-by-sector.patch
Applying: Read mmc device memory capacity fromEXT_CSDif memory is addressed by sector
fatal: corrupt patch at line 50
Repository lacks necessary blobs to fall back on 3-way merge.
Cannot fall back to three-way merge.
Patch failed at 0001 Read mmc device memory capacity fromEXT_CSDif memory is addressed by sector
The copy of the patch that failed is found in:
/home/panto/ti/u-boots/u-boot-mmc.git/.git/rebase-apply/patch
When you have resolved this problem, run "git am --resolved".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Regards
-- Pantelis