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

Reply via email to