patch-2.4.4 linux/drivers/usb/hub.c
Next file: linux/drivers/usb/hub.h
Previous file: linux/drivers/usb/hid.h
Back to the patch index
Back to the overall index
- Lines: 132
- Date:
Wed Apr 25 14:10:47 2001
- Orig file:
v2.4.3/linux/drivers/usb/hub.c
- Orig date:
Sun Mar 25 18:14:21 2001
diff -u --recursive --new-file v2.4.3/linux/drivers/usb/hub.c linux/drivers/usb/hub.c
@@ -98,15 +98,12 @@
hub->nerrors = 0;
/* Something happened, let khubd figure it out */
- if (waitqueue_active(&khubd_wait)) {
- /* Add the hub to the event queue */
- spin_lock_irqsave(&hub_event_lock, flags);
- if (list_empty(&hub->event_list)) {
- list_add(&hub->event_list, &hub_event_list);
- wake_up(&khubd_wait);
- }
- spin_unlock_irqrestore(&hub_event_lock, flags);
+ spin_lock_irqsave(&hub_event_lock, flags);
+ if (list_empty(&hub->event_list)) {
+ list_add(&hub->event_list, &hub_event_list);
+ wake_up(&khubd_wait);
}
+ spin_unlock_irqrestore(&hub_event_lock, flags);
}
static void usb_hub_power_on(struct usb_hub *hub)
@@ -239,7 +236,6 @@
static void *hub_probe(struct usb_device *dev, unsigned int i,
const struct usb_device_id *id)
-
{
struct usb_interface_descriptor *interface;
struct usb_endpoint_descriptor *endpoint;
@@ -293,7 +289,7 @@
INIT_LIST_HEAD(&hub->event_list);
hub->dev = dev;
- init_MUTEX(&hub->khubd_sem);
+ atomic_set(&hub->refcnt, 1);
/* Record the new hub's existence */
spin_lock_irqsave(&hub_event_lock, flags);
@@ -322,11 +318,34 @@
return NULL;
}
+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)) {
+ if (hub->descriptor) {
+ kfree(hub->descriptor);
+ hub->descriptor = NULL;
+ }
+
+ kfree(hub);
+ }
+}
+
static void hub_disconnect(struct usb_device *dev, void *ptr)
{
struct usb_hub *hub = (struct usb_hub *)ptr;
unsigned long flags;
+ if (hub->urb) {
+ usb_unlink_urb(hub->urb);
+ usb_free_urb(hub->urb);
+ hub->urb = NULL;
+ }
+
spin_lock_irqsave(&hub_event_lock, flags);
/* Delete it and then reset it */
@@ -337,22 +356,7 @@
spin_unlock_irqrestore(&hub_event_lock, flags);
- down(&hub->khubd_sem); /* Wait for khubd to leave this hub alone. */
- up(&hub->khubd_sem);
-
- if (hub->urb) {
- usb_unlink_urb(hub->urb);
- usb_free_urb(hub->urb);
- hub->urb = NULL;
- }
-
- if (hub->descriptor) {
- kfree(hub->descriptor);
- hub->descriptor = NULL;
- }
-
- /* Free the memory */
- kfree(hub);
+ hub_put(hub);
}
static int hub_ioctl(struct usb_device *hub, unsigned int code, void *user_data)
@@ -406,6 +410,7 @@
if (usb_reset_device(dev))
return -1;
+ hub->urb->dev = dev;
if (usb_submit_urb(hub->urb))
return -1;
@@ -663,7 +668,7 @@
list_del(tmp);
INIT_LIST_HEAD(tmp);
- down(&hub->khubd_sem); /* never blocks, we were on list */
+ hub_get(hub);
spin_unlock_irqrestore(&hub_event_lock, flags);
if (hub->error) {
@@ -672,7 +677,7 @@
if (usb_hub_reset(hub)) {
err("error resetting hub %d - disconnecting", dev->devnum);
usb_hub_disconnect(dev);
- up(&hub->khubd_sem);
+ hub_put(hub);
continue;
}
@@ -748,7 +753,7 @@
usb_hub_power_on(hub);
}
}
- up(&hub->khubd_sem);
+ hub_put(hub);
} /* end while (1) */
spin_unlock_irqrestore(&hub_event_lock, flags);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)