[U-Boot] [PATCH 9/9] dfu: Support larger than memory transfers.

kasim ling kasimling at gmail.com
Thu Jan 3 09:30:10 CET 2013


Hi, Pantelis,
A little confusion about FAT fs write supporting,


On Sat, Dec 1, 2012 at 12:51 AM, Pantelis Antoniou
<panto at antoniou-consulting.com> wrote:
>
> We didn't support upload/download larger than available memory.
> This is pretty bad when you have to update your root filesystem for
> example.
>
> This patch removes the limitation (and the crashes when you transfered
> any file larger than 4MB).
> On top of that reduces the huge dfu buffer from 4MB to just 64K, which
> was over the top.
>
> The sequence number is a 16 bit counter; make sure we
> handle rollover correctly. This fixes the wrong transfers for
> large (> 256MB) images.
>
> Also utilize a variable to handle initialization, so that we
> don't rely on just the counter sent by the host.
>
> Signed-off-by: Pantelis Antoniou <panto at antoniou-consulting.com>
> ---
>  drivers/dfu/dfu.c     | 244 +++++++++++++++++++++++++++++++++++++++-----------
>  drivers/dfu/dfu_mmc.c |  82 +++++++++++------
>  include/dfu.h         |  21 ++++-
>  3 files changed, 264 insertions(+), 83 deletions(-)

> diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
> index 083d745..29a2c2e 100644
> --- a/drivers/dfu/dfu_mmc.c
> +++ b/drivers/dfu/dfu_mmc.c
> @@ -22,6 +22,7 @@
>  #include <common.h>
>  #include <malloc.h>
>  #include <errno.h>
> +#include <div64.h>
>  #include <dfu.h>
>
>  enum dfu_mmc_op {
> @@ -30,35 +31,48 @@ enum dfu_mmc_op {
>  };
>
>  static int mmc_block_op(enum dfu_mmc_op op, struct dfu_entity *dfu,
> -                       void *buf, long *len)
> +                       u64 offset, void *buf, long *len)
>  {
>         char cmd_buf[DFU_CMD_BUF_SIZE];
> +       u32 blk_start, blk_count;
>
> -       sprintf(cmd_buf, "mmc %s 0x%x %x %x",
> -               op == DFU_OP_READ ? "read" : "write",
> -               (unsigned int) buf,
> -               dfu->data.mmc.lba_start,
> -               dfu->data.mmc.lba_size);
> -
> -       if (op == DFU_OP_READ)
> +       /* if buf == NULL return total size of the area */
> +       if (buf == NULL) {
>                 *len = dfu->data.mmc.lba_blk_size * dfu->data.mmc.lba_size;
> +               return 0;
> +       }
> +
> +       blk_start = dfu->data.mmc.lba_start +
> +                       (u32)lldiv(offset, dfu->data.mmc.lba_blk_size);
> +       blk_count = *len / dfu->data.mmc.lba_blk_size;
> +       if (blk_start + blk_count >
> +                       dfu->data.mmc.lba_start + dfu->data.mmc.lba_size) {
> +               debug("%s: block_op out of bounds\n", __func__);
> +               return -1;
> +       }
> +
> +       sprintf(cmd_buf, "mmc %s %p %x %x",
> +               op == DFU_OP_READ ? "read" : "write",
> +                buf, blk_start, blk_count);
>
>         debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf);
>         return run_command(cmd_buf, 0);
>  }
>
> -static inline int mmc_block_write(struct dfu_entity *dfu, void *buf, long *len)
> +static inline int mmc_block_write(struct dfu_entity *dfu,
> +               u64 offset, void *buf, long *len)
>  {
> -       return mmc_block_op(DFU_OP_WRITE, dfu, buf, len);
> +       return mmc_block_op(DFU_OP_WRITE, dfu, offset, buf, len);
>  }
>
> -static inline int mmc_block_read(struct dfu_entity *dfu, void *buf, long *len)
> +static inline int mmc_block_read(struct dfu_entity *dfu,
> +               u64 offset, void *buf, long *len)
>  {
> -       return mmc_block_op(DFU_OP_READ, dfu, buf, len);
> +       return mmc_block_op(DFU_OP_READ, dfu, offset, buf, len);
>  }
>
>  static int mmc_file_op(enum dfu_mmc_op op, struct dfu_entity *dfu,
> -                       void *buf, long *len)
> +                       u64 offset, void *buf, long *len)
>  {
>         char cmd_buf[DFU_CMD_BUF_SIZE];
>         char *str_env;
> @@ -66,12 +80,17 @@ static int mmc_file_op(enum dfu_mmc_op op, struct dfu_entity *dfu,
>
>         switch (dfu->layout) {
>         case DFU_FS_FAT:
> -               sprintf(cmd_buf, "fat%s mmc %d:%d 0x%x %s %lx",
> +               sprintf(cmd_buf, "fat%s mmc %d:%d 0x%x %s %lx %llx",
>                         op == DFU_OP_READ ? "load" : "write",
>                         dfu->data.mmc.dev, dfu->data.mmc.part,
> -                       (unsigned int) buf, dfu->name, *len);
> +                       (unsigned int) buf, dfu->name, *len, offset);
Did you tested it on FAT partitions? According to do_fat_fswrite()
defined in common/cmd_fat.c, the "fatwrite" command does not support
"offset" argument.


Thanks,
Alex


More information about the U-Boot mailing list