Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 Apr 2009 19:15:55 GMT
From:      Sylvestre Gallon <syl@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 161348 for review
Message-ID:  <200904291915.n3TJFtxA036888@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=161348

Change 161348 by syl@syl_atuin on 2009/04/29 19:15:44

	       - Change on libusb10_desc.c, following Hans Petter Selasky advices.
	       - Rewrite of libusb_get_config_descriptor. It imply a simplification
	         into libusb_free_config_descriptor.
	       - Align descriptors structures on sizeof(void *) to follow the allocation
	         scheme used by libusb20.

Affected files ...

.. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb.h#3 edit
.. //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10_desc.c#3 edit

Differences ...

==== //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb.h#3 (text+ko) ====

@@ -262,7 +262,7 @@
 	uint8_t	bSynchAddress;
 	unsigned char *extra;
 	int	extra_length;
-}	libusb_endpoint_descriptor;
+}	libusb_endpoint_descriptor __aligned(sizeof(void *));
 
 typedef struct libusb_interface_descriptor {
 	uint8_t	bLength;
@@ -277,12 +277,12 @@
 	struct libusb_endpoint_descriptor *endpoint;
 	unsigned char *extra;
 	int	extra_length;
-}	libusb_interface_descriptor;
+}	libusb_interface_descriptor __aligned(sizeof(void *));
 
 typedef struct libusb_interface {
 	struct libusb_interface_descriptor *altsetting;
 	int	num_altsetting;
-}	libusb_interface;
+}	libusb_interface __aligned(sizeof(void *));
 
 typedef struct libusb_config_descriptor {
 	uint8_t	bLength;
@@ -296,7 +296,7 @@
 	struct libusb_interface *interface;
 	unsigned char *extra;
 	int	extra_length;
-}	libusb_config_descriptor;
+}	libusb_config_descriptor __aligned(sizeof(void *));
 
 typedef struct libusb_control_setup {
 	uint8_t	bmRequestType;

==== //depot/projects/soc2009/syl_usb/src/lib/libusb/libusb10_desc.c#3 (text+ko) ====

@@ -59,9 +59,9 @@
 	desc->idProduct = pdesc->idProduct;
 	desc->bcdDevice = pdesc->bcdDevice;
 	desc->iManufacturer = pdesc->iManufacturer;
-	desc->iProduct = desc->iProduct;
-	desc->iSerialNumber = desc->iSerialNumber;
-	desc->bNumConfigurations = desc->bNumConfigurations;
+	desc->iProduct = pdesc->iProduct;
+	desc->iSerialNumber = pdesc->iSerialNumber;
+	desc->bNumConfigurations = pdesc->bNumConfigurations;
 
 	return (0);
 }
@@ -78,118 +78,167 @@
 	return (libusb_get_config_descriptor(dev, idx, config));
 }
 
