On Sat, September 20, 2014 7:45 pm, Jonathan Gray wrote: > On Sat, Sep 20, 2014 at 06:01:51PM +0200, Cédric Tessier wrote: >> 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 > > These bits do not appear to be reserved. In your case bit 4 > seems to indicate HS200/200 MHz clock capable. > > Bit 5 is HS400/400 MHz clock capable. > >> - read sectors count from EXT_CSD >> - fix sectors count and enable SDHC if High Capacity eMMC is detected > > Is the old method of reading the block length still supported > with emmc and csd ver > 2? That wasn't the case for normal sd card. > > It seems the emmc situation is a bit different as the capacity > stored in a seperate place. > >> + >> + 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; >> + } > > I think this should change to > > if (sectors > (2u * 1024 * 1024 * 1024) / 512) > sf->flags |= SFF_SDHC; > sf->csd.capacity = sectors; > > All csd rev > 2 cards should report valid sectors in the extended space. >
This seems not to be the case, the EXT_CSD_SEC_COUNT is only valid for capacities over 2G. I'd use this field only if it's not zero, like freebsd does. Instead of masking the EXT_CSD_CARD_TYPE field, it may be better to just check for the relevant bits as in the diff below. Does this still work for you, Cédric? Index: sys/dev/sdmmc/sdmmc_mem.c =================================================================== RCS file: /cvs/src/sys/dev/sdmmc/sdmmc_mem.c,v retrieving revision 1.19 diff -u -p -r1.19 sdmmc_mem.c --- sys/dev/sdmmc/sdmmc_mem.c 12 Jul 2014 18:48:52 -0000 1.19 +++ sys/dev/sdmmc/sdmmc_mem.c 21 Sep 2014 12:02:35 -0000 @@ -428,6 +428,7 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s 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,18 +440,12 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s return error; } - switch (ext_csd[EXT_CSD_CARD_TYPE]) { - case EXT_CSD_CARD_TYPE_26M: - speed = 26000; - break; - case EXT_CSD_CARD_TYPE_52M: - case EXT_CSD_CARD_TYPE_52M_V18: - case EXT_CSD_CARD_TYPE_52M_V12: - case EXT_CSD_CARD_TYPE_52M_V12_18: + if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_52M) { speed = 52000; hs_timing = 1; - break; - default: + } else if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_26M) { + speed = 26000; + } else { printf("%s: unknown CARD_TYPE 0x%x\n", DEVNAME(sc), ext_csd[EXT_CSD_CARD_TYPE]); } @@ -487,6 +482,16 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s printf("%s, HS_TIMING set failed\n", DEVNAME(sc)); return EINVAL; } + } + + 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; + + if (sectors != 0) { + sf->flags |= SFF_SDHC; + sf->csd.capacity = sectors; } } Index: sys/dev/sdmmc/sdmmcreg.h =================================================================== RCS file: /cvs/src/sys/dev/sdmmc/sdmmcreg.h,v retrieving revision 1.5 diff -u -p -r1.5 sdmmcreg.h --- sys/dev/sdmmc/sdmmcreg.h 12 Sep 2013 11:54:04 -0000 1.5 +++ sys/dev/sdmmc/sdmmcreg.h 21 Sep 2014 12:02:35 -0000 @@ -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)