mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
69803d4f48
commit
994324bbab
|
@ -301,7 +301,13 @@ static void mmc_select_card_type(struct mmc_card *card)
|
||||||
|
|
||||||
static void mmc_manage_enhanced_area(struct mmc_card *card, u8 *ext_csd)
|
static void mmc_manage_enhanced_area(struct mmc_card *card, u8 *ext_csd)
|
||||||
{
|
{
|
||||||
u8 hc_erase_grp_sz = 0, hc_wp_grp_sz = 0;
|
u8 hc_erase_grp_sz, hc_wp_grp_sz;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable these attributes by default
|
||||||
|
*/
|
||||||
|
card->ext_csd.enhanced_area_offset = -EINVAL;
|
||||||
|
card->ext_csd.enhanced_area_size = -EINVAL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enhanced area feature support -- check whether the eMMC
|
* 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)
|
||||||
*/
|
*/
|
||||||
if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
|
if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
|
||||||
(ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
|
(ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
|
||||||
hc_erase_grp_sz =
|
if (card->ext_csd.partition_setting_completed) {
|
||||||
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
|
hc_erase_grp_sz =
|
||||||
hc_wp_grp_sz =
|
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
|
||||||
ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
|
hc_wp_grp_sz =
|
||||||
|
ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* calculate the enhanced data area offset, in bytes
|
* calculate the enhanced data area offset, in bytes
|
||||||
*/
|
*/
|
||||||
card->ext_csd.enhanced_area_offset =
|
card->ext_csd.enhanced_area_offset =
|
||||||
(ext_csd[139] << 24) + (ext_csd[138] << 16) +
|
(ext_csd[139] << 24) + (ext_csd[138] << 16) +
|
||||||
(ext_csd[137] << 8) + ext_csd[136];
|
(ext_csd[137] << 8) + ext_csd[136];
|
||||||
if (mmc_card_blockaddr(card))
|
if (mmc_card_blockaddr(card))
|
||||||
card->ext_csd.enhanced_area_offset <<= 9;
|
card->ext_csd.enhanced_area_offset <<= 9;
|
||||||
/*
|
/*
|
||||||
* calculate the enhanced data area size, in kilobytes
|
* calculate the enhanced data area size, in kilobytes
|
||||||
*/
|
*/
|
||||||
card->ext_csd.enhanced_area_size =
|
card->ext_csd.enhanced_area_size =
|
||||||
(ext_csd[142] << 16) + (ext_csd[141] << 8) +
|
(ext_csd[142] << 16) + (ext_csd[141] << 8) +
|
||||||
ext_csd[140];
|
ext_csd[140];
|
||||||
card->ext_csd.enhanced_area_size *=
|
card->ext_csd.enhanced_area_size *=
|
||||||
(size_t)(hc_erase_grp_sz * hc_wp_grp_sz);
|
(size_t)(hc_erase_grp_sz * hc_wp_grp_sz);
|
||||||
card->ext_csd.enhanced_area_size <<= 9;
|
card->ext_csd.enhanced_area_size <<= 9;
|
||||||
} else {
|
} else {
|
||||||
/*
|
pr_warn("%s: defines enhanced area without partition setting complete\n",
|
||||||
* If the enhanced area is not enabled, disable these
|
mmc_hostname(card->host));
|
||||||
* device attributes.
|
}
|
||||||
*/
|
|
||||||
card->ext_csd.enhanced_area_offset = -EINVAL;
|
|
||||||
card->ext_csd.enhanced_area_size = -EINVAL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd)
|
static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd)
|
||||||
{
|
{
|
||||||
unsigned int part_size;
|
|
||||||
u8 hc_erase_grp_sz = 0, hc_wp_grp_sz = 0;
|
|
||||||
int idx;
|
int idx;
|
||||||
|
u8 hc_erase_grp_sz, hc_wp_grp_sz;
|
||||||
|
unsigned int part_size;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* General purpose partition feature support --
|
* General purpose partition feature support --
|
||||||
|
@ -355,18 +359,21 @@ static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd)
|
||||||
*/
|
*/
|
||||||
if (ext_csd[EXT_CSD_PARTITION_SUPPORT] &
|
if (ext_csd[EXT_CSD_PARTITION_SUPPORT] &
|
||||||
EXT_CSD_PART_SUPPORT_PART_EN) {
|
EXT_CSD_PART_SUPPORT_PART_EN) {
|
||||||
if (card->ext_csd.partition_setting_completed) {
|
hc_erase_grp_sz =
|
||||||
hc_erase_grp_sz =
|
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
|
||||||
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
|
hc_wp_grp_sz =
|
||||||
hc_wp_grp_sz =
|
ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
|
||||||
ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) {
|
for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) {
|
||||||
if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] &&
|
if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] &&
|
||||||
!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] &&
|
!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] &&
|
||||||
!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2])
|
!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2])
|
||||||
continue;
|
continue;
|
||||||
|
if (card->ext_csd.partition_setting_completed == 0) {
|
||||||
|
pr_warn("%s: has partition size defined without partition complete\n",
|
||||||
|
mmc_hostname(card->host));
|
||||||
|
break;
|
||||||
|
}
|
||||||
part_size =
|
part_size =
|
||||||
(ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]
|
(ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]
|
||||||
<< 16) +
|
<< 16) +
|
||||||
|
|
Loading…
Reference in New Issue