PERFORCE change 166123 for review

Hans Petter Selasky hselasky at FreeBSD.org
Wed Jul 15 09:32:53 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=166123

Change 166123 by hselasky at hselasky_laptop001 on 2009/07/15 09:32:44

	
	LibUSB v1.0:
	
	- Cleanup "libusb_get_config_descriptor()". 
	
	- Make sure that the extra fields in the configuration
	descriptor gets properly allocated.
	
	- Optimise "libusb_get_config_descriptor_by_value()".

Affected files ...

.. //depot/projects/usb/src/lib/libusb/libusb10_desc.c#6 edit

Differences ...

==== //depot/projects/usb/src/lib/libusb/libusb10_desc.c#6 (text+ko) ====

@@ -23,10 +23,10 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/queue.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <pthread.h>
+#include <sys/queue.h>
 
 #include "libusb20.h"
 #include "libusb20_desc.h"
@@ -37,15 +37,11 @@
 /* USB descriptors */
 
 int
-libusb_get_device_descriptor(libusb_device * dev,
+libusb_get_device_descriptor(libusb_device *dev,
     struct libusb_device_descriptor *desc)
 {
 	struct LIBUSB20_DEVICE_DESC_DECODED *pdesc;
 	struct libusb20_device *pdev;
-	libusb_context *ctx;
-
-	ctx = GET_CONTEXT(NULL);
-	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_descriptor enter");
 
 	if ((dev == NULL) || (desc == NULL))
 		return (LIBUSB_ERROR_INVALID_PARAM);
@@ -68,52 +64,47 @@
 	desc->iSerialNumber = pdesc->iSerialNumber;
 	desc->bNumConfigurations = pdesc->bNumConfigurations;
 
-	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_descriptor leave");
 	return (0);
 }
 
 int
-libusb_get_active_config_descriptor(libusb_device * dev,
+libusb_get_active_config_descriptor(libusb_device *dev,
     struct libusb_config_descriptor **config)
 {
 	struct libusb20_device *pdev;
-	libusb_context *ctx;
-	uint8_t idx;
-
-	ctx = GET_CONTEXT(NULL);
-	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_active_config_descriptor enter");
+	uint8_t config_index;
 
 	pdev = dev->os_priv;
-	idx = libusb20_dev_get_config_index(pdev);
+	config_index = libusb20_dev_get_config_index(pdev);
 
-	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_active_config_descriptor leave");
-	return (libusb_get_config_descriptor(dev, idx, config));
+	return (libusb_get_config_descriptor(dev, config_index, config));
 }
 
-/*
- * XXX Need to check if extra need a dup because
- * XXX free pconf could free this char *
- */
 int
-libusb_get_config_descriptor(libusb_device * dev, uint8_t config_index,
+libusb_get_config_descriptor(libusb_device *dev, uint8_t config_index,
     struct libusb_config_descriptor **config)
 {
 	struct libusb20_device *pdev;
 	struct libusb20_config *pconf;
 	struct libusb20_interface *pinf;
 	struct libusb20_endpoint *pend;
-	libusb_interface_descriptor *ifd;
-	libusb_endpoint_descriptor *endd;
-	libusb_context *ctx;
-	uint8_t nif, nend, nalt, i, j, k;
-	uint32_t if_idx, endp_idx;
+	struct libusb_config_descriptor *pconfd;
+	struct libusb_interface_descriptor *ifd;
+	struct libusb_endpoint_descriptor *endd;
+	uint8_t *pextra;
+	uint16_t nextra;
+	uint8_t nif;
+	uint8_t nep;
+	uint8_t nalt;
+	uint8_t i;
+	uint8_t j;
+	uint8_t k;
 
-	ctx = GET_CONTEXT(NULL);
-	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_config_descriptor enter");
-
 	if (dev == NULL || config == NULL)
 		return (LIBUSB_ERROR_INVALID_PARAM);
 
+	*config = NULL;
+
 	pdev = dev->os_priv;
 	pconf = libusb20_dev_alloc_config(pdev, config_index);
 
@@ -121,75 +112,101 @@
 		return (LIBUSB_ERROR_NOT_FOUND);
 
 	nalt = nif = pconf->num_interface;
-	nend = 0;
-	for (i = 0 ; i < nif ; i++) {
-		if (pconf->interface[i].num_altsetting > 0)
-		{
-			nalt += pconf->interface[i].num_altsetting;
-			for (j = 0 ; j < nalt ; j++) {
-				nend += pconf->interface[i].altsetting[j].num_endpoints;
+	nep = 0;
+	nextra = pconf->extra.len;
+
+	for (i = 0; i < nif; i++) {
+
+		pinf = pconf->interface + i;
+		nextra += pinf->extra.len;
+		nep += pinf->num_endpoints;
+		k = pinf->num_endpoints;
+		pend = pinf->endpoints;
+		while (k--) {
+			nextra += pend->extra.len;
+			pend++;
+		}
+
+		j = pinf->num_altsetting;
+		nalt += pinf->num_altsetting;
+		pinf = pinf->altsetting;
+		while (j--) {
+			nextra += pinf->extra.len;
+			nep += pinf->num_endpoints;
+			k = pinf->num_endpoints;
+			pend = pinf->endpoints;
+			while (k--) {
+				nextra += pend->extra.len;
+				pend++;
 			}
+			pinf++;
 		}
-		nend += pconf->interface[i].num_endpoints;
 	}
 
-	*config = malloc(sizeof(libusb_config_descriptor) + 
+	nextra = nextra +
+	    (1 * sizeof(libusb_config_descriptor)) +
 	    (nif * sizeof(libusb_interface)) +
 	    (nalt * sizeof(libusb_interface_descriptor)) +
-	    (nend * sizeof(libusb_endpoint_descriptor)));
-	if (*config == NULL) {
+	    (nep * sizeof(libusb_endpoint_descriptor));
+
+	pconfd = malloc(nextra);
+
+	if (pconfd == NULL) {
 		free(pconf);
 		return (LIBUSB_ERROR_NO_MEM);
 	}
+	/* make sure memory is clean */
+	memset(pconfd, 0, nextra);
 
-	(*config)->interface = (libusb_interface *)(*config + 
+	pconfd->interface = (libusb_interface *) (pconfd +
 	    sizeof(libusb_config_descriptor));
-	for (i = if_idx = endp_idx = 0 ; i < nif ; if_idx++, i++) {
-		(*config)->interface[i].altsetting = (libusb_interface_descriptor *)
-		    (*config + sizeof(libusb_config_descriptor) +
-		    (nif * sizeof(libusb_interface)) +
-		    (if_idx * sizeof(libusb_interface_descriptor)));
-		(*config)->interface[i].altsetting[0].endpoint = 
-		    (libusb_endpoint_descriptor *) (*config +
-	   	    sizeof(libusb_config_descriptor) +
-		    (nif * sizeof(libusb_interface)) +
-		    (nalt * sizeof(libusb_interface_descriptor)) +
-		    (endp_idx * sizeof(libusb_endpoint_descriptor)));
-		    endp_idx += pconf->interface[i].num_endpoints;
+
+	ifd = (libusb_interface_descriptor *) (pconfd->interface + nif);
+	endd = (libusb_endpoint_descriptor *) (ifd + nalt);
+	pextra = (uint8_t *)(endd + nep);
+
+	/* fill in config descriptor */
+
+	pconfd->bLength = pconf->desc.bLength;
+	pconfd->bDescriptorType = pconf->desc.bDescriptorType;
+	pconfd->wTotalLength = pconf->desc.wTotalLength;
+	pconfd->bNumInterfaces = pconf->desc.bNumInterfaces;
+	pconfd->bConfigurationValue = pconf->desc.bConfigurationValue;
+	pconfd->iConfiguration = pconf->desc.iConfiguration;
+	pconfd->bmAttributes = pconf->desc.bmAttributes;
+	pconfd->MaxPower = pconf->desc.bMaxPower;
+
+	if (pconf->extra.len != 0) {
+		pconfd->extra_length = pconf->extra.len;
+		pconfd->extra = pextra;
+		memcpy(pextra, pconf->extra.ptr, pconfd->extra_length);
+		pextra += pconfd->extra_length;
+	}
+	/* setup all interface and endpoint pointers */
+
+	for (i = 0; i < nif; i++) {
+
+		pconfd->interface[i].altsetting = ifd;
+		ifd->endpoint = endd;
+		endd += pconf->interface[i].num_endpoints;
+		ifd++;
 
-		if (pconf->interface[i].num_altsetting > 0)
-		{
-			for (j = 0 ; j < pconf->interface[i].num_altsetting ; j++, if_idx++) {
-				(*config)->interface[i].altsetting[j + 1].endpoint = 
-		    		(libusb_endpoint_descriptor *) (*config +
-	   	    		sizeof(libusb_config_descriptor) +
-		    		(nif * sizeof(libusb_interface)) +
-		    		(nalt * sizeof(libusb_interface_descriptor)) +
-		    		(endp_idx * sizeof(libusb_endpoint_descriptor)));
-				endp_idx += pconf->interface[i].altsetting[j].num_endpoints;
-			}
+		for (j = 0; j < pconf->interface[i].num_altsetting; j++) {
+			ifd->endpoint = endd;
+			endd += pconf->interface[i].altsetting[j].num_endpoints;
+			ifd++;
 		}
 	}
 
-	(*config)->bLength = pconf->desc.bLength;
-	(*config)->bDescriptorType = pconf->desc.bDescriptorType;
-	(*config)->wTotalLength = pconf->desc.wTotalLength;
-	(*config)->bNumInterfaces = pconf->desc.bNumInterfaces;
-	(*config)->bConfigurationValue = pconf->desc.bConfigurationValue;
-	(*config)->iConfiguration = pconf->desc.iConfiguration;
-	(*config)->bmAttributes = pconf->desc.bmAttributes;
-	(*config)->MaxPower = pconf->desc.bMaxPower;
-	(*config)->extra_length = pconf->extra.len;
-	if ((*config)->extra_length != 0)
-		(*config)->extra = pconf->extra.ptr;
+	/* fill in all interface and endpoint data */
 
-	for (i = 0 ; i < nif ; i++) {
+	for (i = 0; i < nif; i++) {
 		pinf = &pconf->interface[i];
-		(*config)->interface[i].num_altsetting = pinf->num_altsetting + 1;
-		for (j = 0 ; j < (*config)->interface[i].num_altsetting ; j++) {
+		pconfd->interface[i].num_altsetting = pinf->num_altsetting + 1;
+		for (j = 0; j < pconfd->interface[i].num_altsetting; j++) {
 			if (j != 0)
 				pinf = &pconf->interface[i].altsetting[j - 1];
-			ifd = &(*config)->interface[i].altsetting[j];
+			ifd = &pconfd->interface[i].altsetting[j];
 			ifd->bLength = pinf->desc.bLength;
 			ifd->bDescriptorType = pinf->desc.bDescriptorType;
 			ifd->bInterfaceNumber = pinf->desc.bInterfaceNumber;
@@ -199,10 +216,13 @@
 			ifd->bInterfaceSubClass = pinf->desc.bInterfaceSubClass;
 			ifd->bInterfaceProtocol = pinf->desc.bInterfaceProtocol;
 			ifd->iInterface = pinf->desc.iInterface;
-			ifd->extra_length = pinf->extra.len;
-			if (ifd->extra_length != 0)
-				ifd->extra = pinf->extra.ptr;
-			for (k = 0 ; k < pinf->num_endpoints ; k++) {
+			if (pinf->extra.len != 0) {
+				ifd->extra_length = pinf->extra.len;
+				ifd->extra = pextra;
+				memcpy(pextra, pinf->extra.ptr, pinf->extra.len);
+				pextra += pinf->extra.len;
+			}
+			for (k = 0; k < pinf->num_endpoints; k++) {
 				pend = &pinf->endpoints[k];
 				endd = &ifd->endpoint[k];
 				endd->bLength = pend->desc.bLength;
@@ -213,79 +233,71 @@
 				endd->bInterval = pend->desc.bInterval;
 				endd->bRefresh = pend->desc.bRefresh;
 				endd->bSynchAddress = pend->desc.bSynchAddress;
-				endd->extra_length = pend->extra.len;
-				if (endd->extra_length != 0)
-					endd->extra = pend->extra.ptr;
+				if (pend->extra.len != 0) {
+					endd->extra_length = pend->extra.len;
+					endd->extra = pextra;
+					memcpy(pextra, pend->extra.ptr, pend->extra.len);
+					pextra += pend->extra.len;
+				}
 			}
-		}	
+		}
 	}
 
 	free(pconf);
-	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_config_descriptor leave");
-	return (0);
+
+	*config = pconfd;
+
+	return (0);			/* success */
 }
 
 int
-libusb_get_config_descriptor_by_value(libusb_device * dev,
+libusb_get_config_descriptor_by_value(libusb_device *dev,
     uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
 {
 	struct LIBUSB20_DEVICE_DESC_DECODED *pdesc;
 	struct libusb20_device *pdev;
-	struct libusb20_config *pconf;
-	libusb_context *ctx;
 	int i;
-
-	ctx = GET_CONTEXT(NULL);
-	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_config_descriptor_by_value enter");
+	int err;
 
 	if (dev == NULL || config == NULL)
 		return (LIBUSB_ERROR_INVALID_PARAM);
-	
+
 	pdev = dev->os_priv;
 	pdesc = libusb20_dev_get_device_desc(pdev);
 
-	for (i = 0 ; i < pdesc->bNumConfigurations ; i++) {
-		pconf = libusb20_dev_alloc_config(pdev, i);
-	       	if (pconf->desc.bConfigurationValue == bConfigurationValue) {
-			free(pconf);
-			return libusb_get_config_descriptor(dev, i, config);	
+	for (i = 0; i < pdesc->bNumConfigurations; i++) {
+		err = libusb_get_config_descriptor(dev, i, config);
+		if (err)
+			return (err);
+
+		if ((*config)->bConfigurationValue == bConfigurationValue)
+			return (0);	/* success */
 
-		}
-		free(pconf);
+		libusb_free_config_descriptor(*config);
 	}
 
-	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_config_descriptor_by_value leave");
+	*config = NULL;
+
 	return (LIBUSB_ERROR_NOT_FOUND);
 }
 
 void
 libusb_free_config_descriptor(struct libusb_config_descriptor *config)
 {
-	libusb_context *ctx;
-
-	ctx = GET_CONTEXT(NULL);
-	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_config_descriptor enter");
-
 	free(config);
-	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_config_descriptor leave");
 }
 
 int
-libusb_get_string_descriptor_ascii(libusb_device_handle * dev,
+libusb_get_string_descriptor_ascii(libusb_device_handle *pdev,
     uint8_t desc_index, unsigned char *data, int length)
 {
-	struct libusb20_device *pdev;
-	libusb_context *ctx;
+	if (pdev == NULL || data == NULL || length < 1)
+		return (LIBUSB20_ERROR_INVALID_PARAM);
 
-	ctx = GET_CONTEXT(NULL);
-	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_string_descriptor_ascii enter");
+	/* put some default data into the destination buffer */
+	data[0] = 0;
 
-	if (dev == NULL || data == NULL)
-		return (LIBUSB20_ERROR_INVALID_PARAM);
-
-	pdev = dev->os_priv;
-	DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_string_descriptor_ascii leave");
-	if (libusb20_dev_req_string_simple_sync(pdev, desc_index, 
+	if (libusb20_dev_req_string_simple_sync(pdev, desc_index,
 	    data, length) == 0)
 		return (strlen(data));
 


More information about the p4-projects mailing list