summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-08-22 11:47:00 +0100
committerPete Batard <pete@akeo.ie>2012-08-23 20:24:14 +0100
commit34807a115263ff4fe94b1dc894f93f076e759d5f (patch)
treed4f9a5f15788658f94cb4e5beca998451df6420d
parentede02ba91920f9be787a7f3cd006c5a4b92b5eab (diff)
downloadlibusb-34807a115263ff4fe94b1dc894f93f076e759d5f.tar.gz
Linux: Return ERROR_NOT_FOUND in detach-kernel-driver if usbfs is already bound
* Currently applications for devices which only are accessed from userspace can use claim / release interface to make sure they don't get in each others way. * The same however does not work for applications which first need to detach a "native" / in kernel driver, as this detach will not only detach native drivers but also the usbfs driver, thus stealing the device from another userspace / libusbx app. * This patch fixes libusb_detach_kernel_driver to only detach "real" kernel drivers and not the special usbfs driver used for userspace access to USB devices. If the usbfs driver is found LIBUSB_ERROR_NOT_FOUND will be returned to indicate no driver was detached.
-rw-r--r--libusb/core.c4
-rw-r--r--libusb/os/linux_usbfs.c6
-rw-r--r--libusb/version_nano.h2
3 files changed, 11 insertions, 1 deletions
diff --git a/libusb/core.c b/libusb/core.c
index 17e2780..5f2cd34 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -1512,6 +1512,10 @@ int API_EXPORTED libusb_kernel_driver_active(libusb_device_handle *dev,
*
* This functionality is not available on Darwin or Windows.
*
+ * Note that libusbx itself also talks to the device through a special kernel
+ * driver, if this driver is already attached to the device, this call will
+ * not detach it and return LIBUSB_ERROR_NOT_FOUND.
+ *
* \param dev a device handle
* \param interface_number the interface to detach the driver from
* \returns 0 on success
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index a8768be..5093745 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -1538,12 +1538,18 @@ static int op_detach_kernel_driver(struct libusb_device_handle *handle,
{
int fd = _device_handle_priv(handle)->fd;
struct usbfs_ioctl command;
+ struct usbfs_getdriver getdrv;
int r;
command.ifno = interface;
command.ioctl_code = IOCTL_USBFS_DISCONNECT;
command.data = NULL;
+ getdrv.interface = interface;
+ r = ioctl(fd, IOCTL_USBFS_GETDRIVER, &getdrv);
+ if (r == 0 && strcmp(getdrv.driver, "usbfs") == 0)
+ return LIBUSB_ERROR_NOT_FOUND;
+
r = ioctl(fd, IOCTL_USBFS_IOCTL, &command);
if (r) {
if (errno == ENODATA)
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 97588fa..aa88cb4 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 10555
+#define LIBUSB_NANO 10556