﻿id,summary,reporter,owner,description,type,status,milestone,component,resolution,keywords,cc,blockedby,blocking
42,Error return code of usb_detach_kernel_driver_np(),xiaofan,sbrabec,"For usb_detach_kernel_driver_np(), the compat layer will return ENOENT (for LIBUSB_ERROR_NOT_FOUND) instead of ENODATA which is the value returned by libusb-0.1.

From libusb-1.0 (linux_usbfs.c)
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;
               else if (errno == ENODEV)
                       return LIBUSB_ERROR_NO_DEVICE;

               usbi_err(HANDLE_CTX(handle),
                       ""detach failed error %d errno %d"", r, errno);
               return LIBUSB_ERROR_OTHER;
       }

       return 0;
}

From original libusb-0.1: it is similar to libusb-1.0, so it
can return ENODATA, EINVAL and ENODEV.

int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface)
{
 struct usb_ioctl command;
 int ret;

 command.ifno = interface;
 command.ioctl_code = IOCTL_USB_DISCONNECT;
 command.data = NULL;

 ret = ioctl(dev->fd, IOCTL_USB_IOCTL, &command);
 if (ret)
   USB_ERROR_STR(-errno, ""could not detach kernel driver from
interface %d: %s"",
       interface, strerror(errno));

 return 0;
}

From libusb-0.1-compat:

static int libusb_to_errno(int result)
{
       switch (result) {
       case LIBUSB_SUCCESS:
               return 0;
       case LIBUSB_ERROR_IO:
               return EIO;
       case LIBUSB_ERROR_INVALID_PARAM:
               return EINVAL;
       case LIBUSB_ERROR_ACCESS:
               return EACCES;
       case LIBUSB_ERROR_NO_DEVICE:
               return ENXIO;
       case LIBUSB_ERROR_NOT_FOUND:
               return ENOENT;
       case LIBUSB_ERROR_BUSY:
               return EBUSY;
       case LIBUSB_ERROR_TIMEOUT:
               return ETIMEDOUT;
       case LIBUSB_ERROR_OVERFLOW:
               return EOVERFLOW;
       case LIBUSB_ERROR_PIPE:
               return EPIPE;
       case LIBUSB_ERROR_INTERRUPTED:
               return EINTR;
       case LIBUSB_ERROR_NO_MEM:
               return ENOMEM;
       case LIBUSB_ERROR_NOT_SUPPORTED:
               return ENOSYS;
       default:
               return ERANGE;
       }
}

API_EXPORTED int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface)
{
       return compat_err(libusb_detach_kernel_driver(dev->handle, interface));
}",defect,closed,,libusb-compat-0.1,fixed,errorno,sbrabec@…,,
