summaryrefslogtreecommitdiffstats
path: root/common/ubiformat.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2018-01-10 14:20:57 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2018-01-11 08:32:41 +0100
commit91e08222389da159944d918bbe6eee7510da8872 (patch)
tree570c5a01a24cf8cd2ef0932cff521074a1f95a12 /common/ubiformat.c
parente0e4c722c98737a4202b9fabc60bff6d2c6050f4 (diff)
downloadbarebox-91e08222389da159944d918bbe6eee7510da8872.tar.gz
ubiformat: Add ubiformat write function
The ubiformat C API expects an image file as argument. With upcoming Android fastboot sparse image support we can no longer provide a complete image anymore. With this patch we can write an image in multiple chunks after we've formatted a MTD device with ubiformat. ubiformat_write will skip the EC header in both the MTD device we write to and also the image we read from, so we can flash an image on a MTD device containing EC headers already. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common/ubiformat.c')
-rw-r--r--common/ubiformat.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/common/ubiformat.c b/common/ubiformat.c
index aaa1f5d..4c5f1f5 100644
--- a/common/ubiformat.c
+++ b/common/ubiformat.c
@@ -679,3 +679,64 @@ out_close:
return err;
}
+int ubiformat_write(struct mtd_info *mtd, const void *buf, size_t count,
+ loff_t offset)
+{
+ int writesize = mtd->writesize >> mtd->subpage_sft;
+ size_t retlen;
+ int ret;
+
+ if (offset & (mtd->writesize - 1))
+ return -EINVAL;
+
+ if (count & (mtd->writesize - 1))
+ return -EINVAL;
+
+ while (count) {
+ size_t now;
+
+ now = ALIGN(offset, mtd->erasesize) - offset;
+ if (now > count)
+ now = count;
+
+ if (!now) {
+ const struct ubi_ec_hdr *ec = buf;
+ const struct ubi_vid_hdr *vid;
+
+ if (be32_to_cpu(ec->magic) != UBI_EC_HDR_MAGIC) {
+ pr_err("bad UBI magic %#08x, should be %#08x",
+ be32_to_cpu(ec->magic), UBI_EC_HDR_MAGIC);
+ return -EINVAL;
+ }
+
+ /* skip ec header */
+ offset += writesize;
+ buf += writesize;
+ count -= writesize;
+
+ if (!count)
+ break;
+
+ vid = buf;
+ if (be32_to_cpu(vid->magic) != UBI_VID_HDR_MAGIC) {
+ pr_err("bad UBI magic %#08x, should be %#08x",
+ be32_to_cpu(vid->magic), UBI_VID_HDR_MAGIC);
+ return -EINVAL;
+ }
+
+ continue;
+ }
+
+ ret = mtd_write(mtd, offset, now, &retlen, buf);
+ if (ret < 0)
+ return ret;
+ if (retlen != now)
+ return -EIO;
+
+ buf += now;
+ count -= now;
+ offset += now;
+ }
+
+ return 0;
+}