Author: hselasky
Date: Thu Jun 16 16:17:29 2016
New Revision: 301968
URL: https://svnweb.freebsd.org/changeset/base/301968

Log:
  Add multiple missing descriptor parsing functions to the LibUSB v1.0 API.
  
  Approved by:  re (kib)
  Requested by: swills
  MFC after:    1 week

Modified:
  head/lib/libusb/Makefile
  head/lib/libusb/libusb.3
  head/lib/libusb/libusb.h
  head/lib/libusb/libusb10_desc.c

Modified: head/lib/libusb/Makefile
==============================================================================
--- head/lib/libusb/Makefile    Thu Jun 16 15:25:37 2016        (r301967)
+++ head/lib/libusb/Makefile    Thu Jun 16 16:17:29 2016        (r301968)
@@ -109,8 +109,16 @@ MLINKS += libusb.3 libusb_get_string_des
 MLINKS += libusb.3 libusb_get_string_descriptor_ascii.3
 MLINKS += libusb.3 libusb_parse_ss_endpoint_comp.3
 MLINKS += libusb.3 libusb_free_ss_endpoint_comp.3
+MLINKS += libusb.3 libusb_get_ss_endpoint_companion_descriptor.3
+MLINKS += libusb.3 libusb_free_ss_endpoint_companion_descriptor.3
 MLINKS += libusb.3 libusb_parse_bos_descriptor.3
 MLINKS += libusb.3 libusb_free_bos_descriptor.3
+MLINKS += libusb.3 libusb_get_usb_2_0_extension_descriptor.3
+MLINKS += libusb.3 libusb_free_usb_2_0_extension_descriptor.3
+MLINKS += libusb.3 libusb_get_ss_usb_device_capability_descriptor.3
+MLINKS += libusb.3 libusb_free_ss_usb_device_capability_descriptor.3
+MLINKS += libusb.3 libusb_get_container_id_descriptor.3
+MLINKS += libusb.3 libusb_free_container_id_descriptor.3
 MLINKS += libusb.3 libusb_alloc_transfer.3
 MLINKS += libusb.3 libusb_free_transfer.3
 MLINKS += libusb.3 libusb_submit_transfer.3

Modified: head/lib/libusb/libusb.3
==============================================================================
--- head/lib/libusb/libusb.3    Thu Jun 16 15:25:37 2016        (r301967)
+++ head/lib/libusb/libusb.3    Thu Jun 16 16:17:29 2016        (r301968)
@@ -376,7 +376,31 @@ freed using the libusb_free_ss_endpoint_
 .Pp
 .Ft void
 .Fn libusb_free_ss_endpoint_comp "libusb_ss_endpoint_companion_descriptor 
*ep_comp"
-This function is NULL safe and frees a parsed USB 3.0 endpoint companion 
descriptor.
+This function is NULL safe and frees a parsed USB 3.0 endpoint companion 
descriptor given by
+.Fa ep_comp .
+.Pp
+.Ft int
+.Fn libusb_get_ss_endpoint_companion_descriptor "struct libusb_context *ctx" 
"const struct libusb_endpoint_descriptor *endpoint" "struct 
libusb_ss_endpoint_companion_descriptor **ep_comp"
+This function finds and parses the USB 3.0 endpoint companion descriptor given 
by
+.Fa endpoint .
+Returns zero on success and a LIBUSB_ERROR code on failure.
+On success the parsed USB 3.0 endpoint companion descriptor must be
+freed using the libusb_free_ss_endpoint_companion_descriptor function.
+.Pp
+.Ft void
+.Fn libusb_free_ss_endpoint_companion_descriptor "struct 
libusb_ss_endpoint_companion_descriptor *ep_comp"
+This function is NULL safe and frees a parsed USB 3.0 endpoint companion 
descriptor given by
+.Fa ep_comp .
+.Pp
+.Ft int
+.Fn libusb_get_bos_descriptor "libusb_device_handle *handle" "struct 
libusb_bos_descriptor **bos"
+This function queries the USB device given by
+.Fa handle
+and stores a pointer to a parsed BOS descriptor into
+.Fa bos .
+Returns zero on success and a LIBUSB_ERROR code on failure.
+On success the parsed BOS descriptor must be
+freed using the libusb_free_bos_descriptor function.
 .Pp
 .Ft int
 .Fn libusb_parse_bos_descriptor "const void *buf" "int len" 
