[PATCH] mmc-utils: Support sending Samsung eMMC 4.5 FFU

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This change adds support to invoke Samsung eMMC 4.5 field firmware update
(ffu) process.
New command was added: "emmc45 ffu".

Samsung eMMC 4.5 FFU protocol is similar with eMMC 5.0 FFU without
MODE_OPERATION.
It uses the different EXT_CSD offset.

This patch depends on patch mmc-utils: Support-sending-eMMC-v5.0 committed
by Avi Shchislowski <avi.shchislowski@xxxxxxxxxxx> and mmc: Support FFU for
Samsung eMMC v4.5 committed by Seunguk Shin <seunguk.shin@xxxxxxxxxxx>

---
 mmc.c      |  5 ++++
 mmc.h      |  1 +
 mmc_cmds.c | 87
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 mmc_cmds.h |  1 +
 4 files changed, 94 insertions(+)

diff --git a/mmc.c b/mmc.c
index 7234953..44aaf6d 100644
--- a/mmc.c
+++ b/mmc.c
@@ -115,6 +115,11 @@ static struct Command commands[] = {
 		"run eMMC 5.0 Field firmware update.\n.",
 	  NULL
 	},
+	{ do_emmc45_ffu, -2,
+	  "emmc45 ffu", "<image path> <device>\n"
+		"run eMMC 4.5 Field firmware update for samsung.\n.",
+	  NULL
+	},
 	{ 0, 0, 0, 0 }
 };
 
diff --git a/mmc.h b/mmc.h
index 19eaaba..ca4b70b 100644
--- a/mmc.h
+++ b/mmc.h
@@ -86,6 +86,7 @@
 
 #define FFU_DWONLOAD_OP        302
 #define FFU_INSTALL_OP 303
+#define FFU_SAMSUNG45_OP	304
 
 /*
  * EXT_CSD field definitions
diff --git a/mmc_cmds.c b/mmc_cmds.c
index f667d10..17e50d8 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -1271,3 +1271,90 @@ exit:
        return ret;
 }
 
+static int ffu_execute(int fw_fd, int mmc_fd)
+{
+	int ret = 0;
+	struct mmc_ioc_cmd mmc_ioc_cmd;
+	char data_buff[MMC_IOC_MAX_BYTES];
+	int file_size;
+	int data_length;
+
+	memset(data_buff, 0, sizeof(data_buff));
+	/* get file size */
+	file_size = lseek(fw_fd, 0, SEEK_END);
+	if (file_size < 0) {
+		ret = -1;
+		perror("seek file error \n");
+		goto exit;
+	}
+
+	lseek(fw_fd, 0, SEEK_SET);
+
+	if (file_size > MMC_IOC_MAX_BYTES) {
+		ret = -1;
+		perror("firmware file size error \n");
+		goto exit;
+	} else {
+		/* Read FW data from file */
+		data_length = read(fw_fd, data_buff, file_size);
+		if (data_length == -1) {
+			ret = -1;
+			goto exit;
+		}
+		/* prepare and send ioctl */
+		memset(&mmc_ioc_cmd, 0, sizeof(mmc_ioc_cmd));
+		mmc_ioc_cmd.opcode = FFU_SAMSUNG45_OP;
+		mmc_ioc_cmd.blksz = CARD_BLOCK_SIZE;
+		mmc_ioc_cmd.blocks = (data_length + mmc_ioc_cmd.blksz - 1) /
+			mmc_ioc_cmd.blksz;
+		mmc_ioc_cmd.arg = 0;
+		mmc_ioc_cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 |
MMC_CMD_ADTC;
+		mmc_ioc_cmd.write_flag = 1;
+		mmc_ioc_cmd_set_data(mmc_ioc_cmd, data_buff);
+		ret = ioctl(mmc_fd, MMC_IOC_CMD, &mmc_ioc_cmd);
+
+		if (ret) {
+			perror("ioctl FW download");
+			goto exit;
+		}
+	}
+
+exit:
+
+	return ret;
+}
+
+int do_emmc45_ffu(int nargs, char **argv)
+{
+	int fd, fw_fd, ret;
+	char *device;
+
+	CHECK(nargs != 3, "Usage: ffu <image path> </path/to/mmcblkX> \n",
+		exit(1));
+
+	device = argv[2];
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("device open error \n");
+		exit(1);
+	}
+
+	/* open eMMC4.5 firmware image file */
+	fw_fd = open(argv[1], O_RDONLY);
+	if (fw_fd < 0) {
+		perror("open eMMC4.5 firmware file");
+		ret = -1;
+		goto exit;
+	}
+
+	ret = ffu_execute(fw_fd, fd);
+	if (ret)
+		goto exit;
+
+exit:
+	close(fd);
+	close(fw_fd);
+
+	return ret;
+}
+
diff --git a/mmc_cmds.h b/mmc_cmds.h
index 3ff3440..1ab9cd5 100644
--- a/mmc_cmds.h
+++ b/mmc_cmds.h
@@ -29,3 +29,4 @@ int do_status_get(int nargs, char **argv);
 int do_enh_area_set(int nargs, char **argv);
 int do_write_reliability_set(int nargs, char **argv);
 int do_emmc50_ffu(int nargs, char **argv);
+int do_emmc45_ffu(int nargs, char **argv);
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux