diff options
-rw-r--r-- | drivers/watchdog/mixcomwd.c | 133 |
1 files changed, 63 insertions, 70 deletions
diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c index 1adf1d56027d..2248a8187590 100644 --- a/drivers/watchdog/mixcomwd.c +++ b/drivers/watchdog/mixcomwd.c | |||
@@ -29,7 +29,8 @@ | |||
29 | * - support for one more type board | 29 | * - support for one more type board |
30 | * | 30 | * |
31 | * Version 0.5 (2001/12/14) Matt Domsch <Matt_Domsch@dell.com> | 31 | * Version 0.5 (2001/12/14) Matt Domsch <Matt_Domsch@dell.com> |
32 | * - added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT | 32 | * - added nowayout module option to override |
33 | * CONFIG_WATCHDOG_NOWAYOUT | ||
33 | * | 34 | * |
34 | * Version 0.6 (2002/04/12): Rob Radez <rob@osinvestor.com> | 35 | * Version 0.6 (2002/04/12): Rob Radez <rob@osinvestor.com> |
35 | * - make mixcomwd_opened unsigned, | 36 | * - make mixcomwd_opened unsigned, |
@@ -53,8 +54,8 @@ | |||
53 | #include <linux/init.h> | 54 | #include <linux/init.h> |
54 | #include <linux/jiffies.h> | 55 | #include <linux/jiffies.h> |
55 | #include <linux/timer.h> | 56 | #include <linux/timer.h> |
56 | #include <asm/uaccess.h> | 57 | #include <linux/uaccess.h> |
57 | #include <asm/io.h> | 58 | #include <linux/io.h> |
58 | 59 | ||
59 | /* | 60 | /* |
60 | * We have two types of cards that can be probed: | 61 | * We have two types of cards that can be probed: |
@@ -108,18 +109,19 @@ static char expect_close; | |||
108 | 109 | ||
109 | static int nowayout = WATCHDOG_NOWAYOUT; | 110 | static int nowayout = WATCHDOG_NOWAYOUT; |
110 | module_param(nowayout, int, 0); | 111 | module_param(nowayout, int, 0); |
111 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 112 | MODULE_PARM_DESC(nowayout, |
113 | "Watchdog cannot be stopped once started (default=" | ||
114 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
112 | 115 | ||
113 | static void mixcomwd_ping(void) | 116 | static void mixcomwd_ping(void) |
114 | { | 117 | { |
115 | outb_p(55,watchdog_port); | 118 | outb_p(55, watchdog_port); |
116 | return; | 119 | return; |
117 | } | 120 | } |
118 | 121 | ||
119 | static void mixcomwd_timerfun(unsigned long d) | 122 | static void mixcomwd_timerfun(unsigned long d) |
120 | { | 123 | { |
121 | mixcomwd_ping(); | 124 | mixcomwd_ping(); |
122 | |||
123 | mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); | 125 | mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); |
124 | } | 126 | } |
125 | 127 | ||
@@ -129,22 +131,22 @@ static void mixcomwd_timerfun(unsigned long d) | |||
129 | 131 | ||
130 | static int mixcomwd_open(struct inode *inode, struct file *file) | 132 | static int mixcomwd_open(struct inode *inode, struct file *file) |
131 | { | 133 | { |
132 | if(test_and_set_bit(0,&mixcomwd_opened)) { | 134 | if (test_and_set_bit(0, &mixcomwd_opened)) |
133 | return -EBUSY; | 135 | return -EBUSY; |
134 | } | 136 | |
135 | mixcomwd_ping(); | 137 | mixcomwd_ping(); |
136 | 138 | ||
137 | if (nowayout) { | 139 | if (nowayout) |
138 | /* | 140 | /* |
139 | * fops_get() code via open() has already done | 141 | * fops_get() code via open() has already done |
140 | * a try_module_get() so it is safe to do the | 142 | * a try_module_get() so it is safe to do the |
141 | * __module_get(). | 143 | * __module_get(). |
142 | */ | 144 | */ |
143 | __module_get(THIS_MODULE); | 145 | __module_get(THIS_MODULE); |
144 | } else { | 146 | else { |
145 | if(mixcomwd_timer_alive) { | 147 | if (mixcomwd_timer_alive) { |
146 | del_timer(&mixcomwd_timer); | 148 | del_timer(&mixcomwd_timer); |
147 | mixcomwd_timer_alive=0; | 149 | mixcomwd_timer_alive = 0; |
148 | } | 150 | } |
149 | } | 151 | } |
150 | return nonseekable_open(inode, file); | 152 | return nonseekable_open(inode, file); |
@@ -153,26 +155,27 @@ static int mixcomwd_open(struct inode *inode, struct file *file) | |||
153 | static int mixcomwd_release(struct inode *inode, struct file *file) | 155 | static int mixcomwd_release(struct inode *inode, struct file *file) |
154 | { | 156 | { |
155 | if (expect_close == 42) { | 157 | if (expect_close == 42) { |
156 | if(mixcomwd_timer_alive) { | 158 | if (mixcomwd_timer_alive) { |
157 | printk(KERN_ERR PFX "release called while internal timer alive"); | 159 | printk(KERN_ERR PFX |
160 | "release called while internal timer alive"); | ||
158 | return -EBUSY; | 161 | return -EBUSY; |
159 | } | 162 | } |
160 | mixcomwd_timer_alive=1; | 163 | mixcomwd_timer_alive = 1; |
161 | mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); | 164 | mod_timer(&mixcomwd_timer, jiffies + 5 * HZ); |
162 | } else { | 165 | } else |
163 | printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n"); | 166 | printk(KERN_CRIT PFX |
164 | } | 167 | "WDT device closed unexpectedly. WDT will not stop!\n"); |
165 | 168 | ||
166 | clear_bit(0,&mixcomwd_opened); | 169 | clear_bit(0, &mixcomwd_opened); |
167 | expect_close=0; | 170 | expect_close = 0; |
168 | return 0; | 171 | return 0; |
169 | } | 172 | } |
170 | 173 | ||
171 | 174 | ||
172 | static ssize_t mixcomwd_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) | 175 | static ssize_t mixcomwd_write(struct file *file, const char __user *data, |
176 | size_t len, loff_t *ppos) | ||
173 | { | 177 | { |
174 | if(len) | 178 | if (len) { |
175 | { | ||
176 | if (!nowayout) { | 179 | if (!nowayout) { |
177 | size_t i; | 180 | size_t i; |
178 | 181 | ||
@@ -192,8 +195,8 @@ static ssize_t mixcomwd_write(struct file *file, const char __user *data, size_t | |||
192 | return len; | 195 | return len; |
193 | } | 196 | } |
194 | 197 | ||
195 | static int mixcomwd_ioctl(struct inode *inode, struct file *file, | 198 | static long mixcomwd_ioctl(struct file *file, |
196 | unsigned int cmd, unsigned long arg) | 199 | unsigned int cmd, unsigned long arg) |
197 | { | 200 | { |
198 | void __user *argp = (void __user *)arg; | 201 | void __user *argp = (void __user *)arg; |
199 | int __user *p = argp; | 202 | int __user *p = argp; |
@@ -204,32 +207,23 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file, | |||
204 | .identity = "MixCOM watchdog", | 207 | .identity = "MixCOM watchdog", |
205 | }; | 208 | }; |
206 | 209 | ||
207 | switch(cmd) | 210 | switch (cmd) { |
208 | { | 211 | case WDIOC_GETSTATUS: |
209 | case WDIOC_GETSTATUS: | 212 | status = mixcomwd_opened; |
210 | status=mixcomwd_opened; | 213 | if (!nowayout) |
211 | if (!nowayout) { | 214 | status |= mixcomwd_timer_alive; |
212 | status|=mixcomwd_timer_alive; | 215 | return put_user(status, p); |
213 | } | 216 | case WDIOC_GETBOOTSTATUS: |
214 | if (copy_to_user(p, &status, sizeof(int))) { | 217 | return put_user(0, p); |
215 | return -EFAULT; | 218 | case WDIOC_GETSUPPORT: |
216 | } | 219 | if (copy_to_user(argp, &ident, sizeof(ident))) |
217 | break; | 220 | return -EFAULT; |
218 | case WDIOC_GETBOOTSTATUS: | 221 | break; |
219 | if (copy_to_user(p, &status, sizeof(int))) { | 222 | case WDIOC_KEEPALIVE: |
220 | return -EFAULT; | 223 | mixcomwd_ping(); |
221 | } | 224 | break; |
222 | break; | 225 | default: |
223 | case WDIOC_GETSUPPORT: | 226 | return -ENOTTY; |
224 | if (copy_to_user(argp, &ident, sizeof(ident))) { | ||
225 | return -EFAULT; | ||
226 | } | ||
227 | break; | ||
228 | case WDIOC_KEEPALIVE: | ||
229 | mixcomwd_ping(); | ||
230 | break; | ||
231 | default: | ||
232 | return -ENOTTY; | ||
233 | } | 227 | } |
234 | return 0; | 228 | return 0; |
235 | } | 229 | } |
@@ -238,7 +232,7 @@ static const struct file_operations mixcomwd_fops = { | |||
238 | .owner = THIS_MODULE, | 232 | .owner = THIS_MODULE, |
239 | .llseek = no_llseek, | 233 | .llseek = no_llseek, |
240 | .write = mixcomwd_write, | 234 | .write = mixcomwd_write, |
241 | .ioctl = mixcomwd_ioctl, | 235 | .unlocked_ioctl = mixcomwd_ioctl, |
242 | .open = mixcomwd_open, | 236 | .open = mixcomwd_open, |
243 | .release = mixcomwd_release, | 237 | .release = mixcomwd_release, |
244 | }; | 238 | }; |
@@ -253,15 +247,14 @@ static int __init checkcard(int port, int card_id) | |||
253 | { | 247 | { |
254 | int id; | 248 | int id; |
255 | 249 | ||
256 | if (!request_region(port, 1, "MixCOM watchdog")) { | 250 | if (!request_region(port, 1, "MixCOM watchdog")) |
257 | return 0; | 251 | return 0; |
258 | } | ||
259 | 252 | ||
260 | id=inb_p(port); | 253 | id = inb_p(port); |
261 | if (card_id==MIXCOM_ID) | 254 | if (card_id == MIXCOM_ID) |
262 | id &= 0x3f; | 255 | id &= 0x3f; |
263 | 256 | ||
264 | if (id!=card_id) { | 257 | if (id != card_id) { |
265 | release_region(port, 1); | 258 | release_region(port, 1); |
266 | return 0; | 259 | return 0; |
267 | } | 260 | } |
@@ -270,9 +263,7 @@ static int __init checkcard(int port, int card_id) | |||
270 | 263 | ||
271 | static int __init mixcomwd_init(void) | 264 | static int __init mixcomwd_init(void) |
272 | { | 265 | { |
273 | int i; | 266 | int i, ret, found = 0; |
274 | int ret; | ||
275 | int found=0; | ||
276 | 267 | ||
277 | for (i = 0; !found && mixcomwd_io_info[i].ioport != 0; i++) { | 268 | for (i = 0; !found && mixcomwd_io_info[i].ioport != 0; i++) { |
278 | if (checkcard(mixcomwd_io_info[i].ioport, | 269 | if (checkcard(mixcomwd_io_info[i].ioport, |
@@ -283,20 +274,22 @@ static int __init mixcomwd_init(void) | |||
283 | } | 274 | } |
284 | 275 | ||
285 | if (!found) { | 276 | if (!found) { |
286 | printk(KERN_ERR PFX "No card detected, or port not available.\n"); | 277 | printk(KERN_ERR PFX |
278 | "No card detected, or port not available.\n"); | ||
287 | return -ENODEV; | 279 | return -ENODEV; |
288 | } | 280 | } |
289 | 281 | ||
290 | ret = misc_register(&mixcomwd_miscdev); | 282 | ret = misc_register(&mixcomwd_miscdev); |
291 | if (ret) | 283 | if (ret) { |
292 | { | 284 | printk(KERN_ERR PFX |
293 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 285 | "cannot register miscdev on minor=%d (err=%d)\n", |
294 | WATCHDOG_MINOR, ret); | 286 | WATCHDOG_MINOR, ret); |
295 | goto error_misc_register_watchdog; | 287 | goto error_misc_register_watchdog; |
296 | } | 288 | } |
297 | 289 | ||
298 | printk(KERN_INFO "MixCOM watchdog driver v%s, watchdog port at 0x%3x\n", | 290 | printk(KERN_INFO |
299 | VERSION, watchdog_port); | 291 | "MixCOM watchdog driver v%s, watchdog port at 0x%3x\n", |
292 | VERSION, watchdog_port); | ||
300 | 293 | ||
301 | return 0; | 294 | return 0; |
302 | 295 | ||
@@ -309,15 +302,15 @@ error_misc_register_watchdog: | |||
309 | static void __exit mixcomwd_exit(void) | 302 | static void __exit mixcomwd_exit(void) |
310 | { | 303 | { |
311 | if (!nowayout) { | 304 | if (!nowayout) { |
312 | if(mixcomwd_timer_alive) { | 305 | if (mixcomwd_timer_alive) { |
313 | printk(KERN_WARNING PFX "I quit now, hardware will" | 306 | printk(KERN_WARNING PFX "I quit now, hardware will" |
314 | " probably reboot!\n"); | 307 | " probably reboot!\n"); |
315 | del_timer_sync(&mixcomwd_timer); | 308 | del_timer_sync(&mixcomwd_timer); |
316 | mixcomwd_timer_alive=0; | 309 | mixcomwd_timer_alive = 0; |
317 | } | 310 | } |
318 | } | 311 | } |
319 | misc_deregister(&mixcomwd_miscdev); | 312 | misc_deregister(&mixcomwd_miscdev); |
320 | release_region(watchdog_port,1); | 313 | release_region(watchdog_port, 1); |
321 | } | 314 | } |
322 | 315 | ||
323 | module_init(mixcomwd_init); | 316 | module_init(mixcomwd_init); |