Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wdt_pci.c
Go to the documentation of this file.
1 /*
2  * Industrial Computer Source PCI-WDT500/501 driver
3  *
4  * (c) Copyright 1996-1997 Alan Cox <[email protected]>,
5  * All Rights Reserved.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version
10  * 2 of the License, or (at your option) any later version.
11  *
12  * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
13  * warranty for any of this software. This material is provided
14  * "AS-IS" and at no charge.
15  *
16  * (c) Copyright 1995 Alan Cox <[email protected]>
17  *
18  * Release 0.10.
19  *
20  * Fixes
21  * Dave Gregorich : Modularisation and minor bugs
22  * Alan Cox : Added the watchdog ioctl() stuff
23  * Alan Cox : Fixed the reboot problem (as noted by
24  * Matt Crocker).
25  * Alan Cox : Added wdt= boot option
26  * Alan Cox : Cleaned up copy/user stuff
27  * Tim Hockin : Added insmod parameters, comment cleanup
28  * Parameterized timeout
29  * JP Nollmann : Added support for PCI wdt501p
30  * Alan Cox : Split ISA and PCI cards into two drivers
31  * Jeff Garzik : PCI cleanups
32  * Tigran Aivazian : Restructured wdtpci_init_one() to handle
33  * failures
34  * Joel Becker : Added WDIOC_GET/SETTIMEOUT
35  * Zwane Mwaikambo : Magic char closing, locking changes,
36  * cleanups
37  * Matt Domsch : nowayout module option
38  */
39 
40 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
41 
42 #include <linux/interrupt.h>
43 #include <linux/module.h>
44 #include <linux/moduleparam.h>
45 #include <linux/types.h>
46 #include <linux/miscdevice.h>
47 #include <linux/watchdog.h>
48 #include <linux/ioport.h>
49 #include <linux/delay.h>
50 #include <linux/notifier.h>
51 #include <linux/reboot.h>
52 #include <linux/init.h>
53 #include <linux/fs.h>
54 #include <linux/pci.h>
55 #include <linux/io.h>
56 #include <linux/uaccess.h>
57 
58 
59 #define WDT_IS_PCI
60 #include "wd501p.h"
61 
62 /* We can only use 1 card due to the /dev/watchdog restriction */
63 static int dev_count;
64 
65 static unsigned long open_lock;
66 static DEFINE_SPINLOCK(wdtpci_lock);
67 static char expect_close;
68 
69 static resource_size_t io;
70 static int irq;
71 
72 /* Default timeout */
73 #define WD_TIMO 60 /* Default heartbeat = 60 seconds */
74 
75 static int heartbeat = WD_TIMO;
76 static int wd_heartbeat;
77 module_param(heartbeat, int, 0);
79  "Watchdog heartbeat in seconds. (0<heartbeat<65536, default="
81 
82 static bool nowayout = WATCHDOG_NOWAYOUT;
83 module_param(nowayout, bool, 0);
84 MODULE_PARM_DESC(nowayout,
85  "Watchdog cannot be stopped once started (default="
87 
88 /* Support for the Fan Tachometer on the PCI-WDT501 */
89 static int tachometer;
90 module_param(tachometer, int, 0);
91 MODULE_PARM_DESC(tachometer,
92  "PCI-WDT501 Fan Tachometer support (0=disable, default=0)");
93 
94 static int type = 500;
95 module_param(type, int, 0);
96 MODULE_PARM_DESC(type,
97  "PCI-WDT501 Card type (500 or 501 , default=500)");
98 
99 /*
100  * Programming support
101  */
102 
103 static void wdtpci_ctr_mode(int ctr, int mode)
104 {
105  ctr <<= 6;
106  ctr |= 0x30;
107  ctr |= (mode << 1);
108  outb(ctr, WDT_CR);
109  udelay(8);
110 }
111 
112 static void wdtpci_ctr_load(int ctr, int val)
113 {
114  outb(val & 0xFF, WDT_COUNT0 + ctr);
115  udelay(8);
116  outb(val >> 8, WDT_COUNT0 + ctr);
117  udelay(8);
118 }
119 
126 static int wdtpci_start(void)
127 {
128  unsigned long flags;
129 
130  spin_lock_irqsave(&wdtpci_lock, flags);
131 
132  /*
133  * "pet" the watchdog, as Access says.
134  * This resets the clock outputs.
135  */
136  inb(WDT_DC); /* Disable watchdog */
137  udelay(8);
138  wdtpci_ctr_mode(2, 0); /* Program CTR2 for Mode 0:
139  Pulse on Terminal Count */
140  outb(0, WDT_DC); /* Enable watchdog */
141  udelay(8);
142  inb(WDT_DC); /* Disable watchdog */
143  udelay(8);
144  outb(0, WDT_CLOCK); /* 2.0833MHz clock */
145  udelay(8);
146  inb(WDT_BUZZER); /* disable */
147  udelay(8);
148  inb(WDT_OPTONOTRST); /* disable */
149  udelay(8);
150  inb(WDT_OPTORST); /* disable */
151  udelay(8);
152  inb(WDT_PROGOUT); /* disable */
153  udelay(8);
154  wdtpci_ctr_mode(0, 3); /* Program CTR0 for Mode 3:
155  Square Wave Generator */
156  wdtpci_ctr_mode(1, 2); /* Program CTR1 for Mode 2:
157  Rate Generator */
158  wdtpci_ctr_mode(2, 1); /* Program CTR2 for Mode 1:
159  Retriggerable One-Shot */
160  wdtpci_ctr_load(0, 20833); /* count at 100Hz */
161  wdtpci_ctr_load(1, wd_heartbeat);/* Heartbeat */
162  /* DO NOT LOAD CTR2 on PCI card! -- JPN */
163  outb(0, WDT_DC); /* Enable watchdog */
164  udelay(8);
165 
166  spin_unlock_irqrestore(&wdtpci_lock, flags);
167  return 0;
168 }
169 
176 static int wdtpci_stop(void)
177 {
178  unsigned long flags;
179 
180  /* Turn the card off */
181  spin_lock_irqsave(&wdtpci_lock, flags);
182  inb(WDT_DC); /* Disable watchdog */
183  udelay(8);
184  wdtpci_ctr_load(2, 0); /* 0 length reset pulses now */
185  spin_unlock_irqrestore(&wdtpci_lock, flags);
186  return 0;
187 }
188 
196 static int wdtpci_ping(void)
197 {
198  unsigned long flags;
199 
200  spin_lock_irqsave(&wdtpci_lock, flags);
201  /* Write a watchdog value */
202  inb(WDT_DC); /* Disable watchdog */
203  udelay(8);
204  wdtpci_ctr_mode(1, 2); /* Re-Program CTR1 for Mode 2:
205  Rate Generator */
206  wdtpci_ctr_load(1, wd_heartbeat);/* Heartbeat */
207  outb(0, WDT_DC); /* Enable watchdog */
208  udelay(8);
209  spin_unlock_irqrestore(&wdtpci_lock, flags);
210  return 0;
211 }
212 
221 static int wdtpci_set_heartbeat(int t)
222 {
223  /* Arbitrary, can't find the card's limits */
224  if (t < 1 || t > 65535)
225  return -EINVAL;
226 
227  heartbeat = t;
228  wd_heartbeat = t * 100;
229  return 0;
230 }
231 
243 static int wdtpci_get_status(int *status)
244 {
245  unsigned char new_status;
246  unsigned long flags;
247 
248  spin_lock_irqsave(&wdtpci_lock, flags);
249  new_status = inb(WDT_SR);
250  spin_unlock_irqrestore(&wdtpci_lock, flags);
251 
252  *status = 0;
253  if (new_status & WDC_SR_ISOI0)
254  *status |= WDIOF_EXTERN1;
255  if (new_status & WDC_SR_ISII1)
256  *status |= WDIOF_EXTERN2;
257  if (type == 501) {
258  if (!(new_status & WDC_SR_TGOOD))
259  *status |= WDIOF_OVERHEAT;
260  if (!(new_status & WDC_SR_PSUOVER))
261  *status |= WDIOF_POWEROVER;
262  if (!(new_status & WDC_SR_PSUUNDR))
263  *status |= WDIOF_POWERUNDER;
264  if (tachometer) {
265  if (!(new_status & WDC_SR_FANGOOD))
266  *status |= WDIOF_FANFAULT;
267  }
268  }
269  return 0;
270 }
271 
279 static int wdtpci_get_temperature(int *temperature)
280 {
281  unsigned short c;
282  unsigned long flags;
283  spin_lock_irqsave(&wdtpci_lock, flags);
284  c = inb(WDT_RT);
285  udelay(8);
286  spin_unlock_irqrestore(&wdtpci_lock, flags);
287  *temperature = (c * 11 / 15) + 7;
288  return 0;
289 }
290 
301 static irqreturn_t wdtpci_interrupt(int irq, void *dev_id)
302 {
303  /*
304  * Read the status register see what is up and
305  * then printk it.
306  */
307  unsigned char status;
308 
309  spin_lock(&wdtpci_lock);
310 
311  status = inb(WDT_SR);
312  udelay(8);
313 
314  pr_crit("status %d\n", status);
315 
316  if (type == 501) {
317  if (!(status & WDC_SR_TGOOD)) {
318  pr_crit("Overheat alarm (%d)\n", inb(WDT_RT));
319  udelay(8);
320  }
321  if (!(status & WDC_SR_PSUOVER))
322  pr_crit("PSU over voltage\n");
323  if (!(status & WDC_SR_PSUUNDR))
324  pr_crit("PSU under voltage\n");
325  if (tachometer) {
326  if (!(status & WDC_SR_FANGOOD))
327  pr_crit("Possible fan fault\n");
328  }
329  }
330  if (!(status & WDC_SR_WCCR)) {
331 #ifdef SOFTWARE_REBOOT
332 #ifdef ONLY_TESTING
333  pr_crit("Would Reboot\n");
334 #else
335  pr_crit("Initiating system reboot\n");
337 #endif
338 #else
339  pr_crit("Reset in 5ms\n");
340 #endif
341  }
342  spin_unlock(&wdtpci_lock);
343  return IRQ_HANDLED;
344 }
345 
346 
358 static ssize_t wdtpci_write(struct file *file, const char __user *buf,
359  size_t count, loff_t *ppos)
360 {
361  if (count) {
362  if (!nowayout) {
363  size_t i;
364 
365  /* In case it was set long ago */
366  expect_close = 0;
367 
368  for (i = 0; i != count; i++) {
369  char c;
370  if (get_user(c, buf + i))
371  return -EFAULT;
372  if (c == 'V')
373  expect_close = 42;
374  }
375  }
376  wdtpci_ping();
377  }
378  return count;
379 }
380 
392 static long wdtpci_ioctl(struct file *file, unsigned int cmd,
393  unsigned long arg)
394 {
395  void __user *argp = (void __user *)arg;
396  int __user *p = argp;
397  int new_heartbeat;
398  int status;
399 
400  struct watchdog_info ident = {
401  .options = WDIOF_SETTIMEOUT|
404  .firmware_version = 1,
405  .identity = "PCI-WDT500/501",
406  };
407 
408  /* Add options according to the card we have */
410  if (type == 501) {
413  if (tachometer)
414  ident.options |= WDIOF_FANFAULT;
415  }
416 
417  switch (cmd) {
418  case WDIOC_GETSUPPORT:
419  return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
420  case WDIOC_GETSTATUS:
421  wdtpci_get_status(&status);
422  return put_user(status, p);
423  case WDIOC_GETBOOTSTATUS:
424  return put_user(0, p);
425  case WDIOC_KEEPALIVE:
426  wdtpci_ping();
427  return 0;
428  case WDIOC_SETTIMEOUT:
429  if (get_user(new_heartbeat, p))
430  return -EFAULT;
431  if (wdtpci_set_heartbeat(new_heartbeat))
432  return -EINVAL;
433  wdtpci_ping();
434  /* Fall */
435  case WDIOC_GETTIMEOUT:
436  return put_user(heartbeat, p);
437  default:
438  return -ENOTTY;
439  }
440 }
441 
454 static int wdtpci_open(struct inode *inode, struct file *file)
455 {
456  if (test_and_set_bit(0, &open_lock))
457  return -EBUSY;
458 
459  if (nowayout)
460  __module_get(THIS_MODULE);
461  /*
462  * Activate
463  */
464  wdtpci_start();
465  return nonseekable_open(inode, file);
466 }
467 
480 static int wdtpci_release(struct inode *inode, struct file *file)
481 {
482  if (expect_close == 42) {
483  wdtpci_stop();
484  } else {
485  pr_crit("Unexpected close, not stopping timer!\n");
486  wdtpci_ping();
487  }
488  expect_close = 0;
489  clear_bit(0, &open_lock);
490  return 0;
491 }
492 
504 static ssize_t wdtpci_temp_read(struct file *file, char __user *buf,
505  size_t count, loff_t *ptr)
506 {
507  int temperature;
508 
509  if (wdtpci_get_temperature(&temperature))
510  return -EFAULT;
511 
512  if (copy_to_user(buf, &temperature, 1))
513  return -EFAULT;
514 
515  return 1;
516 }
517 
526 static int wdtpci_temp_open(struct inode *inode, struct file *file)
527 {
528  return nonseekable_open(inode, file);
529 }
530 
539 static int wdtpci_temp_release(struct inode *inode, struct file *file)
540 {
541  return 0;
542 }
543 
556 static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code,
557  void *unused)
558 {
559  if (code == SYS_DOWN || code == SYS_HALT)
560  wdtpci_stop();
561  return NOTIFY_DONE;
562 }
563 
564 /*
565  * Kernel Interfaces
566  */
567 
568 
569 static const struct file_operations wdtpci_fops = {
570  .owner = THIS_MODULE,
571  .llseek = no_llseek,
572  .write = wdtpci_write,
573  .unlocked_ioctl = wdtpci_ioctl,
574  .open = wdtpci_open,
575  .release = wdtpci_release,
576 };
577 
578 static struct miscdevice wdtpci_miscdev = {
580  .name = "watchdog",
581  .fops = &wdtpci_fops,
582 };
583 
584 static const struct file_operations wdtpci_temp_fops = {
585  .owner = THIS_MODULE,
586  .llseek = no_llseek,
587  .read = wdtpci_temp_read,
588  .open = wdtpci_temp_open,
589  .release = wdtpci_temp_release,
590 };
591 
592 static struct miscdevice temp_miscdev = {
593  .minor = TEMP_MINOR,
594  .name = "temperature",
595  .fops = &wdtpci_temp_fops,
596 };
597 
598 /*
599  * The WDT card needs to learn about soft shutdowns in order to
600  * turn the timebomb registers off.
601  */
602 
603 static struct notifier_block wdtpci_notifier = {
604  .notifier_call = wdtpci_notify_sys,
605 };
606 
607 
608 static int __devinit wdtpci_init_one(struct pci_dev *dev,
609  const struct pci_device_id *ent)
610 {
611  int ret = -EIO;
612 
613  dev_count++;
614  if (dev_count > 1) {
615  pr_err("This driver only supports one device\n");
616  return -ENODEV;
617  }
618 
619  if (type != 500 && type != 501) {
620  pr_err("unknown card type '%d'\n", type);
621  return -ENODEV;
622  }
623 
624  if (pci_enable_device(dev)) {
625  pr_err("Not possible to enable PCI Device\n");
626  return -ENODEV;
627  }
628 
629  if (pci_resource_start(dev, 2) == 0x0000) {
630  pr_err("No I/O-Address for card detected\n");
631  ret = -ENODEV;
632  goto out_pci;
633  }
634 
635  if (pci_request_region(dev, 2, "wdt_pci")) {
636  pr_err("I/O address 0x%llx already in use\n",
637  (unsigned long long)pci_resource_start(dev, 2));
638  goto out_pci;
639  }
640 
641  irq = dev->irq;
642  io = pci_resource_start(dev, 2);
643 
644  if (request_irq(irq, wdtpci_interrupt, IRQF_SHARED,
645  "wdt_pci", &wdtpci_miscdev)) {
646  pr_err("IRQ %d is not free\n", irq);
647  goto out_reg;
648  }
649 
650  pr_info("PCI-WDT500/501 (PCI-WDG-CSM) driver 0.10 at 0x%llx (Interrupt %d)\n",
651  (unsigned long long)io, irq);
652 
653  /* Check that the heartbeat value is within its range;
654  if not reset to the default */
655  if (wdtpci_set_heartbeat(heartbeat)) {
656  wdtpci_set_heartbeat(WD_TIMO);
657  pr_info("heartbeat value must be 0 < heartbeat < 65536, using %d\n",
658  WD_TIMO);
659  }
660 
661  ret = register_reboot_notifier(&wdtpci_notifier);
662  if (ret) {
663  pr_err("cannot register reboot notifier (err=%d)\n", ret);
664  goto out_irq;
665  }
666 
667  if (type == 501) {
668  ret = misc_register(&temp_miscdev);
669  if (ret) {
670  pr_err("cannot register miscdev on minor=%d (err=%d)\n",
671  TEMP_MINOR, ret);
672  goto out_rbt;
673  }
674  }
675 
676  ret = misc_register(&wdtpci_miscdev);
677  if (ret) {
678  pr_err("cannot register miscdev on minor=%d (err=%d)\n",
679  WATCHDOG_MINOR, ret);
680  goto out_misc;
681  }
682 
683  pr_info("initialized. heartbeat=%d sec (nowayout=%d)\n",
684  heartbeat, nowayout);
685  if (type == 501)
686  pr_info("Fan Tachometer is %s\n",
687  tachometer ? "Enabled" : "Disabled");
688 
689  ret = 0;
690 out:
691  return ret;
692 
693 out_misc:
694  if (type == 501)
695  misc_deregister(&temp_miscdev);
696 out_rbt:
697  unregister_reboot_notifier(&wdtpci_notifier);
698 out_irq:
699  free_irq(irq, &wdtpci_miscdev);
700 out_reg:
701  pci_release_region(dev, 2);
702 out_pci:
703  pci_disable_device(dev);
704  goto out;
705 }
706 
707 
708 static void __devexit wdtpci_remove_one(struct pci_dev *pdev)
709 {
710  /* here we assume only one device will ever have
711  * been picked up and registered by probe function */
712  misc_deregister(&wdtpci_miscdev);
713  if (type == 501)
714  misc_deregister(&temp_miscdev);
715  unregister_reboot_notifier(&wdtpci_notifier);
716  free_irq(irq, &wdtpci_miscdev);
717  pci_release_region(pdev, 2);
718  pci_disable_device(pdev);
719  dev_count--;
720 }
721 
722 
723 static DEFINE_PCI_DEVICE_TABLE(wdtpci_pci_tbl) = {
724  {
725  .vendor = PCI_VENDOR_ID_ACCESSIO,
727  .subvendor = PCI_ANY_ID,
728  .subdevice = PCI_ANY_ID,
729  },
730  { 0, }, /* terminate list */
731 };
732 MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl);
733 
734 
735 static struct pci_driver wdtpci_driver = {
736  .name = "wdt_pci",
737  .id_table = wdtpci_pci_tbl,
738  .probe = wdtpci_init_one,
739  .remove = __devexit_p(wdtpci_remove_one),
740 };
741 
742 module_pci_driver(wdtpci_driver);
743 
744 MODULE_AUTHOR("JP Nollmann, Alan Cox");
745 MODULE_DESCRIPTION("Driver for the ICS PCI-WDT500/501 watchdog cards");
746 MODULE_LICENSE("GPL");