From: Nathan Hjelm Date: Thu, 29 Nov 2012 20:53:41 +0000 (-0700) Subject: Core: Cache device descriptors in the core X-Git-Tag: upstream/1.0.21~502 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8399b52062e9aa2877ab6f61622fe9cb241fad57;p=platform%2Fupstream%2Flibusb.git Core: Cache device descriptors in the core Discussion: It is necessary to cache the device descriptor in the core to support reading the descriptors after a device is disconnected. We could either 1) allow each backend to handle this caching (which would most certainly duplicate code), or 2) cache the descritors when a device is added. This patch does the later. Further discussion: It might be beneficial to cache more than just the device descriptors in the core. It might also be worthwhile caching the configuration and BOS descriptors as well. Signed-off-by: Hans de Goede --- diff --git a/libusb/core.c b/libusb/core.c index 3fb3999..9a2d1b7 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -537,15 +537,13 @@ struct libusb_device *usbi_alloc_device(struct libusb_context *ctx, int usbi_sanitize_device(struct libusb_device *dev) { int r; - unsigned char raw_desc[DEVICE_DESC_LENGTH]; uint8_t num_configurations; - int host_endian; - r = usbi_backend->get_device_descriptor(dev, raw_desc, &host_endian); + r = usbi_device_cache_descriptor(dev); if (r < 0) return r; - num_configurations = raw_desc[DEVICE_DESC_LENGTH - 1]; + num_configurations = dev->device_descriptor.bNumConfigurations; if (num_configurations > USB_MAXCONFIG) { usbi_err(DEVICE_CTX(dev), "too many configurations"); return LIBUSB_ERROR_IO; diff --git a/libusb/descriptor.c b/libusb/descriptor.c index 7e47aae..505fc28 100644 --- a/libusb/descriptor.c +++ b/libusb/descriptor.c @@ -437,6 +437,25 @@ err: return r; } +int usbi_device_cache_descriptor(libusb_device *dev) +{ + int r, host_endian; + + r = usbi_backend->get_device_descriptor(dev, (unsigned char *) &dev->device_descriptor, + &host_endian); + if (r < 0) + return r; + + if (!host_endian) { + dev->device_descriptor.bcdUSB = libusb_le16_to_cpu(dev->device_descriptor.bcdUSB); + dev->device_descriptor.idVendor = libusb_le16_to_cpu(dev->device_descriptor.idVendor); + dev->device_descriptor.idProduct = libusb_le16_to_cpu(dev->device_descriptor.idProduct); + dev->device_descriptor.bcdDevice = libusb_le16_to_cpu(dev->device_descriptor.bcdDevice); + } + + return LIBUSB_SUCCESS; +} + /** \ingroup desc * Get the USB device descriptor for a given device. * @@ -449,22 +468,9 @@ err: int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev, struct libusb_device_descriptor *desc) { - unsigned char raw_desc[DEVICE_DESC_LENGTH]; - int host_endian = 0; - int r; - usbi_dbg(""); - r = usbi_backend->get_device_descriptor(dev, raw_desc, &host_endian); - if (r < 0) - return r; - - memcpy((unsigned char *) desc, raw_desc, sizeof(raw_desc)); - if (!host_endian) { - desc->bcdUSB = libusb_le16_to_cpu(desc->bcdUSB); - desc->idVendor = libusb_le16_to_cpu(desc->idVendor); - desc->idProduct = libusb_le16_to_cpu(desc->idProduct); - desc->bcdDevice = libusb_le16_to_cpu(desc->bcdDevice); - } + memcpy((unsigned char *) desc, (unsigned char *) &dev->device_descriptor, + sizeof (dev->device_descriptor)); return 0; } diff --git a/libusb/libusbi.h b/libusb/libusbi.h index 1957053..b0cc53e 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -288,6 +288,9 @@ struct libusb_device { struct list_head list; unsigned long session_data; + + struct libusb_device_descriptor device_descriptor; + unsigned char os_priv[0]; }; @@ -394,6 +397,7 @@ int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer); int usbi_parse_descriptor(unsigned char *source, const char *descriptor, void *dest, int host_endian); +int usbi_device_cache_descriptor(libusb_device *dev); int usbi_get_config_index_by_value(struct libusb_device *dev, uint8_t bConfigurationValue, int *idx); diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c index e0d2a1c..9c0888a 100644 --- a/libusb/os/windows_usb.c +++ b/libusb/os/windows_usb.c @@ -1170,6 +1170,8 @@ static int init_device(struct libusb_device* dev, struct libusb_device* parent_d force_hcd_device_descriptor(dev); } + usbi_sanitize_device(dev); + usbi_dbg("(bus: %d, addr: %d, depth: %d, port: %d): '%s'", dev->bus_number, dev->device_address, priv->depth, priv->port, device_id); diff --git a/libusb/version_nano.h b/libusb/version_nano.h index 95fb90e..a4e4971 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 10649 +#define LIBUSB_NANO 10650