diff options
Diffstat (limited to 'drivers/watchdog/wdrtas.c')
| -rw-r--r-- | drivers/watchdog/wdrtas.c | 105 |
1 files changed, 42 insertions, 63 deletions
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c index 1d64e277567d..5d3b1a8e28b0 100644 --- a/drivers/watchdog/wdrtas.c +++ b/drivers/watchdog/wdrtas.c | |||
| @@ -35,9 +35,9 @@ | |||
| 35 | #include <linux/reboot.h> | 35 | #include <linux/reboot.h> |
| 36 | #include <linux/types.h> | 36 | #include <linux/types.h> |
| 37 | #include <linux/watchdog.h> | 37 | #include <linux/watchdog.h> |
| 38 | #include <linux/uaccess.h> | ||
| 38 | 39 | ||
| 39 | #include <asm/rtas.h> | 40 | #include <asm/rtas.h> |
| 40 | #include <asm/uaccess.h> | ||
| 41 | 41 | ||
| 42 | #define WDRTAS_MAGIC_CHAR 42 | 42 | #define WDRTAS_MAGIC_CHAR 42 |
| 43 | #define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \ | 43 | #define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \ |
| @@ -56,7 +56,7 @@ static int wdrtas_nowayout = 0; | |||
| 56 | #endif | 56 | #endif |
| 57 | 57 | ||
| 58 | static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0); | 58 | static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0); |
| 59 | static char wdrtas_expect_close = 0; | 59 | static char wdrtas_expect_close; |
| 60 | 60 | ||
| 61 | static int wdrtas_interval; | 61 | static int wdrtas_interval; |
| 62 | 62 | ||
| @@ -86,8 +86,8 @@ static char wdrtas_logbuffer[WDRTAS_LOGBUFFER_LEN]; | |||
| 86 | * RTAS function set-indicator (surveillance). The unit of interval is | 86 | * RTAS function set-indicator (surveillance). The unit of interval is |
| 87 | * seconds. | 87 | * seconds. |
| 88 | */ | 88 | */ |
| 89 | static int | 89 | |
| 90 | wdrtas_set_interval(int interval) | 90 | static int wdrtas_set_interval(int interval) |
| 91 | { | 91 | { |
| 92 | long result; | 92 | long result; |
| 93 | static int print_msg = 10; | 93 | static int print_msg = 10; |
| @@ -97,7 +97,7 @@ wdrtas_set_interval(int interval) | |||
| 97 | 97 | ||
| 98 | result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL, | 98 | result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL, |
| 99 | WDRTAS_SURVEILLANCE_IND, 0, interval); | 99 | WDRTAS_SURVEILLANCE_IND, 0, interval); |
| 100 | if ( (result < 0) && (print_msg) ) { | 100 | if (result < 0 && print_msg) { |
| 101 | printk(KERN_ERR "wdrtas: setting the watchdog to %i " | 101 | printk(KERN_ERR "wdrtas: setting the watchdog to %i " |
| 102 | "timeout failed: %li\n", interval, result); | 102 | "timeout failed: %li\n", interval, result); |
| 103 | print_msg--; | 103 | print_msg--; |
| @@ -116,16 +116,14 @@ wdrtas_set_interval(int interval) | |||
| 116 | * as reported by the RTAS function ibm,get-system-parameter. The unit | 116 | * as reported by the RTAS function ibm,get-system-parameter. The unit |
| 117 | * of the return value is seconds. | 117 | * of the return value is seconds. |
| 118 | */ | 118 | */ |
| 119 | static int | 119 | static int wdrtas_get_interval(int fallback_value) |
| 120 | wdrtas_get_interval(int fallback_value) | ||
| 121 | { | 120 | { |
| 122 | long result; | 121 | long result; |
| 123 | char value[4]; | 122 | char value[4]; |
| 124 | 123 | ||
| 125 | result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL, | 124 | result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL, |
| 126 | WDRTAS_SP_SPI, (void *)__pa(&value), 4); | 125 | WDRTAS_SP_SPI, (void *)__pa(&value), 4); |
| 127 | if ( (value[0] != 0) || (value[1] != 2) || (value[3] != 0) || | 126 | if (value[0] != 0 || value[1] != 2 || value[3] != 0 || result < 0) { |
| 128 | (result < 0) ) { | ||
| 129 | printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog " | 127 | printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog " |
| 130 | "timeout (%li). Continuing\n", result); | 128 | "timeout (%li). Continuing\n", result); |
| 131 | return fallback_value; | 129 | return fallback_value; |
| @@ -141,8 +139,7 @@ wdrtas_get_interval(int fallback_value) | |||
| 141 | * wdrtas_timer_start starts the watchdog by calling the RTAS function | 139 | * wdrtas_timer_start starts the watchdog by calling the RTAS function |
| 142 | * set-interval (surveillance) | 140 | * set-interval (surveillance) |
| 143 | */ | 141 | */ |
| 144 | static void | 142 | static void wdrtas_timer_start(void) |
| 145 | wdrtas_timer_start(void) | ||
| 146 | { | 143 | { |
| 147 | wdrtas_set_interval(wdrtas_interval); | 144 | wdrtas_set_interval(wdrtas_interval); |
| 148 | } | 145 | } |
| @@ -153,8 +150,7 @@ wdrtas_timer_start(void) | |||
| 153 | * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function | 150 | * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function |
| 154 | * set-interval (surveillance) | 151 | * set-interval (surveillance) |
| 155 | */ | 152 | */ |
| 156 | static void | 153 | static void wdrtas_timer_stop(void) |
| 157 | wdrtas_timer_stop(void) | ||
| 158 | { | 154 | { |
| 159 | wdrtas_set_interval(0); | 155 | wdrtas_set_interval(0); |
| 160 | } | 156 | } |
| @@ -165,8 +161,7 @@ wdrtas_timer_stop(void) | |||
| 165 | * wdrtas_log_scanned_event prints a message to the log buffer dumping | 161 | * wdrtas_log_scanned_event prints a message to the log buffer dumping |
| 166 | * the results of the last event-scan call | 162 | * the results of the last event-scan call |
| 167 | */ | 163 | */ |
| 168 | static void | 164 | static void wdrtas_log_scanned_event(void) |
| 169 | wdrtas_log_scanned_event(void) | ||
| 170 | { | 165 | { |
| 171 | int i; | 166 | int i; |
| 172 | 167 | ||
| @@ -175,13 +170,13 @@ wdrtas_log_scanned_event(void) | |||
| 175 | "%02x %02x %02x %02x %02x %02x %02x %02x " | 170 | "%02x %02x %02x %02x %02x %02x %02x %02x " |
| 176 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | 171 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", |
| 177 | (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16), | 172 | (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16), |
| 178 | wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1], | 173 | wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1], |
| 179 | wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3], | 174 | wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3], |
| 180 | wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5], | 175 | wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5], |
| 181 | wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7], | 176 | wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7], |
| 182 | wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9], | 177 | wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9], |
| 183 | wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11], | 178 | wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11], |
| 184 | wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13], | 179 | wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13], |
| 185 | wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]); | 180 | wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]); |
| 186 | } | 181 | } |
| 187 | 182 | ||
| @@ -192,8 +187,7 @@ wdrtas_log_scanned_event(void) | |||
| 192 | * RTAS function event-scan and repeats these calls as long as there are | 187 | * RTAS function event-scan and repeats these calls as long as there are |
| 193 | * events available. All events will be dumped. | 188 | * events available. All events will be dumped. |
| 194 | */ | 189 | */ |
| 195 | static void | 190 | static void wdrtas_timer_keepalive(void) |
| 196 | wdrtas_timer_keepalive(void) | ||
| 197 | { | 191 | { |
| 198 | long result; | 192 | long result; |
| 199 | 193 | ||
| @@ -218,8 +212,7 @@ wdrtas_timer_keepalive(void) | |||
| 218 | * wdrtas_get_temperature returns the current temperature in Fahrenheit. It | 212 | * wdrtas_get_temperature returns the current temperature in Fahrenheit. It |
| 219 | * uses the RTAS call get-sensor-state, token 3 to do so | 213 | * uses the RTAS call get-sensor-state, token 3 to do so |
| 220 | */ | 214 | */ |
| 221 | static int | 215 | static int wdrtas_get_temperature(void) |
| 222 | wdrtas_get_temperature(void) | ||
| 223 | { | 216 | { |
| 224 | long result; | 217 | long result; |
| 225 | int temperature = 0; | 218 | int temperature = 0; |
| @@ -243,8 +236,7 @@ wdrtas_get_temperature(void) | |||
| 243 | * returns a bitmask of defines WDIOF_... as defined in | 236 | * returns a bitmask of defines WDIOF_... as defined in |
| 244 | * include/linux/watchdog.h | 237 | * include/linux/watchdog.h |
| 245 | */ | 238 | */ |
| 246 | static int | 239 | static int wdrtas_get_status(void) |
| 247 | wdrtas_get_status(void) | ||
| 248 | { | 240 | { |
| 249 | return 0; /* TODO */ | 241 | return 0; /* TODO */ |
| 250 | } | 242 | } |
| @@ -255,8 +247,7 @@ wdrtas_get_status(void) | |||
| 255 | * returns a bitmask of defines WDIOF_... as defined in | 247 | * returns a bitmask of defines WDIOF_... as defined in |
| 256 | * include/linux/watchdog.h, indicating why the watchdog rebooted the system | 248 | * include/linux/watchdog.h, indicating why the watchdog rebooted the system |
| 257 | */ | 249 | */ |
| 258 | static int | 250 | static int wdrtas_get_boot_status(void) |
| 259 | wdrtas_get_boot_status(void) | ||
| 260 | { | 251 | { |
| 261 | return 0; /* TODO */ | 252 | return 0; /* TODO */ |
| 262 | } | 253 | } |
| @@ -276,8 +267,7 @@ wdrtas_get_boot_status(void) | |||
| 276 | * character 'V'. This character allows the watchdog device to be closed | 267 | * character 'V'. This character allows the watchdog device to be closed |
| 277 | * properly. | 268 | * properly. |
| 278 | */ | 269 | */ |
| 279 | static ssize_t | 270 | static ssize_t wdrtas_write(struct file *file, const char __user *buf, |
| 280 | wdrtas_write(struct file *file, const char __user *buf, | ||
| 281 | size_t len, loff_t *ppos) | 271 | size_t len, loff_t *ppos) |
| 282 | { | 272 | { |
| 283 | int i; | 273 | int i; |
| @@ -306,7 +296,6 @@ out: | |||
| 306 | 296 | ||
| 307 | /** | 297 | /** |
| 308 | * wdrtas_ioctl - ioctl function for the watchdog device | 298 | * wdrtas_ioctl - ioctl function for the watchdog device |
| 309 | * @inode: inode structure | ||
| 310 | * @file: file structure | 299 | * @file: file structure |
| 311 | * @cmd: command for ioctl | 300 | * @cmd: command for ioctl |
| 312 | * @arg: argument pointer | 301 | * @arg: argument pointer |
| @@ -315,16 +304,16 @@ out: | |||
| 315 | * | 304 | * |
| 316 | * wdrtas_ioctl implements the watchdog API ioctls | 305 | * wdrtas_ioctl implements the watchdog API ioctls |
| 317 | */ | 306 | */ |
| 318 | static int | 307 | |
| 319 | wdrtas_ioctl(struct inode *inode, struct file *file, | 308 | static long wdrtas_ioctl(struct file *file, unsigned int cmd, |
| 320 | unsigned int cmd, unsigned long arg) | 309 | unsigned long arg) |
| 321 | { | 310 | { |
| 322 | int __user *argp = (void __user *)arg; | 311 | int __user *argp = (void __user *)arg; |
| 323 | int i; | 312 | int i; |
| 324 | static struct watchdog_info wdinfo = { | 313 | static struct watchdog_info wdinfo = { |
| 325 | .options = WDRTAS_SUPPORTED_MASK, | 314 | .options = WDRTAS_SUPPORTED_MASK, |
| 326 | .firmware_version = 0, | 315 | .firmware_version = 0, |
| 327 | .identity = "wdrtas" | 316 | .identity = "wdrtas", |
| 328 | }; | 317 | }; |
| 329 | 318 | ||
| 330 | switch (cmd) { | 319 | switch (cmd) { |
| @@ -357,9 +346,9 @@ wdrtas_ioctl(struct inode *inode, struct file *file, | |||
| 357 | wdrtas_timer_keepalive(); | 346 | wdrtas_timer_keepalive(); |
| 358 | wdrtas_timer_start(); | 347 | wdrtas_timer_start(); |
| 359 | } | 348 | } |
| 349 | /* not implemented. Done by H8 | ||
| 360 | if (i & WDIOS_TEMPPANIC) { | 350 | if (i & WDIOS_TEMPPANIC) { |
| 361 | /* not implemented. Done by H8 */ | 351 | } */ |
| 362 | } | ||
| 363 | return 0; | 352 | return 0; |
| 364 | 353 | ||
| 365 | case WDIOC_KEEPALIVE: | 354 | case WDIOC_KEEPALIVE: |
| @@ -399,8 +388,7 @@ wdrtas_ioctl(struct inode *inode, struct file *file, | |||
| 399 | * | 388 | * |
| 400 | * function called when watchdog device is opened | 389 | * function called when watchdog device is opened |
| 401 | */ | 390 | */ |
| 402 | static int | 391 | static int wdrtas_open(struct inode *inode, struct file *file) |
| 403 | wdrtas_open(struct inode *inode, struct file *file) | ||
| 404 | { | 392 | { |
| 405 | /* only open once */ | 393 | /* only open once */ |
| 406 | if (atomic_inc_return(&wdrtas_miscdev_open) > 1) { | 394 | if (atomic_inc_return(&wdrtas_miscdev_open) > 1) { |
| @@ -423,8 +411,7 @@ wdrtas_open(struct inode *inode, struct file *file) | |||
| 423 | * | 411 | * |
| 424 | * close function. Always succeeds | 412 | * close function. Always succeeds |
| 425 | */ | 413 | */ |
| 426 | static int | 414 | static int wdrtas_close(struct inode *inode, struct file *file) |
| 427 | wdrtas_close(struct inode *inode, struct file *file) | ||
| 428 | { | 415 | { |
| 429 | /* only stop watchdog, if this was announced using 'V' before */ | 416 | /* only stop watchdog, if this was announced using 'V' before */ |
| 430 | if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR) | 417 | if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR) |
| @@ -453,8 +440,7 @@ wdrtas_close(struct inode *inode, struct file *file) | |||
| 453 | * wdrtas_temp_read gives the temperature to the users by copying this | 440 | * wdrtas_temp_read gives the temperature to the users by copying this |
| 454 | * value as one byte into the user space buffer. The unit is Fahrenheit... | 441 | * value as one byte into the user space buffer. The unit is Fahrenheit... |
| 455 | */ | 442 | */ |
| 456 | static ssize_t | 443 | static ssize_t wdrtas_temp_read(struct file *file, char __user *buf, |
| 457 | wdrtas_temp_read(struct file *file, char __user *buf, | ||
| 458 | size_t count, loff_t *ppos) | 444 | size_t count, loff_t *ppos) |
| 459 | { | 445 | { |
| 460 | int temperature = 0; | 446 | int temperature = 0; |
| @@ -478,8 +464,7 @@ wdrtas_temp_read(struct file *file, char __user *buf, | |||
| 478 | * | 464 | * |
| 479 | * function called when temperature device is opened | 465 | * function called when temperature device is opened |
| 480 | */ | 466 | */ |
| 481 | static int | 467 | static int wdrtas_temp_open(struct inode *inode, struct file *file) |
| 482 | wdrtas_temp_open(struct inode *inode, struct file *file) | ||
| 483 | { | 468 | { |
| 484 | return nonseekable_open(inode, file); | 469 | return nonseekable_open(inode, file); |
| 485 | } | 470 | } |
| @@ -493,8 +478,7 @@ wdrtas_temp_open(struct inode *inode, struct file *file) | |||
| 493 | * | 478 | * |
| 494 | * close function. Always succeeds | 479 | * close function. Always succeeds |
| 495 | */ | 480 | */ |
| 496 | static int | 481 | static int wdrtas_temp_close(struct inode *inode, struct file *file) |
| 497 | wdrtas_temp_close(struct inode *inode, struct file *file) | ||
| 498 | { | 482 | { |
| 499 | return 0; | 483 | return 0; |
| 500 | } | 484 | } |
| @@ -509,10 +493,10 @@ wdrtas_temp_close(struct inode *inode, struct file *file) | |||
| 509 | * | 493 | * |
| 510 | * wdrtas_reboot stops the watchdog in case of a reboot | 494 | * wdrtas_reboot stops the watchdog in case of a reboot |
| 511 | */ | 495 | */ |
| 512 | static int | 496 | static int wdrtas_reboot(struct notifier_block *this, |
| 513 | wdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr) | 497 | unsigned long code, void *ptr) |
| 514 | { | 498 | { |
| 515 | if ( (code==SYS_DOWN) || (code==SYS_HALT) ) | 499 | if (code == SYS_DOWN || code == SYS_HALT) |
| 516 | wdrtas_timer_stop(); | 500 | wdrtas_timer_stop(); |
| 517 | 501 | ||
| 518 | return NOTIFY_DONE; | 502 | return NOTIFY_DONE; |
| @@ -524,7 +508,7 @@ static const struct file_operations wdrtas_fops = { | |||
| 524 | .owner = THIS_MODULE, | 508 | .owner = THIS_MODULE, |
| 525 | .llseek = no_llseek, | 509 | .llseek = no_llseek, |
| 526 | .write = wdrtas_write, | 510 | .write = wdrtas_write, |
| 527 | .ioctl = wdrtas_ioctl, | 511 | .unlocked_ioctl = wdrtas_ioctl, |
| 528 | .open = wdrtas_open, | 512 | .open = wdrtas_open, |
| 529 | .release = wdrtas_close, | 513 | .release = wdrtas_close, |
| 530 | }; | 514 | }; |
| @@ -562,8 +546,7 @@ static struct notifier_block wdrtas_notifier = { | |||
| 562 | * this watchdog driver. It tolerates, if "get-sensor-state" and | 546 | * this watchdog driver. It tolerates, if "get-sensor-state" and |
| 563 | * "ibm,get-system-parameter" are not available. | 547 | * "ibm,get-system-parameter" are not available. |
| 564 | */ | 548 | */ |
| 565 | static int | 549 | static int wdrtas_get_tokens(void) |
| 566 | wdrtas_get_tokens(void) | ||
| 567 | { | 550 | { |
| 568 | wdrtas_token_get_sensor_state = rtas_token("get-sensor-state"); | 551 | wdrtas_token_get_sensor_state = rtas_token("get-sensor-state"); |
| 569 | if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) { | 552 | if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) { |
| @@ -603,8 +586,7 @@ wdrtas_get_tokens(void) | |||
| 603 | * wdrtas_register_devs unregisters the watchdog and temperature watchdog | 586 | * wdrtas_register_devs unregisters the watchdog and temperature watchdog |
| 604 | * misc devs | 587 | * misc devs |
| 605 | */ | 588 | */ |
| 606 | static void | 589 | static void wdrtas_unregister_devs(void) |
| 607 | wdrtas_unregister_devs(void) | ||
| 608 | { | 590 | { |
| 609 | misc_deregister(&wdrtas_miscdev); | 591 | misc_deregister(&wdrtas_miscdev); |
| 610 | if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) | 592 | if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) |
| @@ -619,8 +601,7 @@ wdrtas_unregister_devs(void) | |||
| 619 | * wdrtas_register_devs registers the watchdog and temperature watchdog | 601 | * wdrtas_register_devs registers the watchdog and temperature watchdog |
| 620 | * misc devs | 602 | * misc devs |
| 621 | */ | 603 | */ |
| 622 | static int | 604 | static int wdrtas_register_devs(void) |
| 623 | wdrtas_register_devs(void) | ||
| 624 | { | 605 | { |
| 625 | int result; | 606 | int result; |
| 626 | 607 | ||
| @@ -651,8 +632,7 @@ wdrtas_register_devs(void) | |||
| 651 | * | 632 | * |
| 652 | * registers the file handlers and the reboot notifier | 633 | * registers the file handlers and the reboot notifier |
| 653 | */ | 634 | */ |
| 654 | static int __init | 635 | static int __init wdrtas_init(void) |
| 655 | wdrtas_init(void) | ||
| 656 | { | 636 | { |
| 657 | if (wdrtas_get_tokens()) | 637 | if (wdrtas_get_tokens()) |
| 658 | return -ENODEV; | 638 | return -ENODEV; |
| @@ -680,8 +660,7 @@ wdrtas_init(void) | |||
| 680 | * | 660 | * |
| 681 | * unregisters the file handlers and the reboot notifier | 661 | * unregisters the file handlers and the reboot notifier |
| 682 | */ | 662 | */ |
| 683 | static void __exit | 663 | static void __exit wdrtas_exit(void) |
| 684 | wdrtas_exit(void) | ||
| 685 | { | 664 | { |
| 686 | if (!wdrtas_nowayout) | 665 | if (!wdrtas_nowayout) |
| 687 | wdrtas_timer_stop(); | 666 | wdrtas_timer_stop(); |
