[U-Boot] [PATCH 0/4] dfu: Provide proper Poll Timeout values

This patch series adds support for DFU's proper Poll Timeout setting. This fixes problem with "dying" transmission of a large files (like rootfs).
Moreover some very simple clean-up patches have been included.
Test HW: Exynos4210 - TRATS board
Lukasz Majewski (4): dfu: Export allocated dfu buffer size usb: dfu: f_dfu: Provide infrastructure to adjust DFU's Poll Timeout value usb: f_dfu: cosmetic: Code cleanup ARM: trats: dfu: Enable default Poll Timeout for Trats board
drivers/dfu/dfu.c | 5 +++++ drivers/usb/gadget/f_dfu.c | 43 ++++++++++++++++++++++++++++++++++++++----- drivers/usb/gadget/f_dfu.h | 2 ++ include/configs/trats.h | 1 + include/dfu.h | 4 ++++ 5 files changed, 50 insertions(+), 5 deletions(-)

The method for exporting size of allocated buffer is provided. It is afterwards used by USB's dfu function code.
Signed-off-by: Lukasz Majewski l.majewski@samsung.com --- drivers/dfu/dfu.c | 5 +++++ include/dfu.h | 1 + 2 files changed, 6 insertions(+)
diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index 1eb92e5..07011e9 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -74,6 +74,11 @@ unsigned char *dfu_free_buf(void) return dfu_buf; }
+unsigned long dfu_get_buf_size(void) +{ + return dfu_buf_size; +} + unsigned char *dfu_get_buf(void) { char *s; diff --git a/include/dfu.h b/include/dfu.h index cc14044..9a50721 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -131,6 +131,7 @@ bool dfu_reset(void); int dfu_init_env_entities(char *interface, int dev); unsigned char *dfu_get_buf(void); unsigned char *dfu_free_buf(void); +unsigned long dfu_get_buf_size(void);
int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num); int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);

Hello Lukasz,
Am 09.12.2013 16:20, schrieb Lukasz Majewski:
The method for exporting size of allocated buffer is provided. It is afterwards used by USB's dfu function code.
Signed-off-by: Lukasz Majewskil.majewski@samsung.com
drivers/dfu/dfu.c | 5 +++++ include/dfu.h | 1 + 2 files changed, 6 insertions(+)
Tested on the dxr2 board. "dfu -l" "dfu -U" and "dfu -D" worked.
Tested-by: Heiko Schocher hs@denx.de
bye, Heiko

