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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
6d8fc4d28d
commit
93c8bf45e0
@@ -408,6 +408,16 @@ static int usb_match_one_id(struct usb_interface *interface,
|
|||||||
(id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
|
(id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
|
||||||
return 0;
|
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) &&
|
if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
|
||||||
(id->bInterfaceClass != intf->desc.bInterfaceClass))
|
(id->bInterfaceClass != intf->desc.bInterfaceClass))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -476,7 +486,17 @@ static int usb_match_one_id(struct usb_interface *interface,
|
|||||||
* most general; they let drivers bind to any interface on a
|
* most general; they let drivers bind to any interface on a
|
||||||
* multiple-function device. Use the USB_INTERFACE_INFO
|
* multiple-function device. Use the USB_INTERFACE_INFO
|
||||||
* macro, or its siblings, to match class-per-interface style
|
* 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
|
* Within those groups, remember that not all combinations are
|
||||||
* meaningful. For example, don't give a product version range
|
* meaningful. For example, don't give a product version range
|
||||||
|
Reference in New Issue
Block a user