
Hi Kasim,
On Jan 3, 2013, at 10:30 AM, kasim ling wrote:
Hi, Pantelis, A little confusion about FAT fs write supporting,
On Sat, Dec 1, 2012 at 12:51 AM, Pantelis Antoniou panto@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@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.
No I haven't had a use case either for fat or ext2/3/4.
So I guess it is as broken as it was before. If you want to write to a file, make sure it's smaller than the DFU buffer.
One of these days the file access functions must be fixed.
Thanks, Alex
Regards
-- Pantelis