# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.456.2.9 -> 1.456.2.10
#	drivers/usb/core/devio.c	1.24    -> 1.25   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/04/12	david-b@pacbell.net	1.456.2.10
# [PATCH] USB devio device removal fix
# 
# USB devio device removal fix
# 
# Fixes problem with using usbfs and a device is removed while the
# device still has pending events.
# --------------------------------------------
#
diff -Nru a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c	Tue Apr 16 11:35:44 2002
+++ b/drivers/usb/core/devio.c	Tue Apr 16 11:35:44 2002
@@ -297,7 +297,9 @@
 }
 
 /*
- * interface claiming
+ * interface claims are made only at the request of user level code,
+ * which can also release them (explicitly or by closing files).
+ * they're also undone when devices disconnect.
  */
 
 static void *driver_probe(struct usb_device *dev, unsigned int intf,
@@ -310,8 +312,20 @@
 {
 	struct dev_state *ps = (struct dev_state *)context;
 
-	if (ps)
-		ps->ifclaimed = 0;
+	if (!ps)
+		return;
+
+	/* this waits till synchronous requests complete */
+	down_write (&ps->devsem);
+
+	/* prevent new I/O requests */
+	ps->dev = 0;
+	ps->ifclaimed = 0;
+
+	/* force async requests to complete */
+	destroy_all_async (ps);
+
+	up_write (&ps->devsem);
 }
 
 struct usb_driver usbdevfs_driver = {
