aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/README.dfu5
-rw-r--r--drivers/dfu/Kconfig8
-rw-r--r--drivers/dfu/dfu_sf.c52
-rw-r--r--include/dfu.h2
4 files changed, 67 insertions, 0 deletions
diff --git a/doc/README.dfu b/doc/README.dfu
index f5344e2..7a2b5f1 100644
--- a/doc/README.dfu
+++ b/doc/README.dfu
@@ -33,6 +33,7 @@ Configuration Options:
CONFIG_DFU_NAND
CONFIG_DFU_RAM
CONFIG_DFU_SF
+ CONFIG_DFU_SF_PART
CONFIG_CMD_DFU
Environment variables:
@@ -89,6 +90,10 @@ Commands:
cmd: dfu 0 sf <dev>
each element in "dfu_alt_info" =
<name> ram <offset> <size> raw access to sf device
+ <name> part <dev> <part_id> raw acces to partition
+ <name> partubi <dev> <part_id> raw acces to ubi partition
+
+ with <partid> is the MTD partition index
Host tools:
When U-Boot runs the dfu stack, the DFU host tools can be used
diff --git a/drivers/dfu/Kconfig b/drivers/dfu/Kconfig
index 4692736..1cbec81 100644
--- a/drivers/dfu/Kconfig
+++ b/drivers/dfu/Kconfig
@@ -46,5 +46,13 @@ config DFU_SF
This option enables using DFU to read and write to SPI flash based
storage.
+config DFU_SF_PART
+ bool "MTD partition support for SPI flash back end"
+ depends on DFU_SF && CMD_MTDPARTS
+ default y
+ help
+ This option enables the support of "part" and "partubi" target in
+ SPI flash DFU back end.
+
endif
endmenu
diff --git a/drivers/dfu/dfu_sf.c b/drivers/dfu/dfu_sf.c
index b78fcfd..0fdbfae 100644
--- a/drivers/dfu/dfu_sf.c
+++ b/drivers/dfu/dfu_sf.c
@@ -10,6 +10,8 @@
#include <dfu.h>
#include <spi.h>
#include <spi_flash.h>
+#include <jffs2/load_kernel.h>
+#include <linux/mtd/mtd.h>
static int dfu_get_medium_size_sf(struct dfu_entity *dfu, u64 *size)
{
@@ -52,11 +54,33 @@ static int dfu_write_medium_sf(struct dfu_entity *dfu,
static int dfu_flush_medium_sf(struct dfu_entity *dfu)
{
+ u64 off, length;
+
+ if (!CONFIG_IS_ENABLED(DFU_SF_PART) || !dfu->data.sf.ubi)
+ return 0;
+
+ /* in case of ubi partition, erase rest of the partition */
+ off = find_sector(dfu, dfu->data.sf.start, dfu->offset);
+ /* last write ended with unaligned length jump to next */
+ if (off != dfu->data.sf.start + dfu->offset)
+ off += dfu->data.sf.dev->sector_size;
+ length = dfu->data.sf.start + dfu->data.sf.size - off;
+ if (length)
+ return spi_flash_erase(dfu->data.sf.dev, off, length);
+
return 0;
}
static unsigned int dfu_polltimeout_sf(struct dfu_entity *dfu)
{
+ /*
+ * Currently, Poll Timeout != 0 is only needed on nand
+ * ubi partition, as sectors which are not used need
+ * to be erased
+ */
+ if (CONFIG_IS_ENABLED(DFU_SF_PART) && dfu->data.sf.ubi)
+ return DFU_MANIFEST_POLL_TIMEOUT;
+
return DFU_DEFAULT_POLL_TIMEOUT;
}
@@ -133,6 +157,34 @@ int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr, char *s)
dfu->data.sf.start = simple_strtoul(s, &s, 16);
s++;
dfu->data.sf.size = simple_strtoul(s, &s, 16);
+ } else if (CONFIG_IS_ENABLED(DFU_SF_PART) &&
+ (!strcmp(st, "part") || !strcmp(st, "partubi"))) {
+ char mtd_id[32];
+ struct mtd_device *mtd_dev;
+ u8 part_num;
+ struct part_info *pi;
+ int ret, dev, part;
+
+ dfu->layout = DFU_RAW_ADDR;
+
+ dev = simple_strtoul(s, &s, 10);
+ s++;
+ part = simple_strtoul(s, &s, 10);
+
+ sprintf(mtd_id, "%s%d,%d", "nor", dev, part - 1);
+ printf("using id '%s'\n", mtd_id);
+
+ mtdparts_init();
+
+ ret = find_dev_and_part(mtd_id, &mtd_dev, &part_num, &pi);
+ if (ret != 0) {
+ printf("Could not locate '%s'\n", mtd_id);
+ return -1;
+ }
+ dfu->data.sf.start = pi->offset;
+ dfu->data.sf.size = pi->size;
+ if (!strcmp(st, "partubi"))
+ dfu->data.sf.ubi = 1;
} else {
printf("%s: Memory layout (%s) not supported!\n", __func__, st);
spi_flash_free(dfu->data.sf.dev);
diff --git a/include/dfu.h b/include/dfu.h
index 145a157..bf51ab7 100644
--- a/include/dfu.h
+++ b/include/dfu.h
@@ -77,6 +77,8 @@ struct sf_internal_data {
/* RAW programming */
u64 start;
u64 size;
+ /* for sf/ubi use */
+ unsigned int ubi;
};
#define DFU_NAME_SIZE 32