Skip to content

Commit

Permalink
usb: Correct libusb timeout handling
Browse files Browse the repository at this point in the history
The documentation for libusb_bulk_transfer() specifies that in the event
that the read or write request is split into multiple chunks, some of
these may still be transferred despite a LIBUSB_ERROR_TIMEOUT is
returned.

In the transition to libusb this detail was missed and completed
read transfers are sometimes considred to be timeouts and the data
discarded, obviously resulting in failure to continue.

Consider the "transferred" value in the event of timeout, to avoid this.

Although not yet spotted in testing, the same logic is introduced for
the write path.

Signed-off-by: Bjorn Andersson <[email protected]>
  • Loading branch information
quic-bjorande authored and Konrad Dybcio committed Jun 7, 2024
1 parent c647d6d commit a60d45c
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout
int ret;

ret = libusb_bulk_transfer(qdl->usb_handle, qdl->in_ep, buf, len, &actual, timeout);
if (ret < 0)
if ((ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) ||
(ret == LIBUSB_ERROR_TIMEOUT && actual == 0))
return -1;

return actual;
Expand All @@ -218,7 +219,8 @@ int qdl_write(struct qdl_device *qdl, const void *buf, size_t len)

ret = libusb_bulk_transfer(qdl->usb_handle, qdl->out_ep, data,
xfer, &actual, 1000);
if (ret < 0) {
if ((ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) ||
(ret == LIBUSB_ERROR_TIMEOUT && actual == 0)) {
warnx("bulk write failed: %s", libusb_strerror(ret));
return -1;
}
Expand Down

0 comments on commit a60d45c

Please sign in to comment.