PERFORCE change 161348 for review
Sylvestre Gallon
syl at FreeBSD.org
Wed Apr 29 19:15:57 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=161348
Change 161348 by syl at 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);
}
More information about the p4-projects
mailing list