diff options
author | Daniel Drake <dsd@gentoo.org> | 2008-05-04 16:51:23 +0100 |
---|---|---|
committer | Daniel Drake <dsd@gentoo.org> | 2008-05-04 16:51:23 +0100 |
commit | 470b1bc42bf53373ce678fc76bab9160a54d6881 (patch) | |
tree | 2cc2be0a0f1eda347918316589e74b0c57057665 /libusb/os/linux_usbfs.c | |
parent | 17ecfb0ecc833596c43755c80d461cddb9b3b0d7 (diff) | |
download | libusb-470b1bc42bf53373ce678fc76bab9160a54d6881.tar.gz |
add functionality for querying and detaching kernel driver
Diffstat (limited to 'libusb/os/linux_usbfs.c')
-rw-r--r-- | libusb/os/linux_usbfs.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index e67d7b6..40a32f1 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -516,6 +516,51 @@ static int op_reset_device(struct libusb_device_handle *handle) return 0; } +static int op_kernel_driver_active(struct libusb_device_handle *handle, + int interface) +{ + int fd = __device_handle_priv(handle)->fd; + struct usbfs_getdriver getdrv; + int r; + + getdrv.interface = interface; + r = ioctl(fd, IOCTL_USBFS_GETDRIVER, &getdrv); + if (r) { + if (errno == ENODATA) + return 0; + + usbi_err("get driver failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + return 1; +} + +static int op_detach_kernel_driver(struct libusb_device_handle *handle, + int interface) +{ + int fd = __device_handle_priv(handle)->fd; + struct usbfs_ioctl command; + int r; + + command.ifno = interface; + command.ioctl_code = IOCTL_USBFS_DISCONNECT; + command.data = NULL; + + r = ioctl(fd, IOCTL_USBFS_IOCTL, &command); + if (r) { + if (errno == ENODATA) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == EINVAL) + return LIBUSB_ERROR_INVALID_PARAM; + + usbi_err("detach failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + return 0; +} + static void op_destroy_device(struct libusb_device *dev) { unsigned char *nodepath = __device_priv(dev)->nodepath; @@ -1158,6 +1203,9 @@ const struct usbi_os_backend linux_usbfs_backend = { .clear_halt = op_clear_halt, .reset_device = op_reset_device, + .kernel_driver_active = op_kernel_driver_active, + .detach_kernel_driver = op_detach_kernel_driver, + .destroy_device = op_destroy_device, .submit_transfer = op_submit_transfer, |