usb: device: Fix ZLP write race condition

ZLP packet has to be read and acknowledged by host just like any other
DATA packet. Do not end transfer until the host actually acknowledged
the trailing ZLP. This fixes the race condition between host and Zephyr
application where the next transfer could be lost if host did not issue
IN token (that would read read ZLP) before the application tried to
start new transfer.

Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
This commit is contained in:
Tomasz Moń 2023-10-26 09:17:46 +02:00 committed by Carles Cufí
parent b3de643206
commit 08bd1c5ec2

View File

@ -86,12 +86,17 @@ static void usb_transfer_work(struct k_work *item)
if (trans->flags & USB_TRANS_WRITE) {
if (!trans->bsize) {
if (!(trans->flags & USB_TRANS_NO_ZLP)) {
LOG_DBG("Transfer ZLP");
usb_write(ep, NULL, 0, NULL);
if (trans->flags & USB_TRANS_NO_ZLP) {
trans->status = 0;
goto done;
}
trans->status = 0;
goto done;
/* Host have to read the ZLP just like any other DATA
* packet. Set USB_TRANS_NO_ZLP flag so the transfer
* will end next time we get ACK from host.
*/
LOG_DBG("Transfer ZLP");
trans->flags |= USB_TRANS_NO_ZLP;
}
ret = usb_write(ep, trans->buffer, trans->bsize, &bytes);