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>