diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/core/hub.c | 40 |
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 */ |
48 | static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); | 49 | static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); |
49 | 50 | ||
50 | static pid_t khubd_pid = 0; /* PID of khubd */ | 51 | static struct task_struct *khubd_task; |
51 | static 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 */ |
54 | static int blinkenlights = 0; | 54 | static int blinkenlights = 0; |
@@ -2807,23 +2807,16 @@ loop: | |||
2807 | 2807 | ||
2808 | static int hub_thread(void *__unused) | 2808 | static 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 | ||
2829 | static struct usb_device_id hub_id_table [] = { | 2822 | static struct usb_device_id hub_id_table [] = { |
@@ -2849,20 +2842,15 @@ static struct usb_driver hub_driver = { | |||
2849 | 2842 | ||
2850 | int usb_hub_init(void) | 2843 | int 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 | ||
2874 | void usb_hub_cleanup(void) | 2862 | void 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 | |||
2894 | static int config_descriptors_changed(struct usb_device *udev) | 2876 | static int config_descriptors_changed(struct usb_device *udev) |
2895 | { | 2877 | { |
2896 | unsigned index; | 2878 | unsigned index; |