fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / ieee1394 / ieee1394_core.c
index 25ef5a8..9a48ca2 100644 (file)
@@ -20,7 +20,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/string.h>
@@ -33,9 +32,9 @@
 #include <linux/kdev_t.h>
 #include <linux/skbuff.h>
 #include <linux/suspend.h>
+#include <linux/kthread.h>
 
 #include <asm/byteorder.h>
-#include <asm/semaphore.h>
 
 #include "ieee1394_types.h"
 #include "ieee1394.h"
@@ -58,7 +57,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, 0);
+module_param_named(disable_irm, hpsb_disable_irm, bool, 0444);
 MODULE_PARM_DESC(disable_irm,
                 "Disable Isochronous Resource Manager functionality.");
 
@@ -86,7 +85,7 @@ static void dump_packet(const char *text, quadlet_t *data, int size, int speed)
        printk("\n");
 }
 #else
-#define dump_packet(a,b,c,d)
+#define dump_packet(a,b,c,d) do {} while (0)
 #endif
 
 static void abort_requests(struct hpsb_host *host);
@@ -285,9 +284,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,6 +353,13 @@ static void build_speed_map(struct hpsb_host *host, int nodecount)
                        }
                }
        }
+
+#if SELFID_SPEED_UNKNOWN != IEEE1394_SPEED_MAX
+       /* assume maximum speed for 1394b PHYs, nodemgr will correct it */
+       for (n = 0; n < nodecount; n++)
+               if (speedcap[n] == SELFID_SPEED_UNKNOWN)
+                       speedcap[n] = IEEE1394_SPEED_MAX;
+#endif
 }
 
 
@@ -554,11 +560,10 @@ int hpsb_send_packet(struct hpsb_packet *packet)
                return 0;
        }
 
-       if (packet->type == hpsb_async && packet->node_id != ALL_NODES) {
+       if (packet->type == hpsb_async &&
+           NODEID_TO_NODE(packet->node_id) != ALL_NODES)
                packet->speed_code =
-                       host->speed_map[NODEID_TO_NODE(host->node_id) * 64
-                                      + NODEID_TO_NODE(packet->node_id)];
-       }
+                       host->speed[NODEID_TO_NODE(packet->node_id)];
 
        dump_packet("send packet", packet->header, packet->header_size, packet->speed_code);
 
@@ -997,11 +1002,8 @@ 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 int khpsbpkt_pid = -1, khpsbpkt_kill;
-static DECLARE_COMPLETION(khpsbpkt_complete);
+static struct task_struct *khpsbpkt_thread;
 static struct sk_buff_head hpsbpkt_queue;
-static DECLARE_MUTEX_LOCKED(khpsbpkt_sig);
-
 
 static void queue_packet_complete(struct hpsb_packet *packet)
 {
@@ -1011,9 +1013,7 @@ static void queue_packet_complete(struct hpsb_packet *packet)
        }
        if (packet->complete_routine != NULL) {
                skb_queue_tail(&hpsbpkt_queue, packet->skb);
-
-               /* Signal the kernel thread to handle this */
-               up(&khpsbpkt_sig);
+               wake_up_process(khpsbpkt_thread);
        }
        return;
 }
@@ -1025,19 +1025,9 @@ static int hpsbpkt_thread(void *__hi)
        void (*complete_routine)(void*);
        void *complete_data;
 
-       daemonize("khpsbpkt");
-
        current->flags |= PF_NOFREEZE;
 
-       while (1) {
-               if (down_interruptible(&khpsbpkt_sig)) {
-                       printk("khpsbpkt: received unexpected signal?!\n" );
-                       break;
-               }
-
-               if (khpsbpkt_kill)
-                       break;
-
+       while (!kthread_should_stop()) {
                while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) {
                        packet = (struct hpsb_packet *)skb->data;
 
@@ -1048,9 +1038,13 @@ static int hpsbpkt_thread(void *__hi)
 
                        complete_routine(complete_data);
                }
-       }
 
-       complete_and_exit(&khpsbpkt_complete, 0);
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (!skb_peek(&hpsbpkt_queue))
+                       schedule();
+               __set_current_state(TASK_RUNNING);
+       }
+       return 0;
 }
 
 static int __init ieee1394_init(void)
@@ -1065,10 +1059,10 @@ static int __init ieee1394_init(void)
                HPSB_ERR("Some features may not be available\n");
        }
 
-       khpsbpkt_pid = kernel_thread(hpsbpkt_thread, NULL, CLONE_KERNEL);
-       if (khpsbpkt_pid < 0) {
+       khpsbpkt_thread = kthread_run(hpsbpkt_thread, NULL, "khpsbpkt");
+       if (IS_ERR(khpsbpkt_thread)) {
                HPSB_ERR("Failed to start hpsbpkt thread!\n");
-               ret = -ENOMEM;
+               ret = PTR_ERR(khpsbpkt_thread);
                goto exit_cleanup_config_roms;
        }
 
@@ -1078,17 +1072,10 @@ 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_devfs;
+               goto release_chrdev;
        }
 
        for (i = 0; fw_bus_attrs[i]; i++) {
@@ -1099,7 +1086,7 @@ static int __init ieee1394_init(void)
                                                fw_bus_attrs[i--]);
                        }
                        bus_unregister(&ieee1394_bus_type);
-                       goto release_devfs;
+                       goto release_chrdev;
                }
        }
 
@@ -1152,15 +1139,10 @@ 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:
-       if (khpsbpkt_pid >= 0) {
-               kill_proc(khpsbpkt_pid, SIGTERM, 1);
-               wait_for_completion(&khpsbpkt_complete);
-       }
+       kthread_stop(khpsbpkt_thread);
 exit_cleanup_config_roms:
        hpsb_cleanup_config_roms();
        return ret;
@@ -1181,20 +1163,14 @@ static void __exit ieee1394_cleanup(void)
                bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]);
        bus_unregister(&ieee1394_bus_type);
 
-       if (khpsbpkt_pid >= 0) {
-               khpsbpkt_kill = 1;
-               mb();
-               up(&khpsbpkt_sig);
-               wait_for_completion(&khpsbpkt_complete);
-       }
+       kthread_stop(khpsbpkt_thread);
 
        hpsb_cleanup_config_roms();
 
        unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
-       devfs_remove("ieee1394");
 }
 
-module_init(ieee1394_init);
+fs_initcall(ieee1394_init); /* same as ohci1394 */
 module_exit(ieee1394_cleanup);
 
 /* Exported symbols */
@@ -1261,10 +1237,10 @@ EXPORT_SYMBOL(highlevel_remove_host);
 /** nodemgr.c **/
 EXPORT_SYMBOL(hpsb_node_fill_packet);
 EXPORT_SYMBOL(hpsb_node_write);
-EXPORT_SYMBOL(hpsb_register_protocol);
+EXPORT_SYMBOL(__hpsb_register_protocol);
 EXPORT_SYMBOL(hpsb_unregister_protocol);
-EXPORT_SYMBOL(ieee1394_bus_type);
 #ifdef CONFIG_IEEE1394_EXPORT_FULL_API
+EXPORT_SYMBOL(ieee1394_bus_type);
 EXPORT_SYMBOL(nodemgr_for_each_host);
 #endif