From stern@rowland.harvard.edu Fri May  6 12:45:18 2005
Date: Fri, 6 May 2005 15:41:08 -0400 (EDT)
From: Alan Stern <stern@rowland.harvard.edu>
To: Greg KH <greg@kroah.com>
cc: Roman Kagan <rkagan@mail.ru>
Subject: usbcore: Don't call device_release_driver recursively
Message-ID: <Pine.LNX.4.44L0.0505061537130.5031-100000@iolanthe.rowland.org>

This patch fixes usb_driver_release_interface() to make it avoid calling
device_release_driver() recursively, i.e., when invoked from within the
disconnect routine for the same device.  The patch applies to your 
"driver" tree.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 drivers/usb/core/usb.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

--- gregkh-2.6.orig/drivers/usb/core/usb.c	2005-05-09 16:58:07.000000000 -0700
+++ gregkh-2.6/drivers/usb/core/usb.c	2005-05-09 17:05:57.000000000 -0700
@@ -322,9 +322,15 @@
 	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);
