Hi Patrick, > Add the support of MTD partition for the MTD backend. > > The expected dfu_alt_info for one alternate on the mtd device : > <name> part <part_id> > <name> partubi <part_id> > > "partubi" also erase up to the end of the partition after write > operation. > > For example: dfu_alt_info = "spl part 1;u-boot part 2; UBI partubi 3"
As in the previous comments - please add this info to dedicated doc entry. > > U-Boot> dfu 0 mtd nand0 > > Signed-off-by: Patrick Delaunay <patrick.delau...@st.com> > --- > > drivers/dfu/dfu_mtd.c | 78 > ++++++++++++++++++++++++++++++++++++++++++++++++++- > include/dfu.h | 2 ++ 2 files changed, 79 insertions(+), 1 > deletion(-) > > diff --git a/drivers/dfu/dfu_mtd.c b/drivers/dfu/dfu_mtd.c > index 1168a6e..223b0fe 100644 > --- a/drivers/dfu/dfu_mtd.c > +++ b/drivers/dfu/dfu_mtd.c > @@ -10,6 +10,7 @@ > #include <common.h> > #include <dfu.h> > #include <mtd.h> > +#include <jffs2/load_kernel.h> > > static bool mtd_is_aligned_with_block_size(struct mtd_info *mtd, u64 > size) { > @@ -181,11 +182,49 @@ static int dfu_write_medium_mtd(struct > dfu_entity *dfu, > static int dfu_flush_medium_mtd(struct dfu_entity *dfu) > { > + struct mtd_info *mtd = dfu->data.mtd.info; > + int ret; > + > + /* in case of ubi partition, erase rest of the partition */ > + if (dfu->data.nand.ubi) { > + struct erase_info erase_op = {}; > + > + erase_op.mtd = dfu->data.mtd.info; > + erase_op.addr = round_up(dfu->data.mtd.start + > dfu->offset + > + dfu->bad_skip, > mtd->erasesize); > + erase_op.len = dfu->data.mtd.start + > dfu->data.mtd.size - > + erase_op.addr; > + erase_op.scrub = 0; > + > + while (erase_op.len) { > + ret = mtd_erase(mtd, &erase_op); > + /* Abort if its not a bad block error */ > + if (ret != -EIO) > + break; > + > + printf("Skipping bad block at 0x%08llx\n", > + erase_op.fail_addr); > + > + /* Skip bad block and continue behind it */ > + erase_op.addr = erase_op.fail_addr + > mtd->erasesize; > + erase_op.len = dfu->data.mtd.start + > + dfu->data.mtd.size - > + erase_op.addr; > + } > + } > return 0; > } > > static unsigned int dfu_polltimeout_mtd(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 (dfu->data.nand.ubi) > + return DFU_MANIFEST_POLL_TIMEOUT; > + > return DFU_DEFAULT_POLL_TIMEOUT; > } > > @@ -194,6 +233,7 @@ int dfu_fill_entity_mtd(struct dfu_entity *dfu, > char *devstr, char *s) char *st; > struct mtd_info *mtd; > bool has_pages; > + int ret, part; > > mtd = get_mtd_device_nm(devstr); > if (IS_ERR_OR_NULL(mtd)) > @@ -212,11 +252,47 @@ int dfu_fill_entity_mtd(struct dfu_entity *dfu, > char *devstr, char *s) dfu->data.mtd.start = simple_strtoul(s, &s, > 16); s++; > dfu->data.mtd.size = simple_strtoul(s, &s, 16); > + } else if ((!strcmp(st, "part")) || (!strcmp(st, > "partubi"))) { > + char mtd_id[32]; > + struct mtd_device *mtd_dev; > + u8 part_num; > + struct part_info *pi; > + > + dfu->layout = DFU_RAW_ADDR; > + > + part = simple_strtoul(s, &s, 10); > + > + sprintf(mtd_id, "%s,%d", devstr, 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; -ENODEV maybe would be more appropriate ? > + } > + > + dfu->data.mtd.start = pi->offset; > + dfu->data.mtd.size = pi->size; > + if (!strcmp(st, "partubi")) > + dfu->data.mtd.ubi = 1; > } else { > - printf("%s: (%s) not supported!\n", __func__, st); > + printf("%s: Memory layout (%s) not supported!\n", > __func__, st); return -1; > } > > + if (!mtd_is_aligned_with_block_size(mtd, > dfu->data.mtd.start)) { > + printf("Offset not aligned with a block (0x%x)\n", > + mtd->erasesize); > + return -EINVAL; > + } > + if (!mtd_is_aligned_with_block_size(mtd, > dfu->data.mtd.size)) { > + printf("Size not aligned with a block (0x%x)\n", > + mtd->erasesize); > + return -EINVAL; > + } > + > dfu->get_medium_size = dfu_get_medium_size_mtd; > dfu->read_medium = dfu_read_medium_mtd; > dfu->write_medium = dfu_write_medium_mtd; > diff --git a/include/dfu.h b/include/dfu.h > index 924952f..a90732c 100644 > --- a/include/dfu.h > +++ b/include/dfu.h > @@ -62,6 +62,8 @@ struct mtd_internal_data { > /* RAW programming */ > u64 start; > u64 size; > + /* for ubi partition */ > + unsigned int ubi; > }; > > struct nand_internal_data { Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lu...@denx.de
pgpcPeMR30SP5.pgp
Description: OpenPGP digital signature
_______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot