diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2006-10-18 16:41:51 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-12-01 17:23:27 -0500 |
commit | 93c8bf45e083b89dffe3a708363c15c1b220c723 (patch) | |
tree | fa9b05fdfdc9ba2d75a2fee9729b8a553b23c678 | |
parent | 6d8fc4d28deaf828606c19fb743fbe94aeab4caf (diff) |
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 <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | 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 113e484c763e..401d76f13419 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_interface *interface, | |||
408 | (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol)) | 408 | (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol)) |
409 | return 0; | 409 | return 0; |
410 | 410 | ||
411 | /* The interface class, subclass, and protocol should never be | ||
412 | * checked for a match if the device class is Vendor Specific, | ||
413 | * unless the match record specifies the Vendor ID. */ | ||
414 | if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC && | ||
415 | !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && | ||
416 | (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS | | ||
417 | USB_DEVICE_ID_MATCH_INT_SUBCLASS | | ||
418 | USB_DEVICE_ID_MATCH_INT_PROTOCOL))) | ||
419 | return 0; | ||
420 | |||
411 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && | 421 | if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && |
412 | (id->bInterfaceClass != intf->desc.bInterfaceClass)) | 422 | (id->bInterfaceClass != intf->desc.bInterfaceClass)) |
413 | return 0; | 423 | return 0; |
@@ -476,7 +486,17 @@ static int usb_match_one_id(struct usb_interface *interface, | |||
476 | * most general; they let drivers bind to any interface on a | 486 | * most general; they let drivers bind to any interface on a |
477 | * multiple-function device. Use the USB_INTERFACE_INFO | 487 | * multiple-function device. Use the USB_INTERFACE_INFO |
478 | * macro, or its siblings, to match class-per-interface style | 488 | * macro, or its siblings, to match class-per-interface style |
479 | * devices (as recorded in bDeviceClass). | 489 | * devices (as recorded in bInterfaceClass). |
490 | * | ||
491 | * Note that an entry created by USB_INTERFACE_INFO won't match | ||
492 | * any interface if the device class is set to Vendor-Specific. | ||
493 | * This is deliberate; according to the USB spec the meanings of | ||
494 | * the interface class/subclass/protocol for these devices are also | ||
495 | * vendor-specific, and hence matching against a standard product | ||
496 | * class wouldn't work anyway. If you really want to use an | ||
497 | * interface-based match for such a device, create a match record | ||
498 | * that also specifies the vendor ID. (Unforunately there isn't a | ||
499 | * standard macro for creating records like this.) | ||
480 | * | 500 | * |
481 | * Within those groups, remember that not all combinations are | 501 | * Within those groups, remember that not all combinations are |
482 | * meaningful. For example, don't give a product version range | 502 | * meaningful. For example, don't give a product version range |