ChangeSet 1.1557.49.20, 2004/02/18 13:12:46-08:00, david-b@pacbell.net

[PATCH] USB: usbcore, avoid RNDIS configs

[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.


 drivers/usb/core/usb.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)


diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c	Thu Feb 19 17:21:27 2004
+++ b/drivers/usb/core/usb.c	Thu Feb 19 17:21: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;
