dfu: allow backend to specify a maximum buffer size
CONFIG_SYS_DFU_DATA_BUF_SIZE may be large to allow for FAT/ext layouts
to transfer large files. However, this means that individual write
operations will take a long time. Allow backends to specify a maximum
buffer size, so that each write operation is limited to a smaller data
block. This prevents the DFU protocol from timing out when e.g. writing
to SPI flash. I would guess that NAND might benefit from setting this
value too, but I can't test that.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
index 26d3b44..b8d382d 100644
--- a/drivers/dfu/dfu.c
+++ b/drivers/dfu/dfu.c
@@ -82,7 +82,7 @@
return dfu_buf_size;
}
-unsigned char *dfu_get_buf(void)
+unsigned char *dfu_get_buf(struct dfu_entity *dfu)
{
char *s;
@@ -92,6 +92,8 @@
s = getenv("dfu_bufsiz");
dfu_buf_size = s ? (unsigned long)simple_strtol(s, NULL, 16) :
CONFIG_SYS_DFU_DATA_BUF_SIZE;
+ if (dfu->max_buf_size && dfu_buf_size > dfu->max_buf_size)
+ dfu_buf_size = dfu->max_buf_size;
dfu_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, dfu_buf_size);
if (dfu_buf == NULL)
@@ -194,10 +196,10 @@
dfu->offset = 0;
dfu->bad_skip = 0;
dfu->i_blk_seq_num = 0;
- dfu->i_buf_start = dfu_get_buf();
+ dfu->i_buf_start = dfu_get_buf(dfu);
if (dfu->i_buf_start == NULL)
return -ENOMEM;
- dfu->i_buf_end = dfu_get_buf() + dfu_buf_size;
+ dfu->i_buf_end = dfu_get_buf(dfu) + dfu_buf_size;
dfu->i_buf = dfu->i_buf_start;
dfu->inited = 1;
@@ -318,7 +320,7 @@
__func__, dfu->name, buf, size, blk_seq_num, dfu->i_buf);
if (!dfu->inited) {
- dfu->i_buf_start = dfu_get_buf();
+ dfu->i_buf_start = dfu_get_buf(dfu);
if (dfu->i_buf_start == NULL)
return -ENOMEM;
@@ -342,7 +344,7 @@
dfu->i_blk_seq_num = 0;
dfu->crc = 0;
dfu->offset = 0;
- dfu->i_buf_end = dfu_get_buf() + dfu_buf_size;
+ dfu->i_buf_end = dfu_get_buf(dfu) + dfu_buf_size;
dfu->i_buf = dfu->i_buf_start;
dfu->b_left = 0;
@@ -398,6 +400,7 @@
strcpy(dfu->name, st);
dfu->alt = alt;
+ dfu->max_buf_size = 0;
/* Specific for mmc device */
if (strcmp(interface, "mmc") == 0) {
diff --git a/drivers/usb/gadget/f_thor.c b/drivers/usb/gadget/f_thor.c
index 4e06273..c85b0fb 100644
--- a/drivers/usb/gadget/f_thor.c
+++ b/drivers/usb/gadget/f_thor.c
@@ -142,7 +142,8 @@
int *cnt)
{
long long int rcv_cnt = 0, left_to_rcv, ret_rcv;
- void *transfer_buffer = dfu_get_buf();
+ struct dfu_entity *dfu_entity = dfu_get_entity(alt_setting_num);
+ void *transfer_buffer = dfu_get_buf(dfu_entity);
void *buf = transfer_buffer;
int usb_pkt_cnt = 0, ret;
@@ -205,7 +206,7 @@
static int download_tail(long long int left, int cnt)
{
struct dfu_entity *dfu_entity = dfu_get_entity(alt_setting_num);
- void *transfer_buffer = dfu_get_buf();
+ void *transfer_buffer = dfu_get_buf(dfu_entity);
int ret;
debug("%s: left: %llu cnt: %d\n", __func__, left, cnt);