Linux: Return ERROR_NOT_FOUND in detach-kernel-driver if usbfs is already bound
authorHans de Goede <hdegoede@redhat.com>
Wed, 22 Aug 2012 10:47:00 +0000 (11:47 +0100)
committerPete Batard <pete@akeo.ie>
Thu, 23 Aug 2012 19:24:14 +0000 (20:24 +0100)
* 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.

libusb/core.c
libusb/os/linux_usbfs.c
libusb/version_nano.h

index 17e2780..5f2cd34 100644 (file)
@@ -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
index a8768be..5093745 100644 (file)
@@ -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)
index 97588fa..aa88cb4 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 10555
+#define LIBUSB_NANO 10556