diff options
author | Rosen Kolev <rosen.kolev@amk-drives.bg> | 2011-09-21 18:11:13 +0300 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2011-09-23 08:53:22 +0200 |
commit | 108b029b68c41f1d3ffada83c6c494e7f75e660e (patch) | |
tree | 4aa95f2670c614c0f9128f0a09679c32df757bf2 /drivers/usb | |
parent | 98e43c5b30f67c60476228225e8cf4d5c12bf021 (diff) | |
download | barebox-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.c | 34 |
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); |