diff options
author | Patrick Delaunay <patrick.delaunay@foss.st.com> | 2021-10-13 18:01:37 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-01-28 18:21:51 +0300 |
commit | 86b6a38863bebb70a65a53f93a1ffafc4a472169 (patch) | |
tree | 6537741d36a0d39b94a4dca531416e185f0f7238 /drivers/usb | |
parent | 51566bc8c37205d73f45ee97409063fedc1cdfd8 (diff) | |
download | u-boot-86b6a38863bebb70a65a53f93a1ffafc4a472169.tar.xz |
dfu: handle short frame result of UPLOAD in state_dfu_idle
In DFU v1.1 specification [1] the DFU_UPLOAD (Short Frame)
is handled only in dfuUPLOADIDLE state:
- Figure A.1 Interface state transition diagram
- the state description in chapter A.2
A.2.3 State 2 dfuIDLE
on Receipt of the DFU_UPLOAD request,and bitCanUpload = 1
the Next State is dfuUPLOADIDLE
A.2.10 State 9 dfuUPLOAD-IDLE
When the length of the data transferred by the device in response
to a DFU_UPLOAD request is less than wLength. (Short frame)
the Next State is dfuIDLE
In current code, when an UPLOAD is completely performed after the first
request (for example with wLength=200 and data read = 9), the DFU state
stay at dfuUPLOADIDLE until receiving a DFU_UPLOAD or a DFU_ABORT request
even it is unnecessary as the previous DFU_UPLOAD request already reached
the EOF.
This patch proposes to finish the DFU uploading (don't go to dfuUPLOADIDLE)
and completes the control-read operation (go to DFU_STATE_dfuIDLE) when
the first UPLOAD response has a short frame as an end of file (EOF)
indicator even if it is not explicitly allowed in the DFU specification
but this seems logical.
[1] https://www.usb.org/sites/default/files/DFU_1.1.pdf
Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/f_dfu.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c index 4bedc7d3a1..e9340ff5cb 100644 --- a/drivers/usb/gadget/f_dfu.c +++ b/drivers/usb/gadget/f_dfu.c @@ -336,6 +336,8 @@ static int state_dfu_idle(struct f_dfu *f_dfu, f_dfu->dfu_state = DFU_STATE_dfuUPLOAD_IDLE; f_dfu->blk_seq_num = 0; value = handle_upload(req, len); + if (value >= 0 && value < len) + f_dfu->dfu_state = DFU_STATE_dfuIDLE; break; case USB_REQ_DFU_ABORT: /* no zlp? */ |