"libusb_bos_descriptor **bos"
@@ -392,7 +416,53 @@ libusb_free_bos_descriptor function.
 .Pp
 .Ft void
 .Fn libusb_free_bos_descriptor "libusb_bos_descriptor *bos"
-This function is NULL safe and frees a parsed BOS descriptor.
+This function is NULL safe and frees a parsed BOS descriptor given by
+.Fa bos .
+.Pp
+.Ft int
+.Fn libusb_get_usb_2_0_extension_descriptor "struct libusb_context *ctx" 
"struct libusb_bos_dev_capability_descriptor *dev_cap" "struct 
libusb_usb_2_0_extension_descriptor **usb_2_0_extension"
+This function parses the USB 2.0 extension descriptor from the descriptor 
given by
+.Fa dev_cap
+and stores a pointer to the parsed descriptor into
+.Fa usb_2_0_extension .
+Returns zero on success and a LIBUSB_ERROR code on failure.
+On success the parsed USB 2.0 extension descriptor must be freed using the
+libusb_free_usb_2_0_extension_descriptor function.
+.Pp
+.Ft void
+.Fn libusb_free_usb_2_0_extension_descriptor "struct 
libusb_usb_2_0_extension_descriptor *usb_2_0_extension"
+This function is NULL safe and frees a parsed USB 2.0 extension descriptor 
given by
+.Fa usb_2_0_extension .
+.Pp
+.Ft int
+.Fn libusb_get_ss_usb_device_capability_descriptor "struct libusb_context 
*ctx" "struct libusb_bos_dev_capability_descriptor *dev_cap" "struct 
libusb_ss_usb_device_capability_descriptor **ss_usb_device_capability"
+This function parses the SuperSpeed device capability descriptor from the 
descriptor given by
+.Fa dev_cap
+and stores a pointer to the parsed descriptor into
+.Fa ss_usb_device_capability .
+Returns zero on success and a LIBUSB_ERROR code on failure.
+On success the parsed SuperSpeed device capability descriptor must be freed 
using the
+libusb_free_ss_usb_device_capability_descriptor function.
+.Pp
+.Ft void
+.Fn libusb_free_ss_usb_device_capability_descriptor "struct 
libusb_ss_usb_device_capability_descriptor *ss_usb_device_capability"
+This function is NULL safe and frees a parsed SuperSpeed device capability 
descriptor given by
+.Fa ss_usb_device_capability .
+.Pp
+.Ft int
+.Fn libusb_get_container_id_descriptor "struct libusb_context *ctx" "struct 
libusb_bos_dev_capability_descriptor *dev_cap" "struct 
libusb_container_id_descriptor **container_id"
+This function parses the container ID descriptor from the descriptor given by
+.Fa dev_cap
+and stores a pointer to the parsed descriptor into
+.Fa container_id .
+Returns zero on success and a LIBUSB_ERROR code on failure.
+On success the parsed container ID descriptor must be freed using the
+libusb_free_container_id_descriptor function.
+.Pp
+.Ft void
+.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 .
 .Sh USB ASYNCHRONOUS I/O
 .Ft struct libusb_transfer *
 .Fn libusb_alloc_transfer "int iso_packets"

