This patch teaches the "avoid proprietary configurations"
heuristic about RNDIS, which cloaks itself as CDC ACM.

That lets Linux work with some cable modems that behaved
fine on 2.4 kernels.  Like some normal telecomm modems,
these have a MSFT-oriented configuration in addition to
one that's more openly developed/specified ... and which
works on most non-MSFT host operating systems.

Please merge.

- Dave




[USB] usbcore avoids RNDIS configuration.

Modifies the "choose a configuration" heuristic to recognize the other
case that 2.4 handled:  RNDIS, a MSFT protocol that's sometimes used as
the first/default configuration (as specified by MSFT) on cable modems.
CDC Ethernet is vendor-neutral, and preferred (except by MSFT).

The initial version didn't catch RNDIS because it cloaks its ethernet
links as a kind of CDC ACM (modem) device.


--- 1.151/drivers/usb/core/usb.c        Tue Dec 30 03:34:27 2003
+++ edited/drivers/usb/core/usb.c       Wed Feb 18 10:55:27 2004
@@ -1152,12 +1152,19 @@
        config = dev->config[0].desc.bConfigurationValue;
        if (dev->descriptor.bNumConfigurations != 1) {
                for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
+                       struct usb_interface_descriptor *desc;
+
                        /* 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)
+                       desc = &dev->config[i].interface[0]
+                                       ->altsetting->desc;
+                       if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
+                               continue;
+                       /* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS */
+                       if (desc->bInterfaceClass == USB_CLASS_COMM
+                                       && desc->bInterfaceSubClass == 2
+                                       && desc->bInterfaceProtocol == 0xff)
                                continue;
                        config = dev->config[i].desc.bConfigurationValue;
                        break;


Reply via email to