diff options
Diffstat (limited to 'drivers/watchdog/pcwd_pci.c')
-rw-r--r-- | drivers/watchdog/pcwd_pci.c | 161 |
1 files changed, 77 insertions, 84 deletions
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c index 61a89e959642..90eb1d4271d7 100644 --- a/drivers/watchdog/pcwd_pci.c +++ b/drivers/watchdog/pcwd_pci.c | |||
@@ -46,9 +46,8 @@ | |||
46 | #include <linux/pci.h> /* For pci functions */ | 46 | #include <linux/pci.h> /* For pci functions */ |
47 | #include <linux/ioport.h> /* For io-port access */ | 47 | #include <linux/ioport.h> /* For io-port access */ |
48 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ | 48 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ |
49 | 49 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ | |
50 | #include <asm/uaccess.h> /* For copy_to_user/put_user/... */ | 50 | #include <linux/io.h> /* For inb/outb/... */ |
51 | #include <asm/io.h> /* For inb/outb/... */ | ||
52 | 51 | ||
53 | /* Module and version information */ | 52 | /* Module and version information */ |
54 | #define WATCHDOG_VERSION "1.03" | 53 | #define WATCHDOG_VERSION "1.03" |
@@ -97,7 +96,7 @@ | |||
97 | #define CMD_GET_CLEAR_RESET_COUNT 0x84 | 96 | #define CMD_GET_CLEAR_RESET_COUNT 0x84 |
98 | 97 | ||
99 | /* Watchdog's Dip Switch heartbeat values */ | 98 | /* Watchdog's Dip Switch heartbeat values */ |
100 | static const int heartbeat_tbl [] = { | 99 | static const int heartbeat_tbl[] = { |
101 | 5, /* OFF-OFF-OFF = 5 Sec */ | 100 | 5, /* OFF-OFF-OFF = 5 Sec */ |
102 | 10, /* OFF-OFF-ON = 10 Sec */ | 101 | 10, /* OFF-OFF-ON = 10 Sec */ |
103 | 30, /* OFF-ON-OFF = 30 Sec */ | 102 | 30, /* OFF-ON-OFF = 30 Sec */ |
@@ -220,11 +219,10 @@ static void pcipcwd_show_card_info(void) | |||
220 | int option_switches; | 219 | int option_switches; |
221 | 220 | ||
222 | got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor); | 221 | got_fw_rev = send_command(CMD_GET_FIRMWARE_VERSION, &fw_rev_major, &fw_rev_minor); |
223 | if (got_fw_rev) { | 222 | if (got_fw_rev) |
224 | sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor); | 223 | sprintf(fw_ver_str, "%u.%02u", fw_rev_major, fw_rev_minor); |
225 | } else { | 224 | else |
226 | sprintf(fw_ver_str, "<card no answer>"); | 225 | sprintf(fw_ver_str, "<card no answer>"); |
227 | } | ||
228 | 226 | ||
229 | /* Get switch settings */ | 227 | /* Get switch settings */ |
230 | option_switches = pcipcwd_get_option_switches(); | 228 | option_switches = pcipcwd_get_option_switches(); |
@@ -331,7 +329,7 @@ static int pcipcwd_get_status(int *status) | |||
331 | { | 329 | { |
332 | int control_status; | 330 | int control_status; |
333 | 331 | ||
334 | *status=0; | 332 | *status = 0; |
335 | control_status = inb_p(pcipcwd_private.io_addr + 1); | 333 | control_status = inb_p(pcipcwd_private.io_addr + 1); |
336 | if (control_status & WD_PCI_WTRP) | 334 | if (control_status & WD_PCI_WTRP) |
337 | *status |= WDIOF_CARDRESET; | 335 | *status |= WDIOF_CARDRESET; |
@@ -369,8 +367,8 @@ static int pcipcwd_clear_status(void) | |||
369 | outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP, pcipcwd_private.io_addr + 1); | 367 | outb_p((control_status & WD_PCI_R2DS) | WD_PCI_WTRP, pcipcwd_private.io_addr + 1); |
370 | 368 | ||
371 | /* clear reset counter */ | 369 | /* clear reset counter */ |
372 | msb=0; | 370 | msb = 0; |
373 | reset_counter=0xff; | 371 | reset_counter = 0xff; |
374 | send_command(CMD_GET_CLEAR_RESET_COUNT, &msb, &reset_counter); | 372 | send_command(CMD_GET_CLEAR_RESET_COUNT, &msb, &reset_counter); |
375 | 373 | ||
376 | if (debug >= DEBUG) { | 374 | if (debug >= DEBUG) { |
@@ -442,7 +440,7 @@ static ssize_t pcipcwd_write(struct file *file, const char __user *data, | |||
442 | /* scan to see whether or not we got the magic character */ | 440 | /* scan to see whether or not we got the magic character */ |
443 | for (i = 0; i != len; i++) { | 441 | for (i = 0; i != len; i++) { |
444 | char c; | 442 | char c; |
445 | if(get_user(c, data+i)) | 443 | if (get_user(c, data + i)) |
446 | return -EFAULT; | 444 | return -EFAULT; |
447 | if (c == 'V') | 445 | if (c == 'V') |
448 | expect_release = 42; | 446 | expect_release = 42; |
@@ -455,8 +453,8 @@ static ssize_t pcipcwd_write(struct file *file, const char __user *data, | |||
455 | return len; | 453 | return len; |
456 | } | 454 | } |
457 | 455 | ||
458 | static int pcipcwd_ioctl(struct inode *inode, struct file *file, | 456 | static long pcipcwd_ioctl(struct file *file, unsigned int cmd, |
459 | unsigned int cmd, unsigned long arg) | 457 | unsigned long arg) |
460 | { | 458 | { |
461 | void __user *argp = (void __user *)arg; | 459 | void __user *argp = (void __user *)arg; |
462 | int __user *p = argp; | 460 | int __user *p = argp; |
@@ -471,92 +469,89 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file, | |||
471 | }; | 469 | }; |
472 | 470 | ||
473 | switch (cmd) { | 471 | switch (cmd) { |
474 | case WDIOC_GETSUPPORT: | 472 | case WDIOC_GETSUPPORT: |
475 | return copy_to_user(argp, &ident, | 473 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
476 | sizeof (ident)) ? -EFAULT : 0; | 474 | |
475 | case WDIOC_GETSTATUS: | ||
476 | { | ||
477 | int status; | ||
478 | pcipcwd_get_status(&status); | ||
479 | return put_user(status, p); | ||
480 | } | ||
477 | 481 | ||
478 | case WDIOC_GETSTATUS: | 482 | case WDIOC_GETBOOTSTATUS: |
479 | { | 483 | return put_user(pcipcwd_private.boot_status, p); |
480 | int status; | ||
481 | 484 | ||
482 | pcipcwd_get_status(&status); | 485 | case WDIOC_GETTEMP: |
486 | { | ||
487 | int temperature; | ||
483 | 488 | ||
484 | return put_user(status, p); | 489 | if (pcipcwd_get_temperature(&temperature)) |
485 | } | 490 | return -EFAULT; |
486 | 491 | ||
487 | case WDIOC_GETBOOTSTATUS: | 492 | return put_user(temperature, p); |
488 | return put_user(pcipcwd_private.boot_status, p); | 493 | } |
489 | 494 | ||
490 | case WDIOC_GETTEMP: | 495 | case WDIOC_SETOPTIONS: |
491 | { | 496 | { |
492 | int temperature; | 497 | int new_options, retval = -EINVAL; |
493 | 498 | ||
494 | if (pcipcwd_get_temperature(&temperature)) | 499 | if (get_user(new_options, p)) |
495 | return -EFAULT; | 500 | return -EFAULT; |
496 | 501 | ||
497 | return put_user(temperature, p); | 502 | if (new_options & WDIOS_DISABLECARD) { |
503 | if (pcipcwd_stop()) | ||
504 | return -EIO; | ||
505 | retval = 0; | ||
498 | } | 506 | } |
499 | 507 | ||
500 | case WDIOC_KEEPALIVE: | 508 | if (new_options & WDIOS_ENABLECARD) { |
501 | pcipcwd_keepalive(); | 509 | if (pcipcwd_start()) |
502 | return 0; | 510 | return -EIO; |
503 | 511 | retval = 0; | |
504 | case WDIOC_SETOPTIONS: | 512 | } |
505 | { | ||
506 | int new_options, retval = -EINVAL; | ||
507 | |||
508 | if (get_user (new_options, p)) | ||
509 | return -EFAULT; | ||
510 | |||
511 | if (new_options & WDIOS_DISABLECARD) { | ||
512 | if (pcipcwd_stop()) | ||
513 | return -EIO; | ||
514 | retval = 0; | ||
515 | } | ||
516 | 513 | ||
517 | if (new_options & WDIOS_ENABLECARD) { | 514 | if (new_options & WDIOS_TEMPPANIC) { |
518 | if (pcipcwd_start()) | 515 | temp_panic = 1; |
519 | return -EIO; | 516 | retval = 0; |
520 | retval = 0; | 517 | } |
521 | } | ||
522 | 518 | ||
523 | if (new_options & WDIOS_TEMPPANIC) { | 519 | return retval; |
524 | temp_panic = 1; | 520 | } |
525 | retval = 0; | ||
526 | } | ||
527 | 521 | ||
528 | return retval; | 522 | case WDIOC_KEEPALIVE: |
529 | } | 523 | pcipcwd_keepalive(); |
524 | return 0; | ||
530 | 525 | ||
531 | case WDIOC_SETTIMEOUT: | 526 | case WDIOC_SETTIMEOUT: |
532 | { | 527 | { |
533 | int new_heartbeat; | 528 | int new_heartbeat; |
534 | 529 | ||
535 | if (get_user(new_heartbeat, p)) | 530 | if (get_user(new_heartbeat, p)) |
536 | return -EFAULT; | 531 | return -EFAULT; |
537 | 532 | ||
538 | if (pcipcwd_set_heartbeat(new_heartbeat)) | 533 | if (pcipcwd_set_heartbeat(new_heartbeat)) |
539 | return -EINVAL; | 534 | return -EINVAL; |
540 | 535 | ||
541 | pcipcwd_keepalive(); | 536 | pcipcwd_keepalive(); |
542 | /* Fall */ | 537 | /* Fall */ |
543 | } | 538 | } |
544 | 539 | ||
545 | case WDIOC_GETTIMEOUT: | 540 | case WDIOC_GETTIMEOUT: |
546 | return put_user(heartbeat, p); | 541 | return put_user(heartbeat, p); |
547 | 542 | ||
548 | case WDIOC_GETTIMELEFT: | 543 | case WDIOC_GETTIMELEFT: |
549 | { | 544 | { |
550 | int time_left; | 545 | int time_left; |
551 | 546 | ||
552 | if (pcipcwd_get_timeleft(&time_left)) | 547 | if (pcipcwd_get_timeleft(&time_left)) |
553 | return -EFAULT; | 548 | return -EFAULT; |
554 | 549 | ||
555 | return put_user(time_left, p); | 550 | return put_user(time_left, p); |
556 | } | 551 | } |
557 | 552 | ||
558 | default: | 553 | default: |
559 | return -ENOTTY; | 554 | return -ENOTTY; |
560 | } | 555 | } |
561 | } | 556 | } |
562 | 557 | ||
@@ -603,7 +598,7 @@ static ssize_t pcipcwd_temp_read(struct file *file, char __user *data, | |||
603 | if (pcipcwd_get_temperature(&temperature)) | 598 | if (pcipcwd_get_temperature(&temperature)) |
604 | return -EFAULT; | 599 | return -EFAULT; |
605 | 600 | ||
606 | if (copy_to_user (data, &temperature, 1)) | 601 | if (copy_to_user(data, &temperature, 1)) |
607 | return -EFAULT; | 602 | return -EFAULT; |
608 | 603 | ||
609 | return 1; | 604 | return 1; |
@@ -628,10 +623,8 @@ static int pcipcwd_temp_release(struct inode *inode, struct file *file) | |||
628 | 623 | ||
629 | static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 624 | static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused) |
630 | { | 625 | { |
631 | if (code==SYS_DOWN || code==SYS_HALT) { | 626 | if (code == SYS_DOWN || code == SYS_HALT) |
632 | /* Turn the WDT off */ | 627 | pcipcwd_stop(); /* Turn the WDT off */ |
633 | pcipcwd_stop(); | ||
634 | } | ||
635 | 628 | ||
636 | return NOTIFY_DONE; | 629 | return NOTIFY_DONE; |
637 | } | 630 | } |
@@ -644,7 +637,7 @@ static const struct file_operations pcipcwd_fops = { | |||
644 | .owner = THIS_MODULE, | 637 | .owner = THIS_MODULE, |
645 | .llseek = no_llseek, | 638 | .llseek = no_llseek, |
646 | .write = pcipcwd_write, | 639 | .write = pcipcwd_write, |
647 | .ioctl = pcipcwd_ioctl, | 640 | .unlocked_ioctl = pcipcwd_ioctl, |
648 | .open = pcipcwd_open, | 641 | .open = pcipcwd_open, |
649 | .release = pcipcwd_release, | 642 | .release = pcipcwd_release, |
650 | }; | 643 | }; |