diff options
author | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2015-10-14 08:46:36 (GMT) |
---|---|---|
committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2015-10-14 08:46:36 (GMT) |
commit | 13a3972585af60ec367d209cedbd3601e0c77467 (patch) | |
tree | 4b3312669b3e501f6bc10b39d8c7bbf516f07aac /drivers/dfu | |
parent | 208bd51396fb606dbdcf45b064e6b372d7dd3e81 (diff) | |
parent | 297faccca2235e359012118495b9b73451d54bb9 (diff) | |
download | u-boot-13a3972585af60ec367d209cedbd3601e0c77467.tar.xz |
Merge remote-tracking branch 'u-boot/master'
Diffstat (limited to 'drivers/dfu')
-rw-r--r-- | drivers/dfu/dfu.c | 15 | ||||
-rw-r--r-- | drivers/dfu/dfu_mmc.c | 27 |
2 files changed, 28 insertions, 14 deletions
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index 6cf240d..8f5915e 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -164,7 +164,6 @@ static int dfu_write_buffer_drain(struct dfu_entity *dfu) void dfu_write_transaction_cleanup(struct dfu_entity *dfu) { /* clear everything */ - dfu_free_buf(); dfu->crc = 0; dfu->offset = 0; dfu->i_blk_seq_num = 0; @@ -339,17 +338,6 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) dfu->r_left = dfu->get_medium_size(dfu); if (dfu->r_left < 0) return dfu->r_left; - switch (dfu->layout) { - case DFU_RAW_ADDR: - case DFU_RAM_ADDR: - break; - default: - if (dfu->r_left > dfu_buf_size) { - printf("%s: File too big for buffer\n", - __func__); - return -EOVERFLOW; - } - } debug("%s: %s %ld [B]\n", __func__, dfu->name, dfu->r_left); @@ -385,7 +373,6 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) dfu_hash_algo->name, dfu->crc); puts("\nUPLOAD ... done\nCtrl+C to exit ...\n"); - dfu_free_buf(); dfu->i_blk_seq_num = 0; dfu->crc = 0; dfu->offset = 0; @@ -433,6 +420,7 @@ static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt, __func__, interface); return -1; } + dfu_get_buf(dfu); return 0; } @@ -441,6 +429,7 @@ void dfu_free_entities(void) { struct dfu_entity *dfu, *p, *t = NULL; + dfu_free_buf(); list_for_each_entry_safe_reverse(dfu, p, &dfu_list, list) { list_del(&dfu->list); if (dfu->free_entity) diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c index 2a780f7..5a9fb4a 100644 --- a/drivers/dfu/dfu_mmc.c +++ b/drivers/dfu/dfu_mmc.c @@ -18,6 +18,7 @@ static unsigned char *dfu_file_buf; static long dfu_file_buf_len; +static long dfu_file_buf_filled; static int mmc_access_part(struct dfu_entity *dfu, struct mmc *mmc, int part) { @@ -230,9 +231,12 @@ long dfu_get_medium_size_mmc(struct dfu_entity *dfu) return dfu->data.mmc.lba_size * dfu->data.mmc.lba_blk_size; case DFU_FS_FAT: case DFU_FS_EXT4: + dfu_file_buf_filled = -1; ret = mmc_file_op(DFU_OP_SIZE, dfu, NULL, &len); if (ret < 0) return ret; + if (len > CONFIG_SYS_DFU_MAX_FILE_SIZE) + return -1; return len; default: printf("%s: Layout (%s) not (yet) supported!\n", __func__, @@ -241,6 +245,27 @@ long dfu_get_medium_size_mmc(struct dfu_entity *dfu) } } +static int mmc_file_unbuffer(struct dfu_entity *dfu, u64 offset, void *buf, + long *len) +{ + int ret; + long file_len; + + if (dfu_file_buf_filled == -1) { + ret = mmc_file_op(DFU_OP_READ, dfu, dfu_file_buf, &file_len); + if (ret < 0) + return ret; + dfu_file_buf_filled = file_len; + } + if (offset + *len > dfu_file_buf_filled) + return -EINVAL; + + /* Add to the current buffer. */ + memcpy(buf, dfu_file_buf + offset, *len); + + return 0; +} + int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf, long *len) { @@ -252,7 +277,7 @@ int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf, break; case DFU_FS_FAT: case DFU_FS_EXT4: - ret = mmc_file_op(DFU_OP_READ, dfu, buf, len); + ret = mmc_file_unbuffer(dfu, offset, buf, len); break; default: printf("%s: Layout (%s) not (yet) supported!\n", __func__, |