dfu: allow backend to specify a maximum buffer size
authorStephen Warren <swarren@nvidia.com>
Wed, 11 Jun 2014 22:03:34 +0000 (16:03 -0600)
committerTom Rini <trini@ti.com>
Sat, 9 Aug 2014 15:16:58 +0000 (11:16 -0400)
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>
drivers/dfu/dfu.c
drivers/usb/gadget/f_thor.c
include/dfu.h

index 26d3b44e40f5b2640a223e0476daa037b550bd5a..b8d382d9b5dfefd453557ff122c2a3399b31d318 100644 (file)
@@ -82,7 +82,7 @@ unsigned long dfu_get_buf_size(void)
        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 @@ unsigned char *dfu_get_buf(void)
        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 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
                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 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
               __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 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
                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 @@ static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt,
        strcpy(dfu->name, st);
 
        dfu->alt = alt;
+       dfu->max_buf_size = 0;
 
        /* Specific for mmc device */
        if (strcmp(interface, "mmc") == 0) {
index 4e06273f7fb7e678b96a6bb3e11d6b8d6a4830a5..c85b0fbd3ca5102d14c5d660a3733b7099ea8f61 100644 (file)
@@ -142,7 +142,8 @@ static long long int download_head(unsigned long long total,
                                   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 long long int download_head(unsigned long long total,
 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);
index 21390aa9b7b31046e661ddb0f7ee27ba64fd21a6..d5562dcb37d1a28dcfe78251123ed76cb4b0b6df 100644 (file)
@@ -91,6 +91,7 @@ struct dfu_entity {
        void                    *dev_private;
        enum dfu_device_type    dev_type;
        enum dfu_layout         layout;
+       unsigned long           max_buf_size;
 
        union {
                struct mmc_internal_data mmc;
@@ -138,7 +139,7 @@ void dfu_trigger_reset(void);
 int dfu_get_alt(char *name);
 bool dfu_reset(void);
 int dfu_init_env_entities(char *interface, char *devstr);
-unsigned char *dfu_get_buf(void);
+unsigned char *dfu_get_buf(struct dfu_entity *dfu);
 unsigned char *dfu_free_buf(void);
 unsigned long dfu_get_buf_size(void);