aboutsummaryrefslogtreecommitdiff
path: root/drivers/dfu
diff options
context:
space:
mode:
authorPatrick Delaunay <patrick.delaunay@foss.st.com>2022-01-18 10:26:21 +0100
committerTom Rini <trini@konsulko.com>2022-01-28 17:58:41 -0500
commit562274730a959094c85e1be5e0eb344ea272432a (patch)
tree348e13d87ae05eab5a98c68db962912aafe6d28d /drivers/dfu
parent1a4942f1d90f3fe883db27fcad11f21e5698d46c (diff)
downloadu-boot-562274730a959094c85e1be5e0eb344ea272432a.zip
u-boot-562274730a959094c85e1be5e0eb344ea272432a.tar.gz
u-boot-562274730a959094c85e1be5e0eb344ea272432a.tar.bz2
dfu: mtd: skip empty pages when writing page for UBI partition
Align the DFU MTD backend for the UBI partitions with the mtd command write behavior when the option .dontskipff is not used: don't write the empty pages (full of 0xFF); it is not required for UBI, see [1] for details. This patch avoids the "free space fixup" procedure in the kernel [2] and allows to program a UBIFS volume generated by mkfs.ubifs without the option -F, --space-fixup. The MTD DFU backend implements this behavior introduced on DFU NAND backend by the commit 13cb7cc9e8e4 ("dfu: Add option to skip empty pages when flashing UBI images to NAND") and also supported by the command nand by CONFIG_CMD_NAND_TRIMFFS and by commit c9494866df83 ("cmd_nand: add nand write.trimffs command"). [1] http://www.linux-mtd.infradead.org/doc/ubi.html#L_flasher_algo [2] http://www.linux-mtd.infradead.org/faq/ubifs.html#L_free_space_fixup Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
Diffstat (limited to 'drivers/dfu')
-rw-r--r--drivers/dfu/dfu_mtd.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/dfu/dfu_mtd.c b/drivers/dfu/dfu_mtd.c
index 0b7f177..cce9ce0 100644
--- a/drivers/dfu/dfu_mtd.c
+++ b/drivers/dfu/dfu_mtd.c
@@ -18,6 +18,20 @@ static bool mtd_is_aligned_with_block_size(struct mtd_info *mtd, u64 size)
return !do_div(size, mtd->erasesize);
}
+/* Logic taken from cmd/mtd.c:mtd_oob_write_is_empty() */
+static bool mtd_page_is_empty(struct mtd_oob_ops *op)
+{
+ int i;
+
+ for (i = 0; i < op->len; i++)
+ if (op->datbuf[i] != 0xff)
+ return false;
+
+ /* oob is not used, with MTD_OPS_AUTO_OOB & ooblen=0 */
+
+ return true;
+}
+
static int mtd_block_op(enum dfu_op op, struct dfu_entity *dfu,
u64 offset, void *buf, long *len)
{
@@ -129,8 +143,14 @@ static int mtd_block_op(enum dfu_op op, struct dfu_entity *dfu,
if (op == DFU_OP_READ)
ret = mtd_read_oob(mtd, off, &io_op);
- else
+ else if (has_pages && dfu->data.mtd.ubi && mtd_page_is_empty(&io_op)) {
+ /* in case of ubi partition, do not write an empty page, only skip it */
+ ret = 0;
+ io_op.retlen = mtd->writesize;
+ io_op.oobretlen = mtd->oobsize;
+ } else {
ret = mtd_write_oob(mtd, off, &io_op);
+ }
if (ret) {
printf("Failure while %s at offset 0x%llx\n",