diff options
Diffstat (limited to 'libusb')
-rw-r--r-- | libusb/io.c | 16 | ||||
-rw-r--r-- | libusb/libusb.h | 13 |
2 files changed, 29 insertions, 0 deletions
diff --git a/libusb/io.c b/libusb/io.c index 77b68ab..118c8b0 100644 --- a/libusb/io.c +++ b/libusb/io.c @@ -248,10 +248,23 @@ static void handle_transfer_completion(struct usbi_transfer *itransfer, if (status == LIBUSB_TRANSFER_SILENT_COMPLETION) return; + if (status == LIBUSB_TRANSFER_COMPLETED + && transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) { + int rqlen = transfer->length; + if (transfer->endpoint_type == LIBUSB_ENDPOINT_TYPE_CONTROL) + rqlen -= LIBUSB_CONTROL_SETUP_SIZE; + if (rqlen != itransfer->transferred) { + usbi_dbg("interpreting short transfer as error"); + status = LIBUSB_TRANSFER_ERROR; + } + } + transfer->status = status; transfer->actual_length = itransfer->transferred; if (transfer->callback) transfer->callback(transfer); + if (transfer->flags & LIBUSB_TRANSFER_FREE_TRANSFER) + libusb_free_transfer(transfer); } static void handle_transfer_cancellation(struct usbi_transfer *transfer) @@ -534,6 +547,9 @@ API_EXPORTED void libusb_free_transfer(struct libusb_transfer *transfer) if (!transfer) return; + if (transfer->flags & LIBUSB_TRANSFER_FREE_BUFFER) + free(transfer->buffer); + itransfer = TRANSFER_TO_PRIV(transfer); free(itransfer); } diff --git a/libusb/libusb.h b/libusb/libusb.h index a697e4e..4f38ddf 100644 --- a/libusb/libusb.h +++ b/libusb/libusb.h @@ -189,16 +189,29 @@ typedef struct libusb_device_handle libusb_device_handle; enum libusb_transfer_status { LIBUSB_TRANSFER_SILENT_COMPLETION = 0, LIBUSB_TRANSFER_COMPLETED, + LIBUSB_TRANSFER_ERROR, LIBUSB_TRANSFER_TIMED_OUT, LIBUSB_TRANSFER_CANCELLED, }; +/* libusb_transfer.flags values */ + +/* report short frames as errors */ +#define LIBUSB_TRANSFER_SHORT_NOT_OK (1<<0) + +/* automatically free() transfer buffer during libusb_free_transfer() */ +#define LIBUSB_TRANSFER_FREE_BUFFER (1<<1) + +/* automatically call libusb_free_transfer() after callback returns */ +#define LIBUSB_TRANSFER_FREE_TRANSFER (1<<2) + struct libusb_transfer; typedef void (*libusb_transfer_cb_fn)(struct libusb_transfer *transfer); struct libusb_transfer { libusb_device_handle *dev_handle; + uint8_t flags; unsigned char endpoint; unsigned char endpoint_type; unsigned int timeout; |