From: Daniel Drake Date: Sat, 10 May 2008 19:56:44 +0000 (+0100) Subject: Linux: fix caching of active configuration for non-sysfs X-Git-Tag: upstream/1.0.21~1055 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8ebb4ccdfaf5f095a1c38787d909d280ea64405c;p=platform%2Fupstream%2Flibusb.git Linux: fix caching of active configuration for non-sysfs --- diff --git a/TODO b/TODO index 2b53246..f1e4345 100644 --- a/TODO +++ b/TODO @@ -5,7 +5,6 @@ review functionality missing over 0.1 endianness of control setup, issues when resubmitting transfers serialization of handle_events internal docs for OS porters -configuration handling check which messages are sent during open, claim interface, close, release unconfigured devices diff --git a/libusb/descriptor.c b/libusb/descriptor.c index 8814ced..f545c7f 100644 --- a/libusb/descriptor.c +++ b/libusb/descriptor.c @@ -557,6 +557,32 @@ err: return NULL; } +/* iterate through all configurations, returning the index of the configuration + * matching a specific bConfigurationValue in the idx output parameter, or -1 + * if the config was not found. + * returns 0 or a LIBUSB_ERROR code + */ +int usbi_get_config_index_by_value(struct libusb_device *dev, + uint8_t bConfigurationValue, int *idx) +{ + int i; + + usbi_dbg("value %d", bConfigurationValue); + for (i = 0; i < dev->num_configurations; i++) { + unsigned char tmp[6]; + int r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp)); + if (r < 0) + return r; + if (tmp[5] == bConfigurationValue) { + *idx = i; + return 0; + } + } + + *idx = -1; + return 0; +} + /** \ingroup desc * Get a USB configuration descriptor with a specific bConfigurationValue. * This is a non-blocking function which does not involve any requests being @@ -575,26 +601,12 @@ API_EXPORTED struct libusb_config_descriptor *libusb_get_config_descriptor_by_value( libusb_device *dev, uint8_t bConfigurationValue) { - int i; - int r; - int found = -1; - - usbi_dbg("value %d", bConfigurationValue); - for (i = 0; i < dev->num_configurations; i++) { - unsigned char tmp[6]; - r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp)); - if (r < 0) - return NULL; - if (tmp[5] == bConfigurationValue) { - found = 1; - break; - } - } - - if (!found) + int idx; + int r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx); + if (r < 0 || idx == -1) return NULL; else - return libusb_get_config_descriptor(dev, i); + return libusb_get_config_descriptor(dev, idx); } /** \ingroup desc diff --git a/libusb/libusbi.h b/libusb/libusbi.h index c807903..a59a5e6 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -229,6 +229,8 @@ void usbi_handle_transfer_completion(struct usbi_transfer *itransfer, void usbi_handle_transfer_cancellation(struct usbi_transfer *transfer); int usbi_parse_descriptor(unsigned char *source, char *descriptor, void *dest); +int usbi_get_config_index_by_value(struct libusb_device *dev, + uint8_t bConfigurationValue, int *idx); /* polling */ diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index 957900a..4c0fb41 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -383,10 +383,16 @@ static int cache_active_config(struct libusb_device *dev, int fd, struct libusb_config_descriptor config; unsigned char tmp[8]; unsigned char *buf; + int idx; int r; - /* FIXME */ - r = get_config_descriptor(fd, active_config, tmp, sizeof(tmp)); + r = usbi_get_config_index_by_value(dev, active_config, &idx); + if (r < 0) + return r; + if (idx == -1) + return LIBUSB_ERROR_NOT_FOUND; + + r = get_config_descriptor(fd, idx, tmp, sizeof(tmp)); if (r < 0) { usbi_err("first read error %d", r); return r; @@ -397,7 +403,7 @@ static int cache_active_config(struct libusb_device *dev, int fd, if (!buf) return LIBUSB_ERROR_NO_MEM; - r = get_config_descriptor(fd, active_config, buf, config.wTotalLength); + r = get_config_descriptor(fd, idx, buf, config.wTotalLength); if (r < 0) { free(buf); return r;