# 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.566   -> 1.567  
#	   drivers/usb/usb.c	1.36    -> 1.37   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/03/27	david-b@pacbell.net	1.567
# USB core sanity check
#   
#   Periodically folk have run into problems where usb-ohci oopses
#   due to device refcount bugs ...
#     
#   This is a minor patch to move the sanity check out of usb-ohci
#   into the generic bits of usbcore.    There are comments that
#   suggest a path for a more comprehensive approach too.
#     
#   Applies cleanly against 2.5.7 and I've been testing with it
#   for a while.  I can't think of any reason it shouldn't also go
#   into 2.4, beyond the patch not applying cleanly there ... :)
# --------------------------------------------
#
diff -Nru a/drivers/usb/usb.c b/drivers/usb/usb.c
--- a/drivers/usb/usb.c	Wed Apr  3 16:39:28 2002
+++ b/drivers/usb/usb.c	Wed Apr  3 16:39:28 2002
@@ -791,9 +791,22 @@
 
 // usbcore-internal ...
 // but usb_dec_dev_use() is #defined to this, and that's public!!
+// FIXME the public call should BUG() whenever count goes to zero,
+// the usbcore-internal one should do so _unless_ it does so...
 void usb_free_dev(struct usb_device *dev)
 {
 	if (atomic_dec_and_test(&dev->refcnt)) {
+		/* Normally only goes to zero in usb_disconnect(), from
+		 * khubd or from roothub shutdown (rmmod/apmd/... thread).
+		 * Abnormally, roothub init errors can happen, so HCDs
+		 * call this directly.
+		 *
+		 * Otherwise this is a nasty device driver bug, often in
+		 * disconnect processing.
+		 */
+		if (in_interrupt ())
+			BUG ();
+
 		dev->bus->op->deallocate(dev);
 		usb_destroy_configuration(dev);
 
