This is extremely similar to the MMC backend, but there are some notable
differences.
Works with a DFU string like
scsi 4=u-boot-bin part 11
Where "4" is the SCSI dev number (sequential LUN across all SCSI devices)
and "11" is the partition number.
Signed-off-by: Caleb Connolly
---
doc/usage/dfu.rst | 31
drivers/dfu/Kconfig| 7 +
drivers/dfu/Makefile | 1 +
drivers/dfu/dfu.c | 5 +-
drivers/dfu/dfu_scsi.c | 437 +
include/dfu.h | 26 +++
6 files changed, 506 insertions(+), 1 deletion(-)
diff --git a/doc/usage/dfu.rst b/doc/usage/dfu.rst
index 8cc09c308d82..dc4f8d672f99 100644
--- a/doc/usage/dfu.rst
+++ b/doc/usage/dfu.rst
@@ -166,8 +166,38 @@ mmc
Please note that this means the user will be able to execute any
arbitrary commands just like in the u-boot's shell.
+scsi
+for UFS storage::
+
+dfu 0 scsi
+
+each element in *dfu_alt_info* being
+
+* raw raw access to SCSI LUN
+* part raw access to partition
+* fatfile in FAT partition
+* ext4 file in EXT4 partition
+* skip 0 0ignore flashed data
+* script 0 0 execute commands in shell
+
+with
+
+size
+is the size of the access area (hexadecimal without "0x")
+or 0 which means whole device
+partid
+is the GPT or DOS partition index.
+dev
+is the SCSI LU (Logical Unit) index (decimal only)
+
+A value of environment variable *dfu_alt_info* for UFS could be::
+
+u-boot part 4;bl2 raw 0x1e 0x1d
+
+See mmc section above for details on the skip and script types.
+
nand
raw slc nand device::
dfu 0 nand
@@ -277,8 +307,9 @@ alternate list separated by '&' with the same format for
each ::
mmc =;;
nand =;;
ram =;;
+scsi =;;
sf =;;
mtd =;;
virt =;;
diff --git a/drivers/dfu/Kconfig b/drivers/dfu/Kconfig
index 0360d9da1427..158c660e6c4e 100644
--- a/drivers/dfu/Kconfig
+++ b/drivers/dfu/Kconfig
@@ -86,8 +86,15 @@ config DFU_VIRT
This option enables using DFU to read and write to VIRTUAL device
used at board level to manage specific behavior
(OTP update for example).
+config DFU_SCSI
+ bool "SCSI flash back end for DFU"
+ help
+ This option enables using DFU to read and write to SCSI devices
+ used at board level to manage specific behavior
+ (OTP update for example).
+
config SET_DFU_ALT_INFO
bool "Dynamic set of DFU alternate information"
help
This option allows to call the function set_dfu_alt_info to
diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile
index dfbf64da6677..3b3ba0994b3a 100644
--- a/drivers/dfu/Makefile
+++ b/drivers/dfu/Makefile
@@ -10,4 +10,5 @@ obj-$(CONFIG_$(SPL_)DFU_NAND) += dfu_nand.o
obj-$(CONFIG_$(SPL_)DFU_RAM) += dfu_ram.o
obj-$(CONFIG_$(SPL_)DFU_SF) += dfu_sf.o
obj-$(CONFIG_$(SPL_)DFU_WRITE_ALT) += dfu_alt.o
obj-$(CONFIG_$(SPL_)DFU_VIRT) += dfu_virt.o
+obj-$(CONFIG_$(SPL_)DFU_SCSI) += dfu_scsi.o
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index 540d48fab77d..c81fa7724268 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -547,8 +547,11 @@ static int dfu_fill_entity(struct dfu_entity *dfu, char
*s, int alt,
return -1;
} else if (strcmp(interface, "virt") == 0) {
if (dfu_fill_entity_virt(dfu, devstr, argv, argc))
return -1;
+ } else if (strcmp(interface, "scsi") == 0) {
+ if (dfu_fill_entity_scsi(dfu, devstr, argv, argc))
+ return -1;
} else {
printf("%s: Device %s not (yet) supported!\n",
__func__, interface);
return -1;
@@ -643,9 +646,9 @@ int dfu_config_entities(char *env, char *interface, char
*devstr)
const char *dfu_get_dev_type(enum dfu_device_type t)
{
const char *const dev_t[] = {NULL, "eMMC", "OneNAND", "NAND", "RAM",
-"SF", "MTD", "VIRT"};
+"SF", "MTD", "VIRT", "SCSI"};
return dev_t[t];
}
const char *dfu_get_layout(enum dfu_layout l)
diff --git a/drivers/dfu/dfu_scsi.c b/drivers/dfu/dfu_scsi.c
new file mode 100644
index ..63c3bcffe769
--- /dev/null
+++ b/drivers/dfu/dfu_scsi.c
@@ -0,0 +1,437 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * DFU SCSI backend (based on MMC backend).
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * author: Lukasz Majewski
+ * Copyright (C) 2024 Linaro Ltd.
+ */
+
+#define LOG_DEBUG
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static unsigned char *dfu_file_buf;
+static u64 dfu_file_buf_len;
+static u64 dfu_file_buf_offset;
+
+#define scsi_get_blk_desc(dev) ((s