aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/pcwd_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/watchdog/pcwd_pci.c')
-rw-r--r--drivers/watchdog/pcwd_pci.c161
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 */
100static const int heartbeat_tbl [] = { 99static 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
458static int pcipcwd_ioctl(struct inode *inode, struct file *file, 456static 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
629static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, void *unused) 624static 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};