-
-/*
- * Need rework, this function is pretty ugly now ...
+/* 
+ * XXX Code need to be updated concerning altsetting 
  */
 int
 libusb_get_config_descriptor(libusb_device * dev, uint8_t config_index,
     struct libusb_config_descriptor **config)
 {
-	struct LIBUSB20_CONFIG_DESC_DECODED *pdesc;
-	struct LIBUSB20_INTERFACE_DESC_DECODED *pint;
-	struct LIBUSB20_ENDPOINT_DESC_DECODED *pend;
-	libusb_config_descriptor *conf;
-	libusb_interface_descriptor *ifdesc;
-	libusb_endpoint_descriptor *enddesc;
-	const char *rawdesc;
+	struct LIBUSB20_DEVICE_DESC_DECODED ddev;
+	struct LIBUSB20_CONFIG_DESC_DECODED dconf;
+	struct LIBUSB20_INTERFACE_DESC_DECODED dinf;
+	struct LIBUSB20_ENDPOINT_DESC_DECODED dend;
 	struct libusb20_device *pdev;
-	int i, j;
+	struct libusb20_me_struct me;
+	libusb_interface_descriptor *ifd;
+	libusb_endpoint_descriptor *endd;
+	uint8_t nif, nend, i, j;
+	const char *ptr;
+	char *ptr_save;
 
-	if ((dev == NULL) || (config == NULL))
-		return (LIBUSB_ERROR_NO_MEM);
-	
-	*config = conf = malloc(sizeof(struct libusb_config_descriptor));
-	if (conf == NULL)
+	if (dev == NULL || config == NULL)
 		return (LIBUSB_ERROR_NO_MEM);
 
-	if (config_index > dev->num_configurations)
-		return (LIBUSB_ERROR_NOT_FOUND);
+	LIBUSB20_INIT(LIBUSB20_DEVICE_DESC, &ddev);
+	LIBUSB20_INIT(LIBUSB20_CONFIG_DESC, &dconf);
+	LIBUSB20_INIT(LIBUSB20_INTERFACE_DESC, &dinf);
+	LIBUSB20_INIT(LIBUSB20_ENDPOINT_DESC, &dend);
 
 	pdev = dev->os_priv;
-	rawdesc = libusb20_dev_get_desc(pdev);
+	ptr = libusb20_dev_get_desc(pdev);
+
+	/*
+	 * Get the good configuration.
+	 */
+
+	me.ptr = LIBUSB20_ADD_BYTES(ptr,0);
+	me.len = strlen(ptr);
+	me.type = LIBUSB20_ME_IS_RAW;
 
-	j = 0x12;
-	for (i = 0 ; i < dev->num_configurations && i != config_index ; i++) {
-		pdesc = (struct LIBUSB20_CONFIG_DESC_DECODED *) 
-	   	     &rawdesc[j];
-		j += pdesc->wTotalLength;
+	while ((ptr = libusb20_desc_foreach(&me, ptr))) {
+		switch (ptr[1]) {
+			case LIBUSB20_DT_DEVICE:
+				libusb20_me_decode(ptr, ptr[0], &ddev);
+				if (ddev.bNumConfigurations < config_index)
+					return LIBUSB_ERROR_NOT_FOUND;
+				break;
+			case LIBUSB20_DT_CONFIG:
+				libusb20_me_decode(ptr, ptr[0], &dconf);
+				if (dconf.bConfigurationValue == config_index)
+					goto out;
+				break;
+			default:
+				break;
+		}
 	}
-	
-	conf->bLength = pdesc->bLength;
-	conf->bDescriptorType = pdesc->bDescriptorType;
-	conf->wTotalLength = pdesc->wTotalLength;
-	conf->bNumInterfaces = pdesc->bNumInterfaces;
-	conf->bConfigurationValue = pdesc->bConfigurationValue;
-	conf->iConfiguration = pdesc->iConfiguration;
-	conf->bmAttributes = pdesc->bmAttributes;
-	conf->MaxPower = pdesc->bMaxPower;
+
+out:
+	if (ptr[1] != LIBUSB20_DT_CONFIG)
+		return (LIBUSB_ERROR_NOT_FOUND);
+
+	/*
+	 * Get number of interfaces and enpoints for allocation
+	 */
 
-	conf->interface = malloc(pdesc->bNumInterfaces * sizeof(*(conf->interface)));
-	pint = (struct LIBUSB20_INTERFACE_DESC_DECODED *)
-	    ((uint32_t)pdesc + (uint32_t)pdesc->bLength);
+	me.ptr = LIBUSB20_ADD_BYTES(ptr, 0);
+	me.len = dconf.wTotalLength;
+	me.type = LIBUSB20_ME_IS_RAW;
 
-	for (i = 0 ; i < conf->bNumInterfaces ; i++) {
-		conf->interface[i].num_altsetting = pdesc->bNumInterfaces;
-		ifdesc = malloc(sizeof(*(conf->interface[i].altsetting)));
-		conf->interface[i].altsetting = ifdesc; 
+	ptr_save = (char *)ptr;
+	nif = nend = 0;
+	while ((ptr = libusb20_desc_foreach(&me, ptr))) {
+		if (ptr[1] == LIBUSB20_DT_INTERFACE)
+			nif++;
+		else if (ptr[1] == LIBUSB20_DT_ENDPOINT)
+			nend++;
+	}
 
-		ifdesc->bLength = (uint8_t)pint->bLength;
-		ifdesc->bDescriptorType = pint->bDescriptorType;
-		ifdesc->bInterfaceNumber = pint->bInterfaceNumber;
-		ifdesc->bAlternateSetting = pint->bAlternateSetting;
-		ifdesc->bNumEndpoints = pint->bNumEndpoints;
-		ifdesc->bInterfaceClass = pint->bInterfaceClass;
-		ifdesc->bInterfaceSubClass = pint->bInterfaceSubClass;
-		ifdesc->bInterfaceProtocol = pint->bInterfaceProtocol;
-		ifdesc->iInterface = pint->iInterface;
+	/*
+	 * Alloc config and fill it
+	 */
+	*config = malloc(sizeof(libusb_config_descriptor) + 
+	    (nif * sizeof(libusb_interface)) +
+	    (nif * sizeof(libusb_interface_descriptor)) +
+	    (nend * sizeof(libusb_endpoint_descriptor)));
 
-		ifdesc->endpoint = malloc(pint->bNumEndpoints * 
-		    sizeof(struct libusb_endpoint_descriptor));
-		pend = (struct LIBUSB20_ENDPOINT_DESC_DECODED *)
-		    ((uint32_t)pint + (uint32_t)ifdesc->bLength);
+	ptr = (const char *)ptr_save;
+	me.ptr = LIBUSB20_ADD_BYTES(ptr, 0);
+	me.len = dconf.wTotalLength;
+	me.type = LIBUSB20_ME_IS_RAW;
+	i = j = 0 - 1;
+	ifd = NULL;
 
-		for (j = 0 ; j < pint->bNumEndpoints ; j++) {
-			enddesc = &(ifdesc->endpoint[j]);
-			enddesc->bLength = pend->bLength;
-			enddesc->bDescriptorType = pend->bDescriptorType;
-			enddesc->bEndpointAddress = pend->bEndpointAddress;
-			enddesc->bmAttributes = pend->bmAttributes;
-			enddesc->wMaxPacketSize = pend->wMaxPacketSize;
-			enddesc->bInterval = pend->bInterval;
-			enddesc->bRefresh = pend->bRefresh;
-			enddesc->bSynchAddress = pend->bSynchAddress;
-			pend = (struct LIBUSB20_ENDPOINT_DESC_DECODED *)
-			    ((uint32_t)pend + (uint32_t)pend->bLength);
+	while (ptr = libusb20_desc_foreach(&me, ptr)) {
+		switch (ptr[i]) {
+		    case LIBUSB20_DT_INTERFACE:
+			i++;
+			j = 0 - 1;
+			libusb20_me_decode(ptr, ptr[0], &dinf);
+			(*config)->interface[i].num_altsetting = 
+			    dconf.bNumInterfaces - 1;
+			ifd = (*config)->interface[i].altsetting;
+			ifd->bLength = dinf.bLength;
+			ifd->bDescriptorType = dinf.bDescriptorType;
+			ifd->bInterfaceNumber = dinf.bInterfaceNumber;
+			ifd->bAlternateSetting = dinf.bAlternateSetting;
+			ifd->bNumEndpoints = dinf.bNumEndpoints;
+			ifd->bInterfaceClass = dinf.bInterfaceClass;
+			ifd->bInterfaceSubClass = dinf.bInterfaceSubClass;
+			ifd->bInterfaceProtocol = dinf.bInterfaceProtocol;
+			ifd->iInterface = dinf.iInterface;
+			break;
+		    case LIBUSB20_DT_ENDPOINT:
+			if (ifd != NULL) {
+				j++;
+				libusb20_me_decode(ptr, ptr[0], &dend);
+				endd = &ifd->endpoint[j];
+				endd->bLength = dend.bLength;
+				endd->bDescriptorType = dend.bDescriptorType;
+				endd->bEndpointAddress = dend.bEndpointAddress;
+				endd->bmAttributes = dend.bmAttributes;
+				endd->wMaxPacketSize = dend.wMaxPacketSize;
+				endd->bInterval = dend.bInterval;
+				endd->bRefresh = dend.bRefresh;
+				endd->bSynchAddress = dend.bSynchAddress;
+				break;
+			}
 		}
-		pint = (struct LIBUSB20_INTERFACE_DESC_DECODED*)pend;
-		/* XXX need Check on libusb10 for extra field */
 	}
+
 	return (0);
 }
 
+/*
+ * XXX Check that value means bConfigurationValue...
+ */
 int
 libusb_get_config_descriptor_by_value(libusb_device * dev,
     uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
 {
-	struct LIBUSB20_CONFIG_DESC_DECODED *pdesc;
+	struct LIBUSB20_CONFIG_DESC_DECODED *pconf;
 	struct libusb20_device *pdev;
-	const char *rawdesc;
-	int i, j;
+	struct libusb20_me_struct me;
+	const char *ptr;
 
 	if (dev == NULL || config == NULL)
 		return (LIBUSB_ERROR_NO_MEM);
 	
 	pdev = dev->os_priv;
-	rawdesc = libusb20_dev_get_desc(pdev);
+	ptr = libusb20_dev_get_desc(pdev);
+
+
+	me.ptr = LIBUSB20_ADD_BYTES(ptr, 0);
+	me.len = strlen(ptr);
+	me.type = LIBUSB20_ME_IS_RAW;
 
-	j = 0x12;
-	for (i = 0 ; i < dev->num_configurations ; i++) {
-		pdesc = (struct LIBUSB20_CONFIG_DESC_DECODED *) 
-	   	     &rawdesc[j];
-		j += pdesc->wTotalLength;
-		if (pdesc->bConfigurationValue == bConfigurationValue)
-			return (libusb_get_config_descriptor(dev, i, config));
+	while (ptr = libusb20_desc_foreach(&me, ptr)) {
+		if (ptr[1] == LIBUSB20_DT_CONFIG) {
+			pconf = (struct LIBUSB20_CONFIG_DESC_DECODED *) ptr;
+			if (pconf->bConfigurationValue == bConfigurationValue)
+				return (libusb_get_config_descriptor(dev, 
+				    pconf->bConfigurationValue , config));
+		}
 	}
 
 	return (LIBUSB_ERROR_NOT_FOUND);
@@ -198,17 +247,6 @@
 void
 libusb_free_config_descriptor(struct libusb_config_descriptor *config)
 {
-	int i, j;
-
-	for (i = 0 ; i < config->bNumInterfaces ; i++) {
-		for (j = 0 ; j < config->interface[i].altsetting->bNumEndpoints ; j++) {
-			free((void *)config->interface[i].altsetting->endpoint[j].extra);
-		}
-		free((void *)config->interface[i].altsetting->endpoint);
-		free((void *)config->interface[i].altsetting->extra);
-		free((void *)config->interface[i].altsetting);
-	}
-	free((void *)config->interface);
 	free(config);
 }
 



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