This patch drops khubd_sem from the hub driver in favor of using reference counting. This gets rid of the ugly and abusive usage of semaphores to do pretty much the same thing :)
I have done some light testing with it and it seems to be fine. Comments and reports are welcome before I submit to Greg. JE # This is a BitKeeper generated patch for the following project: # Project Name: greg k-h's linux 2.5 USB kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.899 -> 1.900 # drivers/usb/core/hub.c 1.65 -> 1.66 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/10/15 [EMAIL PROTECTED] 1.900 # hub.c: # Drop khub_sem in favor of using reference counting # -------------------------------------------- # diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c --- a/drivers/usb/core/hub.c Fri Oct 25 07:23:27 2002 +++ b/drivers/usb/core/hub.c Fri Oct 25 07:23:27 2002 @@ -2,10 +2,9 @@ * USB hub driver. * * (C) Copyright 1999 Linus Torvalds - * (C) Copyright 1999 Johannes Erdfelt + * (C) Copyright 1999-2002 Johannes Erdfelt * (C) Copyright 1999 Gregory P. Smith * (C) Copyright 2001 Brad Hards ([EMAIL PROTECTED]) - * */ #include <linux/config.h> @@ -57,6 +56,17 @@ } #endif +static void hub_get(struct usb_hub *hub) +{ + atomic_inc(&hub->refcnt); +} + +static void hub_put(struct usb_hub *hub) +{ + if (atomic_dec_and_test(&hub->refcnt)) + kfree(hub); +} + /* USB 2.0 spec Section 11.24.4.5 */ static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size) { @@ -146,6 +156,7 @@ spin_lock_irqsave(&hub_event_lock, flags); if (list_empty(&hub->event_list)) { list_add(&hub->event_list, &hub_event_list); + hub_get(hub); /* khubd will put */ wake_up(&khubd_wait); } spin_unlock_irqrestore(&hub_event_lock, flags); @@ -419,6 +430,8 @@ kfree(hub->descriptor); return -1; } + + hub_get(hub); /* for reference to hub in URB */ /* Wake up khubd */ wake_up(&khubd_wait); @@ -447,9 +460,6 @@ spin_unlock_irqrestore(&hub_event_lock, flags); - down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */ - up(&hub->khubd_sem); - /* assuming we used keventd, it must quiesce too */ if (hub->tt.hub) flush_scheduled_work (); @@ -458,6 +468,7 @@ usb_unlink_urb(hub->urb); usb_free_urb(hub->urb); hub->urb = NULL; + hub_put(hub); } if (hub->descriptor) { @@ -465,8 +476,7 @@ hub->descriptor = NULL; } - /* Free the memory */ - kfree(hub); + hub_put(hub); } static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -524,13 +534,14 @@ memset(hub, 0, sizeof(*hub)); + atomic_set(&hub->refcnt, 2); /* one for us and one for on the bus */ + INIT_LIST_HEAD(&hub->event_list); + INIT_LIST_HEAD(&hub->hub_list); hub->intf = intf; - init_MUTEX(&hub->khubd_sem); /* Record the new hub's existence */ spin_lock_irqsave(&hub_event_lock, flags); - INIT_LIST_HEAD(&hub->hub_list); list_add(&hub->hub_list, &hub_list); spin_unlock_irqrestore(&hub_event_lock, flags); @@ -538,6 +549,7 @@ if (usb_hub_configure(hub, endpoint) >= 0) { strcpy (intf->dev.name, "Hub"); + hub_put(hub); return 0; } @@ -943,9 +955,6 @@ list_del_init(tmp); - if (unlikely(down_trylock(&hub->khubd_sem))) - BUG(); /* never blocks, we were on list */ - spin_unlock_irqrestore(&hub_event_lock, flags); if (hub->error) { @@ -955,8 +964,8 @@ if (usb_hub_reset(hub)) { err("error resetting hub %s - disconnecting", dev->devpath); - up(&hub->khubd_sem); usb_hub_disconnect(dev); + hub_put(hub); continue; } @@ -1038,7 +1047,7 @@ usb_hub_power_on(hub); } } - up(&hub->khubd_sem); + hub_put(hub); } /* end while (1) */ spin_unlock_irqrestore(&hub_event_lock, flags); ------------------------------------------------------- This sf.net email is sponsored by: Influence the future of Java(TM) technology. Join the Java Community Process(SM) (JCP(SM)) program now. http://ads.sourceforge.net/cgi-bin/redirect.pl?sunm0004en _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel