X-Git-Url: http://git.onelab.eu/?p=linux-2.6.git;a=blobdiff_plain;f=drivers%2Fieee1394%2Fieee1394_core.c;fp=drivers%2Fieee1394%2Fieee1394_core.c;h=25ef5a86f5f0dc62f27b0b34b088949c2b325b94;hp=f43739c5cab2ed11176c8493d4cf90de2e9a5f49;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index f43739c5c..25ef5a86f 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c @@ -20,6 +20,7 @@ * */ +#include #include #include #include @@ -32,7 +33,6 @@ #include #include #include -#include #include #include @@ -58,7 +58,7 @@ MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality."); /* Disable Isochronous Resource Manager functionality */ int hpsb_disable_irm = 0; -module_param_named(disable_irm, hpsb_disable_irm, bool, 0444); +module_param_named(disable_irm, hpsb_disable_irm, bool, 0); MODULE_PARM_DESC(disable_irm, "Disable Isochronous Resource Manager functionality."); @@ -285,9 +285,9 @@ static int check_selfids(struct hpsb_host *host) static void build_speed_map(struct hpsb_host *host, int nodecount) { + u8 speedcap[nodecount]; u8 cldcnt[nodecount]; u8 *map = host->speed_map; - u8 *speedcap = host->speed; struct selfid *sid; struct ext_selfid *esid; int i, j, n; @@ -354,11 +354,6 @@ static void build_speed_map(struct hpsb_host *host, int nodecount) } } } - - /* assume maximum speed for 1394b PHYs, nodemgr will correct it */ - for (n = 0; n < nodecount; n++) - if (speedcap[n] == 3) - speedcap[n] = IEEE1394_SPEED_MAX; } @@ -559,10 +554,11 @@ int hpsb_send_packet(struct hpsb_packet *packet) return 0; } - if (packet->type == hpsb_async && - NODEID_TO_NODE(packet->node_id) != ALL_NODES) + if (packet->type == hpsb_async && packet->node_id != ALL_NODES) { packet->speed_code = - host->speed[NODEID_TO_NODE(packet->node_id)]; + host->speed_map[NODEID_TO_NODE(host->node_id) * 64 + + NODEID_TO_NODE(packet->node_id)]; + } dump_packet("send packet", packet->header, packet->header_size, packet->speed_code); @@ -1001,8 +997,11 @@ void abort_timedouts(unsigned long __opaque) * packets that have a "complete" function are sent here. This way, the * completion is run out of kernel context, and doesn't block the rest of * the stack. */ -static struct task_struct *khpsbpkt_thread; +static int khpsbpkt_pid = -1, khpsbpkt_kill; +static DECLARE_COMPLETION(khpsbpkt_complete); static struct sk_buff_head hpsbpkt_queue; +static DECLARE_MUTEX_LOCKED(khpsbpkt_sig); + static void queue_packet_complete(struct hpsb_packet *packet) { @@ -1012,7 +1011,9 @@ static void queue_packet_complete(struct hpsb_packet *packet) } if (packet->complete_routine != NULL) { skb_queue_tail(&hpsbpkt_queue, packet->skb); - wake_up_process(khpsbpkt_thread); + + /* Signal the kernel thread to handle this */ + up(&khpsbpkt_sig); } return; } @@ -1024,9 +1025,19 @@ static int hpsbpkt_thread(void *__hi) void (*complete_routine)(void*); void *complete_data; + daemonize("khpsbpkt"); + current->flags |= PF_NOFREEZE; - while (!kthread_should_stop()) { + while (1) { + if (down_interruptible(&khpsbpkt_sig)) { + printk("khpsbpkt: received unexpected signal?!\n" ); + break; + } + + if (khpsbpkt_kill) + break; + while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) { packet = (struct hpsb_packet *)skb->data; @@ -1037,13 +1048,9 @@ static int hpsbpkt_thread(void *__hi) complete_routine(complete_data); } - - set_current_state(TASK_INTERRUPTIBLE); - if (!skb_peek(&hpsbpkt_queue)) - schedule(); - __set_current_state(TASK_RUNNING); } - return 0; + + complete_and_exit(&khpsbpkt_complete, 0); } static int __init ieee1394_init(void) @@ -1058,10 +1065,10 @@ static int __init ieee1394_init(void) HPSB_ERR("Some features may not be available\n"); } - khpsbpkt_thread = kthread_run(hpsbpkt_thread, NULL, "khpsbpkt"); - if (IS_ERR(khpsbpkt_thread)) { + khpsbpkt_pid = kernel_thread(hpsbpkt_thread, NULL, CLONE_KERNEL); + if (khpsbpkt_pid < 0) { HPSB_ERR("Failed to start hpsbpkt thread!\n"); - ret = PTR_ERR(khpsbpkt_thread); + ret = -ENOMEM; goto exit_cleanup_config_roms; } @@ -1071,10 +1078,17 @@ static int __init ieee1394_init(void) goto exit_release_kernel_thread; } + /* actually this is a non-fatal error */ + ret = devfs_mk_dir("ieee1394"); + if (ret < 0) { + HPSB_ERR("unable to make devfs dir for device major %d!\n", IEEE1394_MAJOR); + goto release_chrdev; + } + ret = bus_register(&ieee1394_bus_type); if (ret < 0) { HPSB_INFO("bus register failed"); - goto release_chrdev; + goto release_devfs; } for (i = 0; fw_bus_attrs[i]; i++) { @@ -1085,7 +1099,7 @@ static int __init ieee1394_init(void) fw_bus_attrs[i--]); } bus_unregister(&ieee1394_bus_type); - goto release_chrdev; + goto release_devfs; } } @@ -1138,10 +1152,15 @@ release_all_bus: for (i = 0; fw_bus_attrs[i]; i++) bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]); bus_unregister(&ieee1394_bus_type); +release_devfs: + devfs_remove("ieee1394"); release_chrdev: unregister_chrdev_region(IEEE1394_CORE_DEV, 256); exit_release_kernel_thread: - kthread_stop(khpsbpkt_thread); + if (khpsbpkt_pid >= 0) { + kill_proc(khpsbpkt_pid, SIGTERM, 1); + wait_for_completion(&khpsbpkt_complete); + } exit_cleanup_config_roms: hpsb_cleanup_config_roms(); return ret; @@ -1162,11 +1181,17 @@ static void __exit ieee1394_cleanup(void) bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]); bus_unregister(&ieee1394_bus_type); - kthread_stop(khpsbpkt_thread); + if (khpsbpkt_pid >= 0) { + khpsbpkt_kill = 1; + mb(); + up(&khpsbpkt_sig); + wait_for_completion(&khpsbpkt_complete); + } hpsb_cleanup_config_roms(); unregister_chrdev_region(IEEE1394_CORE_DEV, 256); + devfs_remove("ieee1394"); } module_init(ieee1394_init);