Linux: fix caching of active configuration for non-sysfs
authorDaniel Drake <dsd@gentoo.org>
Sat, 10 May 2008 19:56:44 +0000 (20:56 +0100)
committerDaniel Drake <dsd@gentoo.org>
Sat, 10 May 2008 19:56:44 +0000 (20:56 +0100)
TODO
libusb/descriptor.c
libusb/libusbi.h
libusb/os/linux_usbfs.c

diff --git a/TODO b/TODO
index 2b53246..f1e4345 100644 (file)
--- 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
 
index 8814ced..f545c7f 100644 (file)
@@ -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
index c807903..a59a5e6 100644 (file)
@@ -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 */
 
index 957900a..4c0fb41 100644 (file)
@@ -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;