aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/core/hub.c40
1 files changed, 11 insertions, 29 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 32ff32181852..c3e46d24a37e 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -26,6 +26,7 @@
26#include <linux/ioctl.h> 26#include <linux/ioctl.h>
27#include <linux/usb.h> 27#include <linux/usb.h>
28#include <linux/usbdevice_fs.h> 28#include <linux/usbdevice_fs.h>
29#include <linux/kthread.h>
29 30
30#include <asm/semaphore.h> 31#include <asm/semaphore.h>
31#include <asm/uaccess.h> 32#include <asm/uaccess.h>
@@ -47,8 +48,7 @@ static LIST_HEAD(hub_event_list); /* List of hubs needing servicing */
47/* Wakes up khubd */ 48/* Wakes up khubd */
48static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); 49static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);
49 50
50static pid_t khubd_pid = 0; /* PID of khubd */ 51static struct task_struct *khubd_task;
51static DECLARE_COMPLETION(khubd_exited);
52 52
53/* cycle leds on hubs that aren't blinking for attention */ 53/* cycle leds on hubs that aren't blinking for attention */
54static int blinkenlights = 0; 54static int blinkenlights = 0;
@@ -2807,23 +2807,16 @@ loop:
2807 2807
2808static int hub_thread(void *__unused) 2808static int hub_thread(void *__unused)
2809{ 2809{
2810 /*
2811 * This thread doesn't need any user-level access,
2812 * so get rid of all our resources
2813 */
2814
2815 daemonize("khubd");
2816 allow_signal(SIGKILL);
2817
2818 /* Send me a signal to get me die (for debugging) */
2819 do { 2810 do {
2820 hub_events(); 2811 hub_events();
2821 wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); 2812 wait_event_interruptible(khubd_wait,
2813 !list_empty(&hub_event_list) ||
2814 kthread_should_stop());
2822 try_to_freeze(); 2815 try_to_freeze();
2823 } while (!signal_pending(current)); 2816 } while (!kthread_should_stop() || !list_empty(&hub_event_list));
2824 2817
2825 pr_debug ("%s: khubd exiting\n", usbcore_name); 2818 pr_debug("%s: khubd exiting\n", usbcore_name);
2826 complete_and_exit(&khubd_exited, 0); 2819 return 0;
2827} 2820}
2828 2821
2829static struct usb_device_id hub_id_table [] = { 2822static struct usb_device_id hub_id_table [] = {
@@ -2849,20 +2842,15 @@ static struct usb_driver hub_driver = {
2849 2842
2850int usb_hub_init(void) 2843int usb_hub_init(void)
2851{ 2844{
2852 pid_t pid;
2853
2854 if (usb_register(&hub_driver) < 0) { 2845 if (usb_register(&hub_driver) < 0) {
2855 printk(KERN_ERR "%s: can't register hub driver\n", 2846 printk(KERN_ERR "%s: can't register hub driver\n",
2856 usbcore_name); 2847 usbcore_name);
2857 return -1; 2848 return -1;
2858 } 2849 }
2859 2850
2860 pid = kernel_thread(hub_thread, NULL, CLONE_KERNEL); 2851 khubd_task = kthread_run(hub_thread, NULL, "khubd");
2861 if (pid >= 0) { 2852 if (!IS_ERR(khubd_task))
2862 khubd_pid = pid;
2863
2864 return 0; 2853 return 0;
2865 }
2866 2854
2867 /* Fall through if kernel_thread failed */ 2855 /* Fall through if kernel_thread failed */
2868 usb_deregister(&hub_driver); 2856 usb_deregister(&hub_driver);
@@ -2873,12 +2861,7 @@ int usb_hub_init(void)
2873 2861
2874void usb_hub_cleanup(void) 2862void usb_hub_cleanup(void)
2875{ 2863{
2876 int ret; 2864 kthread_stop(khubd_task);
2877
2878 /* Kill the thread */
2879 ret = kill_proc(khubd_pid, SIGKILL, 1);
2880
2881 wait_for_completion(&khubd_exited);
2882 2865
2883 /* 2866 /*
2884 * Hub resources are freed for us by usb_deregister. It calls 2867 * Hub resources are freed for us by usb_deregister. It calls
@@ -2890,7 +2873,6 @@ void usb_hub_cleanup(void)
2890 usb_deregister(&hub_driver); 2873 usb_deregister(&hub_driver);
2891} /* usb_hub_cleanup() */ 2874} /* usb_hub_cleanup() */
2892 2875
2893
2894static int config_descriptors_changed(struct usb_device *udev) 2876static int config_descriptors_changed(struct usb_device *udev)
2895{ 2877{
2896 unsigned index; 2878 unsigned index;