summaryrefslogtreecommitdiffstats
path: root/lib/libusb
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2016-06-16 14:26:04 +0000
committerhselasky <hselasky@FreeBSD.org>2016-06-16 14:26:04 +0000
commitb6f02274aa36f1ea0540239debc17bd9bd331fc4 (patch)
tree4d526c30986644cb58497ef2990bd8713ab7da91 /lib/libusb
parentbe411a556e8b17aad2f64a249f5bcc1203537077 (diff)
downloadFreeBSD-src-b6f02274aa36f1ea0540239debc17bd9bd331fc4.zip
FreeBSD-src-b6f02274aa36f1ea0540239debc17bd9bd331fc4.tar.gz
Add support for libusb_set_auto_detach_kernel_driver() to the LibUSB v1.0 API.
Approved by: re (kostikbel) Requested by: swills MFC after: 1 week
Diffstat (limited to 'lib/libusb')
-rw-r--r--lib/libusb/Makefile2
-rw-r--r--lib/libusb/libusb.312
-rw-r--r--lib/libusb/libusb.h1
-rw-r--r--lib/libusb/libusb10.c27
-rw-r--r--lib/libusb/libusb20.c6
-rw-r--r--lib/libusb/libusb20_int.h3
6 files changed, 47 insertions, 4 deletions
diff --git a/lib/libusb/Makefile b/lib/libusb/Makefile
index eb710e2..dcb95de 100644
--- a/lib/libusb/Makefile
+++ b/lib/libusb/Makefile
@@ -74,6 +74,7 @@ MLINKS += libusb.3 libusb_set_debug.3
MLINKS += libusb.3 libusb_get_device_list.3
MLINKS += libusb.3 libusb_free_device_list.3
MLINKS += libusb.3 libusb_get_bus_number.3
+MLINKS += libusb.3 libusb_get_port_number.3
MLINKS += libusb.3 libusb_get_device_address.3
MLINKS += libusb.3 libusb_get_device_speed.3
MLINKS += libusb.3 libusb_get_max_packet_size.3
@@ -98,6 +99,7 @@ MLINKS += libusb.3 libusb_get_driver_np.3
MLINKS += libusb.3 libusb_detach_kernel_driver.3
MLINKS += libusb.3 libusb_detach_kernel_driver_np.3
MLINKS += libusb.3 libusb_attach_kernel_driver.3
+MLINKS += libusb.3 libusb_set_auto_detach_kernel_driver.3
MLINKS += libusb.3 libusb_get_device_descriptor.3
MLINKS += libusb.3 libusb_get_active_config_descriptor.3
MLINKS += libusb.3 libusb_get_config_descriptor.3
diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3
index c91c61d..ea4bf2d 100644
--- a/lib/libusb/libusb.3
+++ b/lib/libusb/libusb.3
@@ -298,6 +298,18 @@ LIBUSB_ERROR_NO_DEVICE
if the device has been disconnected, LIBUSB_ERROR_BUSY if the driver cannot be
attached because the interface is claimed by a program or driver and a
LIBUSB_ERROR code on failure.
+.Pp
+.Ft int
+.Fn libusb_set_auto_detach_kernel_driver "libusb_device_handle *devh" "int enable"
+This function enables automatic kernel interface driver detach when an
+interface is claimed.
+When the interface is restored the kernel driver is allowed to be re-attached.
+If the
+.Fa enable
+argument is non-zero the feature is enabled.
+Else disabled.
+Returns 0 on success and a LIBUSB_ERROR code on
+failure.
.Sh USB DESCRIPTORS
.Ft int
.Fn libusb_get_device_descriptor "libusb_device *dev" "libusb_device_descriptor *desc"
diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h
index c3d69f5..ca1ba88 100644
--- a/lib/libusb/libusb.h
+++ b/lib/libusb/libusb.h
@@ -432,6 +432,7 @@ int libusb_get_driver(libusb_device_handle * devh, int interface, char *name, in
int libusb_detach_kernel_driver_np(libusb_device_handle * devh, int interface);
int libusb_detach_kernel_driver(libusb_device_handle * devh, int interface);
int libusb_attach_kernel_driver(libusb_device_handle * devh, int interface);
+int libusb_set_auto_detach_kernel_driver(libusb_device_handle *dev, int enable);
int libusb_set_interface_alt_setting(libusb_device_handle * devh, int interface_number, int alternate_setting);
/* USB Descriptors */
diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c
index 1f64252..7e1d9b6 100644
--- a/lib/libusb/libusb10.c
+++ b/lib/libusb/libusb10.c
@@ -637,6 +637,7 @@ int
libusb_claim_interface(struct libusb20_device *pdev, int interface_number)
{
libusb_device *dev;
+ int err = 0;
dev = libusb_get_device(pdev);
if (dev == NULL)
@@ -645,11 +646,17 @@ libusb_claim_interface(struct libusb20_device *pdev, int interface_number)
if (interface_number < 0 || interface_number > 31)
return (LIBUSB_ERROR_INVALID_PARAM);
+ if (pdev->auto_detach != 0) {
+ err = libusb_detach_kernel_driver(pdev, interface_number);
+ if (err != 0)
+ goto done;
+ }
+
CTX_LOCK(dev->ctx);
dev->claimed_interfaces |= (1 << interface_number);
CTX_UNLOCK(dev->ctx);
-
- return (0);
+done:
+ return (err);
}
int
@@ -665,13 +672,19 @@ libusb_release_interface(struct libusb20_device *pdev, int interface_number)
if (interface_number < 0 || interface_number > 31)
return (LIBUSB_ERROR_INVALID_PARAM);
+ if (pdev->auto_detach != 0) {
+ err = libusb_attach_kernel_driver(pdev, interface_number);
+ if (err != 0)
+ goto done;
+ }
+
CTX_LOCK(dev->ctx);
if (!(dev->claimed_interfaces & (1 << interface_number)))
err = LIBUSB_ERROR_NOT_FOUND;
-
- if (!err)
+ else
dev->claimed_interfaces &= ~(1 << interface_number);
CTX_UNLOCK(dev->ctx);
+done:
return (err);
}
@@ -873,6 +886,12 @@ libusb_attach_kernel_driver(struct libusb20_device *pdev, int interface)
return (0);
}
+int
+libusb_set_auto_detach_kernel_driver(libusb_device_handle *dev, int enable)
+{
+ dev->auto_detach = (enable ? 1 : 0);
+}
+
/* Asynchronous device I/O */
struct libusb_transfer *
diff --git a/lib/libusb/libusb20.c b/lib/libusb/libusb20.c
index 2eb75f1..2f4ee78 100644
--- a/lib/libusb/libusb20.c
+++ b/lib/libusb/libusb20.c
@@ -601,6 +601,12 @@ libusb20_dev_close(struct libusb20_device *pdev)
*/
pdev->claimed_interface = 0;
+ /*
+ * The following variable is only used by the libusb v1.0
+ * compat layer:
+ */
+ pdev->auto_detach = 0;
+
return (error);
}
diff --git a/lib/libusb/libusb20_int.h b/lib/libusb/libusb20_int.h
index 27adf00..7a1c515 100644
--- a/lib/libusb/libusb20_int.h
+++ b/lib/libusb/libusb20_int.h
@@ -213,6 +213,9 @@ struct libusb20_device {
/* claimed interface */
uint8_t claimed_interface;
+ /* auto detach kernel driver */
+ uint8_t auto_detach;
+
/* device file handle */
int file;
OpenPOWER on IntegriCloud