aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBjørn Mork <bjorn@mork.no>2012-05-18 15:27:43 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-06-13 18:40:09 -0400
commit81df2d594340dcb6d1a02191976be88a1ca8120c (patch)
treef5a20ebf416c03b41611518d54706019d0c0ffa2 /drivers
parent7e97243c2080ecae7129e83635227fdebd4feef6 (diff)
USB: allow match on bInterfaceNumber
Some composite USB devices provide multiple interfaces with different functions, all using "vendor-specific" for class/subclass/protocol. Another OS use interface numbers to match the driver and interface. It seems these devices are designed with that in mind - using static interface numbers for the different functions. This adds support for matching against the bInterfaceNumber, allowing such devices to be supported without having to resort to testing against interface number whitelists and/or blacklists in the probe. Signed-off-by: Bjørn Mork <bjorn@mork.no> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/core/driver.c9
-rw-r--r--drivers/usb/core/message.c5
-rw-r--r--drivers/usb/core/sysfs.c5
3 files changed, 13 insertions, 6 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index f536aebc958e..23d7bbd199a5 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -622,14 +622,15 @@ int usb_match_one_id(struct usb_interface *interface,
622 if (!usb_match_device(dev, id)) 622 if (!usb_match_device(dev, id))
623 return 0; 623 return 0;
624 624
625 /* The interface class, subclass, and protocol should never be 625 /* The interface class, subclass, protocol and number should never be
626 * checked for a match if the device class is Vendor Specific, 626 * checked for a match if the device class is Vendor Specific,
627 * unless the match record specifies the Vendor ID. */ 627 * unless the match record specifies the Vendor ID. */
628 if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC && 628 if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
629 !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && 629 !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
630 (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS | 630 (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |
631 USB_DEVICE_ID_MATCH_INT_SUBCLASS | 631 USB_DEVICE_ID_MATCH_INT_SUBCLASS |
632 USB_DEVICE_ID_MATCH_INT_PROTOCOL))) 632 USB_DEVICE_ID_MATCH_INT_PROTOCOL |
633 USB_DEVICE_ID_MATCH_INT_NUMBER)))
633 return 0; 634 return 0;
634 635
635 if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) && 636 if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
@@ -644,6 +645,10 @@ int usb_match_one_id(struct usb_interface *interface,
644 (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol)) 645 (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
645 return 0; 646 return 0;
646 647
648 if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) &&
649 (id->bInterfaceNumber != intf->desc.bInterfaceNumber))
650 return 0;
651
647 return 1; 652 return 1;
648} 653}
649EXPORT_SYMBOL_GPL(usb_match_one_id); 654EXPORT_SYMBOL_GPL(usb_match_one_id);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index b548cf1dbc62..ca7fc392fd9e 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1559,7 +1559,7 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
1559 1559
1560 if (add_uevent_var(env, 1560 if (add_uevent_var(env,
1561 "MODALIAS=usb:" 1561 "MODALIAS=usb:"
1562 "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", 1562 "v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02Xin%02X",
1563 le16_to_cpu(usb_dev->descriptor.idVendor), 1563 le16_to_cpu(usb_dev->descriptor.idVendor),
1564 le16_to_cpu(usb_dev->descriptor.idProduct), 1564 le16_to_cpu(usb_dev->descriptor.idProduct),
1565 le16_to_cpu(usb_dev->descriptor.bcdDevice), 1565 le16_to_cpu(usb_dev->descriptor.bcdDevice),
@@ -1568,7 +1568,8 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
1568 usb_dev->descriptor.bDeviceProtocol, 1568 usb_dev->descriptor.bDeviceProtocol,
1569 alt->desc.bInterfaceClass, 1569 alt->desc.bInterfaceClass,
1570 alt->desc.bInterfaceSubClass, 1570 alt->desc.bInterfaceSubClass,
1571 alt->desc.bInterfaceProtocol)) 1571 alt->desc.bInterfaceProtocol,
1572 alt->desc.bInterfaceNumber))
1572 return -ENOMEM; 1573 return -ENOMEM;
1573 1574
1574 return 0; 1575 return 0;
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 9a56e3adf476..777f03c37725 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -840,7 +840,7 @@ static ssize_t show_modalias(struct device *dev,
840 alt = intf->cur_altsetting; 840 alt = intf->cur_altsetting;
841 841
842 return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X" 842 return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02X"
843 "ic%02Xisc%02Xip%02X\n", 843 "ic%02Xisc%02Xip%02Xin%02X\n",
844 le16_to_cpu(udev->descriptor.idVendor), 844 le16_to_cpu(udev->descriptor.idVendor),
845 le16_to_cpu(udev->descriptor.idProduct), 845 le16_to_cpu(udev->descriptor.idProduct),
846 le16_to_cpu(udev->descriptor.bcdDevice), 846 le16_to_cpu(udev->descriptor.bcdDevice),
@@ -849,7 +849,8 @@ static ssize_t show_modalias(struct device *dev,
849 udev->descriptor.bDeviceProtocol, 849 udev->descriptor.bDeviceProtocol,
850 alt->desc.bInterfaceClass, 850 alt->desc.bInterfaceClass,
851 alt->desc.bInterfaceSubClass, 851 alt->desc.bInterfaceSubClass,
852 alt->desc.bInterfaceProtocol); 852 alt->desc.bInterfaceProtocol,
853 alt->desc.bInterfaceNumber);
853} 854}
854static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); 855static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
855 856