Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Jun 2025 16:56:50 GMT
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 4c556a4e8d14 - main - libusb: implement `libusb_get_parent`
Message-ID:  <202506121656.55CGuoa9036561@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202506121656.55CGuoa9036561>