aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorGrégory Soutadé <gsoutade@neotion.com>2014-09-15 11:47:11 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2014-09-18 18:03:36 -0400
commit994324bbabc7e9dce75322bbf839b846aca8e1d6 (patch)
treebfaa55ece5bc628076112ffcec6eb4b8f0ba0568 /drivers/mmc
parent69803d4f487fc60ce740f1fe1f0d2092d97277b6 (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.c81
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
302static void mmc_manage_enhanced_area(struct mmc_card *card, u8 *ext_csd) 302static 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
345static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd) 349static 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) +