Re: Patch: fix high capacity (> 2GB) eMMC support

2014-09-22 Thread Jonathan Gray
On Mon, Sep 22, 2014 at 06:48:49PM +0200, Raphael Graf wrote:
> 
> I'm sorry, this diff was using the wrong defines.
> Here's a corrected version.
> 
> Any comments or oks?
> 

> +
> + if (sectors != 0) {
> + sf->flags |= SFF_SDHC;
> + sf->csd.capacity = sectors;
>   }

I think I'd prefer to see the 2G test back here that the original diff
had.  As the emmc spec says that sector addressing is only for > 2G.

"The lowest common nominator, 2GB in this case, will set the limit. The
implementation of a higher than 2GB of density of memory will not be
backwards compatible with the lower densities. First of all the address
argument for higher than 2GB of density of memory is changed to be
sector address (512B sectors) instead of byte address. Secondly the
density of the card is read from the EXT_CSD register instead of CSD
register."

And though I don't have any emmc using devices here the diff
otherwise looks good, so OK.



Re: Patch: fix high capacity (> 2GB) eMMC support

2014-09-22 Thread Raphael Graf
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:  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 -  1.19
> +++ sys/dev/sdmmc/sdmmc_mem.c 21 Sep 2014 12:02:35 -
> @@ -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_SE

Re: Patch: fix high capacity (> 2GB) eMMC support

2014-09-21 Thread Stefan Sperling
On Sun, Sep 21, 2014 at 03:22:41PM +0200, Cédric Tessier wrote:
> OpenBSD runs impressively well on my BeagleBone, the only drawback I can
> see is that the system is slowed down by poor MMC performances (due to 
> missing DMA support in ommmc driver I suppose ?).

Yes. The ommmc(4) driver should use DMA. Same for shdc(4).
IIRC the only host controller driver that uses DMA is rtsx(4).

And the generic sdmmc stack keeps cards at lowest speed settings.
SD cards use 1 data line instead of possible 4 and the bus is never
switched to voltage levels required for very high data rates.
You will not see max performance from SD cards even with DMA.
This applies to all hardware platforms.

A patch for 4-data-line support was posted here:
http://marc.info/?l=openbsd-tech&m=138385072607035&w=2
It wasn't committed because it breaks rtsx(4):
http://marc.info/?l=openbsd-tech&m=138493960219125&w=2

I'd be very happy if this was fixed ;-)



Re: Patch: fix high capacity (> 2GB) eMMC support

2014-09-21 Thread Cédric Tessier
Hi,

My fix was very conservative (I don't have a good understanding of MMC,
and clearly outdated documentations).

I've tried your patch Raphael, and it's working as expected (and it's so
much cleaner).

OpenBSD runs impressively well on my BeagleBone, the only drawback I can
see is that the system is slowed down by poor MMC performances (due to 
missing DMA support in ommmc driver I suppose ?).

Thanks,

Cédric

Sunday 21 Sep 2014, 14:09:57 (+0200), Raphael Graf:
> 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:  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 -  1.19
> +++ sys/dev/sdmmc/sdmmc_mem.c 21 Sep 2014 12:02:35 -
> @@ -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),
>  

Re: Patch: fix high capacity (> 2GB) eMMC support

2014-09-21 Thread Raphael Graf
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:  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 -  1.19
+++ sys/dev/sdmmc/sdmmc_mem.c   21 Sep 2014 12:02:35 -
@@ -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->fl

Re: Patch: fix high capacity (> 2GB) eMMC support

2014-09-20 Thread Jonathan Gray
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:  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.



Patch: fix high capacity (> 2GB) eMMC support

2014-09-20 Thread Cédric Tessier
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:  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.origSat 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_REV192 /* 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)