# 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);