summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/cmd_mmc.c18
-rw-r--r--common/env_mmc.c14
-rw-r--r--drivers/dfu/dfu_mmc.c26
-rw-r--r--drivers/mmc/mmc.c18
-rw-r--r--drivers/mmc/mmc_write.c9
-rw-r--r--include/mmc.h1
-rw-r--r--include/part.h1
7 files changed, 40 insertions, 47 deletions
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
index 6b5c1ac110..1c7156f19c 100644
--- a/common/cmd_mmc.c
+++ b/common/cmd_mmc.c
@@ -312,20 +312,14 @@ static int do_mmcrpmb(cmd_tbl_t *cmdtp, int flag,
return CMD_RET_FAILURE;
}
/* Switch to the RPMB partition */
- original_part = mmc->part_num;
- if (mmc->part_num != MMC_PART_RPMB) {
- if (mmc_switch_part(curr_device, MMC_PART_RPMB) != 0)
- return CMD_RET_FAILURE;
- mmc->part_num = MMC_PART_RPMB;
- }
+ original_part = mmc->block_dev.part_num;
+ if (mmc_select_hwpart(curr_device, MMC_PART_RPMB) != 0)
+ return CMD_RET_FAILURE;
ret = cp->cmd(cmdtp, flag, argc, argv);
/* Return to original partition */
- if (mmc->part_num != original_part) {
- if (mmc_switch_part(curr_device, original_part) != 0)
- return CMD_RET_FAILURE;
- mmc->part_num = original_part;
- }
+ if (mmc_select_hwpart(curr_device, original_part) != 0)
+ return CMD_RET_FAILURE;
return ret;
}
#endif
@@ -483,7 +477,7 @@ static int do_mmc_dev(cmd_tbl_t *cmdtp, int flag,
printf("mmc%d is current device\n", curr_device);
else
printf("mmc%d(part %d) is current device\n",
- curr_device, mmc->part_num);
+ curr_device, mmc->block_dev.hwpart);
return CMD_RET_SUCCESS;
}
diff --git a/common/env_mmc.c b/common/env_mmc.c
index f182749e8b..15aa43d5e1 100644
--- a/common/env_mmc.c
+++ b/common/env_mmc.c
@@ -69,6 +69,8 @@ __weak uint mmc_get_env_part(struct mmc *mmc)
return CONFIG_SYS_MMC_ENV_PART;
}
+static unsigned char env_mmc_orig_hwpart;
+
static int mmc_set_env_part(struct mmc *mmc)
{
uint part = mmc_get_env_part(mmc);
@@ -79,11 +81,10 @@ static int mmc_set_env_part(struct mmc *mmc)
dev = 0;
#endif
- if (part != mmc->part_num) {
- ret = mmc_switch_part(dev, part);
- if (ret)
- puts("MMC partition switch failed\n");
- }
+ env_mmc_orig_hwpart = mmc->block_dev.hwpart;
+ ret = mmc_select_hwpart(dev, part);
+ if (ret)
+ puts("MMC partition switch failed\n");
return ret;
}
@@ -113,8 +114,7 @@ static void fini_mmc_for_env(struct mmc *mmc)
#ifdef CONFIG_SPL_BUILD
dev = 0;
#endif
- if (mmc_get_env_part(mmc) != mmc->part_num)
- mmc_switch_part(dev, mmc->part_num);
+ mmc_select_hwpart(dev, env_mmc_orig_hwpart);
#endif
}
diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index 7ff2a810f3..395d472e0b 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -20,23 +20,6 @@ static unsigned char *dfu_file_buf;
static long dfu_file_buf_len;
static long dfu_file_buf_filled;
-static int mmc_access_part(struct dfu_entity *dfu, struct mmc *mmc, int part)
-{
- int ret;
-
- if (part == mmc->part_num)
- return 0;
-
- ret = mmc_switch_part(dfu->data.mmc.dev_num, part);
- if (ret) {
- error("Cannot switch to partition %d\n", part);
- return ret;
- }
- mmc->part_num = part;
-
- return 0;
-}
-
static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
u64 offset, void *buf, long *len)
{
@@ -66,8 +49,9 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
}
if (dfu->data.mmc.hw_partition >= 0) {
- part_num_bkp = mmc->part_num;
- ret = mmc_access_part(dfu, mmc, dfu->data.mmc.hw_partition);
+ part_num_bkp = mmc->block_dev.hwpart;
+ ret = mmc_select_hwpart(dfu->data.mmc.dev_num,
+ dfu->data.mmc.hw_partition);
if (ret)
return ret;
}
@@ -91,12 +75,12 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
if (n != blk_count) {
error("MMC operation failed");
if (dfu->data.mmc.hw_partition >= 0)
- mmc_access_part(dfu, mmc, part_num_bkp);
+ mmc_select_hwpart(dfu->data.mmc.dev_num, part_num_bkp);
return -EIO;
}
if (dfu->data.mmc.hw_partition >= 0) {
- ret = mmc_access_part(dfu, mmc, part_num_bkp);
+ ret = mmc_select_hwpart(dfu->data.mmc.dev_num, part_num_bkp);
if (ret)
return ret;
}
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 6d88db4bb6..e6028d503f 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -238,6 +238,7 @@ static ulong mmc_bread(block_dev_desc_t *block_dev, lbaint_t start,
lbaint_t blkcnt, void *dst)
{
int dev_num = block_dev->dev;
+ int err;
lbaint_t cur, blocks_todo = blkcnt;
if (blkcnt == 0)
@@ -247,6 +248,10 @@ static ulong mmc_bread(block_dev_desc_t *block_dev, lbaint_t start,
if (!mmc)
return 0;
+ err = mmc_select_hwpart(dev_num, block_dev->hwpart);
+ if (err < 0)
+ return 0;
+
if ((start + blkcnt) > mmc->block_dev.lba) {
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
@@ -581,7 +586,7 @@ int mmc_select_hwpart(int dev_num, int hwpart)
if (!mmc)
return -ENODEV;
- if (mmc->part_num == hwpart)
+ if (mmc->block_dev.hwpart == hwpart)
return 0;
if (mmc->part_config == MMCPART_NOAVAILABLE) {
@@ -593,8 +598,6 @@ int mmc_select_hwpart(int dev_num, int hwpart)
if (ret)
return ret;
- mmc->part_num = hwpart;
-
return 0;
}
@@ -615,8 +618,10 @@ int mmc_switch_part(int dev_num, unsigned int part_num)
* Set the capacity if the switch succeeded or was intended
* to return to representing the raw device.
*/
- if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0)))
+ if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) {
ret = mmc_set_capacity(mmc, part_num);
+ mmc->block_dev.hwpart = part_num;
+ }
return ret;
}
@@ -1326,7 +1331,7 @@ static int mmc_startup(struct mmc *mmc)
mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
}
- err = mmc_set_capacity(mmc, mmc->part_num);
+ err = mmc_set_capacity(mmc, mmc->block_dev.hwpart);
if (err)
return err;
@@ -1467,6 +1472,7 @@ static int mmc_startup(struct mmc *mmc)
/* fill in device description */
mmc->block_dev.lun = 0;
+ mmc->block_dev.hwpart = 0;
mmc->block_dev.type = 0;
mmc->block_dev.blksz = mmc->read_bl_len;
mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
@@ -1626,7 +1632,7 @@ int mmc_start_init(struct mmc *mmc)
return err;
/* The internal partition reset to user partition(0) at every CMD0*/
- mmc->part_num = 0;
+ mmc->block_dev.hwpart = 0;
/* Test for SD version 2 */
err = mmc_send_if_cond(mmc);
diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
index 6733314942..79b8c4d808 100644
--- a/drivers/mmc/mmc_write.c
+++ b/drivers/mmc/mmc_write.c
@@ -78,6 +78,10 @@ unsigned long mmc_berase(block_dev_desc_t *block_dev, lbaint_t start,
if (!mmc)
return -1;
+ err = mmc_select_hwpart(dev_num, block_dev->hwpart);
+ if (err < 0)
+ return -1;
+
/*
* We want to see if the requested start or total block count are
* unaligned. We discard the whole numbers and only care about the
@@ -172,11 +176,16 @@ ulong mmc_bwrite(block_dev_desc_t *block_dev, lbaint_t start, lbaint_t blkcnt,
{
int dev_num = block_dev->dev;
lbaint_t cur, blocks_todo = blkcnt;
+ int err;
struct mmc *mmc = find_mmc_device(dev_num);
if (!mmc)
return 0;
+ err = mmc_select_hwpart(dev_num, block_dev->hwpart);
+ if (err < 0)
+ return 0;
+
if (mmc_set_blocklen(mmc, mmc->write_bl_len))
return 0;
diff --git a/include/mmc.h b/include/mmc.h
index 9254b716b9..465daeb085 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -364,7 +364,6 @@ struct mmc {
u8 part_attr;
u8 wr_rel_set;
char part_config;
- char part_num;
uint tran_speed;
uint read_bl_len;
uint write_bl_len;
diff --git a/include/part.h b/include/part.h
index 8396ed178e..4d00e220e4 100644
--- a/include/part.h
+++ b/include/part.h
@@ -18,6 +18,7 @@ struct block_dev_desc {
unsigned char part_type; /* partition type */
unsigned char target; /* target SCSI ID */
unsigned char lun; /* target LUN */
+ unsigned char hwpart; /* HW partition, e.g. for eMMC */
unsigned char type; /* device type */
unsigned char removable; /* removable device */
#ifdef CONFIG_LBA48
OpenPOWER on IntegriCloud