mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
usb: dfu: f_dfu: Provide infrastructure to adjust DFU's Poll Timeout value
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>
This commit is contained in:
parent
4fb127898e
commit
33fac4a6a2
3 changed files with 41 additions and 3 deletions
|
@ -40,6 +40,7 @@ struct f_dfu {
|
||||||
|
|
||||||
/* Send/received block number is handy for data integrity check */
|
/* Send/received block number is handy for data integrity check */
|
||||||
int blk_seq_num;
|
int blk_seq_num;
|
||||||
|
unsigned int poll_timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*dfu_state_fn) (struct f_dfu *,
|
typedef int (*dfu_state_fn) (struct f_dfu *,
|
||||||
|
@ -128,6 +129,33 @@ static struct usb_gadget_strings *dfu_strings[] = {
|
||||||
NULL,
|
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)
|
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;
|
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 */
|
/* send status response */
|
||||||
dstat->bStatus = f_dfu->dfu_status;
|
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->bState = f_dfu->dfu_state;
|
||||||
dstat->iString = 0;
|
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.disable = dfu_disable;
|
||||||
f_dfu->usb_function.strings = dfu_generic_strings,
|
f_dfu->usb_function.strings = dfu_generic_strings,
|
||||||
f_dfu->usb_function.setup = dfu_handle,
|
f_dfu->usb_function.setup = dfu_handle,
|
||||||
|
f_dfu->poll_timeout = DFU_DEFAULT_POLL_TIMEOUT;
|
||||||
|
|
||||||
status = usb_add_function(c, &f_dfu->usb_function);
|
status = usb_add_function(c, &f_dfu->usb_function);
|
||||||
if (status)
|
if (status)
|
||||||
|
|
|
@ -82,4 +82,6 @@ struct dfu_function_descriptor {
|
||||||
__le16 wTransferSize;
|
__le16 wTransferSize;
|
||||||
__le16 bcdDFUVersion;
|
__le16 bcdDFUVersion;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
#define DFU_POLL_TIMEOUT_MASK (0xFFFFFFUL)
|
||||||
#endif /* __F_DFU_H_ */
|
#endif /* __F_DFU_H_ */
|
||||||
|
|
|
@ -77,6 +77,9 @@ static inline unsigned int get_mmc_blk_size(int dev)
|
||||||
#ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE
|
#ifndef CONFIG_SYS_DFU_MAX_FILE_SIZE
|
||||||
#define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE
|
#define CONFIG_SYS_DFU_MAX_FILE_SIZE CONFIG_SYS_DFU_DATA_BUF_SIZE
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef DFU_DEFAULT_POLL_TIMEOUT
|
||||||
|
#define DFU_DEFAULT_POLL_TIMEOUT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
struct dfu_entity {
|
struct dfu_entity {
|
||||||
char name[DFU_NAME_SIZE];
|
char name[DFU_NAME_SIZE];
|
||||||
|
|
Loading…
Reference in a new issue