/* if interface was already added, bind now; else let
* the future device_add() bind it, bypassing probe()
*/
- if (!klist_node_attached (&dev->knode_bus))
+ if (klist_node_attached(&dev->knode_bus))
device_bind_driver(dev);
return 0;
if (!dev->driver || dev->driver != &driver->driver)
return;
- /* don't disconnect from disconnect(), or before dev_add() */
- if (!klist_node_attached(&dev->knode_driver) && !klist_node_attached(&dev->knode_bus))
+ /* don't release from within disconnect() */
+ if (iface->condition != USB_INTERFACE_BOUND)
+ return;
+
+ /* release only after device_add() */
+ if (klist_node_attached(&dev->knode_bus)) {
+ iface->condition = USB_INTERFACE_UNBINDING;
device_release_driver(dev);
+ }
dev->driver = NULL;
usb_set_intfdata(iface, NULL);
*/
struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
{
- struct usb_interface *intf = (struct usb_interface *)minor;
+ struct usb_interface *intf = (struct usb_interface *)(long)minor;
int ret;
ret = driver_for_each_device(&drv->driver, NULL, &intf, __find_interface);