112 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Copyright (c) 2007 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);
 | 
						|
	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 = 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:
 | 
						|
	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);
 | 
						|
 |