diff mbox

[U-Boot,1/3] dfu: mmc: Provide support for eMMC boot partition access

Message ID 1396255729-6573-2-git-send-email-l.majewski@samsung.com
State Superseded
Delegated to: Marek Vasut
Headers show

Commit Message

Łukasz Majewski March 31, 2014, 8:48 a.m. UTC
Before this patch it was only possible to access only the default eMMC
partition. By partition selection I mean the access to eMMC via ext_csd[179]
register programming.

It sometimes happens that it is necessary to write to other partitions.
This patch adds extra attributes to "mmc" sub type of the dfu_alt_info
variable (e.g. boot-mmc.bin mmc 0 200 mmcpart 1;)

It saves the original boot value and restores it after storing the file.

Such definition will not impact other definitions of the "mmc" dfu
partitions specifier.

Change-Id: I34069510eb27aa80794189d2d13cdb97e54ba83d
Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
---
 drivers/dfu/dfu_mmc.c |   48 ++++++++++++++++++++++++++++++++++++++++++++++--
 include/dfu.h         |    5 +++++
 2 files changed, 51 insertions(+), 2 deletions(-)

Comments

Marek Vasut March 31, 2014, 8:59 a.m. UTC | #1
On Monday, March 31, 2014 at 10:48:47 AM, Lukasz Majewski wrote:
> Before this patch it was only possible to access only the default eMMC
> partition. By partition selection I mean the access to eMMC via
> ext_csd[179] register programming.
> 
> It sometimes happens that it is necessary to write to other partitions.
> This patch adds extra attributes to "mmc" sub type of the dfu_alt_info
> variable (e.g. boot-mmc.bin mmc 0 200 mmcpart 1;)
> 
> It saves the original boot value and restores it after storing the file.
> 
> Such definition will not impact other definitions of the "mmc" dfu
> partitions specifier.
> 
> Change-Id: I34069510eb27aa80794189d2d13cdb97e54ba83d
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>

Please strip the Change-Id .

Best regards,
Marek Vasut
Łukasz Majewski March 31, 2014, 9:14 a.m. UTC | #2
Hi Marek,

> On Monday, March 31, 2014 at 10:48:47 AM, Lukasz Majewski wrote:
> > Before this patch it was only possible to access only the default
> > eMMC partition. By partition selection I mean the access to eMMC via
> > ext_csd[179] register programming.
> > 
> > It sometimes happens that it is necessary to write to other
> > partitions. This patch adds extra attributes to "mmc" sub type of
> > the dfu_alt_info variable (e.g. boot-mmc.bin mmc 0 200 mmcpart 1;)
> > 
> > It saves the original boot value and restores it after storing the
> > file.
> > 
> > Such definition will not impact other definitions of the "mmc" dfu
> > partitions specifier.
> > 
> > Change-Id: I34069510eb27aa80794189d2d13cdb97e54ba83d
> > Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> 
> Please strip the Change-Id .

Damn, I always forgot about stripping them out.

> 
> Best regards,
> Marek Vasut
diff mbox

Patch

diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
index 651cfff..a7224b6 100644
--- a/drivers/dfu/dfu_mmc.c
+++ b/drivers/dfu/dfu_mmc.c
@@ -18,11 +18,29 @@  static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE)
 				dfu_file_buf[CONFIG_SYS_DFU_MAX_FILE_SIZE];
 static long dfu_file_buf_len;
 
+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->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)
 {
 	struct mmc *mmc = find_mmc_device(dfu->dev_num);
 	u32 blk_start, blk_count, n = 0;
+	int ret, part_num_bkp = 0;
 
 	/*
 	 * We must ensure that we work in lba_blk_size chunks, so ALIGN
@@ -39,6 +57,13 @@  static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
 		return -EINVAL;
 	}
 
+	if (dfu->data.mmc.partition_access != DFU_NOT_SUPPORTED) {
+		part_num_bkp = mmc->part_num;
+		ret = mmc_access_part(dfu, mmc, dfu->data.mmc.partition_access);
+		if (ret)
+			return ret;
+	}
+
 	debug("%s: %s dev: %d start: %d cnt: %d buf: 0x%p\n", __func__,
 	      op == DFU_OP_READ ? "MMC READ" : "MMC WRITE", dfu->dev_num,
 	      blk_start, blk_count, buf);
@@ -57,9 +82,17 @@  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.partition_access != DFU_NOT_SUPPORTED)
+			mmc_access_part(dfu, mmc, part_num_bkp);
 		return -EIO;
 	}
 
+	if (dfu->data.mmc.partition_access != DFU_NOT_SUPPORTED) {
+		ret = mmc_access_part(dfu, mmc, part_num_bkp);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -193,12 +226,22 @@  int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
 	char *st;
 
 	dfu->dev_type = DFU_DEV_MMC;
+	dfu->data.mmc.partition_access = DFU_NOT_SUPPORTED;
+
 	st = strsep(&s, " ");
 	if (!strcmp(st, "mmc")) {
 		dfu->layout = DFU_RAW_ADDR;
 		dfu->data.mmc.lba_start = simple_strtoul(s, &s, 16);
-		dfu->data.mmc.lba_size = simple_strtoul(++s, &s, 16);
+		s++;
+		dfu->data.mmc.lba_size = simple_strtoul(s, &s, 16);
 		dfu->data.mmc.lba_blk_size = get_mmc_blk_size(dfu->dev_num);
+		if (*s) {
+			s++;
+			st = strsep(&s, " ");
+			if (!strcmp(st, "mmcpart"))
+				dfu->data.mmc.partition_access =
+					simple_strtoul(s, &s, 0);
+		}
 	} else if (!strcmp(st, "fat")) {
 		dfu->layout = DFU_FS_FAT;
 	} else if (!strcmp(st, "ext4")) {
@@ -236,7 +279,8 @@  int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
 
 	if (dfu->layout == DFU_FS_EXT4 || dfu->layout == DFU_FS_FAT) {
 		dfu->data.mmc.dev = simple_strtoul(s, &s, 10);
-		dfu->data.mmc.part = simple_strtoul(++s, &s, 10);
+		s++;
+		dfu->data.mmc.part = simple_strtoul(s, &s, 10);
 	}
 
 	dfu->read_medium = dfu_read_medium_mmc;
diff --git a/include/dfu.h b/include/dfu.h
index 6c71ecb..751f0fd 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -37,12 +37,17 @@  enum dfu_op {
 	DFU_OP_WRITE,
 };
 
+#define DFU_NOT_SUPPORTED -1
+
 struct mmc_internal_data {
 	/* RAW programming */
 	unsigned int lba_start;
 	unsigned int lba_size;
 	unsigned int lba_blk_size;
 
+	/* Partition access */
+	int partition_access;
+
 	/* FAT/EXT */
 	unsigned int dev;
 	unsigned int part;