xref: /openbmc/linux/drivers/block/aoe/aoemain.c (revision 896831f5)
152e112b3SEd L. Cashin /* Copyright (c) 2007 Coraid, Inc.  See COPYING for GPL terms. */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * aoemain.c
41da177e4SLinus Torvalds  * Module initialization routines, discover timer
51da177e4SLinus Torvalds  */
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds #include <linux/hdreg.h>
81da177e4SLinus Torvalds #include <linux/blkdev.h>
91da177e4SLinus Torvalds #include <linux/module.h>
10e9bb8fb0SDavid S. Miller #include <linux/skbuff.h>
111da177e4SLinus Torvalds #include "aoe.h"
121da177e4SLinus Torvalds 
131da177e4SLinus Torvalds MODULE_LICENSE("GPL");
141da177e4SLinus Torvalds MODULE_AUTHOR("Sam Hopkins <sah@coraid.com>");
1502edb05eSEd L. Cashin MODULE_DESCRIPTION("AoE block/char driver for 2.6.2 and newer 2.6 kernels");
161da177e4SLinus Torvalds MODULE_VERSION(VERSION);
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds enum { TINIT, TRUN, TKILL };
191da177e4SLinus Torvalds 
201da177e4SLinus Torvalds static void
211da177e4SLinus Torvalds discover_timer(ulong vp)
221da177e4SLinus Torvalds {
231da177e4SLinus Torvalds 	static struct timer_list t;
241da177e4SLinus Torvalds 	static volatile ulong die;
251da177e4SLinus Torvalds 	static spinlock_t lock;
261da177e4SLinus Torvalds 	ulong flags;
271da177e4SLinus Torvalds 	enum { DTIMERTICK = HZ * 60 }; /* one minute */
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds 	switch (vp) {
301da177e4SLinus Torvalds 	case TINIT:
311da177e4SLinus Torvalds 		init_timer(&t);
321da177e4SLinus Torvalds 		spin_lock_init(&lock);
331da177e4SLinus Torvalds 		t.data = TRUN;
341da177e4SLinus Torvalds 		t.function = discover_timer;
351da177e4SLinus Torvalds 		die = 0;
361da177e4SLinus Torvalds 	case TRUN:
371da177e4SLinus Torvalds 		spin_lock_irqsave(&lock, flags);
381da177e4SLinus Torvalds 		if (!die) {
391da177e4SLinus Torvalds 			t.expires = jiffies + DTIMERTICK;
401da177e4SLinus Torvalds 			add_timer(&t);
411da177e4SLinus Torvalds 		}
421da177e4SLinus Torvalds 		spin_unlock_irqrestore(&lock, flags);
431da177e4SLinus Torvalds 
441da177e4SLinus Torvalds 		aoecmd_cfg(0xffff, 0xff);
451da177e4SLinus Torvalds 		return;
461da177e4SLinus Torvalds 	case TKILL:
471da177e4SLinus Torvalds 		spin_lock_irqsave(&lock, flags);
481da177e4SLinus Torvalds 		die = 1;
491da177e4SLinus Torvalds 		spin_unlock_irqrestore(&lock, flags);
501da177e4SLinus Torvalds 
511da177e4SLinus Torvalds 		del_timer_sync(&t);
521da177e4SLinus Torvalds 	default:
531da177e4SLinus Torvalds 		return;
541da177e4SLinus Torvalds 	}
551da177e4SLinus Torvalds }
561da177e4SLinus Torvalds 
571da177e4SLinus Torvalds static void
581da177e4SLinus Torvalds aoe_exit(void)
591da177e4SLinus Torvalds {
601da177e4SLinus Torvalds 	discover_timer(TKILL);
611da177e4SLinus Torvalds 
621da177e4SLinus Torvalds 	aoenet_exit();
631da177e4SLinus Torvalds 	unregister_blkdev(AOE_MAJOR, DEVICE_NAME);
64896831f5SEd Cashin 	aoecmd_exit();
651da177e4SLinus Torvalds 	aoechr_exit();
661da177e4SLinus Torvalds 	aoedev_exit();
671da177e4SLinus Torvalds 	aoeblk_exit();		/* free cache after de-allocating bufs */
681da177e4SLinus Torvalds }
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds static int __init
711da177e4SLinus Torvalds aoe_init(void)
721da177e4SLinus Torvalds {
731da177e4SLinus Torvalds 	int ret;
741da177e4SLinus Torvalds 
751da177e4SLinus Torvalds 	ret = aoedev_init();
761da177e4SLinus Torvalds 	if (ret)
771da177e4SLinus Torvalds 		return ret;
781da177e4SLinus Torvalds 	ret = aoechr_init();
791da177e4SLinus Torvalds 	if (ret)
801da177e4SLinus Torvalds 		goto chr_fail;
811da177e4SLinus Torvalds 	ret = aoeblk_init();
821da177e4SLinus Torvalds 	if (ret)
831da177e4SLinus Torvalds 		goto blk_fail;
841da177e4SLinus Torvalds 	ret = aoenet_init();
851da177e4SLinus Torvalds 	if (ret)
861da177e4SLinus Torvalds 		goto net_fail;
87896831f5SEd Cashin 	ret = aoecmd_init();
88896831f5SEd Cashin 	if (ret)
89896831f5SEd Cashin 		goto cmd_fail;
901da177e4SLinus Torvalds 	ret = register_blkdev(AOE_MAJOR, DEVICE_NAME);
911da177e4SLinus Torvalds 	if (ret < 0) {
92a12c93f0SEd L. Cashin 		printk(KERN_ERR "aoe: can't register major\n");
931da177e4SLinus Torvalds 		goto blkreg_fail;
941da177e4SLinus Torvalds 	}
95a12c93f0SEd L. Cashin 	printk(KERN_INFO "aoe: AoE v%s initialised.\n", VERSION);
961da177e4SLinus Torvalds 	discover_timer(TINIT);
971da177e4SLinus Torvalds 	return 0;
981da177e4SLinus Torvalds  blkreg_fail:
99896831f5SEd Cashin 	aoecmd_exit();
100896831f5SEd Cashin  cmd_fail:
1011da177e4SLinus Torvalds 	aoenet_exit();
1021da177e4SLinus Torvalds  net_fail:
1031da177e4SLinus Torvalds 	aoeblk_exit();
1041da177e4SLinus Torvalds  blk_fail:
1051da177e4SLinus Torvalds 	aoechr_exit();
1061da177e4SLinus Torvalds  chr_fail:
1071da177e4SLinus Torvalds 	aoedev_exit();
1081da177e4SLinus Torvalds 
109a12c93f0SEd L. Cashin 	printk(KERN_INFO "aoe: initialisation failure.\n");
1101da177e4SLinus Torvalds 	return ret;
1111da177e4SLinus Torvalds }
1121da177e4SLinus Torvalds 
1131da177e4SLinus Torvalds module_init(aoe_init);
1141da177e4SLinus Torvalds module_exit(aoe_exit);
1151da177e4SLinus Torvalds 
116