summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/block/aoe/aoemain.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/block/aoe/aoemain.c')
-rw-r--r--kernel/drivers/block/aoe/aoemain.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/kernel/drivers/block/aoe/aoemain.c b/kernel/drivers/block/aoe/aoemain.c
new file mode 100644
index 000000000..4b987c2fe
--- /dev/null
+++ b/kernel/drivers/block/aoe/aoemain.c
@@ -0,0 +1,115 @@
+/* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */
+/*
+ * aoemain.c
+ * Module initialization routines, discover timer
+ */
+
+#include <linux/hdreg.h>
+#include <linux/blkdev.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include "aoe.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sam Hopkins <sah@coraid.com>");
+MODULE_DESCRIPTION("AoE block/char driver for 2.6.2 and newer 2.6 kernels");
+MODULE_VERSION(VERSION);
+
+enum { TINIT, TRUN, TKILL };
+
+static void
+discover_timer(ulong vp)
+{
+ static struct timer_list t;
+ static volatile ulong die;
+ static spinlock_t lock;
+ ulong flags;
+ enum { DTIMERTICK = HZ * 60 }; /* one minute */
+
+ switch (vp) {
+ case TINIT:
+ init_timer(&t);
+ spin_lock_init(&lock);
+ t.data = TRUN;
+ t.function = discover_timer;
+ die = 0;
+ case TRUN:
+ spin_lock_irqsave(&lock, flags);
+ if (!die) {
+ t.expires = jiffies + DTIMERTICK;
+ add_timer(&t);
+ }
+ spin_unlock_irqrestore(&lock, flags);
+
+ aoecmd_cfg(0xffff, 0xff);
+ return;
+ case TKILL:
+ spin_lock_irqsave(&lock, flags);
+ die = 1;
+ spin_unlock_irqrestore(&lock, flags);
+
+ del_timer_sync(&t);
+ default:
+ return;
+ }
+}
+
+static void
+aoe_exit(void)
+{
+ discover_timer(TKILL);
+
+ aoenet_exit();
+ unregister_blkdev(AOE_MAJOR, DEVICE_NAME);
+ aoecmd_exit();
+ aoechr_exit();
+ aoedev_exit();
+ aoeblk_exit(); /* free cache after de-allocating bufs */
+}
+
+static int __init
+aoe_init(void)
+{
+ int ret;
+
+ ret = aoedev_init();
+ if (ret)
+ return ret;
+ ret = aoechr_init();
+ if (ret)
+ goto chr_fail;
+ ret = aoeblk_init();
+ if (ret)
+ goto blk_fail;
+ ret = aoenet_init();
+ if (ret)
+ goto net_fail;
+ ret = aoecmd_init();
+ if (ret)
+ goto cmd_fail;
+ ret = register_blkdev(AOE_MAJOR, DEVICE_NAME);
+ if (ret < 0) {
+ printk(KERN_ERR "aoe: can't register major\n");
+ goto blkreg_fail;
+ }
+ printk(KERN_INFO "aoe: AoE v%s initialised.\n", VERSION);
+ discover_timer(TINIT);
+ return 0;
+ blkreg_fail:
+ aoecmd_exit();
+ cmd_fail:
+ aoenet_exit();
+ net_fail:
+ aoeblk_exit();
+ blk_fail:
+ aoechr_exit();
+ chr_fail:
+ aoedev_exit();
+
+ printk(KERN_INFO "aoe: initialisation failure.\n");
+ return ret;
+}
+
+module_init(aoe_init);
+module_exit(aoe_exit);
+