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 | ||
