1 /*
2 * SoftDog 0.02: A Software Watchdog Device
3 *
4 * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
5 *
6 * Email us for quotes on Linux software and driver development.
7 *
8 * -----------------------
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 *
15 * -----------------------
16 *
17 * Software only watchdog driver. Unlike its big brother the WDT501P
18 * driver this won't always recover a failed machine.
19 */
20
21 #include <linux/config.h>
22 #include <linux/types.h>
23 #include <linux/kernel.h>
24 #include <linux/fs.h>
25 #include <linux/mm.h>
26 #include <linux/miscdevice.h>
27
28 #define WATCHDOG_MINOR 130
29 #define TIMER_MARGIN (60*HZ) /* Allow 1 minute */
30
31 /*
32 * Our timer
33 */
34
35 struct timer_list watchdog_ticktock;
36 static int timer_alive = 0;
37
38
39 /*
40 * If the timer expires..
41 */
42
43 static void watchdog_fire(unsigned long data)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
44 {
45 extern void hard_reset_now(void);
46 hard_reset_now();
47 printk("WATCHDOG: Reboot didn't ?????\n");
48 }
49
50 /*
51 * Allow only one person to hold it open
52 */
53
54 static int softdog_open(struct inode *inode, struct file *file)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
55 {
56 if(timer_alive)
57 return -EBUSY;
58 /*
59 * Activate timer
60 */
61 watchdog_ticktock.expires=jiffies+TIMER_MARGIN;
62 add_timer(&watchdog_ticktock);
63 timer_alive++;
64 return 0;
65 }
66
67 static void softdog_release(struct inode *inode, struct file *file)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
68 {
69 /*
70 * Shut off the timer.
71 */
72 #ifndef CONFIG_WATCHDOG_NOWAYOUT
73 del_timer(&watchdog_ticktock);
74 #endif
75 timer_alive=0;
76 }
77
78 static int softdog_write(struct inode *inode, struct file *file, const char *data, int len)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
79 {
80 /*
81 * Refresh the timer.
82 */
83 del_timer(&watchdog_ticktock);
84 watchdog_ticktock.expires=jiffies+TIMER_MARGIN;
85 add_timer(&watchdog_ticktock);
86 return 1;
87 }
88
89 /*
90 * The mouse stuff ought to be renamed misc_register etc before 1.4...
91 */
92
93 void watchdog_init(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
94 {
95 static struct file_operations softdog_fops=
96 {
97 NULL, /* Seek */
98 NULL, /* Read */
99 softdog_write, /* Write */
100 NULL, /* Readdir */
101 NULL, /* Select */
102 NULL, /* Ioctl */
103 NULL, /* MMap */
104 softdog_open,
105 softdog_release,
106 NULL,
107 NULL /* Fasync */
108 };
109 static struct miscdevice softdog_mouse={
110 WATCHDOG_MINOR,
111 "softdog",
112 &softdog_fops
113 };
114
115 misc_register(&softdog_mouse);
116 init_timer(&watchdog_ticktock);
117 watchdog_ticktock.function=watchdog_fire;
118 printk("Software Watchdog Timer: 0.03\n");
119 }