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