diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2007-02-17 22:15:27 +0100 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2007-05-01 13:04:15 +0200 |
commit | 85a18ad93ec66888d85758630019b10a84257f3c (patch) | |
tree | 46b1b7f72a8d4baac51916ca4ea09884ed043822 /drivers | |
parent | de85989511f3a0e15b04d18582b23d428d6ddbbd (diff) | |
download | op-kernel-dev-85a18ad93ec66888d85758630019b10a84257f3c.zip op-kernel-dev-85a18ad93ec66888d85758630019b10a84257f3c.tar.gz |
mmc: MMC sector based cards
Support for MMC 4.2 sector based cards. This tweaks the init a
bit and reads a new field out of the EXT_CSD.
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/mmc.c | 25 | ||||
-rw-r--r-- | drivers/mmc/mmc_block.c | 19 |
2 files changed, 36 insertions, 8 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 2ba4627..f772df9 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1106,11 +1106,29 @@ static void mmc_process_ext_csds(struct mmc_host *host) mmc_wait_for_req(host, &mrq); if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { - printk("%s: unable to read EXT_CSD, performance " - "might suffer.\n", mmc_hostname(card->host)); + if (card->csd.capacity == (4096 * 512)) { + printk(KERN_ERR "%s: unable to read EXT_CSD " + "on a possible high capacity card. " + "Card will be ignored.\n", + mmc_hostname(card->host)); + mmc_card_set_dead(card); + } else { + printk(KERN_WARNING "%s: unable to read " + "EXT_CSD, performance might " + "suffer.\n", + mmc_hostname(card->host)); + } continue; } + card->ext_csd.sectors = + ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | + ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | + ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | + ext_csd[EXT_CSD_SEC_CNT + 3] << 24; + if (card->ext_csd.sectors) + mmc_card_set_blockaddr(card); + switch (ext_csd[EXT_CSD_CARD_TYPE]) { case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: card->ext_csd.hs_max_dtr = 52000000; @@ -1499,7 +1517,8 @@ static void mmc_setup(struct mmc_host *host) mmc_send_app_op_cond(host, host->ocr | (sd2 << 30), NULL); } } else { - mmc_send_op_cond(host, host->ocr, NULL); + /* The extra bit indicates that we support high capacity */ + mmc_send_op_cond(host, host->ocr | (1 << 30), NULL); } mmc_discover_cards(host); diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index 95b0da6..63fbde8 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c @@ -491,11 +491,20 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); - /* - * The CSD capacity field is in units of read_blkbits. - * set_capacity takes units of 512 bytes. - */ - set_capacity(md->disk, card->csd.capacity << (card->csd.read_blkbits - 9)); + if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { + /* + * The EXT_CSD sector count is in number or 512 byte + * sectors. + */ + set_capacity(md->disk, card->ext_csd.sectors); + } else { + /* + * The CSD capacity field is in units of read_blkbits. + * set_capacity takes units of 512 bytes. + */ + set_capacity(md->disk, + card->csd.capacity << (card->csd.read_blkbits - 9)); + } return md; err_putdisk: |