Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[deliverable/linux.git] / drivers / usb / core / driver.c
index f536aebc958e71d459f71ee5b9ae19f717a851c6..445455a4429bef2f9a26cff9a3aa88ac4629c1ac 100644 (file)
@@ -367,6 +367,7 @@ static int usb_probe_interface(struct device *dev)
        return error;
 
  err:
+       usb_set_intfdata(intf, NULL);
        intf->needs_remote_wakeup = 0;
        intf->condition = USB_INTERFACE_UNBOUND;
        usb_cancel_queued_reset(intf);
@@ -606,30 +607,19 @@ int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)
 }
 
 /* returns 0 if no match, 1 if match */
-int usb_match_one_id(struct usb_interface *interface,
-                    const struct usb_device_id *id)
+int usb_match_one_id_intf(struct usb_device *dev,
+                         struct usb_host_interface *intf,
+                         const struct usb_device_id *id)
 {
-       struct usb_host_interface *intf;
-       struct usb_device *dev;
-
-       /* proc_connectinfo in devio.c may call us with id == NULL. */
-       if (id == NULL)
-               return 0;
-
-       intf = interface->cur_altsetting;
-       dev = interface_to_usbdev(interface);
-
-       if (!usb_match_device(dev, id))
-               return 0;
-
-       /* The interface class, subclass, and protocol should never be
+       /* The interface class, subclass, protocol and number should never be
         * checked for a match if the device class is Vendor Specific,
         * unless the match record specifies the Vendor ID. */
        if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
                        !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
                        (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |
                                USB_DEVICE_ID_MATCH_INT_SUBCLASS |
-                               USB_DEVICE_ID_MATCH_INT_PROTOCOL)))
+                               USB_DEVICE_ID_MATCH_INT_PROTOCOL |
+                               USB_DEVICE_ID_MATCH_INT_NUMBER)))
                return 0;
 
        if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
@@ -644,8 +634,32 @@ int usb_match_one_id(struct usb_interface *interface,
            (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
                return 0;
 
+       if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) &&
+           (id->bInterfaceNumber != intf->desc.bInterfaceNumber))
+               return 0;
+
        return 1;
 }
+
+/* returns 0 if no match, 1 if match */
+int usb_match_one_id(struct usb_interface *interface,
+                    const struct usb_device_id *id)
+{
+       struct usb_host_interface *intf;
+       struct usb_device *dev;
+
+       /* proc_connectinfo in devio.c may call us with id == NULL. */
+       if (id == NULL)
+               return 0;
+
+       intf = interface->cur_altsetting;
+       dev = interface_to_usbdev(interface);
+
+       if (!usb_match_device(dev, id))
+               return 0;
+
+       return usb_match_one_id_intf(dev, intf, id);
+}
 EXPORT_SYMBOL_GPL(usb_match_one_id);
 
 /**
This page took 0.027295 seconds and 5 git commands to generate.