mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 23:24:38 +00:00
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>
This commit is contained in:
parent
dd64827eb6
commit
7ac1b410ac
3 changed files with 13 additions and 8 deletions
|
@ -82,7 +82,7 @@ unsigned long dfu_get_buf_size(void)
|
||||||
return dfu_buf_size;
|
return dfu_buf_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *dfu_get_buf(void)
|
unsigned char *dfu_get_buf(struct dfu_entity *dfu)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
|
@ -92,6 +92,8 @@ unsigned char *dfu_get_buf(void)
|
||||||
s = getenv("dfu_bufsiz");
|
s = getenv("dfu_bufsiz");
|
||||||
dfu_buf_size = s ? (unsigned long)simple_strtol(s, NULL, 16) :
|
dfu_buf_size = s ? (unsigned long)simple_strtol(s, NULL, 16) :
|
||||||
CONFIG_SYS_DFU_DATA_BUF_SIZE;
|
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);
|
dfu_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, dfu_buf_size);
|
||||||
if (dfu_buf == NULL)
|
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->offset = 0;
|
||||||
dfu->bad_skip = 0;
|
dfu->bad_skip = 0;
|
||||||
dfu->i_blk_seq_num = 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)
|
if (dfu->i_buf_start == NULL)
|
||||||
return -ENOMEM;
|
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->i_buf = dfu->i_buf_start;
|
||||||
|
|
||||||
dfu->inited = 1;
|
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);
|
__func__, dfu->name, buf, size, blk_seq_num, dfu->i_buf);
|
||||||
|
|
||||||
if (!dfu->inited) {
|
if (!dfu->inited) {
|
||||||
dfu->i_buf_start = dfu_get_buf();
|
dfu->i_buf_start = dfu_get_buf(dfu);
|
||||||
if (dfu->i_buf_start == NULL)
|
if (dfu->i_buf_start == NULL)
|
||||||
return -ENOMEM;
|
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->i_blk_seq_num = 0;
|
||||||
dfu->crc = 0;
|
dfu->crc = 0;
|
||||||
dfu->offset = 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->i_buf = dfu->i_buf_start;
|
||||||
dfu->b_left = 0;
|
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);
|
strcpy(dfu->name, st);
|
||||||
|
|
||||||
dfu->alt = alt;
|
dfu->alt = alt;
|
||||||
|
dfu->max_buf_size = 0;
|
||||||
|
|
||||||
/* Specific for mmc device */
|
/* Specific for mmc device */
|
||||||
if (strcmp(interface, "mmc") == 0) {
|
if (strcmp(interface, "mmc") == 0) {
|
||||||
|
|
|
@ -142,7 +142,8 @@ static long long int download_head(unsigned long long total,
|
||||||
int *cnt)
|
int *cnt)
|
||||||
{
|
{
|
||||||
long long int rcv_cnt = 0, left_to_rcv, ret_rcv;
|
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;
|
void *buf = transfer_buffer;
|
||||||
int usb_pkt_cnt = 0, ret;
|
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)
|
static int download_tail(long long int left, int cnt)
|
||||||
{
|
{
|
||||||
struct dfu_entity *dfu_entity = dfu_get_entity(alt_setting_num);
|
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;
|
int ret;
|
||||||
|
|
||||||
debug("%s: left: %llu cnt: %d\n", __func__, left, cnt);
|
debug("%s: left: %llu cnt: %d\n", __func__, left, cnt);
|
||||||
|
|
|
@ -91,6 +91,7 @@ struct dfu_entity {
|
||||||
void *dev_private;
|
void *dev_private;
|
||||||
enum dfu_device_type dev_type;
|
enum dfu_device_type dev_type;
|
||||||
enum dfu_layout layout;
|
enum dfu_layout layout;
|
||||||
|
unsigned long max_buf_size;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct mmc_internal_data mmc;
|
struct mmc_internal_data mmc;
|
||||||
|
@ -138,7 +139,7 @@ void dfu_trigger_reset(void);
|
||||||
int dfu_get_alt(char *name);
|
int dfu_get_alt(char *name);
|
||||||
bool dfu_reset(void);
|
bool dfu_reset(void);
|
||||||
int dfu_init_env_entities(char *interface, char *devstr);
|
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 char *dfu_free_buf(void);
|
||||||
unsigned long dfu_get_buf_size(void);
|
unsigned long dfu_get_buf_size(void);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue