diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h --- a/lib/libusb/libusb.h +++ b/lib/libusb/libusb.h @@ -250,6 +250,7 @@ LIBUSB_TRANSFER_SHORT_NOT_OK = 1 << 0, LIBUSB_TRANSFER_FREE_BUFFER = 1 << 1, LIBUSB_TRANSFER_FREE_TRANSFER = 1 << 2, + LIBUSB_TRANSFER_ADD_ZERO_PACKET = 1 << 3, }; enum libusb_log_level { diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c --- a/lib/libusb/libusb10.c +++ b/lib/libusb/libusb10.c @@ -1326,6 +1326,17 @@ } /* check for end of data */ if (sxfer->rem_len == 0) { + if (flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) { + uxfer->flags &= + ~LIBUSB_TRANSFER_ADD_ZERO_PACKET; + libusb20_tr_setup_bulk(pxfer, sxfer->curr_data, + 0, uxfer->timeout); + libusb20_tr_submit(pxfer); + libusb10_submit_transfer_sub( + libusb20_tr_get_priv_sc0(pxfer), + uxfer->endpoint); + break; + } libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED); break; } @@ -1347,7 +1358,8 @@ libusb20_tr_submit(pxfer); /* check if we can fork another USB transfer */ - if (sxfer->rem_len == 0) + if (sxfer->rem_len == 0 && + !(flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET)) libusb10_submit_transfer_sub(libusb20_tr_get_priv_sc0(pxfer), uxfer->endpoint); break; @@ -1606,6 +1618,16 @@ } else if (dev->device_is_gone != 0) { err = LIBUSB_ERROR_NO_DEVICE; } else { + /* + * We unset the ZLP flag when the sxfer is "in" direction and + * the length is not a multiplier of MPS + */ + if ((uxfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) && + ((uxfer->endpoint & LIBUSB_ENDPOINT_IN) || + (uxfer->length % + libusb20_tr_get_max_packet_length(pxfer0)))) { + uxfer->flags &= ~LIBUSB_TRANSFER_ADD_ZERO_PACKET; + } /* set pending state */ sxfer->state = LIBUSB_SUPER_XFER_ST_PEND;