ChangeSet 1.1337.3.6, 2003/10/23 17:03:25-07:00, [EMAIL PROTECTED]

[PATCH] USB: usbcore, better heuristic for choosing configs

Until now, the Linux-USB core has always chosen the first device
configuration, even when there was a choice.  In 2.4 kernels,
device driver probe() routines were allowed to override that
initial policy decisions.  But 2.6 kernels can't do that from
probe() routines, causing problems with some CDC-ACM modems
where the first config uses MSFT-proprietary protocols.

This patch switches to a smarter heuristic:  Linux now prefers
standard interface classes when there's a choice.  So those
CDC-ACM modems don't need a "write bConfigurationValue in sysfs"
step when they are connected; they act just like on 2.4 kernels.
(And sysfs can still be used to handle any problem cases.)


 drivers/usb/core/usb.c |   21 +++++++++++++++++----
 1 files changed, 17 insertions(+), 4 deletions(-)


diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c    Mon Dec 29 14:27:37 2003
+++ b/drivers/usb/core/usb.c    Mon Dec 29 14:27:37 2003
@@ -991,6 +991,7 @@
        int err = -EINVAL;
        int i;
        int j;
+       int config;
 
        /*
         * Set the driver for the usb device to point to the "generic" driver.
@@ -1105,18 +1106,30 @@
 
        /* choose and set the configuration. that registers the interfaces
         * with the driver core, and lets usb device drivers bind to them.
+        * NOTE:  should interact with hub power budgeting.
         */
+       config = dev->config[0].desc.bConfigurationValue;
        if (dev->descriptor.bNumConfigurations != 1) {
+               for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
+                       /* heuristic:  Linux is more likely to have class
+                        * drivers, so avoid vendor-specific interfaces.
+                        */
+                       if (dev->config[i].interface[0]->altsetting
+                                               ->desc.bInterfaceClass
+                                       == USB_CLASS_VENDOR_SPEC)
+                               continue;
+                       config = dev->config[i].desc.bConfigurationValue;
+                       break;
+               }
                dev_info(&dev->dev,
                        "configuration #%d chosen from %d choices\n",
-                       dev->config[0].desc.bConfigurationValue,
+                       config,
                        dev->descriptor.bNumConfigurations);
        }
-       err = usb_set_configuration(dev,
-                       dev->config[0].desc.bConfigurationValue);
+       err = usb_set_configuration(dev, config);
        if (err) {
                dev_err(&dev->dev, "can't set config #%d, error %d\n",
-                       dev->config[0].desc.bConfigurationValue, err);
+                       config, err);
                goto fail;
        }
 



-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials.
Become an expert in LINUX or just sharpen your skills.  Sign up for IBM's
Free Linux Tutorials.  Learn everything from the bash shell to sys admin.
Click now! http://ads.osdn.com/?ad_id78&alloc_id371&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to