U-Boot only has support for one configuration for devices.

Extract handing of selecting active configuration to a helper function
to make it easier for drivers to select a different configuration.

This include a small change in behavior, errors from parsing config
descriptors are no longer ignored and is instead returned.

Signed-off-by: Jonas Karlman <[email protected]>
---
 common/usb.c  | 59 ++++++++++++++++++++++++++++++---------------------
 include/usb.h | 10 +++++++++
 2 files changed, 45 insertions(+), 24 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index 6a4ad346f4ba..625512a1c99a 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -1149,11 +1149,38 @@ static int usb_device_is_ignored(u16 id_vendor, u16 
id_product)
        return 0;
 }
 
-int usb_select_config(struct usb_device *dev)
+int usb_select_configuration_no(struct usb_device *dev, int cfgno)
 {
        unsigned char *tmpbuf = NULL;
        int err;
 
+       err = usb_get_configuration_len(dev, cfgno);
+       if (err >= 0) {
+               tmpbuf = (unsigned char *)malloc_cache_aligned(err);
+               if (!tmpbuf)
+                       err = -ENOMEM;
+               else
+                       err = usb_get_configuration_no(dev, cfgno, tmpbuf, err);
+       }
+       if (err < 0) {
+               free(tmpbuf);
+               return err;
+       }
+
+       err = usb_parse_config(dev, tmpbuf, cfgno);
+       free(tmpbuf);
+       if (err < 0)
+               return err;
+
+       usb_set_maxpacket(dev);
+
+       return usb_set_configuration(dev, dev->config.desc.bConfigurationValue);
+}
+
+int usb_select_config(struct usb_device *dev)
+{
+       int err;
+
        err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE);
        if (err)
                return err;
@@ -1193,34 +1220,18 @@ int usb_select_config(struct usb_device *dev)
         */
        mdelay(1);
 
-       /* only support for one config for now */
-       err = usb_get_configuration_len(dev, 0);
-       if (err >= 0) {
-               tmpbuf = (unsigned char *)malloc_cache_aligned(err);
-               if (!tmpbuf)
-                       err = -ENOMEM;
-               else
-                       err = usb_get_configuration_no(dev, 0, tmpbuf, err);
-       }
-       if (err < 0) {
-               printf("usb_new_device: Cannot read configuration, " \
-                      "skipping device %04x:%04x\n",
-                      dev->descriptor.idVendor, dev->descriptor.idProduct);
-               free(tmpbuf);
-               return err;
-       }
-       usb_parse_config(dev, tmpbuf, 0);
-       free(tmpbuf);
-       usb_set_maxpacket(dev);
        /*
-        * we set the default configuration here
+        * we select the default configuration here
         * This seems premature. If the driver wants a different configuration
         * it will need to select itself.
         */
-       err = usb_set_configuration(dev, dev->config.desc.bConfigurationValue);
+       err = usb_select_configuration_no(dev, 0);
        if (err < 0) {
-               printf("failed to set default configuration " \
-                       "len %d, status %lX\n", dev->act_len, dev->status);
+               printf("failed to select default configuration " \
+                       "len %d, status %lX, " \
+                       "skipping device %04x:%04x\n",
+                       dev->act_len, dev->status,
+                       dev->descriptor.idVendor, dev->descriptor.idProduct);
                return err;
        }
 
diff --git a/include/usb.h b/include/usb.h
index 44c5d1cc5999..e9d16ee6c9fd 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -900,6 +900,16 @@ int usb_scan_device(struct udevice *parent, int port,
  */
 struct udevice *usb_get_bus(struct udevice *dev);
 
+/**
+ * usb_select_configuration_no() - Select configuration to use for a device
+ *
+ * This re-reads the configuration descriptor and sets the configuration.
+ *
+ * @dev:       Device to select configuration
+ * @cfgno:     Configuration number to set
+ */
+int usb_select_configuration_no(struct usb_device *dev, int cfgno);
+
 /**
  * usb_select_config() - Set up a device ready for use
  *
-- 
2.54.0

Reply via email to