Message ID | 1300687405-4078-1-git-send-email-r65388@freescale.com |
---|---|
State | Superseded |
Headers | show |
Hi Terry, On Mon, Mar 21, 2011 at 7:03 AM, Terry Lv <r65388@freescale.com> wrote: > MMC driver may wrongly regconize some 2GB eMMC as high capacity card. > > This patch is based on the patch picked from community. > > fc8a0985c2846292312556cba10b8a4182f55967 > From: Hanumath Prasad <hanumath.prasad@stericsson.com> > Date: Tue, 10 Aug 2010 18:01:45 -0700 > Subject: [PATCH] mmc: only set blockaddressed for > 2GiB cards > > A non-zero value of SEC_COUNT does not indicate that the card is sector > addressed. According to the MMC specification, cards > with a densitygreater than 2GiB are sector addressed. > > Signed-off-by: Terry Lv <r65388@freescale.com> > --- > drivers/mmc/mmc.c | 4 +++- > 1 files changed, 3 insertions(+), 1 deletions(-) > > diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c > index 6805b33..6f97911 100644 > --- a/drivers/mmc/mmc.c > +++ b/drivers/mmc/mmc.c > @@ -399,7 +399,9 @@ int mmc_change_freq(struct mmc *mmc) > if (err) > return err; > > - if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215]) > + /* Cards with density > 2GiB are sector addressed */ > + if ((ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215]) && > + (mmc->capacity > (2u * 1024 * 1024 * 1024) / 512)) > mmc->high_capacity = 1; > > cardtype = ext_csd[196] & 0xf; > -- I have applied your patch, but, with Toshiba v4.41 2GB it doesn't work, because mmc->capacity is equal to 1962934272 and you are instead using the block's number , not byte's number. Changing the patch in the following way it works in my case. - if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215]) + printf ("mmc->capacity = %lu\n", (long unsigned int)mmc->capacity); + if ((ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215]) && + (mmc->capacity > (2u * 1024 * 1024 * 1024))) { mmc->high_capacity = 1; + printf("Setting high capacity\n"); + } Fixing that the situation is also better for me, in fact in my situation I was not able to read 256KB starting from sector 8 (512 bytes size). The card status reported ADDRESS_MISALIGN. That happened because mmc_read_blocks was using high_capacity addressing way, wrong for me. I've also noticed that the capacity variable (expressed in number of bytes) has to be re-calculated differently if <=2GB (high_capacity=0) or if >2GB (high_capacity=1). So capacity calculation depends on high_capacity. But curiously high_capacity depends on capacity. Not nice! Looking at JEDEC Standard No. 84-A441 at the end of pag.42 we have to use mmc_send_op_cond. So I guess: mmc_init calls mmc_send_op_cond that set high_capacity, than it calls mmc_startup, that, with MMC_CMD_SEND_CSD command, set the capacity, using values in CSD register. So I guess that mmc_change_freq should not recalculate high_capacity. It seems better, isn't it? Regards, Raffaele
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 6805b33..6f97911 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -399,7 +399,9 @@ int mmc_change_freq(struct mmc *mmc) if (err) return err; - if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215]) + /* Cards with density > 2GiB are sector addressed */ + if ((ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215]) && + (mmc->capacity > (2u * 1024 * 1024 * 1024) / 512)) mmc->high_capacity = 1; cardtype = ext_csd[196] & 0xf;