Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Aug 2025 14:20:34 GMT
From:      ShengYi Hung <aokblast@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 20056f0e5a7f - main - libusb: implement libusb_get_platform_descriptor
Message-ID:  <202508061420.576EKY1r009685@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by aokblast:

URL: https://cgit.FreeBSD.org/src/commit/?id=20056f0e5a7fe8df85a9934150d32594d6fe84da

commit 20056f0e5a7fe8df85a9934150d32594d6fe84da
Author:     ShengYi Hung <aokblast@FreeBSD.org>
AuthorDate: 2025-07-11 03:55:37 +0000
Commit:     ShengYi Hung <aokblast@FreeBSD.org>
CommitDate: 2025-08-06 14:05:40 +0000

    libusb: implement libusb_get_platform_descriptor
    
    This adds a function introduced in libusb 1.0.27 to parse
    platform-specific USB descriptors, enabling access to vendor- or OS-specific information.
    
    Approved by:    lwhsu (mentor)
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D51242
---
 lib/libusb/libusb.3        | 15 ++++++++++++++
 lib/libusb/libusb.h        | 13 ++++++++++++
 lib/libusb/libusb10_desc.c | 51 +++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3
index 09140c914d68..607a7f645d95 100644
--- a/lib/libusb/libusb.3
+++ b/lib/libusb/libusb.3
@@ -544,6 +544,21 @@ libusb_free_container_id_descriptor function.
 .Fn libusb_free_container_id_descriptor "struct libusb_container_id_descriptor *container_id"
 This function is NULL safe and frees a parsed container ID descriptor given by
 .Fa container_id .
+.Pp
+.Ft int
+.Fn libusb_get_platform_descriptor "struct libusb_context *ctx" "struct libusb_bos_dev_capability_descriptor *dev_cap" "struct libusb_platform_descriptor **platform_descriptor"
+This function parses the platform descriptor from the descriptor given by
+.Fa dev_cap
+and stores a pointer to the parsed descriptor into
+.Fa platform_descriptor .
+Returns zero on success and a LIBUSB_ERROR code on failure.
+On success the parsed platform descriptor must be freed using the
+libusb_free_platform_descriptor function.
+.Pp
+.Ft void
+.Fn libusb_free_platform_descriptor "struct libusb_platform_descriptor *platform_descriptor"
+This function is NULL safe and frees a parsed platform descriptor given by
+.Fa platform_descriptor .
 .Sh USB ASYNCHRONOUS I/O
 .Ft struct libusb_transfer *
 .Fn libusb_alloc_transfer "int iso_packets"
diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h
index a2ce4136f82a..623b56fb273b 100644
--- a/lib/libusb/libusb.h
+++ b/lib/libusb/libusb.h
@@ -107,6 +107,7 @@ enum libusb_device_capability_type {
 #define	LIBUSB_BT_USB_2_0_EXTENSION_SIZE	7
 #define	LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE	10
 #define	LIBUSB_BT_CONTAINER_ID_SIZE		20
+#define	LIBUSB_BT_PLATFORM_DESCRIPTOR_MIN_SIZE	20
 
 #define	LIBUSB_ENDPOINT_ADDRESS_MASK	0x0f
 #define	LIBUSB_ENDPOINT_DIR_MASK	0x80
@@ -189,6 +190,7 @@ enum libusb_bos_type {
 	LIBUSB_BT_USB_2_0_EXTENSION = 2,
 	LIBUSB_BT_SS_USB_DEVICE_CAPABILITY = 3,
 	LIBUSB_BT_CONTAINER_ID = 4,
+	LIBUSB_BT_PLATFORM_DESCRIPTOR = 5,
 };
 
 enum libusb_capability {
@@ -446,6 +448,15 @@ typedef struct libusb_container_id_descriptor {
 	uint8_t ContainerID[16];
 }	libusb_container_id_descriptor __aligned(sizeof(void *));
 
+typedef struct libusb_platform_descriptor {
+	uint8_t bLength;
+	uint8_t bDescriptorType;
+	uint8_t bDevCapabilityType;
+	uint8_t bReserved;
+	uint8_t PlatformCapabilityUUID[16];
+	uint8_t CapabilityData[];
+}	libusb_platform_descriptor __aligned(sizeof(void *));
+
 typedef struct libusb_control_setup {
 	uint8_t	bmRequestType;
 	uint8_t	bRequest;
@@ -554,6 +565,8 @@ int	libusb_get_ss_usb_device_capability_descriptor(struct libusb_context *ctx, s
 void	libusb_free_ss_usb_device_capability_descriptor(struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_capability);
 int	libusb_get_container_id_descriptor(struct libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_container_id_descriptor **container_id);
 void	libusb_free_container_id_descriptor(struct libusb_container_id_descriptor *container_id);
+int	libusb_get_platform_descriptor(libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_platform_descriptor **platform_descriptor);
+void	libusb_free_platform_descriptor(struct libusb_platform_descriptor *platform_descriptor);
 
 /* Asynchronous device I/O */
 
diff --git a/lib/libusb/libusb10_desc.c b/lib/libusb/libusb10_desc.c
index 5f4c46740688..7da5c84f4ad2 100644
--- a/lib/libusb/libusb10_desc.c
+++ b/lib/libusb/libusb10_desc.c
@@ -711,6 +711,55 @@ void
 libusb_free_container_id_descriptor(
     struct libusb_container_id_descriptor *container_id)
 {
-
 	free(container_id);
 }
+
+int
+libusb_get_platform_descriptor(libusb_context *ctx,
+    struct libusb_bos_dev_capability_descriptor *bos_cap,
+    struct libusb_platform_descriptor **pd)
+{
+	struct libusb_platform_descriptor *desc;
+	uint8_t *cap_data;
+
+	if (bos_cap == NULL ||
+	    bos_cap->bDescriptorType != LIBUSB_BT_PLATFORM_DESCRIPTOR ||
+	    pd == NULL)
+		return (LIBUSB_ERROR_INVALID_PARAM);
+
+	if (bos_cap->bLength < LIBUSB_BT_PLATFORM_DESCRIPTOR_MIN_SIZE)
+		return (LIBUSB_ERROR_IO);
+
+	cap_data = bos_cap->dev_capability_data;
+	desc = calloc(1, bos_cap->bLength);
+	if (desc == NULL)
+		return (LIBUSB_ERROR_NO_MEM);
+
+	desc->bLength = bos_cap->bLength;
+	desc->bDescriptorType = LIBUSB_BT_PLATFORM_DESCRIPTOR;
+	desc->bDevCapabilityType = bos_cap->bDevCapabilityType;
+	desc->bReserved = cap_data[0];
+	memcpy(desc->PlatformCapabilityUUID, cap_data + 1,
+	    sizeof(desc->PlatformCapabilityUUID));
+
+	/*
+	 * UUID (16 bytes) + bReserved
+	 */
+	cap_data += sizeof(desc->PlatformCapabilityUUID) + 1;
+	/*
+	 * UUID (16 bytes) + bReserved + bLength + bDescriptortype +
+	 * bDevCapabilitytype
+	 */
+	memcpy(desc->CapabilityData, cap_data,
+	    bos_cap->bLength - (sizeof(desc->PlatformCapabilityUUID) + 4));
+	*pd = desc;
+
+	return (LIBUSB_SUCCESS);
+}
+
+void
+libusb_free_platform_descriptor(
+    struct libusb_platform_descriptor *platform_descriptor)
+{
+	free(platform_descriptor);
+}



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