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