It is necessary to deter the host from sending subsequent DFU_GETSTATUS request in the case of e.g. writing the buffer to medium.
Here the timeout is increased when we fill up the whole buffer. This delay allows eMMC memory to perform its internal operations. Otherwise we end up with HOST's error regarding GET_STATUS receive timeout. Signed-off-by: Lukasz Majewski l.majewski@samsung.com --- drivers/usb/gadget/f_dfu.c | 39 ++++++++++++++++++++++++++++++++++++--- drivers/usb/gadget/f_dfu.h | 2 ++ include/dfu.h | 3 +++ 3 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index 37d04a1..b4b4aa4 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -40,6 +40,7 @@ struct f_dfu {
/* Send/received block number is handy for data integrity check */ int blk_seq_num; + unsigned int poll_timeout; };
typedef int (*dfu_state_fn) (struct f_dfu *, @@ -128,6 +129,33 @@ static struct usb_gadget_strings *dfu_strings[] = { NULL, };
+static void dfu_set_poll_timeout(struct dfu_status *dstat, unsigned int ms) +{ + /* + * The bwPollTimeout DFU_GETSTATUS request payload provides information + * about minimum time, in milliseconds, that the host should wait before + * sending a subsequent DFU_GETSTATUS request + * + * This permits the device to vary the delay depending on its need to + * erase or program the memory + * + */ + + unsigned char *p = (unsigned char *)&ms; + + if (!ms || (ms & ~DFU_POLL_TIMEOUT_MASK)) { + dstat->bwPollTimeout[0] = 0; + dstat->bwPollTimeout[1] = 0; + dstat->bwPollTimeout[2] = 0; + + return; + } + + dstat->bwPollTimeout[0] = *p++; + dstat->bwPollTimeout[1] = *p++; + dstat->bwPollTimeout[2] = *p; +} + /*-------------------------------------------------------------------------*/
static void dnload_request_complete(struct usb_ep *ep, struct usb_request *req) @@ -157,11 +185,15 @@ static void handle_getstatus(struct usb_request *req) break; }
+ dfu_set_poll_timeout(dstat, 0); + + if (f_dfu->poll_timeout) + if (!(f_dfu->blk_seq_num % + (dfu_get_buf_size() / DFU_USB_BUFSIZ))) + dfu_set_poll_timeout(dstat, f_dfu->poll_timeout); + /* send status response */ dstat->bStatus = f_dfu->dfu_status; - dstat->bwPollTimeout[0] = 0; - dstat->bwPollTimeout[1] = 0; - dstat->bwPollTimeout[2] = 0; dstat->bState = f_dfu->dfu_state; dstat->iString = 0; } @@ -725,6 +757,7 @@ static int dfu_bind_config(struct usb_configuration *c) f_dfu->usb_function.disable = dfu_disable; f_dfu->usb_function.strings = dfu_generic_strings, f_dfu->usb_function.setup = dfu_handle, + f_dfu->poll_timeout = DFU_DEFAULT_POLL_TIMEOUT;
status = usb_add_function(c, &f_dfu->usb_function); if (status) diff --git a/drivers/usb/gadget/f_dfu.h b/drivers/usb/gadget/f_dfu.h index cc2c455..0c29954 100644 --- a/drivers/usb/gadget/f_dfu.h +++ b/drivers/usb/gadget/f_dfu.h @@ -82,4 +82,6 @@ struct dfu_function_descriptor { __le16 wTransferSize; __le16 bcdDFUVersion; } __packed; + +#define DFU_POLL_TIMEOUT_MASK (0xFFFFFFUL) #endif /* __F_DFU_H_ */ diff --git a/include/dfu.h b/include/dfu.h index 9a50721..f973426 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -77,6 +77,9 @@ static inline unsigned int get_mmc_blk_size(int dev) #ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE #define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE #endif +#ifndef DFU_DEFAULT_POLL_TIMEOUT +#define DFU_DEFAULT_POLL_TIMEOUT 0 +#endif
struct dfu_entity { char name[DFU_NAME_SIZE];

Hi Lukasz,
On 12/09/2013 11:20 PM, Lukasz Majewski wrote:
diff --git a/drivers/usb/gadget/f_dfu.h b/drivers/usb/gadget/f_dfu.h index cc2c455..0c29954 100644 --- a/drivers/usb/gadget/f_dfu.h +++ b/drivers/usb/gadget/f_dfu.h @@ -82,4 +82,6 @@ struct dfu_function_descriptor { __le16 wTransferSize; __le16 bcdDFUVersion; } __packed;
+#define DFU_POLL_TIMEOUT_MASK (0xFFFFFFUL)
Why this value? How about (~0UL)?
#endif /* __F_DFU_H_ */
Best Regards, Bo Shen

Hi Bo,
Hi Lukasz,
On 12/09/2013 11:20 PM, Lukasz Majewski wrote:
diff --git a/drivers/usb/gadget/f_dfu.h b/drivers/usb/gadget/f_dfu.h index cc2c455..0c29954 100644 --- a/drivers/usb/gadget/f_dfu.h +++ b/drivers/usb/gadget/f_dfu.h @@ -82,4 +82,6 @@ struct dfu_function_descriptor { __le16 wTransferSize; __le16 bcdDFUVersion; } __packed;
+#define DFU_POLL_TIMEOUT_MASK (0xFFFFFFUL)
Why this value? How about (~0UL)?
According to DFU 1.1 standard, the bwPolTimeout field of DFU_GETSTATUS request has 3 bytes in size.
#endif /* __F_DFU_H_ */
Best Regards, Bo Shen

Hi Lukasz,
On 12/10/2013 04:27 PM, Lukasz Majewski wrote:
Hi Bo,
Hi Lukasz,
On 12/09/2013 11:20 PM, Lukasz Majewski wrote:
diff --git a/drivers/usb/gadget/f_dfu.h b/drivers/usb/gadget/f_dfu.h index cc2c455..0c29954 100644 --- a/drivers/usb/gadget/f_dfu.h +++ b/drivers/usb/gadget/f_dfu.h @@ -82,4 +82,6 @@ struct dfu_function_descriptor { __le16 wTransferSize; __le16 bcdDFUVersion; } __packed;
+#define DFU_POLL_TIMEOUT_MASK (0xFFFFFFUL)
Why this value? How about (~0UL)?
According to DFU 1.1 standard, the bwPolTimeout field of DFU_GETSTATUS request has 3 bytes in size.
Thanks for clarify this.
Tested OK on sama5d3xek board. Tested-by: Bo Shen voice.shen@atmel.com
#endif /* __F_DFU_H_ */
Best Regards, Bo Shen
Best Regards, Bo Shen

Hello Lukasz,
Am 09.12.2013 16:20, schrieb Lukasz Majewski:
It is necessary to deter the host from sending subsequent DFU_GETSTATUS request in the case of e.g. writing the buffer to medium.
Here the timeout is increased when we fill up the whole buffer. This delay allows eMMC memory to perform its internal operations. Otherwise we end up with HOST's error regarding GET_STATUS receive timeout.
Signed-off-by: Lukasz Majewskil.majewski@samsung.com
drivers/usb/gadget/f_dfu.c | 39 ++++++++++++++++++++++++++++++++++++--- drivers/usb/gadget/f_dfu.h | 2 ++ include/dfu.h | 3 +++ 3 files changed, 41 insertions(+), 3 deletions(-)
Tested on the dxr2 board. "dfu -l" "dfu -U" and "dfu -D" worked.
Tested-by: Heiko Schocher hs@denx.de
bye, Heiko

Code cleanup for dfu_bind_config function
Signed-off-by: Lukasz Majewski l.majewski@samsung.com --- drivers/usb/gadget/f_dfu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index b4b4aa4..a045864 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -755,8 +755,8 @@ static int dfu_bind_config(struct usb_configuration *c) f_dfu->usb_function.unbind = dfu_unbind; f_dfu->usb_function.set_alt = dfu_set_alt; f_dfu->usb_function.disable = dfu_disable; - f_dfu->usb_function.strings = dfu_generic_strings, - f_dfu->usb_function.setup = dfu_handle, + f_dfu->usb_function.strings = dfu_generic_strings; + f_dfu->usb_function.setup = dfu_handle; f_dfu->poll_timeout = DFU_DEFAULT_POLL_TIMEOUT;
status = usb_add_function(c, &f_dfu->usb_function);

Hello Lukasz,
Am 09.12.2013 16:20, schrieb Lukasz Majewski:
Code cleanup for dfu_bind_config function
Signed-off-by: Lukasz Majewskil.majewski@samsung.com
drivers/usb/gadget/f_dfu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Tested on the dxr2 board. "dfu -l" "dfu -U" and "dfu -D" worked.
Tested-by: Heiko Schocher hs@denx.de
bye, Heiko

Provide default Poll Timeout value for Trats board.
Signed-off-by: Lukasz Majewski l.majewski@samsung.com --- include/configs/trats.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/configs/trats.h b/include/configs/trats.h index 3d080c4..1e37996 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -98,6 +98,7 @@ #define CONFIG_THOR_FUNCTION
#define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_32M +#define DFU_DEFAULT_POLL_TIMEOUT 300 #define CONFIG_DFU_FUNCTION #define CONFIG_DFU_MMC

Hello Lukasz,
Am 09.12.2013 16:20, schrieb Lukasz Majewski:
Provide default Poll Timeout value for Trats board.
Signed-off-by: Lukasz Majewskil.majewski@samsung.com
include/configs/trats.h | 1 + 1 file changed, 1 insertion(+)
Tested on the dxr2 board. "dfu -l" "dfu -U" and "dfu -D" worked.
Tested-by: Heiko Schocher hs@denx.de
bye, Heiko

Hi Heiko,
This patch series adds support for DFU's proper Poll Timeout setting. This fixes problem with "dying" transmission of a large files (like rootfs).
Moreover some very simple clean-up patches have been included.
I'd have a little request. Please check if those patches doesn't break anything on NAND related boards.
Thanks in advance.
Test HW: Exynos4210 - TRATS board
Lukasz Majewski (4): dfu: Export allocated dfu buffer size usb: dfu: f_dfu: Provide infrastructure to adjust DFU's Poll Timeout value usb: f_dfu: cosmetic: Code cleanup ARM: trats: dfu: Enable default Poll Timeout for Trats board
drivers/dfu/dfu.c | 5 +++++ drivers/usb/gadget/f_dfu.c | 43 ++++++++++++++++++++++++++++++++++++++----- drivers/usb/gadget/f_dfu.h | 2 ++ include/configs/trats.h | 1 + include/dfu.h | 4 ++++ 5 files changed, 50 insertions(+), 5 deletions(-)

Hello Lukasz,
How are you?
Am 10.12.2013 10:54, schrieb Lukasz Majewski:
Hi Heiko,
This patch series adds support for DFU's proper Poll Timeout setting. This fixes problem with "dying" transmission of a large files (like rootfs).
Moreover some very simple clean-up patches have been included.
I'd have a little request. Please check if those patches doesn't break anything on NAND related boards.
I had them on my list, but I am hopelessly under water ...
I try to test them today ... feel free to trigger my again, if I forget it ...
bye, Heiko

On Monday, December 09, 2013 at 04:20:12 PM, Lukasz Majewski wrote:
This patch series adds support for DFU's proper Poll Timeout setting. This fixes problem with "dying" transmission of a large files (like rootfs).
Moreover some very simple clean-up patches have been included.
Test HW: Exynos4210 - TRATS board
Lukasz Majewski (4): dfu: Export allocated dfu buffer size usb: dfu: f_dfu: Provide infrastructure to adjust DFU's Poll Timeout value usb: f_dfu: cosmetic: Code cleanup ARM: trats: dfu: Enable default Poll Timeout for Trats board
drivers/dfu/dfu.c | 5 +++++ drivers/usb/gadget/f_dfu.c | 43 ++++++++++++++++++++++++++++++++++++++----- drivers/usb/gadget/f_dfu.h | 2 ++ include/configs/trats.h | 1 + include/dfu.h | 4 ++++ 5 files changed, 50 insertions(+), 5 deletions(-)
Applied all, thanks
Best regards, Marek Vasut
participants (4)
-
Bo Shen
-
Heiko Schocher
-
Lukasz Majewski
-
Marek Vasut