On Sun, September 21, 2014 2:09 pm, Raphael Graf wrote:
> 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)
>
>
>

I'm sorry, this diff was using the wrong defines.
Here's a corrected version.

Any comments or oks?


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   22 Sep 2014 16:45:49 -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_F_52M) {
                        speed = 52000;
                        hs_timing = 1;
-                       break;
-               default:
+               } else if (ext_csd[EXT_CSD_CARD_TYPE] & 
EXT_CSD_CARD_TYPE_F_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    22 Sep 2014 16:45:49 -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)


Reply via email to