diff options
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/Kconfig | 18 | ||||
-rw-r--r-- | drivers/watchdog/wdt_pci.c | 122 |
2 files changed, 66 insertions, 74 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index e8d45b6ccef8..b1ccc04f3c9a 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -1007,24 +1007,16 @@ config WDTPCI | |||
1007 | ---help--- | 1007 | ---help--- |
1008 | If you have a PCI-WDT500/501 watchdog board, say Y here, otherwise N. | 1008 | If you have a PCI-WDT500/501 watchdog board, say Y here, otherwise N. |
1009 | 1009 | ||
1010 | To compile this driver as a module, choose M here: the | 1010 | If you have a PCI-WDT501 watchdog board then you can enable the |
1011 | module will be called wdt_pci. | 1011 | temperature sensor by setting the type parameter to 501. |
1012 | |||
1013 | config WDT_501_PCI | ||
1014 | bool "PCI-WDT501 features" | ||
1015 | depends on WDTPCI | ||
1016 | help | ||
1017 | Saying Y here and creating a character special file /dev/temperature | ||
1018 | with major number 10 and minor number 131 ("man mknod") will give | ||
1019 | you a thermometer inside your computer: reading from | ||
1020 | /dev/temperature yields one byte, the temperature in degrees | ||
1021 | Fahrenheit. This works only if you have a PCI-WDT501 watchdog board | ||
1022 | installed. | ||
1023 | 1012 | ||
1024 | If you want to enable the Fan Tachometer on the PCI-WDT501, then you | 1013 | If you want to enable the Fan Tachometer on the PCI-WDT501, then you |
1025 | can do this via the tachometer parameter. Only do this if you have a | 1014 | can do this via the tachometer parameter. Only do this if you have a |
1026 | fan tachometer actually set up. | 1015 | fan tachometer actually set up. |
1027 | 1016 | ||
1017 | To compile this driver as a module, choose M here: the | ||
1018 | module will be called wdt_pci. | ||
1019 | |||
1028 | # | 1020 | # |
1029 | # USB-based Watchdog Cards | 1021 | # USB-based Watchdog Cards |
1030 | # | 1022 | # |
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c index c45839a4a34d..7a1bdc7c95a9 100644 --- a/drivers/watchdog/wdt_pci.c +++ b/drivers/watchdog/wdt_pci.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Industrial Computer Source PCI-WDT500/501 driver | 2 | * Industrial Computer Source PCI-WDT500/501 driver |
3 | * | 3 | * |
4 | * (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>, | 4 | * (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>, |
5 | * All Rights Reserved. | 5 | * All Rights Reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License | 8 | * modify it under the terms of the GNU General Public License |
@@ -99,14 +99,16 @@ MODULE_PARM_DESC(nowayout, | |||
99 | "Watchdog cannot be stopped once started (default=" | 99 | "Watchdog cannot be stopped once started (default=" |
100 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 100 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
101 | 101 | ||
102 | #ifdef CONFIG_WDT_501_PCI | ||
103 | /* Support for the Fan Tachometer on the PCI-WDT501 */ | 102 | /* Support for the Fan Tachometer on the PCI-WDT501 */ |
104 | static int tachometer; | 103 | static int tachometer; |
105 | |||
106 | module_param(tachometer, int, 0); | 104 | module_param(tachometer, int, 0); |
107 | MODULE_PARM_DESC(tachometer, | 105 | MODULE_PARM_DESC(tachometer, |
108 | "PCI-WDT501 Fan Tachometer support (0=disable, default=0)"); | 106 | "PCI-WDT501 Fan Tachometer support (0=disable, default=0)"); |
109 | #endif /* CONFIG_WDT_501_PCI */ | 107 | |
108 | static int type = 500; | ||
109 | module_param(type, int, 0); | ||
110 | MODULE_PARM_DESC(type, | ||
111 | "PCI-WDT501 Card type (500 or 501 , default=500)"); | ||
110 | 112 | ||
111 | /* | 113 | /* |
112 | * Programming support | 114 | * Programming support |
@@ -266,22 +268,21 @@ static int wdtpci_get_status(int *status) | |||
266 | *status |= WDIOF_EXTERN1; | 268 | *status |= WDIOF_EXTERN1; |
267 | if (new_status & WDC_SR_ISII1) | 269 | if (new_status & WDC_SR_ISII1) |
268 | *status |= WDIOF_EXTERN2; | 270 | *status |= WDIOF_EXTERN2; |
269 | #ifdef CONFIG_WDT_501_PCI | 271 | if (type == 501) { |
270 | if (!(new_status & WDC_SR_TGOOD)) | 272 | if (!(new_status & WDC_SR_TGOOD)) |
271 | *status |= WDIOF_OVERHEAT; | 273 | *status |= WDIOF_OVERHEAT; |
272 | if (!(new_status & WDC_SR_PSUOVER)) | 274 | if (!(new_status & WDC_SR_PSUOVER)) |
273 | *status |= WDIOF_POWEROVER; | 275 | *status |= WDIOF_POWEROVER; |
274 | if (!(new_status & WDC_SR_PSUUNDR)) | 276 | if (!(new_status & WDC_SR_PSUUNDR)) |
275 | *status |= WDIOF_POWERUNDER; | 277 | *status |= WDIOF_POWERUNDER; |
276 | if (tachometer) { | 278 | if (tachometer) { |
277 | if (!(new_status & WDC_SR_FANGOOD)) | 279 | if (!(new_status & WDC_SR_FANGOOD)) |
278 | *status |= WDIOF_FANFAULT; | 280 | *status |= WDIOF_FANFAULT; |
281 | } | ||
279 | } | 282 | } |
280 | #endif /* CONFIG_WDT_501_PCI */ | ||
281 | return 0; | 283 | return 0; |
282 | } | 284 | } |
283 | 285 | ||
284 | #ifdef CONFIG_WDT_501_PCI | ||
285 | /** | 286 | /** |
286 | * wdtpci_get_temperature: | 287 | * wdtpci_get_temperature: |
287 | * | 288 | * |
@@ -300,7 +301,6 @@ static int wdtpci_get_temperature(int *temperature) | |||
300 | *temperature = (c * 11 / 15) + 7; | 301 | *temperature = (c * 11 / 15) + 7; |
301 | return 0; | 302 | return 0; |
302 | } | 303 | } |
303 | #endif /* CONFIG_WDT_501_PCI */ | ||
304 | 304 | ||
305 | /** | 305 | /** |
306 | * wdtpci_interrupt: | 306 | * wdtpci_interrupt: |
@@ -327,22 +327,22 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id) | |||
327 | 327 | ||
328 | printk(KERN_CRIT PFX "status %d\n", status); | 328 | printk(KERN_CRIT PFX "status %d\n", status); |
329 | 329 | ||
330 | #ifdef CONFIG_WDT_501_PCI | 330 | if (type == 501) { |
331 | if (!(status & WDC_SR_TGOOD)) { | 331 | if (!(status & WDC_SR_TGOOD)) { |
332 | u8 alarm = inb(WDT_RT); | 332 | printk(KERN_CRIT PFX "Overheat alarm.(%d)\n", |
333 | printk(KERN_CRIT PFX "Overheat alarm.(%d)\n", alarm); | 333 | inb(WDT_RT)); |
334 | udelay(8); | 334 | udelay(8); |
335 | } | 335 | } |
336 | if (!(status & WDC_SR_PSUOVER)) | 336 | if (!(status & WDC_SR_PSUOVER)) |
337 | printk(KERN_CRIT PFX "PSU over voltage.\n"); | 337 | printk(KERN_CRIT PFX "PSU over voltage.\n"); |
338 | if (!(status & WDC_SR_PSUUNDR)) | 338 | if (!(status & WDC_SR_PSUUNDR)) |
339 | printk(KERN_CRIT PFX "PSU under voltage.\n"); | 339 | printk(KERN_CRIT PFX "PSU under voltage.\n"); |
340 | if (tachometer) { | 340 | if (tachometer) { |
341 | if (!(status & WDC_SR_FANGOOD)) | 341 | if (!(status & WDC_SR_FANGOOD)) |
342 | printk(KERN_CRIT PFX "Possible fan fault.\n"); | 342 | printk(KERN_CRIT PFX "Possible fan fault.\n"); |
343 | } | ||
343 | } | 344 | } |
344 | #endif /* CONFIG_WDT_501_PCI */ | 345 | if (!(status & WDC_SR_WCCR)) { |
345 | if (!(status&WDC_SR_WCCR)) { | ||
346 | #ifdef SOFTWARE_REBOOT | 346 | #ifdef SOFTWARE_REBOOT |
347 | #ifdef ONLY_TESTING | 347 | #ifdef ONLY_TESTING |
348 | printk(KERN_CRIT PFX "Would Reboot.\n"); | 348 | printk(KERN_CRIT PFX "Would Reboot.\n"); |
@@ -371,12 +371,13 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id) | |||
371 | */ | 371 | */ |
372 | 372 | ||
373 | static ssize_t wdtpci_write(struct file *file, const char __user *buf, | 373 | static ssize_t wdtpci_write(struct file *file, const char __user *buf, |
374 | size_t count, loff_t *ppos) | 374 | size_t count, loff_t *ppos) |
375 | { | 375 | { |
376 | if (count) { | 376 | if (count) { |
377 | if (!nowayout) { | 377 | if (!nowayout) { |
378 | size_t i; | 378 | size_t i; |
379 | 379 | ||
380 | /* In case it was set long ago */ | ||
380 | expect_close = 0; | 381 | expect_close = 0; |
381 | 382 | ||
382 | for (i = 0; i != count; i++) { | 383 | for (i = 0; i != count; i++) { |
@@ -406,10 +407,10 @@ static ssize_t wdtpci_write(struct file *file, const char __user *buf, | |||
406 | static long wdtpci_ioctl(struct file *file, unsigned int cmd, | 407 | static long wdtpci_ioctl(struct file *file, unsigned int cmd, |
407 | unsigned long arg) | 408 | unsigned long arg) |
408 | { | 409 | { |
409 | int new_heartbeat; | ||
410 | int status; | ||
411 | void __user *argp = (void __user *)arg; | 410 | void __user *argp = (void __user *)arg; |
412 | int __user *p = argp; | 411 | int __user *p = argp; |
412 | int new_heartbeat; | ||
413 | int status; | ||
413 | 414 | ||
414 | static struct watchdog_info ident = { | 415 | static struct watchdog_info ident = { |
415 | .options = WDIOF_SETTIMEOUT| | 416 | .options = WDIOF_SETTIMEOUT| |
@@ -421,11 +422,12 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd, | |||
421 | 422 | ||
422 | /* Add options according to the card we have */ | 423 | /* Add options according to the card we have */ |
423 | ident.options |= (WDIOF_EXTERN1|WDIOF_EXTERN2); | 424 | ident.options |= (WDIOF_EXTERN1|WDIOF_EXTERN2); |
424 | #ifdef CONFIG_WDT_501_PCI | 425 | if (type == 501) { |
425 | ident.options |= (WDIOF_OVERHEAT|WDIOF_POWERUNDER|WDIOF_POWEROVER); | 426 | ident.options |= (WDIOF_OVERHEAT|WDIOF_POWERUNDER| |
426 | if (tachometer) | 427 | WDIOF_POWEROVER); |
427 | ident.options |= WDIOF_FANFAULT; | 428 | if (tachometer) |
428 | #endif /* CONFIG_WDT_501_PCI */ | 429 | ident.options |= WDIOF_FANFAULT; |
430 | } | ||
429 | 431 | ||
430 | switch (cmd) { | 432 | switch (cmd) { |
431 | case WDIOC_GETSUPPORT: | 433 | case WDIOC_GETSUPPORT: |
@@ -503,7 +505,6 @@ static int wdtpci_release(struct inode *inode, struct file *file) | |||
503 | return 0; | 505 | return 0; |
504 | } | 506 | } |
505 | 507 | ||
506 | #ifdef CONFIG_WDT_501_PCI | ||
507 | /** | 508 | /** |
508 | * wdtpci_temp_read: | 509 | * wdtpci_temp_read: |
509 | * @file: file handle to the watchdog board | 510 | * @file: file handle to the watchdog board |
@@ -554,7 +555,6 @@ static int wdtpci_temp_release(struct inode *inode, struct file *file) | |||
554 | { | 555 | { |
555 | return 0; | 556 | return 0; |
556 | } | 557 | } |
557 | #endif /* CONFIG_WDT_501_PCI */ | ||
558 | 558 | ||
559 | /** | 559 | /** |
560 | * notify_sys: | 560 | * notify_sys: |
@@ -596,7 +596,6 @@ static struct miscdevice wdtpci_miscdev = { | |||
596 | .fops = &wdtpci_fops, | 596 | .fops = &wdtpci_fops, |
597 | }; | 597 | }; |
598 | 598 | ||
599 | #ifdef CONFIG_WDT_501_PCI | ||
600 | static const struct file_operations wdtpci_temp_fops = { | 599 | static const struct file_operations wdtpci_temp_fops = { |
601 | .owner = THIS_MODULE, | 600 | .owner = THIS_MODULE, |
602 | .llseek = no_llseek, | 601 | .llseek = no_llseek, |
@@ -610,7 +609,6 @@ static struct miscdevice temp_miscdev = { | |||
610 | .name = "temperature", | 609 | .name = "temperature", |
611 | .fops = &wdtpci_temp_fops, | 610 | .fops = &wdtpci_temp_fops, |
612 | }; | 611 | }; |
613 | #endif /* CONFIG_WDT_501_PCI */ | ||
614 | 612 | ||
615 | /* | 613 | /* |
616 | * The WDT card needs to learn about soft shutdowns in order to | 614 | * The WDT card needs to learn about soft shutdowns in order to |
@@ -633,6 +631,11 @@ static int __devinit wdtpci_init_one(struct pci_dev *dev, | |||
633 | return -ENODEV; | 631 | return -ENODEV; |
634 | } | 632 | } |
635 | 633 | ||
634 | if (type != 500 && type != 501) { | ||
635 | printk(KERN_ERR PFX "unknown card type '%d'.\n", type); | ||
636 | return -ENODEV; | ||
637 | } | ||
638 | |||
636 | if (pci_enable_device(dev)) { | 639 | if (pci_enable_device(dev)) { |
637 | printk(KERN_ERR PFX "Not possible to enable PCI Device\n"); | 640 | printk(KERN_ERR PFX "Not possible to enable PCI Device\n"); |
638 | return -ENODEV; | 641 | return -ENODEV; |
@@ -678,15 +681,15 @@ static int __devinit wdtpci_init_one(struct pci_dev *dev, | |||
678 | goto out_irq; | 681 | goto out_irq; |
679 | } | 682 | } |
680 | 683 | ||
681 | #ifdef CONFIG_WDT_501_PCI | 684 | if (type == 501) { |
682 | ret = misc_register(&temp_miscdev); | 685 | ret = misc_register(&temp_miscdev); |
683 | if (ret) { | 686 | if (ret) { |
684 | printk(KERN_ERR PFX | 687 | printk(KERN_ERR PFX |
685 | "cannot register miscdev on minor=%d (err=%d)\n", | 688 | "cannot register miscdev on minor=%d (err=%d)\n", |
686 | TEMP_MINOR, ret); | 689 | TEMP_MINOR, ret); |
687 | goto out_rbt; | 690 | goto out_rbt; |
691 | } | ||
688 | } | 692 | } |
689 | #endif /* CONFIG_WDT_501_PCI */ | ||
690 | 693 | ||
691 | ret = misc_register(&wdtpci_miscdev); | 694 | ret = misc_register(&wdtpci_miscdev); |
692 | if (ret) { | 695 | if (ret) { |
@@ -698,20 +701,18 @@ static int __devinit wdtpci_init_one(struct pci_dev *dev, | |||
698 | 701 | ||
699 | printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", | 702 | printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", |
700 | heartbeat, nowayout); | 703 | heartbeat, nowayout); |
701 | #ifdef CONFIG_WDT_501_PCI | 704 | if (type == 501) |
702 | printk(KERN_INFO "wdt: Fan Tachometer is %s\n", | 705 | printk(KERN_INFO "wdt: Fan Tachometer is %s\n", |
703 | (tachometer ? "Enabled" : "Disabled")); | 706 | (tachometer ? "Enabled" : "Disabled")); |
704 | #endif /* CONFIG_WDT_501_PCI */ | ||
705 | 707 | ||
706 | ret = 0; | 708 | ret = 0; |
707 | out: | 709 | out: |
708 | return ret; | 710 | return ret; |
709 | 711 | ||
710 | out_misc: | 712 | out_misc: |
711 | #ifdef CONFIG_WDT_501_PCI | 713 | if (type == 501) |
712 | misc_deregister(&temp_miscdev); | 714 | misc_deregister(&temp_miscdev); |
713 | out_rbt: | 715 | out_rbt: |
714 | #endif /* CONFIG_WDT_501_PCI */ | ||
715 | unregister_reboot_notifier(&wdtpci_notifier); | 716 | unregister_reboot_notifier(&wdtpci_notifier); |
716 | out_irq: | 717 | out_irq: |
717 | free_irq(irq, &wdtpci_miscdev); | 718 | free_irq(irq, &wdtpci_miscdev); |
@@ -728,9 +729,8 @@ static void __devexit wdtpci_remove_one(struct pci_dev *pdev) | |||
728 | /* here we assume only one device will ever have | 729 | /* here we assume only one device will ever have |
729 | * been picked up and registered by probe function */ | 730 | * been picked up and registered by probe function */ |
730 | misc_deregister(&wdtpci_miscdev); | 731 | misc_deregister(&wdtpci_miscdev); |
731 | #ifdef CONFIG_WDT_501_PCI | 732 | if (type == 501) |
732 | misc_deregister(&temp_miscdev); | 733 | misc_deregister(&temp_miscdev); |
733 | #endif /* CONFIG_WDT_501_PCI */ | ||
734 | unregister_reboot_notifier(&wdtpci_notifier); | 734 | unregister_reboot_notifier(&wdtpci_notifier); |
735 | free_irq(irq, &wdtpci_miscdev); | 735 | free_irq(irq, &wdtpci_miscdev); |
736 | release_region(io, 16); | 736 | release_region(io, 16); |