diff options
| author | Pierre Ossman <drzeus@drzeus.cx> | 2007-07-22 18:34:07 -0400 |
|---|---|---|
| committer | Pierre Ossman <drzeus@drzeus.cx> | 2007-09-23 03:14:53 -0400 |
| commit | d7604d76351f7745d0e62d9f2bbcbb917c9013f3 (patch) | |
| tree | c0f0b70a9577156a7add1359dd4dc22e8053c413 | |
| parent | adf66a0dc5e8be8d4e64f3c2114f9b175558235b (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.c | 24 | ||||
| -rw-r--r-- | include/linux/mmc/mmc.h | 1 |
2 files changed, 18 insertions, 7 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 258fe73eeaa7..cdc38b43b799 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) | |||
| 161 | { | 161 | { |
| 162 | int err; | 162 | int err; |
| 163 | u8 *ext_csd; | 163 | u8 *ext_csd; |
| 164 | unsigned int ext_csd_struct; | ||
| 164 | 165 | ||
| 165 | BUG_ON(!card); | 166 | BUG_ON(!card); |
| 166 | 167 | ||
| @@ -209,13 +210,22 @@ static int mmc_read_ext_csd(struct mmc_card *card) | |||
| 209 | goto out; | 210 | goto out; |
| 210 | } | 211 | } |
| 211 | 212 | ||
| 212 | card->ext_csd.sectors = | 213 | ext_csd_struct = ext_csd[EXT_CSD_REV]; |
| 213 | ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | | 214 | if (ext_csd_struct > 2) { |
| 214 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | | 215 | printk("%s: unrecognised EXT_CSD structure version %d\n", |
| 215 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | | 216 | mmc_hostname(card->host), ext_csd_struct); |
| 216 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; | 217 | return -EINVAL; |
| 217 | if (card->ext_csd.sectors) | 218 | } |
| 218 | mmc_card_set_blockaddr(card); | 219 | |
| 220 | if (ext_csd_struct >= 2) { | ||
| 221 | card->ext_csd.sectors = | ||
| 222 | ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | | ||
| 223 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | | ||
| 224 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | | ||
| 225 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; | ||
| 226 | if (card->ext_csd.sectors) | ||
| 227 | mmc_card_set_blockaddr(card); | ||
| 228 | } | ||
| 219 | 229 | ||
| 220 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { | 230 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { |
| 221 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: | 231 | 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 e3ed9b95040e..d1d6cbcc1514 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h | |||
| @@ -227,6 +227,7 @@ struct _mmc_csd { | |||
| 227 | #define EXT_CSD_BUS_WIDTH 183 /* R/W */ | 227 | #define EXT_CSD_BUS_WIDTH 183 /* R/W */ |
| 228 | #define EXT_CSD_HS_TIMING 185 /* R/W */ | 228 | #define EXT_CSD_HS_TIMING 185 /* R/W */ |
| 229 | #define EXT_CSD_CARD_TYPE 196 /* RO */ | 229 | #define EXT_CSD_CARD_TYPE 196 /* RO */ |
| 230 | #define EXT_CSD_REV 192 /* RO */ | ||
| 230 | #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ | 231 | #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ |
| 231 | 232 | ||
| 232 | /* | 233 | /* |
