On Fri, 23 Jan 2004, Greg KH wrote:

> On Fri, Jan 23, 2004 at 02:51:16PM -0500, Alan Stern wrote:
> > Really?  I didn't see any problems in it.  Do you remember just what was 
> > wrong with the patch?
> 
> Did you try it?  It dies horribly.  Now that means either that we have
> our reference counting all wrong, or the patch isn't sane.  I didn't
> take the time to check out either.

I thought I had tried it, but apparently not.  Now that I have, I see what 
you mean.

However the basic principle is sound; it's just the implementation that
was a little off.  You were waiting on a struct completion for the bus to
be deleted, but the completion was itself embedded in the bus!  The patch
below should work better; it puts the completion on the stack instead.  
It applies against your gregkh-2.6 tree as of Sunday noon.

I tried the patch on my system and it worked okay, but my system was not a 
virgin kernel.  In particular, it wouldn't be surprising if trying to 
unload an HCD module caused the rmmod process to hang, thanks to that 
outstanding issue of not releasing a kobject before all its children have 
been released.  My test was done with patch as163 loaded; see

http://marc.theaimsgroup.com/?l=linux-usb-devel&m=107177993125318&w=2

http://marc.theaimsgroup.com/?l=linux-usb-devel&m=107178202227877&w=2

and the ensuing thread.

Alan Stern


===== drivers/usb/core/hcd.c 1.124 vs edited =====
--- 1.124/drivers/usb/core/hcd.c        Tue Dec 30 13:25:12 2003
+++ edited/drivers/usb/core/hcd.c       Sun Jan 25 12:33:22 2004
@@ -585,9 +585,11 @@
 static void usb_host_release(struct class_device *class_dev)
 {
        struct usb_bus *bus = to_usb_bus(class_dev);
+       struct completion *released = bus->released;
 
        if (bus->release)
                bus->release(bus);
+       complete(released);
 }
 
 static struct class usb_host_class = {
@@ -709,6 +711,8 @@
  */
 void usb_deregister_bus (struct usb_bus *bus)
 {
+       struct completion released;
+
        dev_info (bus->controller, "USB bus %d deregistered\n", bus->busnum);
 
        /*
@@ -724,7 +728,10 @@
 
        clear_bit (bus->busnum, busmap.busmap);
 
+       init_completion(&released);
+       bus->released = &released;
        class_device_unregister(&bus->class_dev);
+       wait_for_completion(&released);
 }
 EXPORT_SYMBOL (usb_deregister_bus);
 
===== include/linux/usb.h 1.166 vs edited =====
--- 1.166/include/linux/usb.h   Tue Dec 30 13:25:15 2003
+++ edited/include/linux/usb.h  Sun Jan 25 12:33:22 2004
@@ -210,6 +210,7 @@
 
        struct class_device class_dev;  /* class device for this bus */
        void (*release)(struct usb_bus *bus);   /* function to destroy this bus's 
memory */
+       struct completion *released;    /* wait for release */
 };
 #define        to_usb_bus(d) container_of(d, struct usb_bus, class_dev)
 



-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to