aboutsummaryrefslogtreecommitdiffstats
path: root/libusb
diff options
context:
space:
mode:
Diffstat (limited to 'libusb')
-rw-r--r--libusb/io.c16
-rw-r--r--libusb/libusb.h13
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;