diff options
author | Stephen Warren <swarren@nvidia.com> | 2015-12-07 11:38:49 -0700 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2016-01-13 21:05:19 -0500 |
commit | 873cc1d7775ed5de07e6722c7ff423080c2e8f71 (patch) | |
tree | 6540fea6fcf0edf8da6904f168e2dbd75259dc56 /drivers/mmc | |
parent | 7c4213f6a52f35ff6ba2d97aa4eb04cbfc963b86 (diff) | |
download | u-boot-imx-873cc1d7775ed5de07e6722c7ff423080c2e8f71.zip u-boot-imx-873cc1d7775ed5de07e6722c7ff423080c2e8f71.tar.gz u-boot-imx-873cc1d7775ed5de07e6722c7ff423080c2e8f71.tar.bz2 |
mmc: store hwpart in the block device
This will allow us to have multiple block device structs each referring
to the same eMMC device, yet different HW partitions.
For now, there is still a single block device per eMMC device. As before,
this block device always accesses whichever HW partition was most recently
selected. Clients wishing to make use of multiple block devices referring
to different HW partitions can simply take a copy of this block device
once it points at the correct HW partition, and use each one as they wish.
This feature will be used by the next patch.
In the future, perhaps get_device() could be enhanced to return a
dynamically allocated block device struct, to avoid the client needing to
copy it in order to maintain multiple block devices. However, this would
require all users to be updated to free those block device structs at some
point, which is rather a large change.
Most callers of mmc_switch_part() wish to permanently switch the default
MMC block device's HW partition. Enhance mmc_switch_part() so that it does
this. This removes the need for callers to do this. However,
common/env_mmc.c needs to save and restore the current HW partition. Make
it do this more explicitly.
Replace use of mmc_switch_part() with mmc_select_hwpart() in order to
remove duplicate code that skips the call if that HW partition is already
selected.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/mmc.c | 18 | ||||
-rw-r--r-- | drivers/mmc/mmc_write.c | 9 |
2 files changed, 21 insertions, 6 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 6d88db4..e6028d5 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 6733314..79b8c4d 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; |