Commit:     93c8bf45e083b89dffe3a708363c15c1b220c723
Parent:     6d8fc4d28deaf828606c19fb743fbe94aeab4caf
Author:     Alan Stern <[EMAIL PROTECTED]>
AuthorDate: Wed Oct 18 16:41:51 2006 -0400
Committer:  Greg Kroah-Hartman <[EMAIL PROTECTED]>
CommitDate: Fri Dec 1 14:23:27 2006 -0800

    USB core: don't match interface descriptors for vendor-specific devices
    This patch (as804) makes USB driver matching ignore the interface
    class, subclass, and protocol if the device class is Vendor Specific.
    Drivers can override this policy by specifying a Vendor ID as part
    of the match; then vendor-specific matches are allowed.
    Linus Walleij has reported a problem this patch fixes.  When a
    particular mass-storage device is switched from mass-storage mode to
    Media Transfer Protocol, the interface class remains set to mass-storage
    and usb-storage binds to it erroneously, even though the device class
    changes to Vendor-Specific.
    This may cause a problem for some drivers until their match records can
    be updated to include Vendor IDs.  But if it does, then those records
    were broken to begin with.
    Signed-off-by: Alan Stern <[EMAIL PROTECTED]>
    Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
 drivers/usb/core/driver.c |   22 +++++++++++++++++++++-
 1 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 113e484..401d76f 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -408,6 +408,16 @@ static int usb_match_one_id(struct usb_i
            (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
                return 0;
+       /* The interface class, subclass, and protocol should never be
+        * checked for a match if the device class is Vendor Specific,
+        * unless the match record specifies the Vendor ID. */
+       if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
+                       !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
+                       (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |
+                               USB_DEVICE_ID_MATCH_INT_SUBCLASS |
+                               USB_DEVICE_ID_MATCH_INT_PROTOCOL)))
+               return 0;
        if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
            (id->bInterfaceClass != intf->desc.bInterfaceClass))
                return 0;
@@ -476,7 +486,17 @@ static int usb_match_one_id(struct usb_i
  * most general; they let drivers bind to any interface on a
  * multiple-function device.  Use the USB_INTERFACE_INFO
  * macro, or its siblings, to match class-per-interface style
- * devices (as recorded in bDeviceClass).
+ * devices (as recorded in bInterfaceClass).
+ *
+ * Note that an entry created by USB_INTERFACE_INFO won't match
+ * any interface if the device class is set to Vendor-Specific.
+ * This is deliberate; according to the USB spec the meanings of
+ * the interface class/subclass/protocol for these devices are also
+ * vendor-specific, and hence matching against a standard product
+ * class wouldn't work anyway.  If you really want to use an
+ * interface-based match for such a device, create a match record
+ * that also specifies the vendor ID.  (Unforunately there isn't a
+ * standard macro for creating records like this.)
  * Within those groups, remember that not all combinations are
  * meaningful.  For example, don't give a product version range
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at

Reply via email to