tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: 1024bytes/sect microSD support



From: Paul Fleischer <paul%xpg.dk@localhost>
Subject: Re: 1024bytes/sect microSD support
Date: Fri, 27 Nov 2009 10:50:49 +0100

> 2009/11/27 KIYOHARA Takashi <kiyohara%kk.iij4u.or.jp@localhost>:
> [snip]
> >> : I think that it is necessary to always adjust us to 512 bytes.  If this
> >> : is not supported, we cannot have Linux and interchangeability.
> >> : However, I do not know how to set more better it.  Does anyone have an
> >> : idea?
> 
> As far as I can read from the SD Simplified Physical Layer
> Specification[1] page 19, the 2Gb cards are bit of an exception as
> their CSD announces a block size of 1024, but the actual block size to
> use is 512kb.
> 
> I have patched dev/sdmmc/sdmmc_mem.c to follow this exception. I bet
> the patch can be made more pretty, but it seems to work.
> 
> Cheers,
> Paul
> 
> [1]: http://www.sdcard.org/developers/tech/sdcard/pls/
> 
> Index: dev/sdmmc/sdmmc_mem.c
> ===================================================================
> RCS file: /cvsroot/src/sys/dev/sdmmc/sdmmc_mem.c,v
> retrieving revision 1.2.2.2
> diff -u -r1.2.2.2 sdmmc_mem.c
> --- dev/sdmmc/sdmmc_mem.c     7 Oct 2009 15:41:13 -0000       1.2.2.2
> +++ dev/sdmmc/sdmmc_mem.c     24 Nov 2009 22:23:19 -0000
> @@ -290,6 +290,8 @@
>       };
>       struct sdmmc_csd *csd = &sf->csd;
>       int e, m;
> +     int is_2gb_v1_card = 0;
> +

This is bogus.

>       if (ISSET(sc->sc_flags, SMF_SD_MODE)) {
>               /*
> @@ -309,6 +311,14 @@
>                       DPRINTF(("%s: SD Ver.1.0\n", SDMMCDEVNAME(sc)));
>                       csd->capacity = SD_CSD_CAPACITY(resp);
>                       csd->read_bl_len = SD_CSD_READ_BL_LEN(resp);
> +                     
> +                     /* Special handling for 2GB SD1.0 cards, not quite sure 
> if this
> +                        is the right way to detect it, though.
> +                      */
> +                     if ( (1<<csd->read_bl_len)*csd->capacity >= 
> 1961*1024*1024 ) {
> +                             is_2gb_v1_card = 1;
> +                     }
> +

This is also bogus.


>               default:
> @@ -347,6 +357,13 @@
>           sdmmc_chip_host_maxblklen(sc->sc_sct, sc->sc_sch));
>       if (csd->sector_size < (1 << csd->read_bl_len))
>               csd->capacity *= (1 << csd->read_bl_len) / csd->sector_size;
> +
> +     /* Handle the special case of 2GB ver1.0 SD cards */
> +     if (is_2gb_v1_card && csd->sector_size > 512) {
> +             csd->capacity *= csd->sector_size / 512;
> +             csd->sector_size = 512;
> +     }

This is also bogus.  csd->sector_size shouldn't be used for I/O
operations.  512 (behind a #define) shoould be elsewhere in the code.
The fundamental problem is that csd->sector_size is used for I/O when
it properly shuoldn't be.

>       csd->sector_size_sb = ffs(csd->sector_size) - 1;
> 
>       if (sc->sc_busclk > csd->tran_speed)
> 

Warner


Home | Main Index | Thread Index | Old Index