This source file includes following definitions.
- wdt_ctr_mode
- wdt_ctr_load
- wdt_interrupt
- wdt_lseek
- wdt_write
- wdt_read
- wdt_ioctl
- wdt_open
- wdt_release
- init_module
- cleanup_module
- wdt_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <linux/config.h>
24 #include <linux/module.h>
25 #include <linux/version.h>
26 #include <linux/types.h>
27 #include <linux/errno.h>
28 #include <linux/kernel.h>
29 #include <linux/sched.h>
30 #include <linux/miscdevice.h>
31 #include "wd501p.h"
32 #include <linux/malloc.h>
33 #include <linux/ioport.h>
34 #include <linux/fcntl.h>
35 #include <asm/io.h>
36 #include <asm/segment.h>
37 #include <asm/system.h>
38
39 static int wdt_is_open=0;
40
41
42
43
44
45 int io=0x240;
46 int irq=14;
47
48 #define WD_TIMO (100*60)
49
50
51
52
53
54 static void wdt_ctr_mode(int ctr, int mode)
55 {
56 ctr<<=6;
57 ctr|=0x30;
58 ctr|=(mode<<1);
59 outb_p(ctr, WDT_CR);
60 }
61
62 static void wdt_ctr_load(int ctr, int val)
63 {
64 outb_p(val&0xFF, WDT_COUNT0+ctr);
65 outb_p(val>>8, WDT_COUNT0+ctr);
66 }
67
68
69
70
71
72 static void wdt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
73 {
74
75
76
77
78
79 unsigned char status=inb_p(WDT_SR);
80
81 status|=FEATUREMAP1;
82 status&=~FEATUREMAP2;
83
84 printk(KERN_CRIT "WDT status %d\n", status);
85
86 if(!(status&WDC_SR_TGOOD))
87 printk(KERN_CRIT "Overheat alarm.(%d)\n",inb_p(WDT_RT));
88 if(!(status&WDC_SR_PSUOVER))
89 printk(KERN_CRIT "PSU over voltage.\n");
90 if(!(status&WDC_SR_PSUUNDR))
91 printk(KERN_CRIT "PSU under voltage.\n");
92 if(!(status&WDC_SR_FANGOOD))
93 printk(KERN_CRIT "Possible fan fault.\n");
94 if(!(status&WDC_SR_WCCR))
95 #ifdef SOFTWARE_REBOOT
96 #ifdef ONLY_TESTING
97 printk(KERN_CRIT "Would Reboot.\n");
98 #else
99 printk(KERN_CRIT "Initiating system reboot.\n");
100 hard_reset_now();
101 #endif
102 #else
103 printk(KERN_CRIT "Reset in 5ms.\n");
104 #endif
105 }
106
107
108 static int wdt_lseek(struct inode *inode, struct file *file, off_t offset,
109 int origin)
110 {
111 return -ESPIPE;
112 }
113
114 static int wdt_write(struct inode *inode, struct file *file, const char *buf, int count)
115 {
116
117 inb_p(WDT_DC);
118 wdt_ctr_mode(1,2);
119 wdt_ctr_load(1,WD_TIMO);
120 outb_p(0, WDT_DC);
121 return count;
122 }
123
124
125
126
127
128 static int wdt_read(struct inode *inode, struct file *file, char *buf, int count)
129 {
130 unsigned short c=inb_p(WDT_RT);
131 unsigned char cp;
132 int err;
133
134 switch(MINOR(inode->i_rdev))
135 {
136 case TEMP_MINOR:
137 err=verify_area(VERIFY_WRITE, buf, 1);
138 if(err)
139 return err;
140 c*=11;
141 c/=15;
142 cp=c+7;
143 memcpy_tofs(buf,&cp,1);
144 return 1;
145 default:
146 return -EINVAL;
147 }
148 }
149
150 static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
151 unsigned long arg)
152 {
153 return -EINVAL;
154 }
155
156 static int wdt_open(struct inode *inode, struct file *file)
157 {
158 switch(MINOR(inode->i_rdev))
159 {
160 case WATCHDOG_MINOR:
161 if(wdt_is_open)
162 return -EBUSY;
163 MOD_INC_USE_COUNT;
164
165
166
167
168 wdt_is_open=1;
169 inb_p(WDT_DC);
170 wdt_ctr_mode(0,3);
171 wdt_ctr_mode(1,2);
172 wdt_ctr_mode(2,0);
173 wdt_ctr_load(0, 8948);
174 wdt_ctr_load(1,WD_TIMO);
175 wdt_ctr_load(2,65535);
176 outb_p(0, WDT_DC);
177 return 0;
178 case TEMP_MINOR:
179 MOD_INC_USE_COUNT;
180 return 0;
181 default:
182 return -ENODEV;
183 }
184 }
185
186 static void wdt_release(struct inode *inode, struct file *file)
187 {
188 if(MINOR(inode->i_rdev)==WATCHDOG_MINOR)
189 {
190 #ifndef CONFIG_WATCHDOG_NOWAYOUT
191 inb_p(WDT_DC);
192 wdt_ctr_load(2,0);
193 #endif
194 wdt_is_open=0;
195 }
196 MOD_DEC_USE_COUNT;
197 }
198
199
200
201
202
203
204 static struct file_operations wdt_fops = {
205 wdt_lseek,
206 wdt_read,
207 wdt_write,
208 NULL,
209 NULL,
210 wdt_ioctl,
211 NULL,
212 wdt_open,
213 wdt_release
214 };
215
216 static struct miscdevice wdt_mouse=
217 {
218 WATCHDOG_MINOR,
219 "wdt",
220 &wdt_fops
221 };
222
223 #ifdef CONFIG_WDT_501
224 static struct miscdevice temp_mouse=
225 {
226 TEMP_MINOR,
227 "temperature",
228 &wdt_fops
229 };
230 #endif
231
232 #ifdef MODULE
233
234 int init_module(void)
235 {
236 printk("WDT501-P module at %X(Interrupt %d)\n", io,irq);
237 if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL))
238 {
239 printk("IRQ %d is not free.\n", irq);
240 return -EIO;
241 }
242 mouse_register(&wdt_mouse);
243 #ifdef CONFIG_WDT_501
244 mouse_register(&temp_mouse);
245 #endif
246 request_region(io, 8, "wdt501");
247 return 0;
248 }
249
250 void cleanup_module(void)
251 {
252 mouse_deregister(&wdt_mouse);
253 #ifdef CONFIG_WDT_501
254 misc_deregister(&temp_mouse);
255 #endif
256 release_region(io,8);
257 free_irq(irq, NULL);
258 }
259
260 #else
261
262 int wdt_init(void)
263 {
264 printk("WDT500/501-P driver at %X(Interrupt %d)\n", io,irq);
265 if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL))
266 {
267 printk("IRQ %d is not free.\n", irq);
268 return -EIO;
269 }
270 mouse_register(&wdt_mouse);
271 #ifdef CONFIG_WDT_501
272 misc_register(&temp_mouse);
273 #endif
274 request_region(io, 8, "wdt501");
275 return 0;
276 }
277
278 #endif