diff --git a/src/main/io/util/usb.c b/src/main/io/util/usb.c index 5e05753..c7d3cff 100644 --- a/src/main/io/util/usb.c +++ b/src/main/io/util/usb.c @@ -99,20 +99,6 @@ void *io_usb_open(uint16_t vid, uint16_t pid, uint16_t config, uint16_t iface) return NULL; } - ret = libusb_set_configuration(dev, config); - - if (ret != LIBUSB_SUCCESS) { - libusb_close(dev); - libusb_exit(ctx); - - log_error( - "(%04X:%04X) Setting configuration failed", - vid, - pid, - libusb_error_name(ret)); - return NULL; - } - /* check if the device is attached to the kernel, detach it first then */ if (libusb_kernel_driver_active(dev, iface) == 1) { ret = libusb_detach_kernel_driver(dev, iface); @@ -130,6 +116,20 @@ void *io_usb_open(uint16_t vid, uint16_t pid, uint16_t config, uint16_t iface) } } + ret = libusb_set_configuration(dev, config); + + if (ret != LIBUSB_SUCCESS) { + libusb_close(dev); + libusb_exit(ctx); + + log_error( + "(%04X:%04X) Setting configuration failed", + vid, + pid, + libusb_error_name(ret)); + return NULL; + } + ret = libusb_claim_interface(dev, iface); if (ret != LIBUSB_SUCCESS) { @@ -181,6 +181,31 @@ int32_t io_usb_control_transfer( return ret; } +int32_t io_usb_interrupt_transfer( + void *handle, + int ep, + uint8_t *data, + uint16_t len, + uint32_t timeout) +{ + struct usb_io_ctx *dev = (struct usb_io_ctx *) handle; + int32_t ret, transferred; + + ret = + libusb_interrupt_transfer( + dev->dev, ep, data, len, &transferred, timeout); + + if (transferred != len) { + log_error( + "Interrupt transfer, addr %02x, handle %p failed: %s", + handle, + ep, + libusb_error_name(ret)); + } + + return transferred; +} + void io_usb_close(void *handle) { struct usb_io_ctx *dev = (struct usb_io_ctx *) handle; diff --git a/src/main/io/util/usb_.h b/src/main/io/util/usb_.h index a38f82a..f8a960f 100644 --- a/src/main/io/util/usb_.h +++ b/src/main/io/util/usb_.h @@ -42,6 +42,23 @@ int32_t io_usb_control_transfer( uint16_t len, uint32_t timeout); +/** + * Execute an interrupt transfer request. + * + * @param handle Handle of an opened usb device + * @param ep Endpoint address to communicate with. + * @param data Pointer to an allocated buffer (depending on the vendor + * specific request type, this can be a read or write buffer) + * @param len Length of the data to write/read + * @param timeout Timeout for the operation in ms + * @return Number of bytes read/written or -1 on error + */ +int32_t io_usb_interrupt_transfer( + void *handle, + int ep, + uint8_t *data, + uint16_t len, + uint32_t timeout); /** * Close a opened usb device *