public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Lukasz Majewski <l.majewski@samsung.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] dfu: Handle large transfers correctly
Date: Thu, 29 Nov 2012 10:06:45 +0100	[thread overview]
Message-ID: <20121129100645.5733b24f@amdc308.digital.local> (raw)
In-Reply-To: <1354142330-31130-1-git-send-email-panto@antoniou-consulting.com>

Hi Pantelis,

> The sequence number is a 16 bit counter; make sure we
> handle rollover correctly. This fixes the wrong transfers for
> large (> 256MB) images.

This is a bit misleading comment. 
DFU 1.1 standard says:
"The wBlockNum field is a block sequence number. It increments each time
a block is transferred, wrapping to zero from 65,535. It is used to
provide useful context to the DFU loader in the device."

Maybe above statement shall be put to the comment.

One more thing:

wTransferSize = 4096 and the DFU 1.1 standard says:

"The host sends between bMaxPacketSize0 and wTransferSize" and
increments wBlockNum (which is 16 bits).

Maybe we shall increase the wTransferSize (defined at 
static const struct dfu_function_descriptor dfu_func) to e.g. 32 KiB
and leave the code unchanged?

Can you test this option on your setup?

> 
> Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
> ---
>  drivers/dfu/dfu.c     | 28 +++++++++++++++++++++++-----
>  drivers/dfu/dfu_mmc.c |  3 +++
>  include/dfu.h         |  2 ++
>  3 files changed, 28 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c
> index 1260c55..2483018 100644
> --- a/drivers/dfu/dfu.c
> +++ b/drivers/dfu/dfu.c
> @@ -82,7 +82,7 @@ int dfu_write(struct dfu_entity *dfu, void *buf,
> int size, int blk_seq_num) __func__, dfu->name, buf, size,
> blk_seq_num, dfu->offset, dfu->i_buf - dfu->i_buf_start);
>  
> -	if (blk_seq_num == 0) {
> +	if (dfu->do_init) {
>  		/* initial state */
>  		dfu->crc = 0;
>  		dfu->offset = 0;
> @@ -90,6 +90,8 @@ int dfu_write(struct dfu_entity *dfu, void *buf,
> int size, int blk_seq_num) dfu->i_buf_start = dfu_buf;
>  		dfu->i_buf_end = dfu_buf + sizeof(dfu_buf);
>  		dfu->i_buf = dfu->i_buf_start;
> +
> +		dfu->do_init = 0;
>  	}
>  
>  	if (dfu->i_blk_seq_num != blk_seq_num) {
> @@ -97,7 +99,8 @@ int dfu_write(struct dfu_entity *dfu, void *buf,
> int size, int blk_seq_num) __func__, dfu->i_blk_seq_num, blk_seq_num);
>  		return -1;
>  	}
> -	dfu->i_blk_seq_num++;
> +	/* handle rollover */
> +	dfu->i_blk_seq_num = (dfu->i_blk_seq_num + 1) & 0xffff;
>  
>  	/* flush buffer if overflow */
>  	if ((dfu->i_buf + size) > dfu->i_buf_end) {
> @@ -106,6 +109,13 @@ int dfu_write(struct dfu_entity *dfu, void *buf,
> int size, int blk_seq_num) ret = tret;
>  	}
>  
> +	/* we should be in buffer now (if not then size too large) */
> +	if ((dfu->i_buf + size) > dfu->i_buf_end) {
> +		printf("%s: Wrong size! [%d] [%d] - \n",
> +		       __func__, dfu->i_blk_seq_num, blk_seq_num,
> size);
> +		return -1;
> +	}
> +
>  	memcpy(dfu->i_buf, buf, size);
>  	dfu->i_buf += size;
>  
> @@ -120,7 +130,7 @@ int dfu_write(struct dfu_entity *dfu, void *buf,
> int size, int blk_seq_num) if (size == 0) {
>  		debug("%s: DFU complete CRC32: 0x%x\n", __func__,
> dfu->crc); 
> -		puts("\nDownload complete\n");
> +		printf("\nDownload complete (CRC32 0x%04x)\n",
> dfu->crc); 
>  		/* clear everything */
>  		dfu->crc = 0;
> @@ -129,6 +139,9 @@ int dfu_write(struct dfu_entity *dfu, void *buf,
> int size, int blk_seq_num) dfu->i_buf_start = dfu_buf;
>  		dfu->i_buf_end = dfu_buf + sizeof(dfu_buf);
>  		dfu->i_buf = dfu->i_buf_start;
> +
> +		dfu->do_init = 1;
> +
>  	}
>  
>  	return ret = 0 ? size : ret;
> @@ -190,7 +203,7 @@ int dfu_read(struct dfu_entity *dfu, void *buf,
> int size, int blk_seq_num) debug("%s: name: %s buf: 0x%p size: 0x%x
> p_num: 0x%x i_buf: 0x%p\n", __func__, dfu->name, buf, size,
> blk_seq_num, dfu->i_buf); 
> -	if (blk_seq_num == 0) {
> +	if (dfu->do_init) {
>  		ret = dfu->read_medium(dfu, 0, NULL, &dfu->r_left);
>  		if (ret != 0) {
>  			debug("%s: failed to get r_left\n",
> __func__); @@ -206,6 +219,8 @@ int dfu_read(struct dfu_entity *dfu,
> void *buf, int size, int blk_seq_num) dfu->i_buf_end = dfu_buf +
> sizeof(dfu_buf); dfu->i_buf = dfu->i_buf_start;
>  		dfu->b_left = 0;
> +
> +		dfu->do_init = 0;
>  	}
>  
>  	if (dfu->i_blk_seq_num != blk_seq_num) {
> @@ -213,7 +228,8 @@ int dfu_read(struct dfu_entity *dfu, void *buf,
> int size, int blk_seq_num) __func__, dfu->i_blk_seq_num, blk_seq_num);
>  		return -1;
>  	}
> -	dfu->i_blk_seq_num++;
> +	/* handle rollover */
> +	dfu->i_blk_seq_num = (dfu->i_blk_seq_num + 1) & 0xffff;
>  
>  	ret = dfu_read_buffer_fill(dfu, buf, size);
>  	if (ret < 0) {
> @@ -232,6 +248,8 @@ int dfu_read(struct dfu_entity *dfu, void *buf,
> int size, int blk_seq_num) dfu->i_buf_end = dfu_buf + sizeof(dfu_buf);
>  		dfu->i_buf = dfu->i_buf_start;
>  		dfu->b_left = 0;
> +
> +		dfu->do_init = 1;
>  	}
>  
>  	return ret;
> diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c
> index 4c8994b..906df55 100644
> --- a/drivers/dfu/dfu_mmc.c
> +++ b/drivers/dfu/dfu_mmc.c
> @@ -234,5 +234,8 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu,
> char *s) dfu->read_medium = dfu_read_medium_mmc;
>  	dfu->write_medium = dfu_write_medium_mmc;
>  
> +	/* initial state */
> +	dfu->do_init = 1;
> +
>  	return 0;
>  }
> diff --git a/include/dfu.h b/include/dfu.h
> index b662488..0ce91b7 100644
> --- a/include/dfu.h
> +++ b/include/dfu.h
> @@ -90,6 +90,8 @@ struct dfu_entity {
>  	u8 *i_buf_end;
>  	long r_left;
>  	long b_left;
> +
> +	unsigned int do_init : 1
>  };
>  
>  int dfu_config_entities(char *s, char *interface, int num);



-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

  parent reply	other threads:[~2012-11-29  9:06 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-28 22:38 [U-Boot] [PATCH] dfu: Handle large transfers correctly Pantelis Antoniou
2012-11-29  6:26 ` Marek Vasut
2012-11-29  9:06 ` Lukasz Majewski [this message]
2012-11-29  9:35   ` Pantelis Antoniou
2012-11-29 10:25 ` Lukasz Majewski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20121129100645.5733b24f@amdc308.digital.local \
    --to=l.majewski@samsung.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox