| /* Copyright (c) 2004 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 "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: aoeblk_init: can't register major\n"); |
| goto blkreg_fail; |
| } |
| |
| printk(KERN_INFO |
| "aoe: aoe_init: 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: aoe_init: initialisation failure.\n"); |
| return ret; |
| } |
| |
| module_init(aoe_init); |
| module_exit(aoe_exit); |
| |