diff options
-rw-r--r-- | drivers/usb/core/driver.c | 9 | ||||
-rw-r--r-- | drivers/usb/core/message.c | 5 | ||||
-rw-r--r-- | drivers/usb/core/sysfs.c | 5 | ||||
-rw-r--r-- | include/linux/mod_devicetable.h | 7 | ||||
-rw-r--r-- | include/linux/usb.h | 16 | ||||
-rw-r--r-- | scripts/mod/file2alias.c | 5 |
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 | } |
649 | EXPORT_SYMBOL_GPL(usb_match_one_id); | 654 | EXPORT_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 | } |
854 | static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); | 855 | static 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" */ |
160 | static void do_usb_entry(struct usb_device_id *id, | 160 | static 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, |