git: 4c556a4e8d14 - main - libusb: implement `libusb_get_parent`
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 12 Jun 2025 16:56:50 UTC
The branch main has been updated by kevans:
URL: https://cgit.FreeBSD.org/src/commit/?id=4c556a4e8d149169a7d8e029aee7f3d017fd4e7f
commit 4c556a4e8d149169a7d8e029aee7f3d017fd4e7f
Author: Aymeric Wibo <obiwac@gmail.com>
AuthorDate: 2025-06-12 16:54:13 +0000
Commit: Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2025-06-12 16:56:31 +0000
libusb: implement `libusb_get_parent`
Newer versions of drivers such as libwacom (graphics tablets) or
libfprint (fingerprint scanners) call g_usb_device_get_parent. This in
turn calls libusb_get_parent on platforms which implement it, and
returns NULL on platforms that don't. This patch implements this
function on FreeBSD.
Reviewed by: bapt, kevans
Differential Revision: https://reviews.freebsd.org/D46992
---
lib/libusb/libusb.3 | 9 +++++++--
lib/libusb/libusb.h | 1 +
lib/libusb/libusb10.c | 34 ++++++++++++++++++++++++++++++++--
lib/libusb/libusb10.h | 1 +
4 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3
index 1ca0e677d96f..a9a99f307a86 100644
--- a/lib/libusb/libusb.3
+++ b/lib/libusb/libusb.3
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd May 16, 2025
+.Dd June 12, 2025
.Dt LIBUSB 3
.Os
.Sh NAME
@@ -117,7 +117,7 @@ This function does not return NULL.
.Fn libusb_set_debug "libusb_context *ctx" "int level"
Set the debug level to
.Fa level .
-.Pp
+.Sh DEVICE HANDLING AND ENUMERATION
.Ft ssize_t
.Fn libusb_get_device_list "libusb_context *ctx" "libusb_device ***list"
Populate
@@ -220,6 +220,11 @@ Close a device handle.
Get the device contained by devh.
Returns NULL on error.
.Pp
+.Ft libusb_device *
+.Fn libusb_get_parent "libusb_device *dev"
+Get dev's parent device.
+Returns NULL if the device has no parent (i.e. is a root device).
+.Pp
.Ft int
.Fn libusb_get_configuration "libusb_device_handle *devh" "int *config"
Returns the value of the current configuration.
diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h
index cdac94b17c64..0aad29aa4ecc 100644
--- a/lib/libusb/libusb.h
+++ b/lib/libusb/libusb.h
@@ -503,6 +503,7 @@ int libusb_open(libusb_device * dev, libusb_device_handle ** devh);
libusb_device_handle *libusb_open_device_with_vid_pid(libusb_context * ctx, uint16_t vendor_id, uint16_t product_id);
void libusb_close(libusb_device_handle * devh);
libusb_device *libusb_get_device(libusb_device_handle * devh);
+libusb_device *libusb_get_parent(libusb_device * dev);
int libusb_get_configuration(libusb_device_handle * devh, int *config);
int libusb_set_configuration(libusb_device_handle * devh, int configuration);
int libusb_claim_interface(libusb_device_handle * devh, int interface_number);
diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c
index b442a1f489a0..3e81f234a735 100644
--- a/lib/libusb/libusb10.c
+++ b/lib/libusb/libusb10.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
* Copyright (c) 2009-2023 Hans Petter Selasky
+ * Copyright (c) 2024 Aymeric Wibo
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -311,9 +312,9 @@ ssize_t
libusb_get_device_list(libusb_context *ctx, libusb_device ***list)
{
struct libusb20_backend *usb_backend;
- struct libusb20_device *pdev;
+ struct libusb20_device *pdev, *parent_dev;
struct libusb_device *dev;
- int i;
+ int i, j, k;
ctx = GET_CONTEXT(ctx);
@@ -365,6 +366,9 @@ libusb_get_device_list(libusb_context *ctx, libusb_device ***list)
/* set context we belong to */
dev->ctx = ctx;
+ /* assume we have no parent by default */
+ dev->parent_dev = NULL;
+
/* link together the two structures */
dev->os_priv = pdev;
pdev->privLuData = dev;
@@ -374,6 +378,25 @@ libusb_get_device_list(libusb_context *ctx, libusb_device ***list)
}
(*list)[i] = NULL;
+ /* for each device, find its parent */
+ for (j = 0; j < i; j++) {
+ pdev = (*list)[j]->os_priv;
+
+ for (k = 0; k < i; k++) {
+ if (k == j)
+ continue;
+
+ parent_dev = (*list)[k]->os_priv;
+
+ if (parent_dev->bus_number != pdev->bus_number)
+ continue;
+ if (parent_dev->device_address == pdev->parent_address) {
+ (*list)[j]->parent_dev = libusb_ref_device((*list)[k]);
+ break;
+ }
+ }
+ }
+
libusb20_be_free(usb_backend);
return (i);
}
@@ -540,6 +563,7 @@ libusb_unref_device(libusb_device *dev)
CTX_UNLOCK(dev->ctx);
if (dev->refcnt == 0) {
+ libusb_unref_device(dev->parent_dev);
libusb20_dev_free(dev->os_priv);
free(dev);
}
@@ -816,6 +840,12 @@ libusb_set_interface_alt_setting(struct libusb20_device *pdev,
return (err ? LIBUSB_ERROR_OTHER : 0);
}
+libusb_device *
+libusb_get_parent(libusb_device *dev)
+{
+ return (dev->parent_dev);
+}
+
static struct libusb20_transfer *
libusb10_get_transfer(struct libusb20_device *pdev,
uint8_t endpoint, uint8_t xfer_index)
diff --git a/lib/libusb/libusb10.h b/lib/libusb/libusb10.h
index f34ea25740d6..70b5525df537 100644
--- a/lib/libusb/libusb10.h
+++ b/lib/libusb/libusb10.h
@@ -142,6 +142,7 @@ struct libusb_device {
struct libusb_super_pollfd dev_poll;
struct libusb_context *ctx;
+ struct libusb_device *parent_dev;
TAILQ_ENTRY(libusb_device) hotplug_entry;