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