Hi,
I've bought a BeagleBone Black rev. C board, and I was trying to install
OpenBSD on it, but the internal eMMC was causing errors.
sdmmc1: unknown CARD_TYPE 0x17
scsibus1 at sdmmc1: 2 targets, initiator 0
sd1 at scsibus1 targ 1 lun 0: <SD/MMC, Drive #01, > SCSI2 0/direct fixed
sd1: 1024MB, 512 bytes/sector, 2097152 sectors
Card type and sectors count were wrong, and accessing the device was
causing I/O errors.
I've investigated the problem, and it looks like the support of
High Capacity eMMC (> 2GB) is missing.
I've written a quick and dirty patch (tested on 5.5 and snapshot) which fix
all my issues.
Modifications:
- mask reserved bits for card type value
- read sectors count from EXT_CSD
- fix sectors count and enable SDHC if High Capacity eMMC is detected
Cédric
--- sdmmc_mem.c.orig Sat Jul 12 20:48:52 2014
+++ sdmmc_mem.c Sat Sep 20 14:58:42 2014
@@ -428,6 +428,7 @@
u_int8_t ext_csd[512];
int speed = 0;
int hs_timing = 0;
+ u_int32_t sectors = 0;
if (sf->csd.mmcver >= MMC_CSD_MMCVER_4_0) {
/* read EXT_CSD */
@@ -439,7 +440,7 @@
return error;
}
- switch (ext_csd[EXT_CSD_CARD_TYPE]) {
+ switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
case EXT_CSD_CARD_TYPE_26M:
speed = 26000;
break;
@@ -488,6 +489,22 @@
return EINVAL;
}
}
+
+ if (ext_csd[EXT_CSD_REV] >= 2) {
+ sectors = ext_csd[EXT_CSD_SEC_COUNT + 0] << 0 |
+ ext_csd[EXT_CSD_SEC_COUNT + 1]
<< 8 |
+ ext_csd[EXT_CSD_SEC_COUNT + 2]
<< 16 |
+ ext_csd[EXT_CSD_SEC_COUNT + 3]
<< 24;
+ /*
+ * High capacity MMC seems to report a "magic" 4096 *
512 bytes
+ * capacity in csd, but ext_csd contains the real
sectors count
+ */
+ if ((sf->csd.capacity == (4096 * 512)) &&
+ (sectors > (2u * 1024 * 1024 * 1024) / 512)) {
+ sf->flags |= SFF_SDHC;
+ sf->csd.capacity = sectors;
+ }
+ }
}
return error;
--- sdmmcreg.h.orig Thu Sep 12 13:54:04 2013
+++ sdmmcreg.h Sat Sep 20 13:42:08 2014
@@ -95,6 +95,7 @@
#define EXT_CSD_REV 192 /* RO */
#define EXT_CSD_STRUCTURE 194 /* RO */
#define EXT_CSD_CARD_TYPE 196 /* RO */
+#define EXT_CSD_SEC_COUNT 212 /* RO */
/* EXT_CSD field definitions */
#define EXT_CSD_CMD_SET_NORMAL (1U << 0)
@@ -109,6 +110,7 @@
/* EXT_CSD_CARD_TYPE */
/* The only currently valid values for this field are 0x01, 0x03, 0x07,
* 0x0B and 0x0F. */
+#define EXT_CSD_CARD_TYPE_MASK 0xF /* Mask out reserved bits */
#define EXT_CSD_CARD_TYPE_F_26M (1 << 0)
#define EXT_CSD_CARD_TYPE_F_52M (1 << 1)
#define EXT_CSD_CARD_TYPE_F_52M_1_8V (1 << 2)