diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2007-02-17 16:15:27 -0500 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2007-05-01 07:04:15 -0400 |
commit | 85a18ad93ec66888d85758630019b10a84257f3c (patch) | |
tree | 46b1b7f72a8d4baac51916ca4ea09884ed043822 | |
parent | de85989511f3a0e15b04d18582b23d428d6ddbbd (diff) |
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>
-rw-r--r-- | drivers/mmc/mmc.c | 25 | ||||
-rw-r--r-- | drivers/mmc/mmc_block.c | 19 | ||||
-rw-r--r-- | include/linux/mmc/card.h | 1 | ||||
-rw-r--r-- | include/linux/mmc/protocol.h | 1 |
4 files changed, 38 insertions, 8 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 2ba46273496b..f772df93a398 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) | |||
1106 | mmc_wait_for_req(host, &mrq); | 1106 | mmc_wait_for_req(host, &mrq); |
1107 | 1107 | ||
1108 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { | 1108 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { |
1109 | printk("%s: unable to read EXT_CSD, performance " | 1109 | if (card->csd.capacity == (4096 * 512)) { |
1110 | "might suffer.\n", mmc_hostname(card->host)); | 1110 | printk(KERN_ERR "%s: unable to read EXT_CSD " |
1111 | "on a possible high capacity card. " | ||
1112 | "Card will be ignored.\n", | ||
1113 | mmc_hostname(card->host)); | ||
1114 | mmc_card_set_dead(card); | ||
1115 | } else { | ||
1116 | printk(KERN_WARNING "%s: unable to read " | ||
1117 | "EXT_CSD, performance might " | ||
1118 | "suffer.\n", | ||
1119 | mmc_hostname(card->host)); | ||
1120 | } | ||
1111 | continue; | 1121 | continue; |
1112 | } | 1122 | } |
1113 | 1123 | ||
1124 | card->ext_csd.sectors = | ||
1125 | ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | | ||
1126 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | | ||
1127 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | | ||
1128 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; | ||
1129 | if (card->ext_csd.sectors) | ||
1130 | mmc_card_set_blockaddr(card); | ||
1131 | |||
1114 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { | 1132 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { |
1115 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: | 1133 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: |
1116 | card->ext_csd.hs_max_dtr = 52000000; | 1134 | card->ext_csd.hs_max_dtr = 52000000; |
@@ -1499,7 +1517,8 @@ static void mmc_setup(struct mmc_host *host) | |||
1499 | mmc_send_app_op_cond(host, host->ocr | (sd2 << 30), NULL); | 1517 | mmc_send_app_op_cond(host, host->ocr | (sd2 << 30), NULL); |
1500 | } | 1518 | } |
1501 | } else { | 1519 | } else { |
1502 | mmc_send_op_cond(host, host->ocr, NULL); | 1520 | /* The extra bit indicates that we support high capacity */ |
1521 | mmc_send_op_cond(host, host->ocr | (1 << 30), NULL); | ||
1503 | } | 1522 | } |
1504 | 1523 | ||
1505 | mmc_discover_cards(host); | 1524 | mmc_discover_cards(host); |
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index 95b0da6abe87..63fbde8756ac 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) | |||
491 | 491 | ||
492 | blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); | 492 | blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); |
493 | 493 | ||
494 | /* | 494 | if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { |
495 | * The CSD capacity field is in units of read_blkbits. | 495 | /* |
496 | * set_capacity takes units of 512 bytes. | 496 | * The EXT_CSD sector count is in number or 512 byte |
497 | */ | 497 | * sectors. |
498 | set_capacity(md->disk, card->csd.capacity << (card->csd.read_blkbits - 9)); | 498 | */ |
499 | set_capacity(md->disk, card->ext_csd.sectors); | ||
500 | } else { | ||
501 | /* | ||
502 | * The CSD capacity field is in units of read_blkbits. | ||
503 | * set_capacity takes units of 512 bytes. | ||
504 | */ | ||
505 | set_capacity(md->disk, | ||
506 | card->csd.capacity << (card->csd.read_blkbits - 9)); | ||
507 | } | ||
499 | return md; | 508 | return md; |
500 | 509 | ||
501 | err_putdisk: | 510 | err_putdisk: |
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index e45712acfac5..5d9896c260a2 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
@@ -41,6 +41,7 @@ struct mmc_csd { | |||
41 | 41 | ||
42 | struct mmc_ext_csd { | 42 | struct mmc_ext_csd { |
43 | unsigned int hs_max_dtr; | 43 | unsigned int hs_max_dtr; |
44 | unsigned int sectors; | ||
44 | }; | 45 | }; |
45 | 46 | ||
46 | struct sd_scr { | 47 | struct sd_scr { |
diff --git a/include/linux/mmc/protocol.h b/include/linux/mmc/protocol.h index c90b6768329d..d740ab94fa25 100644 --- a/include/linux/mmc/protocol.h +++ b/include/linux/mmc/protocol.h | |||
@@ -284,6 +284,7 @@ struct _mmc_csd { | |||
284 | #define EXT_CSD_BUS_WIDTH 183 /* R/W */ | 284 | #define EXT_CSD_BUS_WIDTH 183 /* R/W */ |
285 | #define EXT_CSD_HS_TIMING 185 /* R/W */ | 285 | #define EXT_CSD_HS_TIMING 185 /* R/W */ |
286 | #define EXT_CSD_CARD_TYPE 196 /* RO */ | 286 | #define EXT_CSD_CARD_TYPE 196 /* RO */ |
287 | #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ | ||
287 | 288 | ||
288 | /* | 289 | /* |
289 | * EXT_CSD field definitions | 290 | * EXT_CSD field definitions |