svn commit: r322322 - head/lib/libusb

Kyle Evans kevans at FreeBSD.org
Wed Aug 9 18:06:29 UTC 2017


Author: kevans
Date: Wed Aug  9 18:06:27 2017
New Revision: 322322
URL: https://svnweb.freebsd.org/changeset/base/322322

Log:
  libusb(3): Expose device caps as libusb_bos_descriptor::dev_capability
  
  Some libusb consumers in Linux-land (in this case, libusb4java) expect a
  dev_capability member that they can use to enumerate the device
  capabilities.
  
  No particular layout is expected of this, just that it can be traversed
  using the bLength member until bNumDeviceCapabilities are read and that the
  consumer may then use one of the libusb_get_*_descriptor methods to extract
  specific (usb 2.0 vs. ss) capability information.
  
  In collaboration with:	hselasky
  Reviewed by:	hselasky
  Approved by:	emaste (mentor)
  Differential Revision:	https://reviews.freebsd.org/D11494

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

Modified: head/lib/libusb/libusb.h
==============================================================================
--- head/lib/libusb/libusb.h	Wed Aug  9 17:48:38 2017	(r322321)
+++ head/lib/libusb/libusb.h	Wed Aug  9 18:06:27 2017	(r322322)
@@ -388,6 +388,7 @@ typedef struct libusb_bos_descriptor {
 	uint8_t bNumDeviceCapabilities;
 	struct libusb_usb_2_0_device_capability_descriptor *usb_2_0_ext_cap;
 	struct libusb_ss_usb_device_capability_descriptor *ss_usb_cap;
+	struct libusb_bos_dev_capability_descriptor **dev_capability;
 }	libusb_bos_descriptor __aligned(sizeof(void *));
 
 typedef struct libusb_usb_2_0_extension_descriptor {

Modified: head/lib/libusb/libusb10_desc.c
==============================================================================
--- head/lib/libusb/libusb10_desc.c	Wed Aug  9 17:48:38 2017	(r322321)
+++ head/lib/libusb/libusb10_desc.c	Wed Aug  9 18:06:27 2017	(r322322)
@@ -433,6 +433,7 @@ libusb_parse_bos_descriptor(const void *buf, int len,
 	struct libusb_bos_descriptor *ptr;
 	struct libusb_usb_2_0_device_capability_descriptor *dcap_20 = NULL;
 	struct libusb_ss_usb_device_capability_descriptor *ss_cap = NULL;
+	uint8_t index = 0;
 
 	if (buf == NULL || bos == NULL || len < 1)
 		return (LIBUSB_ERROR_INVALID_PARAM);
@@ -453,7 +454,8 @@ libusb_parse_bos_descriptor(const void *buf, int len,
 			break;
 
 		if (dlen >= LIBUSB_DT_BOS_SIZE &&
-		    dtype == LIBUSB_DT_BOS) {
+		    dtype == LIBUSB_DT_BOS &&
+		    ptr == NULL) {
 
 			ptr = malloc(sizeof(*ptr) + sizeof(*dcap_20) +
 			    sizeof(*ss_cap));
@@ -470,6 +472,11 @@ libusb_parse_bos_descriptor(const void *buf, int len,
 			ptr->bNumDeviceCapabilities = ((const uint8_t *)buf)[4];
 			ptr->usb_2_0_ext_cap = NULL;
 			ptr->ss_usb_cap = NULL;
+			ptr->dev_capability = calloc(ptr->bNumDeviceCapabilities, sizeof(void *));
+			if (ptr->dev_capability == NULL) {
+				free(ptr);
+				return (LIBUSB_ERROR_NO_MEM);
+			}
 
 			dcap_20 = (void *)(ptr + 1);
 			ss_cap = (void *)(dcap_20 + 1);
@@ -477,6 +484,15 @@ libusb_parse_bos_descriptor(const void *buf, int len,
 		if (dlen >= 3 &&
 		    ptr != NULL &&
 		    dtype == LIBUSB_DT_DEVICE_CAPABILITY) {
+			if (index != ptr->bNumDeviceCapabilities) {
+				ptr->dev_capability[index] = malloc(dlen);
+				if (ptr->dev_capability[index] == NULL) {
+					libusb_free_bos_descriptor(ptr);
+					return LIBUSB_ERROR_NO_MEM;
+				}
+				memcpy(ptr->dev_capability[index], buf, dlen);
+				index++;
+			}
 			switch (((const uint8_t *)buf)[2]) {
 			case LIBUSB_USB_2_0_EXTENSION_DEVICE_CAPABILITY:
 				if (ptr->usb_2_0_ext_cap != NULL || dcap_20 == NULL)
@@ -523,8 +539,11 @@ libusb_parse_bos_descriptor(const void *buf, int len,
 		buf = ((const uint8_t *)buf) + dlen;
 		len -= dlen;
 	}
-	if (ptr != NULL)
+
+	if (ptr != NULL) {
+		ptr->bNumDeviceCapabilities = index;
 		return (0);		/* success */
+	}
 
 	return (LIBUSB_ERROR_IO);
 }
@@ -532,9 +551,14 @@ libusb_parse_bos_descriptor(const void *buf, int len,
 void
 libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos)
 {
+	uint8_t i;
+
 	if (bos == NULL)
 		return;
 
+	for (i = 0; i != bos->bNumDeviceCapabilities; i++)
+		free(bos->dev_capability[i]);
+	free(bos->dev_capability);
 	free(bos);
 }
 


More information about the svn-src-all mailing list