[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