Import 2.1.118
[davej-history.git] / drivers / char / softdog.c
blobc611b53448186348cb3ad4b618412cee9b7a2595
1 /*
2 * SoftDog 0.05: A Software Watchdog Device
4 * (c) Copyright 1996 Alan Cox <alan@cymru.net>, All Rights Reserved.
5 * http://www.cymru.net
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
12 * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
13 * warranty for any of this software. This material is provided
14 * "AS-IS" and at no charge.
16 * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
18 * Software only watchdog driver. Unlike its big brother the WDT501P
19 * driver this won't always recover a failed machine.
21 * 03/96: Angelo Haritsis <ah@doc.ic.ac.uk> :
22 * Modularised.
23 * Added soft_margin; use upon insmod to change the timer delay.
24 * NB: uses same minor as wdt (WATCHDOG_MINOR); we could use separate
25 * minors.
28 #include <linux/module.h>
29 #include <linux/config.h>
30 #include <linux/types.h>
31 #include <linux/kernel.h>
32 #include <linux/fs.h>
33 #include <linux/mm.h>
34 #include <linux/miscdevice.h>
35 #include <linux/watchdog.h>
36 #include <linux/reboot.h>
37 #include <linux/init.h>
38 #include <asm/uaccess.h>
40 #define TIMER_MARGIN 60 /* (secs) Default is 1 minute */
42 static int soft_margin = TIMER_MARGIN; /* in seconds */
44 #ifdef MODULE
45 MODULE_PARM(soft_margin,"i");
46 #endif
49 * Our timer
52 struct timer_list watchdog_ticktock;
53 static int timer_alive = 0;
57 * If the timer expires..
60 static void watchdog_fire(unsigned long data)
62 #ifdef ONLY_TESTING
63 printk(KERN_CRIT "SOFTDOG: Would Reboot.\n");
64 #else
65 printk(KERN_CRIT "SOFTDOG: Initiating system reboot.\n");
66 machine_restart(NULL);
67 printk("WATCHDOG: Reboot didn't ?????\n");
68 #endif
72 * Allow only one person to hold it open
75 static int softdog_open(struct inode *inode, struct file *file)
77 if(timer_alive)
78 return -EBUSY;
79 MOD_INC_USE_COUNT;
81 * Activate timer
83 del_timer(&watchdog_ticktock);
84 watchdog_ticktock.expires=jiffies + (soft_margin * HZ);
85 add_timer(&watchdog_ticktock);
86 timer_alive=1;
87 return 0;
90 static int softdog_release(struct inode *inode, struct file *file)
93 * Shut off the timer.
94 * Lock it in if it's a module and we defined ...NOWAYOUT
96 #ifndef CONFIG_WATCHDOG_NOWAYOUT
97 del_timer(&watchdog_ticktock);
98 MOD_DEC_USE_COUNT;
99 #endif
100 timer_alive=0;
101 return 0;
104 static void softdog_ping(void)
107 * Refresh the timer.
109 del_timer(&watchdog_ticktock);
110 watchdog_ticktock.expires=jiffies + (soft_margin * HZ);
111 add_timer(&watchdog_ticktock);
112 return;
115 static ssize_t softdog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
117 /* Can't seek (pwrite) on this device */
118 if (ppos != &file->f_pos)
119 return -ESPIPE;
122 * Refresh the timer.
124 if(len)
126 softdog_ping();
127 return 1;
129 return 0;
132 static int softdog_ioctl(struct inode *inode, struct file *file,
133 unsigned int cmd, unsigned long arg)
135 int i;
136 static struct watchdog_info ident=
140 "Software Watchdog"
142 switch(cmd)
144 default:
145 return -ENOIOCTLCMD;
146 case WDIOC_GETSUPPORT:
147 i = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct watchdog_info));
148 if (i)
149 return i;
150 else
151 return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident));
152 case WDIOC_GETSTATUS:
153 case WDIOC_GETBOOTSTATUS:
154 return put_user(0,(int *)arg);
155 case WDIOC_KEEPALIVE:
156 softdog_ping();
157 return 0;
161 static struct file_operations softdog_fops=
163 NULL, /* Seek */
164 NULL, /* Read */
165 softdog_write, /* Write */
166 NULL, /* Readdir */
167 NULL, /* Select */
168 softdog_ioctl, /* Ioctl */
169 NULL, /* MMap */
170 softdog_open,
171 NULL, /* flush */
172 softdog_release,
173 NULL,
174 NULL /* Fasync */
177 static struct miscdevice softdog_miscdev=
179 WATCHDOG_MINOR,
180 "watchdog",
181 &softdog_fops
184 __initfunc(void watchdog_init(void))
186 misc_register(&softdog_miscdev);
187 init_timer(&watchdog_ticktock);
188 watchdog_ticktock.function=watchdog_fire;
189 printk("Software Watchdog Timer: 0.05, timer margin: %d sec\n", soft_margin);
192 #ifdef MODULE
193 int init_module(void)
195 watchdog_init();
196 return 0;
199 void cleanup_module(void)
201 misc_deregister(&softdog_miscdev);
203 #endif