diff options
author | Grégory Soutadé <gsoutade@neotion.com> | 2014-09-15 11:47:11 -0400 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2014-09-18 18:03:36 -0400 |
commit | 994324bbabc7e9dce75322bbf839b846aca8e1d6 (patch) | |
tree | bfaa55ece5bc628076112ffcec6eb4b8f0ba0568 /drivers/mmc | |
parent | 69803d4f487fc60ce740f1fe1f0d2092d97277b6 (diff) |
mmc: Checks EXT_CSD_PARTITION_SETTING_COMPLETED before partitions computation
Checks EXT_CSD_PARTITION_SETTING_COMPLETED bit before
computing enhanced user area offset and size, and
adding mmc general purpose partitions. The two needs
EXT_CSD_PARTITION_SETTING_COMPLETED bit be set to be
valid (as described in JEDEC standard).
Warn user in case of misconfiguration.
Signed-off-by: Grégory Soutadé <gsoutade@neotion.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/core/mmc.c | 81 |
1 files changed, 44 insertions, 37 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index eb78fcd01e52..ce11d89aa305 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -301,7 +301,13 @@ static void mmc_select_card_type(struct mmc_card *card) | |||
301 | 301 | ||
302 | static void mmc_manage_enhanced_area(struct mmc_card *card, u8 *ext_csd) | 302 | static void mmc_manage_enhanced_area(struct mmc_card *card, u8 *ext_csd) |
303 | { | 303 | { |
304 | u8 hc_erase_grp_sz = 0, hc_wp_grp_sz = 0; | 304 | u8 hc_erase_grp_sz, hc_wp_grp_sz; |
305 | |||
306 | /* | ||
307 | * Disable these attributes by default | ||
308 | */ | ||
309 | card->ext_csd.enhanced_area_offset = -EINVAL; | ||
310 | card->ext_csd.enhanced_area_size = -EINVAL; | ||
305 | 311 | ||
306 | /* | 312 | /* |
307 | * Enhanced area feature support -- check whether the eMMC | 313 | * Enhanced area feature support -- check whether the eMMC |
@@ -310,43 +316,41 @@ static void mmc_manage_enhanced_area(struct mmc_card *card, u8 *ext_csd) | |||
310 | */ | 316 | */ |
311 | if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && | 317 | if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && |
312 | (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { | 318 | (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { |
313 | hc_erase_grp_sz = | 319 | if (card->ext_csd.partition_setting_completed) { |
314 | ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; | 320 | hc_erase_grp_sz = |
315 | hc_wp_grp_sz = | 321 | ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; |
316 | ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; | 322 | hc_wp_grp_sz = |
323 | ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; | ||
317 | 324 | ||
318 | /* | 325 | /* |
319 | * calculate the enhanced data area offset, in bytes | 326 | * calculate the enhanced data area offset, in bytes |
320 | */ | 327 | */ |
321 | card->ext_csd.enhanced_area_offset = | 328 | card->ext_csd.enhanced_area_offset = |
322 | (ext_csd[139] << 24) + (ext_csd[138] << 16) + | 329 | (ext_csd[139] << 24) + (ext_csd[138] << 16) + |
323 | (ext_csd[137] << 8) + ext_csd[136]; | 330 | (ext_csd[137] << 8) + ext_csd[136]; |
324 | if (mmc_card_blockaddr(card)) | 331 | if (mmc_card_blockaddr(card)) |
325 | card->ext_csd.enhanced_area_offset <<= 9; | 332 | card->ext_csd.enhanced_area_offset <<= 9; |
326 | /* | 333 | /* |
327 | * calculate the enhanced data area size, in kilobytes | 334 | * calculate the enhanced data area size, in kilobytes |
328 | */ | 335 | */ |
329 | card->ext_csd.enhanced_area_size = | 336 | card->ext_csd.enhanced_area_size = |
330 | (ext_csd[142] << 16) + (ext_csd[141] << 8) + | 337 | (ext_csd[142] << 16) + (ext_csd[141] << 8) + |
331 | ext_csd[140]; | 338 | ext_csd[140]; |
332 | card->ext_csd.enhanced_area_size *= | 339 | card->ext_csd.enhanced_area_size *= |
333 | (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); | 340 | (size_t)(hc_erase_grp_sz * hc_wp_grp_sz); |
334 | card->ext_csd.enhanced_area_size <<= 9; | 341 | card->ext_csd.enhanced_area_size <<= 9; |
335 | } else { | 342 | } else { |
336 | /* | 343 | pr_warn("%s: defines enhanced area without partition setting complete\n", |
337 | * If the enhanced area is not enabled, disable these | 344 | mmc_hostname(card->host)); |
338 | * device attributes. | 345 | } |
339 | */ | ||
340 | card->ext_csd.enhanced_area_offset = -EINVAL; | ||
341 | card->ext_csd.enhanced_area_size = -EINVAL; | ||
342 | } | 346 | } |
343 | } | 347 | } |
344 | 348 | ||
345 | static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd) | 349 | static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd) |
346 | { | 350 | { |
347 | unsigned int part_size; | ||
348 | u8 hc_erase_grp_sz = 0, hc_wp_grp_sz = 0; | ||
349 | int idx; | 351 | int idx; |
352 | u8 hc_erase_grp_sz, hc_wp_grp_sz; | ||
353 | unsigned int part_size; | ||
350 | 354 | ||
351 | /* | 355 | /* |
352 | * General purpose partition feature support -- | 356 | * General purpose partition feature support -- |
@@ -355,18 +359,21 @@ static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd) | |||
355 | */ | 359 | */ |
356 | if (ext_csd[EXT_CSD_PARTITION_SUPPORT] & | 360 | if (ext_csd[EXT_CSD_PARTITION_SUPPORT] & |
357 | EXT_CSD_PART_SUPPORT_PART_EN) { | 361 | EXT_CSD_PART_SUPPORT_PART_EN) { |
358 | if (card->ext_csd.partition_setting_completed) { | 362 | hc_erase_grp_sz = |
359 | hc_erase_grp_sz = | 363 | ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; |
360 | ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; | 364 | hc_wp_grp_sz = |
361 | hc_wp_grp_sz = | 365 | ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; |
362 | ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; | ||
363 | } | ||
364 | 366 | ||
365 | for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) { | 367 | for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) { |
366 | if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] && | 368 | if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] && |
367 | !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] && | 369 | !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] && |
368 | !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]) | 370 | !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]) |
369 | continue; | 371 | continue; |
372 | if (card->ext_csd.partition_setting_completed == 0) { | ||
373 | pr_warn("%s: has partition size defined without partition complete\n", | ||
374 | mmc_hostname(card->host)); | ||
375 | break; | ||
376 | } | ||
370 | part_size = | 377 | part_size = |
371 | (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2] | 378 | (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2] |
372 | << 16) + | 379 | << 16) + |