1/* Copyright (c) 2012 Coraid, Inc.  See COPYING for GPL terms. */
2/*
3 * aoemain.c
4 * Module initialization routines, discover timer
5 */
6
7#include <linux/hdreg.h>
8#include <linux/blkdev.h>
9#include <linux/module.h>
10#include <linux/skbuff.h>
11#include "aoe.h"
12
13MODULE_LICENSE("GPL");
14MODULE_AUTHOR("Sam Hopkins <sah@coraid.com>");
15MODULE_DESCRIPTION("AoE block/char driver for 2.6.2 and newer 2.6 kernels");
16MODULE_VERSION(VERSION);
17
18enum { TINIT, TRUN, TKILL };
19
20static void
21discover_timer(ulong vp)
22{
23	static struct timer_list t;
24	static volatile ulong die;
25	static spinlock_t lock;
26	ulong flags;
27	enum { DTIMERTICK = HZ * 60 }; /* one minute */
28
29	switch (vp) {
30	case TINIT:
31		init_timer(&t);
32		spin_lock_init(&lock);
33		t.data = TRUN;
34		t.function = discover_timer;
35		die = 0;
36	case TRUN:
37		spin_lock_irqsave(&lock, flags);
38		if (!die) {
39			t.expires = jiffies + DTIMERTICK;
40			add_timer(&t);
41		}
42		spin_unlock_irqrestore(&lock, flags);
43
44		aoecmd_cfg(0xffff, 0xff);
45		return;
46	case TKILL:
47		spin_lock_irqsave(&lock, flags);
48		die = 1;
49		spin_unlock_irqrestore(&lock, flags);
50
51		del_timer_sync(&t);
52	default:
53		return;
54	}
55}
56
57static void
58aoe_exit(void)
59{
60	discover_timer(TKILL);
61
62	aoenet_exit();
63	unregister_blkdev(AOE_MAJOR, DEVICE_NAME);
64	aoecmd_exit();
65	aoechr_exit();
66	aoedev_exit();
67	aoeblk_exit();		/* free cache after de-allocating bufs */
68}
69
70static int __init
71aoe_init(void)
72{
73	int ret;
74
75	ret = aoedev_init();
76	if (ret)
77		return ret;
78	ret = aoechr_init();
79	if (ret)
80		goto chr_fail;
81	ret = aoeblk_init();
82	if (ret)
83		goto blk_fail;
84	ret = aoenet_init();
85	if (ret)
86		goto net_fail;
87	ret = aoecmd_init();
88	if (ret)
89		goto cmd_fail;
90	ret = register_blkdev(AOE_MAJOR, DEVICE_NAME);
91	if (ret < 0) {
92		printk(KERN_ERR "aoe: can't register major\n");
93		goto blkreg_fail;
94	}
95	printk(KERN_INFO "aoe: AoE v%s initialised.\n", VERSION);
96	discover_timer(TINIT);
97	return 0;
98 blkreg_fail:
99	aoecmd_exit();
100 cmd_fail:
101	aoenet_exit();
102 net_fail:
103	aoeblk_exit();
104 blk_fail:
105	aoechr_exit();
106 chr_fail:
107	aoedev_exit();
108
109	printk(KERN_INFO "aoe: initialisation failure.\n");
110	return ret;
111}
112
113module_init(aoe_init);
114module_exit(aoe_exit);
115
116