summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorRosen Kolev <rosen.kolev@amk-drives.bg>2011-09-21 18:11:13 +0300
committerSascha Hauer <s.hauer@pengutronix.de>2011-09-23 08:53:22 +0200
commit108b029b68c41f1d3ffada83c6c494e7f75e660e (patch)
tree4aa95f2670c614c0f9128f0a09679c32df757bf2 /drivers/usb
parent98e43c5b30f67c60476228225e8cf4d5c12bf021 (diff)
downloadbarebox-108b029b68c41f1d3ffada83c6c494e7f75e660e.tar.gz
barebox-108b029b68c41f1d3ffada83c6c494e7f75e660e.tar.xz
Extended USB device matching.
Extended the USB device matching, adding checks for interface class, interface subclass, and interface protocol.
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/usb.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index a23446ad1b..67c20166d7 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -1283,10 +1283,13 @@ static int usb_match_device(struct usb_device *dev, const struct usb_device_id *
return 1;
}
+
/* returns 0 if no match, 1 if match */
static int usb_match_one_id(struct usb_device *usbdev,
const struct usb_device_id *id)
{
+ int ifno;
+
/* proc_connectinfo in devio.c may call us with id == NULL. */
if (id == NULL)
return 0;
@@ -1294,6 +1297,37 @@ static int usb_match_one_id(struct usb_device *usbdev,
if (!usb_match_device(usbdev, id))
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 (usbdev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
+ !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
+ (id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO))
+ return 0;
+
+ if ( (id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO) ) {
+ /* match any interface */
+ for (ifno=0; ifno<usbdev->config.no_of_if; ifno++) {
+ struct usb_interface_descriptor *intf;
+ intf = &usbdev->config.if_desc[ifno];
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
+ (id->bInterfaceClass != intf->bInterfaceClass))
+ continue;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
+ (id->bInterfaceSubClass != intf->bInterfaceSubClass))
+ continue;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
+ (id->bInterfaceProtocol != intf->bInterfaceProtocol))
+ continue;
+ break;
+ }
+ if (ifno >= usbdev->config.no_of_if)
+ return 0;
+ }
+
return 1;
}
EXPORT_SYMBOL(usb_match_one_id);