usb: interface authorization: Control interface probing and claiming
[linux-2.6-microblaze.git] / drivers / usb / core / message.c
index f7b7713..3d25d89 100644 (file)
@@ -1551,6 +1551,7 @@ static void usb_release_interface(struct device *dev)
                        altsetting_to_usb_interface_cache(intf->altsetting);
 
        kref_put(&intfc->ref, usb_release_interface_cache);
+       usb_put_dev(interface_to_usbdev(intf));
        kfree(intf);
 }
 
@@ -1626,24 +1627,6 @@ static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev,
 
 /*
  * Internal function to queue a device reset
- *
- * This is initialized into the workstruct in 'struct
- * usb_device->reset_ws' that is launched by
- * message.c:usb_set_configuration() when initializing each 'struct
- * usb_interface'.
- *
- * It is safe to get the USB device without reference counts because
- * the life cycle of @iface is bound to the life cycle of @udev. Then,
- * this function will be ran only if @iface is alive (and before
- * freeing it any scheduled instances of it will have been cancelled).
- *
- * We need to set a flag (usb_dev->reset_running) because when we call
- * the reset, the interfaces might be unbound. The current interface
- * cannot try to remove the queued work as it would cause a deadlock
- * (you cannot remove your work from within your executing
- * workqueue). This flag lets it know, so that
- * usb_cancel_queued_reset() doesn't try to do it.
- *
  * See usb_queue_reset_device() for more details
  */
 static void __usb_queue_reset_device(struct work_struct *ws)
@@ -1655,11 +1638,10 @@ static void __usb_queue_reset_device(struct work_struct *ws)
 
        rc = usb_lock_device_for_reset(udev, iface);
        if (rc >= 0) {
-               iface->reset_running = 1;
                usb_reset_device(udev);
-               iface->reset_running = 0;
                usb_unlock_device(udev);
        }
+       usb_put_intf(iface);    /* Undo _get_ in usb_queue_reset_device() */
 }
 
 
@@ -1825,6 +1807,7 @@ free_interfaces:
                intfc = cp->intf_cache[i];
                intf->altsetting = intfc->altsetting;
                intf->num_altsetting = intfc->num_altsetting;
+               intf->authorized = !!HCD_INTF_AUTHORIZED(hcd);
                kref_get(&intfc->ref);
 
                alt = usb_altnum_to_altsetting(intf, 0);
@@ -1854,6 +1837,7 @@ free_interfaces:
                dev_set_name(&intf->dev, "%d-%s:%d.%d",
                        dev->bus->busnum, dev->devpath,
                        configuration, alt->desc.bInterfaceNumber);
+               usb_get_dev(dev);
        }
        kfree(new_interfaces);