Modified: head/lib/libusb/libusb.h
==============================================================================
--- head/lib/libusb/libusb.h    Thu Jun 16 15:25:37 2016        (r301967)
+++ head/lib/libusb/libusb.h    Thu Jun 16 16:17:29 2016        (r301968)
@@ -101,6 +101,10 @@ enum libusb_device_capability_type {
 #define        LIBUSB_USB_2_0_EXTENSION_DEVICE_CAPABILITY_SIZE 7
 #define        LIBUSB_SS_USB_DEVICE_CAPABILITY_SIZE    10
 
+#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_ENDPOINT_ADDRESS_MASK    0x0f
 #define        LIBUSB_ENDPOINT_DIR_MASK        0x80
 
@@ -165,6 +169,13 @@ enum libusb_iso_usage_type {
        LIBUSB_ISO_USAGE_TYPE_IMPLICIT = 2,
 };
 
+enum libusb_bos_type {
+       LIBUSB_BT_WIRELESS_USB_DEVICE_CAPABILITY = 1,
+       LIBUSB_BT_USB_2_0_EXTENSION = 2,
+       LIBUSB_BT_SS_USB_DEVICE_CAPABILITY = 3,
+       LIBUSB_BT_CONTAINER_ID = 4,
+};
+
 enum libusb_error {
        LIBUSB_SUCCESS = 0,
        LIBUSB_ERROR_IO = -1,
@@ -349,6 +360,13 @@ typedef struct libusb_ss_usb_device_capa
        uint16_t wU2DevExitLat;
 }      libusb_ss_usb_device_capability_descriptor __aligned(sizeof(void *));
 
+typedef struct libusb_bos_dev_capability_descriptor {
+       uint8_t bLength;
+       uint8_t bDescriptorType;
+       uint8_t bDevCapabilityType;
+       uint8_t dev_capability_data[0];
+}      libusb_bos_dev_capability_descriptor __aligned(sizeof(void *));
+
 typedef struct libusb_bos_descriptor {
        uint8_t bLength;
        uint8_t bDescriptorType;
@@ -358,6 +376,21 @@ typedef struct libusb_bos_descriptor {
        struct libusb_ss_usb_device_capability_descriptor *ss_usb_cap;
 }      libusb_bos_descriptor __aligned(sizeof(void *));
 
+typedef struct libusb_usb_2_0_extension_descriptor {
+       uint8_t bLength;
+       uint8_t bDescriptorType;
+       uint8_t bDevCapabilityType;
+       uint32_t bmAttributes;
+}      libusb_usb_2_0_extension_descriptor __aligned(sizeof(void *));
+
+typedef struct libusb_container_id_descriptor {
+       uint8_t bLength;
+       uint8_t bDescriptorType;
+       uint8_t bDevCapabilityType;
+       uint8_t bReserved;
+       uint8_t ContainerID[16];
+}      libusb_container_id_descriptor __aligned(sizeof(void *));
+
 typedef struct libusb_control_setup {
        uint8_t bmRequestType;
        uint8_t bRequest;
@@ -442,6 +475,8 @@ int libusb_get_active_config_descriptor(
 int    libusb_get_config_descriptor(libusb_device * dev, uint8_t config_index, 
struct libusb_config_descriptor **config);
 int    libusb_get_config_descriptor_by_value(libusb_device * dev, uint8_t 
bConfigurationValue, struct libusb_config_descriptor **config);
 void   libusb_free_config_descriptor(struct libusb_config_descriptor *config);
+int    libusb_get_ss_endpoint_companion_descriptor(struct libusb_context *ctx, 
const struct libusb_endpoint_descriptor *endpoint, struct 
libusb_ss_endpoint_companion_descriptor **ep_comp);
+void   libusb_free_ss_endpoint_companion_descriptor(struct 
libusb_ss_endpoint_companion_descriptor *ep_comp);
 int    libusb_get_string_descriptor(libusb_device_handle * devh, uint8_t 
desc_index, uint16_t langid, unsigned char *data, int length);
 int    libusb_get_string_descriptor_ascii(libusb_device_handle * devh, uint8_t 
desc_index, uint8_t *data, int length);
 int    libusb_get_descriptor(libusb_device_handle * devh, uint8_t desc_type, 
uint8_t desc_index, uint8_t *data, int length);
@@ -449,6 +484,13 @@ int        libusb_parse_ss_endpoint_comp(const 
 void   libusb_free_ss_endpoint_comp(struct 
libusb_ss_endpoint_companion_descriptor *ep_comp);
 int    libusb_parse_bos_descriptor(const void *buf, int len, struct 
libusb_bos_descriptor **bos);
 void   libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos);
+int    libusb_get_bos_descriptor(libusb_device_handle *handle, struct 
libusb_bos_descriptor **bos);
+int    libusb_get_usb_2_0_extension_descriptor(struct libusb_context *ctx, 
struct libusb_bos_dev_capability_descriptor *dev_cap, struct 
libusb_usb_2_0_extension_descriptor **usb_2_0_extension);
+void   libusb_free_usb_2_0_extension_descriptor(struct 
libusb_usb_2_0_extension_descriptor *usb_2_0_extension);
+int    libusb_get_ss_usb_device_capability_descriptor(struct libusb_context 
*ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct 
libusb_ss_usb_device_capability_descriptor **ss_usb_device_capability);
+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);
 
 /* Asynchronous device I/O */
 

Modified: head/lib/libusb/libusb10_desc.c
==============================================================================
--- head/lib/libusb/libusb10_desc.c     Thu Jun 16 15:25:37 2016        
(r301967)
+++ head/lib/libusb/libusb10_desc.c     Thu Jun 16 16:17:29 2016        
(r301968)
@@ -410,6 +410,23 @@ libusb_free_ss_endpoint_comp(struct libu
 }
 
 int
+libusb_get_ss_endpoint_companion_descriptor(struct libusb_context *ctx,
+    const struct libusb_endpoint_descriptor *endpoint,
+    struct libusb_ss_endpoint_companion_descriptor **ep_comp)
+{
+       if (endpoint == NULL)
+               return (LIBUSB_ERROR_INVALID_PARAM);
+       return (libusb_parse_ss_endpoint_comp(endpoint->extra, 
endpoint->extra_length, ep_comp));
+}
+
+void
+libusb_free_ss_endpoint_companion_descriptor(struct 
libusb_ss_endpoint_companion_descriptor *ep_comp)
+{
+
+       libusb_free_ss_endpoint_comp(ep_comp);
+}
+
+int
 libusb_parse_bos_descriptor(const void *buf, int len,
     struct libusb_bos_descriptor **bos)
 {
@@ -520,3 +537,154 @@ libusb_free_bos_descriptor(struct libusb
 
        free(bos);
 }
+
+int
+libusb_get_bos_descriptor(libusb_device_handle *handle,
+    struct libusb_bos_descriptor **bos)
+{
+       uint8_t bos_header[LIBUSB_DT_BOS_SIZE] = {0};
+       uint16_t wTotalLength;
+       uint8_t *bos_data;
+       int err;
+
+       err = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0,
+           bos_header, sizeof(bos_header));
+       if (err < 0)
+               return (err);
+
+       wTotalLength = bos_header[2] | (bos_header[3] << 8);
+       if (wTotalLength < LIBUSB_DT_BOS_SIZE)
+               return (LIBUSB_ERROR_INVALID_PARAM);
+
+       bos_data = calloc(wTotalLength, 1);
+       if (bos_data == NULL)
+               return (LIBUSB_ERROR_NO_MEM);
+
+       err = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0,
+           bos_data, wTotalLength);
+       if (err < 0)
+               goto done;
+
+       /* avoid descriptor length mismatches */
+       bos_data[2] = (wTotalLength & 0xFF);
+       bos_data[3] = (wTotalLength >> 8);
+
+       err = libusb_parse_bos_descriptor(bos_data, wTotalLength, bos);
+done:
+       free(bos_data);
+       return (err);
+}
+
+int
+libusb_get_usb_2_0_extension_descriptor(struct libusb_context *ctx,
+    struct libusb_bos_dev_capability_descriptor *dev_cap,
+    struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension)
+{
+       struct libusb_usb_2_0_extension_descriptor *desc;
+
+       if (dev_cap == NULL || usb_2_0_extension == NULL ||
+           dev_cap->bDevCapabilityType != LIBUSB_BT_USB_2_0_EXTENSION)
+               return (LIBUSB_ERROR_INVALID_PARAM);
+       if (dev_cap->bLength < LIBUSB_BT_USB_2_0_EXTENSION_SIZE)
+               return (LIBUSB_ERROR_IO);
+
+       desc = malloc(sizeof(*desc));
+       if (desc == NULL)
+               return (LIBUSB_ERROR_NO_MEM);
+
+       desc->bLength = LIBUSB_BT_USB_2_0_EXTENSION_SIZE;
+       desc->bDescriptorType = dev_cap->bDescriptorType;
+       desc->bDevCapabilityType = dev_cap->bDevCapabilityType;
+       desc->bmAttributes =
+           (dev_cap->dev_capability_data[0]) |
+           (dev_cap->dev_capability_data[1] << 8) |
+           (dev_cap->dev_capability_data[2] << 16) |
+           (dev_cap->dev_capability_data[3] << 24);
+
+       *usb_2_0_extension = desc;
+       return (0);
+}
+
+void
+libusb_free_usb_2_0_extension_descriptor(
+    struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension)
+{
+
+       free(usb_2_0_extension);
+}
+
+int
+libusb_get_ss_usb_device_capability_descriptor(struct libusb_context *ctx,
+    struct libusb_bos_dev_capability_descriptor *dev_cap,
+    struct libusb_ss_usb_device_capability_descriptor 
**ss_usb_device_capability)
+{
+       struct libusb_ss_usb_device_capability_descriptor *desc;
+
+       if (dev_cap == NULL || ss_usb_device_capability == NULL ||
+           dev_cap->bDevCapabilityType != LIBUSB_BT_SS_USB_DEVICE_CAPABILITY)
+               return (LIBUSB_ERROR_INVALID_PARAM);
+       if (dev_cap->bLength < LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE)
+               return (LIBUSB_ERROR_IO);
+
+       desc = malloc(sizeof(*desc));
+       if (desc == NULL)
+               return (LIBUSB_ERROR_NO_MEM);
+
+       desc->bLength = LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE;
+       desc->bDescriptorType = dev_cap->bDescriptorType;
+       desc->bDevCapabilityType = dev_cap->bDevCapabilityType;
+       desc->bmAttributes = dev_cap->dev_capability_data[0];
+       desc->wSpeedSupported = dev_cap->dev_capability_data[1] |
+           (dev_cap->dev_capability_data[2] << 8);
+       desc->bFunctionalitySupport = dev_cap->dev_capability_data[3];
+       desc->bU1DevExitLat = dev_cap->dev_capability_data[4];
+       desc->wU2DevExitLat = dev_cap->dev_capability_data[5] |
+           (dev_cap->dev_capability_data[6] << 8);
+
+       *ss_usb_device_capability = desc;
+       return (0);
+}
+
+void
+libusb_free_ss_usb_device_capability_descriptor(
+    struct libusb_ss_usb_device_capability_descriptor 
*ss_usb_device_capability)
+{
+
+       free(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)
+{
+       struct libusb_container_id_descriptor *desc;
+
+       if (dev_cap == NULL || container_id == NULL ||
+           dev_cap->bDevCapabilityType != LIBUSB_BT_CONTAINER_ID)
+               return (LIBUSB_ERROR_INVALID_PARAM);
+       if (dev_cap->bLength < LIBUSB_BT_CONTAINER_ID_SIZE)
+               return (LIBUSB_ERROR_IO);
+
+       desc = malloc(sizeof(*desc));
+       if (desc == NULL)
+               return (LIBUSB_ERROR_NO_MEM);
+
+       desc->bLength = LIBUSB_BT_CONTAINER_ID_SIZE;
+       desc->bDescriptorType = dev_cap->bDescriptorType;
+       desc->bDevCapabilityType = dev_cap->bDevCapabilityType;
+       desc->bReserved = dev_cap->dev_capability_data[0];
+       memcpy(desc->ContainerID, dev_cap->dev_capability_data + 1,
+           sizeof(desc->ContainerID));
+
+       *container_id = desc;
+       return (0);
+}
+
+void
+libusb_free_container_id_descriptor(
+    struct libusb_container_id_descriptor *container_id)
+{
+
+       free(container_id);
+}
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to