/*******************************************************
 *
 * COPYRIGHT (C) FUJITSU,LTD. 2001 ALL RIGHTS RESERVED.
 * 
 * Created by T.INDOH <indou.takao@jp.fujitsu.com>
 *
 *******************************************************/
#define EXPORT_SYMTAB

#include <linux/module.h>
#include <linux/modversions.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/lkst.h>


MODULE_AUTHOR("T.INDOH <indou.takao@jp.fujitsu.com>");
MODULE_LICENSE("GPL");

/* 
 * Define event type.
 * These should be defined in lkst_events.h as follows,
 * 
 * LKST_ETYPE_DEF(0x100, 0x0b, MODULE, NEW_EVENT1, NEW_EVENT1, 
 *                "New event 1(insmod)", 0, "0", NULL, NULL, NULL)
 * LKST_ETYPE_DEF(0x101, 0x0b, MODULE, NEW_EVENT2, NEW_EVENT2,
 *                "New event 2(reset timer)", 0, "jiffies", NULL, NULL, NULL)
 * LKST_ETYPE_DEF(0x102, 0x0b, MODULE, NEW_EVENT3, NEW_EVENT3,
 *                "New event 3(rmmod)", 0, "1", NULL, NULL, NULL)
 */
#define NEW_EVENT1 0x100
#define NEW_EVENT2 0x101
#define NEW_EVENT3 0x102

/* Declaration of hook header */
LKST_HOOK_DECLARE(NEW_EVENT1);
LKST_HOOK_DECLARE(NEW_EVENT2);
LKST_HOOK_DECLARE(NEW_EVENT3);

static struct timer_list test_timer;

void func(void)
{
	/* reset the timer */
	printk("reset timer\n");
	mod_timer(&test_timer, jiffies + 10 * HZ);

	LKST_HOOK(NEW_EVENT2,
	          LKST_ARG32(jiffies,0), LKST_ARG32(0,0),
	          LKST_ARG32(0,0), LKST_ARG32(0,0));
}

static int __init testmod_init(void)
{
	int ret, retall=0;
	printk("testmod installed\n");

	/* Initialization of hook header */
	LKST_HOOK_INIT_MODULE(NEW_EVENT1, ret);
	retall += ret;
	LKST_HOOK_INIT_MODULE(NEW_EVENT2, ret);
	retall += ret;
	LKST_HOOK_INIT_MODULE(NEW_EVENT3, ret);
	retall += ret;
	if(ret) return ret;

	LKST_HOOK(NEW_EVENT1,
	          LKST_ARG32(0,0), LKST_ARG32(0,0),
	          LKST_ARG32(0,0), LKST_ARG32(0,0));

	/* set timer */
	init_timer(&test_timer);
	test_timer.expires  = jiffies + 10 * HZ;
	test_timer.data     = 0;
	test_timer.function = (void *)&func;
	add_timer(&test_timer);

	return 0;
}

static void __exit testmod_exit(void)
{
	int ret;
	printk("testmod uninstalled\n");
	del_timer(&test_timer);

	LKST_HOOK(NEW_EVENT3,
	          LKST_ARG32(1,0), LKST_ARG32(0,0),
	          LKST_ARG32(0,0), LKST_ARG32(0,0));

	/* Cleanup of hook header for module */
	LKST_HOOK_TERMINATE_MODULE(NEW_EVENT1, ret);
	LKST_HOOK_TERMINATE_MODULE(NEW_EVENT2, ret);
	LKST_HOOK_TERMINATE_MODULE(NEW_EVENT3, ret);
}

module_init(testmod_init);
module_exit(testmod_exit);
