From 47c46f076a347a4c85ed2cff89fcac9feee8dd25 Mon Sep 17 00:00:00 2001 From: lly Date: Sun, 16 Aug 2009 17:02:20 -0400 Subject: [PATCH] USB: Backport fix of infinite loop in khubd occured in case of active requests to disconnected hub (due to driver unload or hardware lost). --- release/src/linux/linux/drivers/usb/hub.c | 10 ++++++++-- release/src/linux/linux/drivers/usb/hub.h | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/release/src/linux/linux/drivers/usb/hub.c b/release/src/linux/linux/drivers/usb/hub.c index d57deced37..3cd92b6d42 100644 --- a/release/src/linux/linux/drivers/usb/hub.c +++ b/release/src/linux/linux/drivers/usb/hub.c @@ -132,7 +132,7 @@ static void hub_irq(struct urb *urb) /* Something happened, let khubd figure it out */ spin_lock_irqsave(&hub_event_lock, flags); - if (list_empty(&hub->event_list)) { + if (!hub->disconnected && list_empty(&hub->event_list)) { list_add(&hub->event_list, &hub_event_list); wake_up(&khubd_wait); } @@ -425,6 +425,7 @@ static void hub_disconnect(struct usb_device *dev, void *ptr) /* Delete it and then reset it */ list_del(&hub->event_list); INIT_LIST_HEAD(&hub->event_list); + hub->disconnected = 1; list_del(&hub->hub_list); INIT_LIST_HEAD(&hub->hub_list); @@ -842,6 +843,9 @@ static void usb_hub_events(void) down(&hub->khubd_sem); /* never blocks, we were on list */ spin_unlock_irqrestore(&hub_event_lock, flags); + if (unlikely(hub->disconnected)) + goto loop; + if (hub->error) { dbg("resetting hub %d for error %d", dev->devnum, hub->error); @@ -923,6 +927,7 @@ static void usb_hub_events(void) } kfree(hubsts); } +loop: up(&hub->khubd_sem); } /* end while (1) */ @@ -1006,7 +1011,8 @@ void usb_hub_cleanup(void) /* Kill the thread */ ret = kill_proc(khubd_pid, SIGTERM, 1); - wait_for_completion(&khubd_exited); + if (ret != -ESRCH) + wait_for_completion(&khubd_exited); /* * Hub resources are freed for us by usb_deregister. It calls diff --git a/release/src/linux/linux/drivers/usb/hub.h b/release/src/linux/linux/drivers/usb/hub.h index ec19ac6827..b438136c80 100644 --- a/release/src/linux/linux/drivers/usb/hub.h +++ b/release/src/linux/linux/drivers/usb/hub.h @@ -144,6 +144,8 @@ struct usb_hub { struct semaphore khubd_sem; struct usb_tt tt; /* Transaction Translator */ + + unsigned disconnected:1; }; #endif /* __LINUX_HUB_H */ -- 2.11.4.GIT