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/mouse.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, 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 inb_p(WDT_DC);
191 wdt_ctr_load(2,0);
192 wdt_is_open=0;
193 }
194 MOD_DEC_USE_COUNT;
195 }
196
197
198
199
200
201
202 static struct file_operations wdt_fops = {
203 wdt_lseek,
204 wdt_read,
205 wdt_write,
206 NULL,
207 NULL,
208 wdt_ioctl,
209 NULL,
210 wdt_open,
211 wdt_release
212 };
213
214 static struct mouse wdt_mouse=
215 {
216 WATCHDOG_MINOR,
217 "wdt",
218 &wdt_fops
219 };
220
221 #ifdef CONFIG_WDT_501
222 static struct mouse temp_mouse=
223 {
224 TEMP_MINOR,
225 "temperature",
226 &wdt_fops
227 };
228 #endif
229
230 #ifdef MODULE
231
232 int init_module(void)
233 {
234 printk("WDT501-P module at %X(Interrupt %d)\n", io,irq);
235 if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p"))
236 {
237 printk("IRQ %d is not free.\n", irq);
238 return -EIO;
239 }
240 mouse_register(&wdt_mouse);
241 #ifdef CONFIG_WDT_501
242 mouse_register(&temp_mouse);
243 #endif
244 request_region(io, 8, "wdt501");
245 return 0;
246 }
247
248 void cleanup_module(void)
249 {
250 mouse_deregister(&wdt_mouse);
251 #ifdef CONFIG_WDT_501
252 mouse_deregister(&temp_mouse);
253 #endif
254 release_region(io,8);
255 free_irq(irq);
256 }
257
258 #else
259
260 int wdt_init(void)
261 {
262 printk("WDT500/501-P driver at %X(Interrupt %d)\n", io,irq);
263 if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p"))
264 {
265 printk("IRQ %d is not free.\n", irq);
266 return -EIO;
267 }
268 mouse_register(&wdt_mouse);
269 #ifdef CONFIG_WDT_501
270 mouse_register(&temp_mouse);
271 #endif
272 request_region(io, 8, "wdt501");
273 return 0;
274 }
275
276 #endif