aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2007-07-23 00:34:07 +0200
committerPierre Ossman <drzeus@drzeus.cx>2007-09-23 09:14:53 +0200
commitd7604d76351f7745d0e62d9f2bbcbb917c9013f3 (patch)
treec0f0b70a9577156a7add1359dd4dc22e8053c413
parentadf66a0dc5e8be8d4e64f3c2114f9b175558235b (diff)
mmc: read ext_csd version number
Make sure we do not try to parse a structure we do not understand. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
-rw-r--r--drivers/mmc/core/mmc.c24
-rw-r--r--include/linux/mmc/mmc.h1
2 files changed, 18 insertions, 7 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 258fe73eeaa..cdc38b43b79 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -161,6 +161,7 @@ static int mmc_read_ext_csd(struct mmc_card *card)
{
int err;
u8 *ext_csd;
+ unsigned int ext_csd_struct;
BUG_ON(!card);
@@ -209,13 +210,22 @@ static int mmc_read_ext_csd(struct mmc_card *card)
goto out;
}
- 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);
+ ext_csd_struct = ext_csd[EXT_CSD_REV];
+ if (ext_csd_struct > 2) {
+ printk("%s: unrecognised EXT_CSD structure version %d\n",
+ mmc_hostname(card->host), ext_csd_struct);
+ return -EINVAL;
+ }
+
+ if (ext_csd_struct >= 2) {
+ 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:
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index e3ed9b95040..d1d6cbcc151 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -227,6 +227,7 @@ struct _mmc_csd {
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
#define EXT_CSD_HS_TIMING 185 /* R/W */
#define EXT_CSD_CARD_TYPE 196 /* RO */
+#define EXT_CSD_REV 192 /* RO */
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
/*