dfu, nand, ubi: add partubi alt settings for updating ubi partition
authorHeiko Schocher <hs@denx.de>
Thu, 25 Jul 2013 04:43:11 +0000 (06:43 +0200)
committerMarek Vasut <marex@denx.de>
Mon, 26 Aug 2013 19:56:34 +0000 (21:56 +0200)
updating an ubi partition needs a completely erased mtd partition,
see:
http://lists.infradead.org/pipermail/linux-mtd/2011-May/035416.html

So, add partubi alt setting for the dfu_alt_info environment
variable to mark this partition as an ubi partition. In case we
update an ubi partition, we erase after flashing the image into the
partition, the remaining sektors.

Signed-off-by: Heiko Schocher <hs@denx.de>
Cc: Pantelis Antoniou <panto@antoniou-consulting.com>
Cc: Tom Rini <trini@ti.com>
Cc: Lukasz Majewski <l.majewski@samsung.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Marek Vasut <marex@denx.de>
Cc: Wolfgang Denk <wd@denx.de>
Cc: Scott Wood <scottwood@freescale.com>
drivers/dfu/dfu_nand.c
include/dfu.h

index 2a01cc11b80546a39162e5b7c8485cdef72791d0..0ec12cff264fe8ad88117f8fe8748851cf0d4e85 100644 (file)
@@ -136,11 +136,43 @@ static int dfu_read_medium_nand(struct dfu_entity *dfu, u64 offset, void *buf,
        return ret;
 }
 
+static int dfu_flush_medium_nand(struct dfu_entity *dfu)
+{
+       int ret = 0;
+
+       /* in case of ubi partition, erase rest of the partition */
+       if (dfu->data.nand.ubi) {
+               nand_info_t *nand;
+               nand_erase_options_t opts;
+
+               if (nand_curr_device < 0 ||
+                   nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE ||
+                   !nand_info[nand_curr_device].name) {
+                       printf("%s: invalid nand device\n", __func__);
+                       return -1;
+               }
+
+               nand = &nand_info[nand_curr_device];
+
+               memset(&opts, 0, sizeof(opts));
+               opts.offset = dfu->data.nand.start + dfu->offset +
+                               dfu->bad_skip;
+               opts.length = dfu->data.nand.start +
+                               dfu->data.nand.size - opts.offset;
+               ret = nand_erase_opts(nand, &opts);
+               if (ret != 0)
+                       printf("Failure erase: %d\n", ret);
+       }
+
+       return ret;
+}
+
 int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)
 {
        char *st;
        int ret, dev, part;
 
+       dfu->data.nand.ubi = 0;
        dfu->dev_type = DFU_DEV_NAND;
        st = strsep(&s, " ");
        if (!strcmp(st, "raw")) {
@@ -148,7 +180,7 @@ int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)
                dfu->data.nand.start = simple_strtoul(s, &s, 16);
                s++;
                dfu->data.nand.size = simple_strtoul(s, &s, 16);
-       } else if (!strcmp(st, "part")) {
+       } else if ((!strcmp(st, "part")) || (!strcmp(st, "partubi"))) {
                char mtd_id[32];
                struct mtd_device *mtd_dev;
                u8 part_num;
@@ -173,7 +205,8 @@ int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)
 
                dfu->data.nand.start = pi->offset;
                dfu->data.nand.size = pi->size;
-
+               if (!strcmp(st, "partubi"))
+                       dfu->data.nand.ubi = 1;
        } else {
                printf("%s: Memory layout (%s) not supported!\n", __func__, st);
                return -1;
@@ -181,6 +214,7 @@ int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)
 
        dfu->read_medium = dfu_read_medium_nand;
        dfu->write_medium = dfu_write_medium_nand;
+       dfu->flush_medium = dfu_flush_medium_nand;
 
        /* initial state */
        dfu->inited = 0;
index 1d4006de8bab3f31bb119fe45b477c7d432d6bcc..47b90559d5bbe705fdba2fcc050d29d1481b6e49 100644 (file)
@@ -47,6 +47,8 @@ struct nand_internal_data {
 
        unsigned int dev;
        unsigned int part;
+       /* for nand/ubi use */
+       unsigned int ubi;
 };
 
 static inline unsigned int get_mmc_blk_size(int dev)