Signed-off-by: Hans de Goede <[email protected]>
---
libusb/os/linux_usbfs.c | 28 ++++++++++++++++++++++++++++
libusb/os/linux_usbfs.h | 10 ++++++++++
2 files changed, 38 insertions(+)
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index b6194ce..9cadca0 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -1604,9 +1604,37 @@ static int op_detach_kernel_driver_and_claim(
const char *driver_name)
{
int fd = _device_handle_priv(handle)->fd;
+ struct usbfs_disconnect_claim dc;
struct usbfs_getdriver getdrv;
int r;
+ dc.interface = interface;
+ if (driver_name) {
+ snprintf(dc.driver, sizeof(dc.driver), "%s", driver_name);
+ dc.flags = USBFS_DISCONNECT_CLAIM_IF_DRIVER;
+ } else {
+ snprintf(dc.driver, sizeof(dc.driver), "usbfs");
+ dc.flags = USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER;
+ }
+ r = ioctl(fd, IOCTL_USBFS_DISCONNECT_CLAIM, &dc);
+ if (r == 0 || (r != 0 && errno != ENOTTY)) {
+ if (r == 0)
+ return 0;
+ switch (errno) {
+ case EBUSY:
+ return LIBUSB_ERROR_BUSY;
+ case EINVAL:
+ return LIBUSB_ERROR_INVALID_PARAM;
+ case ENODEV:
+ return LIBUSB_ERROR_NO_DEVICE;
+ }
+
+ usbi_err(HANDLE_CTX(handle),
+ "disconnect-and-claim failed errno %d", errno);
+ return LIBUSB_ERROR_OTHER;
+ }
+
+ /* Fallback code for kernels which don't support the dc ioctl */
if (driver_name) {
getdrv.interface = interface;
r = ioctl(fd, IOCTL_USBFS_GETDRIVER, &getdrv);
diff --git a/libusb/os/linux_usbfs.h b/libusb/os/linux_usbfs.h
index 593e736..3ee80ff 100644
--- a/libusb/os/linux_usbfs.h
+++ b/libusb/os/linux_usbfs.h
@@ -123,6 +123,15 @@ struct usbfs_hub_portinfo {
#define USBFS_CAP_NO_PACKET_SIZE_LIM 0x04
#define USBFS_CAP_BULK_SCATTER_GATHER 0x08
+#define USBFS_DISCONNECT_CLAIM_IF_DRIVER 0x01
+#define USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02
+
+struct usbfs_disconnect_claim {
+ unsigned int interface;
+ unsigned int flags;
+ char driver[USBFS_MAXDRIVERNAME + 1];
+};
+
#define IOCTL_USBFS_CONTROL _IOWR('U', 0, struct usbfs_ctrltransfer)
#define IOCTL_USBFS_BULK _IOWR('U', 2, struct usbfs_bulktransfer)
#define IOCTL_USBFS_RESETEP _IOR('U', 3, unsigned int)
@@ -145,5 +154,6 @@ struct usbfs_hub_portinfo {
#define IOCTL_USBFS_CLAIM_PORT _IOR('U', 24, unsigned int)
#define IOCTL_USBFS_RELEASE_PORT _IOR('U', 25, unsigned int)
#define IOCTL_USBFS_GET_CAPABILITIES _IOR('U', 26, __u32)
+#define IOCTL_USBFS_DISCONNECT_CLAIM _IOR('U', 27, struct
usbfs_disconnect_claim)
#endif
--
1.7.11.4
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusbx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libusbx-devel