s390/appldata: restore missing init_virt_timer()
[deliverable/linux.git] / drivers / usb / core / driver.c
index 47aade2a5e741ade190022342590c363316514d7..5d01558cef666233b47f29d569595a1f42dda8b2 100644 (file)
@@ -37,6 +37,7 @@
  * and cause the driver to probe for all devices again.
  */
 ssize_t usb_store_new_id(struct usb_dynids *dynids,
+                        const struct usb_device_id *id_table,
                         struct device_driver *driver,
                         const char *buf, size_t count)
 {
@@ -44,11 +45,12 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,
        u32 idVendor = 0;
        u32 idProduct = 0;
        unsigned int bInterfaceClass = 0;
+       u32 refVendor, refProduct;
        int fields = 0;
        int retval = 0;
 
-       fields = sscanf(buf, "%x %x %x", &idVendor, &idProduct,
-                                       &bInterfaceClass);
+       fields = sscanf(buf, "%x %x %x %x %x", &idVendor, &idProduct,
+                       &bInterfaceClass, &refVendor, &refProduct);
        if (fields < 2)
                return -EINVAL;
 
@@ -60,11 +62,30 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,
        dynid->id.idVendor = idVendor;
        dynid->id.idProduct = idProduct;
        dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE;
-       if (fields == 3) {
+       if (fields > 2 && bInterfaceClass) {
+               if (bInterfaceClass > 255)
+                       return -EINVAL;
+
                dynid->id.bInterfaceClass = (u8)bInterfaceClass;
                dynid->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS;
        }
 
+       if (fields > 4) {
+               const struct usb_device_id *id = id_table;
+
+               if (!id)
+                       return -ENODEV;
+
+               for (; id->match_flags; id++)
+                       if (id->idVendor == refVendor && id->idProduct == refProduct)
+                               break;
+
+               if (id->match_flags)
+                       dynid->id.driver_info = id->driver_info;
+               else
+                       return -ENODEV;
+       }
+
        spin_lock(&dynids->lock);
        list_add_tail(&dynid->node, &dynids->list);
        spin_unlock(&dynids->lock);
@@ -106,7 +127,7 @@ static ssize_t new_id_store(struct device_driver *driver,
 {
        struct usb_driver *usb_drv = to_usb_driver(driver);
 
-       return usb_store_new_id(&usb_drv->dynids, driver, buf, count);
+       return usb_store_new_id(&usb_drv->dynids, usb_drv->id_table, driver, buf, count);
 }
 static DRIVER_ATTR_RW(new_id);
 
@@ -839,7 +860,7 @@ int usb_register_device_driver(struct usb_device_driver *new_udriver,
                return -ENODEV;
 
        new_udriver->drvwrap.for_devices = 1;
-       new_udriver->drvwrap.driver.name = (char *) new_udriver->name;
+       new_udriver->drvwrap.driver.name = new_udriver->name;
        new_udriver->drvwrap.driver.bus = &usb_bus_type;
        new_udriver->drvwrap.driver.probe = usb_probe_device;
        new_udriver->drvwrap.driver.remove = usb_unbind_device;
@@ -900,7 +921,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
                return -ENODEV;
 
        new_driver->drvwrap.for_devices = 0;
-       new_driver->drvwrap.driver.name = (char *) new_driver->name;
+       new_driver->drvwrap.driver.name = new_driver->name;
        new_driver->drvwrap.driver.bus = &usb_bus_type;
        new_driver->drvwrap.driver.probe = usb_probe_interface;
        new_driver->drvwrap.driver.remove = usb_unbind_interface;
This page took 0.028489 seconds and 5 git commands to generate.