aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/core/driver.c9
-rw-r--r--drivers/usb/core/message.c5
-rw-r--r--drivers/usb/core/sysfs.c5
-rw-r--r--include/linux/mod_devicetable.h7
-rw-r--r--include/linux/usb.h16
-rw-r--r--scripts/mod/file2alias.c5
6 files changed, 40 insertions, 7 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
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 5db93821f9c7..7771d453e5f3 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -78,6 +78,9 @@ struct ieee1394_device_id {
78 * of a given interface; other interfaces may support other classes. 78 * of a given interface; other interfaces may support other classes.
79 * @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass. 79 * @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass.
80 * @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass. 80 * @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass.
81 * @bInterfaceNumber: Number of interface; composite devices may use
82 * fixed interface numbers to differentiate between vendor-specific
83 * interfaces.
81 * @driver_info: Holds information used by the driver. Usually it holds 84 * @driver_info: Holds information used by the driver. Usually it holds
82 * a pointer to a descriptor understood by the driver, or perhaps 85 * a pointer to a descriptor understood by the driver, or perhaps
83 * device flags. 86 * device flags.
@@ -115,6 +118,9 @@ struct usb_device_id {
115 __u8 bInterfaceSubClass; 118 __u8 bInterfaceSubClass;
116 __u8 bInterfaceProtocol; 119 __u8 bInterfaceProtocol;
117 120
121 /* Used for vendor-specific interface matches */
122 __u8 bInterfaceNumber;
123
118 /* not matched against */ 124 /* not matched against */
119 kernel_ulong_t driver_info; 125 kernel_ulong_t driver_info;
120}; 126};
@@ -130,6 +136,7 @@ struct usb_device_id {
130#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080 136#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080
131#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100 137#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100
132#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 138#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
139#define USB_DEVICE_ID_MATCH_INT_NUMBER 0x0400
133 140
134#define HID_ANY_ID (~0) 141#define HID_ANY_ID (~0)
135#define HID_BUS_ANY 0xffff 142#define HID_BUS_ANY 0xffff
diff --git a/include/linux/usb.h b/include/linux/usb.h
index dea39dc551d4..f717fbdaee8e 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -777,6 +777,22 @@ static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size)
777 .bInterfaceProtocol = (pr) 777 .bInterfaceProtocol = (pr)
778 778
779/** 779/**
780 * USB_DEVICE_INTERFACE_NUMBER - describe a usb device with a specific interface number
781 * @vend: the 16 bit USB Vendor ID
782 * @prod: the 16 bit USB Product ID
783 * @num: bInterfaceNumber value
784 *
785 * This macro is used to create a struct usb_device_id that matches a
786 * specific interface number of devices.
787 */
788#define USB_DEVICE_INTERFACE_NUMBER(vend, prod, num) \
789 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
790 USB_DEVICE_ID_MATCH_INT_NUMBER, \
791 .idVendor = (vend), \
792 .idProduct = (prod), \
793 .bInterfaceNumber = (num)
794
795/**
780 * USB_DEVICE_INFO - macro used to describe a class of usb devices 796 * USB_DEVICE_INFO - macro used to describe a class of usb devices
781 * @cl: bDeviceClass value 797 * @cl: bDeviceClass value
782 * @sc: bDeviceSubClass value 798 * @sc: bDeviceSubClass value
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 5759751a1f61..7ed6864ef65b 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -156,7 +156,7 @@ static void device_id_check(const char *modname, const char *device_id,
156} 156}
157 157
158/* USB is special because the bcdDevice can be matched against a numeric range */ 158/* USB is special because the bcdDevice can be matched against a numeric range */
159/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */ 159/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */
160static void do_usb_entry(struct usb_device_id *id, 160static void do_usb_entry(struct usb_device_id *id,
161 unsigned int bcdDevice_initial, int bcdDevice_initial_digits, 161 unsigned int bcdDevice_initial, int bcdDevice_initial_digits,
162 unsigned char range_lo, unsigned char range_hi, 162 unsigned char range_lo, unsigned char range_hi,
@@ -210,6 +210,9 @@ static void do_usb_entry(struct usb_device_id *id,
210 ADD(alias, "ip", 210 ADD(alias, "ip",
211 id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL, 211 id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL,
212 id->bInterfaceProtocol); 212 id->bInterfaceProtocol);
213 ADD(alias, "in",
214 id->match_flags&USB_DEVICE_ID_MATCH_INT_NUMBER,
215 id->bInterfaceNumber);
213 216
214 add_wildcard(alias); 217 add_wildcard(alias);
215 buf_printf(&mod->dev_table_buf, 218 buf_printf(&mod->dev_table_buf,