mirror of
https://git.freebsd.org/src.git
synced 2026-01-11 19:57:22 +00:00
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
This commit is contained in:
parent
315dec5ce6
commit
20056f0e5a
3 changed files with 78 additions and 1 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue