diff options
-rw-r--r-- | drivers/ieee1394/ieee1394_core.c | 48 |
1 files changed, 15 insertions, 33 deletions
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index c83e2b8295e3..49354de9fb8a 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/kdev_t.h> | 33 | #include <linux/kdev_t.h> |
34 | #include <linux/skbuff.h> | 34 | #include <linux/skbuff.h> |
35 | #include <linux/suspend.h> | 35 | #include <linux/suspend.h> |
36 | #include <linux/kthread.h> | ||
36 | 37 | ||
37 | #include <asm/byteorder.h> | 38 | #include <asm/byteorder.h> |
38 | #include <asm/semaphore.h> | 39 | #include <asm/semaphore.h> |
@@ -1001,11 +1002,8 @@ void abort_timedouts(unsigned long __opaque) | |||
1001 | * packets that have a "complete" function are sent here. This way, the | 1002 | * packets that have a "complete" function are sent here. This way, the |
1002 | * completion is run out of kernel context, and doesn't block the rest of | 1003 | * completion is run out of kernel context, and doesn't block the rest of |
1003 | * the stack. */ | 1004 | * the stack. */ |
1004 | static int khpsbpkt_pid = -1, khpsbpkt_kill; | 1005 | static struct task_struct *khpsbpkt_thread; |
1005 | static DECLARE_COMPLETION(khpsbpkt_complete); | ||
1006 | static struct sk_buff_head hpsbpkt_queue; | 1006 | static struct sk_buff_head hpsbpkt_queue; |
1007 | static DECLARE_MUTEX_LOCKED(khpsbpkt_sig); | ||
1008 | |||
1009 | 1007 | ||
1010 | static void queue_packet_complete(struct hpsb_packet *packet) | 1008 | static void queue_packet_complete(struct hpsb_packet *packet) |
1011 | { | 1009 | { |
@@ -1015,9 +1013,7 @@ static void queue_packet_complete(struct hpsb_packet *packet) | |||
1015 | } | 1013 | } |
1016 | if (packet->complete_routine != NULL) { | 1014 | if (packet->complete_routine != NULL) { |
1017 | skb_queue_tail(&hpsbpkt_queue, packet->skb); | 1015 | skb_queue_tail(&hpsbpkt_queue, packet->skb); |
1018 | 1016 | wake_up_process(khpsbpkt_thread); | |
1019 | /* Signal the kernel thread to handle this */ | ||
1020 | up(&khpsbpkt_sig); | ||
1021 | } | 1017 | } |
1022 | return; | 1018 | return; |
1023 | } | 1019 | } |
@@ -1029,19 +1025,9 @@ static int hpsbpkt_thread(void *__hi) | |||
1029 | void (*complete_routine)(void*); | 1025 | void (*complete_routine)(void*); |
1030 | void *complete_data; | 1026 | void *complete_data; |
1031 | 1027 | ||
1032 | daemonize("khpsbpkt"); | ||
1033 | |||
1034 | current->flags |= PF_NOFREEZE; | 1028 | current->flags |= PF_NOFREEZE; |
1035 | 1029 | ||
1036 | while (1) { | 1030 | while (!kthread_should_stop()) { |
1037 | if (down_interruptible(&khpsbpkt_sig)) { | ||
1038 | printk("khpsbpkt: received unexpected signal?!\n" ); | ||
1039 | break; | ||
1040 | } | ||
1041 | |||
1042 | if (khpsbpkt_kill) | ||
1043 | break; | ||
1044 | |||
1045 | while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) { | 1031 | while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) { |
1046 | packet = (struct hpsb_packet *)skb->data; | 1032 | packet = (struct hpsb_packet *)skb->data; |
1047 | 1033 | ||
@@ -1052,9 +1038,13 @@ static int hpsbpkt_thread(void *__hi) | |||
1052 | 1038 | ||
1053 | complete_routine(complete_data); | 1039 | complete_routine(complete_data); |
1054 | } | 1040 | } |
1055 | } | ||
1056 | 1041 | ||
1057 | complete_and_exit(&khpsbpkt_complete, 0); | 1042 | set_current_state(TASK_INTERRUPTIBLE); |
1043 | if (!skb_peek(&hpsbpkt_queue)) | ||
1044 | schedule(); | ||
1045 | __set_current_state(TASK_RUNNING); | ||
1046 | } | ||
1047 | return 0; | ||
1058 | } | 1048 | } |
1059 | 1049 | ||
1060 | static int __init ieee1394_init(void) | 1050 | static int __init ieee1394_init(void) |
@@ -1069,10 +1059,10 @@ static int __init ieee1394_init(void) | |||
1069 | HPSB_ERR("Some features may not be available\n"); | 1059 | HPSB_ERR("Some features may not be available\n"); |
1070 | } | 1060 | } |
1071 | 1061 | ||
1072 | khpsbpkt_pid = kernel_thread(hpsbpkt_thread, NULL, CLONE_KERNEL); | 1062 | khpsbpkt_thread = kthread_run(hpsbpkt_thread, NULL, "khpsbpkt"); |
1073 | if (khpsbpkt_pid < 0) { | 1063 | if (IS_ERR(khpsbpkt_thread)) { |
1074 | HPSB_ERR("Failed to start hpsbpkt thread!\n"); | 1064 | HPSB_ERR("Failed to start hpsbpkt thread!\n"); |
1075 | ret = -ENOMEM; | 1065 | ret = PTR_ERR(khpsbpkt_thread); |
1076 | goto exit_cleanup_config_roms; | 1066 | goto exit_cleanup_config_roms; |
1077 | } | 1067 | } |
1078 | 1068 | ||
@@ -1152,10 +1142,7 @@ release_all_bus: | |||
1152 | release_chrdev: | 1142 | release_chrdev: |
1153 | unregister_chrdev_region(IEEE1394_CORE_DEV, 256); | 1143 | unregister_chrdev_region(IEEE1394_CORE_DEV, 256); |
1154 | exit_release_kernel_thread: | 1144 | exit_release_kernel_thread: |
1155 | if (khpsbpkt_pid >= 0) { | 1145 | kthread_stop(khpsbpkt_thread); |
1156 | kill_proc(khpsbpkt_pid, SIGTERM, 1); | ||
1157 | wait_for_completion(&khpsbpkt_complete); | ||
1158 | } | ||
1159 | exit_cleanup_config_roms: | 1146 | exit_cleanup_config_roms: |
1160 | hpsb_cleanup_config_roms(); | 1147 | hpsb_cleanup_config_roms(); |
1161 | return ret; | 1148 | return ret; |
@@ -1176,12 +1163,7 @@ static void __exit ieee1394_cleanup(void) | |||
1176 | bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]); | 1163 | bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]); |
1177 | bus_unregister(&ieee1394_bus_type); | 1164 | bus_unregister(&ieee1394_bus_type); |
1178 | 1165 | ||
1179 | if (khpsbpkt_pid >= 0) { | 1166 | kthread_stop(khpsbpkt_thread); |
1180 | khpsbpkt_kill = 1; | ||
1181 | mb(); | ||
1182 | up(&khpsbpkt_sig); | ||
1183 | wait_for_completion(&khpsbpkt_complete); | ||
1184 | } | ||
1185 | 1167 | ||
1186 | hpsb_cleanup_config_roms(); | 1168 | hpsb_cleanup_config_roms(); |
1187 | 1169 | ||