xref: /openbmc/linux/drivers/block/aoe/aoemain.c (revision a12c93f0)
12611464dSEd L. Cashin /* Copyright (c) 2006 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>
101da177e4SLinus Torvalds #include "aoe.h"
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds MODULE_LICENSE("GPL");
131da177e4SLinus Torvalds MODULE_AUTHOR("Sam Hopkins <sah@coraid.com>");
1402edb05eSEd L. Cashin MODULE_DESCRIPTION("AoE block/char driver for 2.6.2 and newer 2.6 kernels");
151da177e4SLinus Torvalds MODULE_VERSION(VERSION);
161da177e4SLinus Torvalds 
171da177e4SLinus Torvalds enum { TINIT, TRUN, TKILL };
181da177e4SLinus Torvalds 
191da177e4SLinus Torvalds static void
201da177e4SLinus Torvalds discover_timer(ulong vp)
211da177e4SLinus Torvalds {
221da177e4SLinus Torvalds 	static struct timer_list t;
231da177e4SLinus Torvalds 	static volatile ulong die;
241da177e4SLinus Torvalds 	static spinlock_t lock;
251da177e4SLinus Torvalds 	ulong flags;
261da177e4SLinus Torvalds 	enum { DTIMERTICK = HZ * 60 }; /* one minute */
271da177e4SLinus Torvalds 
281da177e4SLinus Torvalds 	switch (vp) {
291da177e4SLinus Torvalds 	case TINIT:
301da177e4SLinus Torvalds 		init_timer(&t);
311da177e4SLinus Torvalds 		spin_lock_init(&lock);
321da177e4SLinus Torvalds 		t.data = TRUN;
331da177e4SLinus Torvalds 		t.function = discover_timer;
341da177e4SLinus Torvalds 		die = 0;
351da177e4SLinus Torvalds 	case TRUN:
361da177e4SLinus Torvalds 		spin_lock_irqsave(&lock, flags);
371da177e4SLinus Torvalds 		if (!die) {
381da177e4SLinus Torvalds 			t.expires = jiffies + DTIMERTICK;
391da177e4SLinus Torvalds 			add_timer(&t);
401da177e4SLinus Torvalds 		}
411da177e4SLinus Torvalds 		spin_unlock_irqrestore(&lock, flags);
421da177e4SLinus Torvalds 
431da177e4SLinus Torvalds 		aoecmd_cfg(0xffff, 0xff);
441da177e4SLinus Torvalds 		return;
451da177e4SLinus Torvalds 	case TKILL:
461da177e4SLinus Torvalds 		spin_lock_irqsave(&lock, flags);
471da177e4SLinus Torvalds 		die = 1;
481da177e4SLinus Torvalds 		spin_unlock_irqrestore(&lock, flags);
491da177e4SLinus Torvalds 
501da177e4SLinus Torvalds 		del_timer_sync(&t);
511da177e4SLinus Torvalds 	default:
521da177e4SLinus Torvalds 		return;
531da177e4SLinus Torvalds 	}
541da177e4SLinus Torvalds }
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds static void
571da177e4SLinus Torvalds aoe_exit(void)
581da177e4SLinus Torvalds {
591da177e4SLinus Torvalds 	discover_timer(TKILL);
601da177e4SLinus Torvalds 
611da177e4SLinus Torvalds 	aoenet_exit();
621da177e4SLinus Torvalds 	unregister_blkdev(AOE_MAJOR, DEVICE_NAME);
631da177e4SLinus Torvalds 	aoechr_exit();
641da177e4SLinus Torvalds 	aoedev_exit();
651da177e4SLinus Torvalds 	aoeblk_exit();		/* free cache after de-allocating bufs */
661da177e4SLinus Torvalds }
671da177e4SLinus Torvalds 
681da177e4SLinus Torvalds static int __init
691da177e4SLinus Torvalds aoe_init(void)
701da177e4SLinus Torvalds {
711da177e4SLinus Torvalds 	int ret;
721da177e4SLinus Torvalds 
731da177e4SLinus Torvalds 	ret = aoedev_init();
741da177e4SLinus Torvalds 	if (ret)
751da177e4SLinus Torvalds 		return ret;
761da177e4SLinus Torvalds 	ret = aoechr_init();
771da177e4SLinus Torvalds 	if (ret)
781da177e4SLinus Torvalds 		goto chr_fail;
791da177e4SLinus Torvalds 	ret = aoeblk_init();
801da177e4SLinus Torvalds 	if (ret)
811da177e4SLinus Torvalds 		goto blk_fail;
821da177e4SLinus Torvalds 	ret = aoenet_init();
831da177e4SLinus Torvalds 	if (ret)
841da177e4SLinus Torvalds 		goto net_fail;
851da177e4SLinus Torvalds 	ret = register_blkdev(AOE_MAJOR, DEVICE_NAME);
861da177e4SLinus Torvalds 	if (ret < 0) {
87a12c93f0SEd L. Cashin 		printk(KERN_ERR "aoe: can't register major\n");
881da177e4SLinus Torvalds 		goto blkreg_fail;
891da177e4SLinus Torvalds 	}
901da177e4SLinus Torvalds 
91a12c93f0SEd L. Cashin 	printk(KERN_INFO "aoe: AoE v%s initialised.\n", VERSION);
921da177e4SLinus Torvalds 	discover_timer(TINIT);
931da177e4SLinus Torvalds 	return 0;
941da177e4SLinus Torvalds 
951da177e4SLinus Torvalds  blkreg_fail:
961da177e4SLinus Torvalds 	aoenet_exit();
971da177e4SLinus Torvalds  net_fail:
981da177e4SLinus Torvalds 	aoeblk_exit();
991da177e4SLinus Torvalds  blk_fail:
1001da177e4SLinus Torvalds 	aoechr_exit();
1011da177e4SLinus Torvalds  chr_fail:
1021da177e4SLinus Torvalds 	aoedev_exit();
1031da177e4SLinus Torvalds 
104a12c93f0SEd L. Cashin 	printk(KERN_INFO "aoe: initialisation failure.\n");
1051da177e4SLinus Torvalds 	return ret;
1061da177e4SLinus Torvalds }
1071da177e4SLinus Torvalds 
1081da177e4SLinus Torvalds module_init(aoe_init);
1091da177e4SLinus Torvalds module_exit(aoe_exit);
1101da177e4SLinus Torvalds 
111