diff options
author | Hans de Goede <hdegoede@redhat.com> | 2013-09-11 13:06:38 +0200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2014-04-22 14:31:35 +0200 |
commit | 0504375ea965dd25f00d4828a19c329b7e7525d4 (patch) | |
tree | e207b92c7e777046288be44de2c344b51068906e /libusb/os/linux_usbfs.c | |
parent | c59d574b211bedcab951b2f19de58bb03a04d671 (diff) | |
download | libusb-0504375ea965dd25f00d4828a19c329b7e7525d4.tar.gz |
Add API for allocating / freeing usb3 bulk streams + Linux implementation
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'libusb/os/linux_usbfs.c')
-rw-r--r-- | libusb/os/linux_usbfs.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index 5ad6129..2f6b4af 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -1495,6 +1495,56 @@ out: return ret; } +static int do_streams_ioctl(struct libusb_device_handle *handle, long req, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints) +{ + int r, fd = _device_handle_priv(handle)->fd; + struct usbfs_streams *streams; + + if (num_endpoints > 30) /* Max 15 in + 15 out eps */ + return LIBUSB_ERROR_INVALID_PARAM; + + streams = malloc(sizeof(struct usbfs_streams) + num_endpoints); + if (!streams) + return LIBUSB_ERROR_NO_MEM; + + streams->num_streams = num_streams; + streams->num_eps = num_endpoints; + memcpy(streams->eps, endpoints, num_endpoints); + + r = ioctl(fd, req, streams); + + free(streams); + + if (r < 0) { + if (errno == ENOTTY) + return LIBUSB_ERROR_NOT_SUPPORTED; + else if (errno == EINVAL) + return LIBUSB_ERROR_INVALID_PARAM; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "streams-ioctl failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + return r; +} + +static int op_alloc_streams(struct libusb_device_handle *handle, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints) +{ + return do_streams_ioctl(handle, IOCTL_USBFS_ALLOC_STREAMS, + num_streams, endpoints, num_endpoints); +} + +static int op_free_streams(struct libusb_device_handle *handle, + unsigned char *endpoints, int num_endpoints) +{ + return do_streams_ioctl(handle, IOCTL_USBFS_FREE_STREAMS, 0, + endpoints, num_endpoints); +} + static int op_kernel_driver_active(struct libusb_device_handle *handle, int interface) { @@ -2596,6 +2646,9 @@ const struct usbi_os_backend linux_usbfs_backend = { .clear_halt = op_clear_halt, .reset_device = op_reset_device, + .alloc_streams = op_alloc_streams, + .free_streams = op_free_streams, + .kernel_driver_active = op_kernel_driver_active, .detach_kernel_driver = op_detach_kernel_driver, .attach_kernel_driver = op_attach_kernel_driver, |