Version:  2.0.40 2.2.26 2.4.37 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17

Linux/drivers/watchdog/wdt_pci.c

  1 /*
  2  *      Industrial Computer Source PCI-WDT500/501 driver
  3  *
  4  *      (c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
  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 <alan@lxorguk.ukuu.org.uk>
 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/fs.h>
 53 #include <linux/pci.h>
 54 #include <linux/io.h>
 55 #include <linux/uaccess.h>
 56 
 57 
 58 #define WDT_IS_PCI
 59 #include "wd501p.h"
 60 
 61 /* We can only use 1 card due to the /dev/watchdog restriction */
 62 static int dev_count;
 63 
 64 static unsigned long open_lock;
 65 static DEFINE_SPINLOCK(wdtpci_lock);
 66 static char expect_close;
 67 
 68 static resource_size_t io;
 69 static int irq;
 70 
 71 /* Default timeout */
 72 #define WD_TIMO 60                      /* Default heartbeat = 60 seconds */
 73 
 74 static int heartbeat = WD_TIMO;
 75 static int wd_heartbeat;
 76 module_param(heartbeat, int, 0);
 77 MODULE_PARM_DESC(heartbeat,
 78                 "Watchdog heartbeat in seconds. (0<heartbeat<65536, default="
 79                                 __MODULE_STRING(WD_TIMO) ")");
 80 
 81 static bool nowayout = WATCHDOG_NOWAYOUT;
 82 module_param(nowayout, bool, 0);
 83 MODULE_PARM_DESC(nowayout,
 84                 "Watchdog cannot be stopped once started (default="
 85                                 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 86 
 87 /* Support for the Fan Tachometer on the PCI-WDT501 */
 88 static int tachometer;
 89 module_param(tachometer, int, 0);
 90 MODULE_PARM_DESC(tachometer,
 91                 "PCI-WDT501 Fan Tachometer support (0=disable, default=0)");
 92 
 93 static int type = 500;
 94 module_param(type, int, 0);
 95 MODULE_PARM_DESC(type,
 96                 "PCI-WDT501 Card type (500 or 501 , default=500)");
 97 
 98 /*
 99  *      Programming support
100  */
101 
102 static void wdtpci_ctr_mode(int ctr, int mode)
103 {
104         ctr <<= 6;
105         ctr |= 0x30;
106         ctr |= (mode << 1);
107         outb(ctr, WDT_CR);
108         udelay(8);
109 }
110 
111 static void wdtpci_ctr_load(int ctr, int val)
112 {
113         outb(val & 0xFF, WDT_COUNT0 + ctr);
114         udelay(8);
115         outb(val >> 8, WDT_COUNT0 + ctr);
116         udelay(8);
117 }
118 
119 /**
120  *      wdtpci_start:
121  *
122  *      Start the watchdog driver.
123  */
124 
125 static int wdtpci_start(void)
126 {
127         unsigned long flags;
128 
129         spin_lock_irqsave(&wdtpci_lock, flags);
130 
131         /*
132          * "pet" the watchdog, as Access says.
133          * This resets the clock outputs.
134          */
135         inb(WDT_DC);                    /* Disable watchdog */
136         udelay(8);
137         wdtpci_ctr_mode(2, 0);          /* Program CTR2 for Mode 0:
138                                                 Pulse on Terminal Count */
139         outb(0, WDT_DC);                /* Enable watchdog */
140         udelay(8);
141         inb(WDT_DC);                    /* Disable watchdog */
142         udelay(8);
143         outb(0, WDT_CLOCK);             /* 2.0833MHz clock */
144         udelay(8);
145         inb(WDT_BUZZER);                /* disable */
146         udelay(8);
147         inb(WDT_OPTONOTRST);            /* disable */
148         udelay(8);
149         inb(WDT_OPTORST);               /* disable */
150         udelay(8);
151         inb(WDT_PROGOUT);               /* disable */
152         udelay(8);
153         wdtpci_ctr_mode(0, 3);          /* Program CTR0 for Mode 3:
154                                                 Square Wave Generator */
155         wdtpci_ctr_mode(1, 2);          /* Program CTR1 for Mode 2:
156                                                 Rate Generator */
157         wdtpci_ctr_mode(2, 1);          /* Program CTR2 for Mode 1:
158                                                 Retriggerable One-Shot */
159         wdtpci_ctr_load(0, 20833);      /* count at 100Hz */
160         wdtpci_ctr_load(1, wd_heartbeat);/* Heartbeat */
161         /* DO NOT LOAD CTR2 on PCI card! -- JPN */
162         outb(0, WDT_DC);                /* Enable watchdog */
163         udelay(8);
164 
165         spin_unlock_irqrestore(&wdtpci_lock, flags);
166         return 0;
167 }
168 
169 /**
170  *      wdtpci_stop:
171  *
172  *      Stop the watchdog driver.
173  */
174 
175 static int wdtpci_stop(void)
176 {
177         unsigned long flags;
178 
179         /* Turn the card off */
180         spin_lock_irqsave(&wdtpci_lock, flags);
181         inb(WDT_DC);                    /* Disable watchdog */
182         udelay(8);
183         wdtpci_ctr_load(2, 0);          /* 0 length reset pulses now */
184         spin_unlock_irqrestore(&wdtpci_lock, flags);
185         return 0;
186 }
187 
188 /**
189  *      wdtpci_ping:
190  *
191  *      Reload counter one with the watchdog heartbeat. We don't bother
192  *      reloading the cascade counter.
193  */
194 
195 static int wdtpci_ping(void)
196 {
197         unsigned long flags;
198 
199         spin_lock_irqsave(&wdtpci_lock, flags);
200         /* Write a watchdog value */
201         inb(WDT_DC);                    /* Disable watchdog */
202         udelay(8);
203         wdtpci_ctr_mode(1, 2);          /* Re-Program CTR1 for Mode 2:
204                                                         Rate Generator */
205         wdtpci_ctr_load(1, wd_heartbeat);/* Heartbeat */
206         outb(0, WDT_DC);                /* Enable watchdog */
207         udelay(8);
208         spin_unlock_irqrestore(&wdtpci_lock, flags);
209         return 0;
210 }
211 
212 /**
213  *      wdtpci_set_heartbeat:
214  *      @t:             the new heartbeat value that needs to be set.
215  *
216  *      Set a new heartbeat value for the watchdog device. If the heartbeat
217  *      value is incorrect we keep the old value and return -EINVAL.
218  *      If successful we return 0.
219  */
220 static int wdtpci_set_heartbeat(int t)
221 {
222         /* Arbitrary, can't find the card's limits */
223         if (t < 1 || t > 65535)
224                 return -EINVAL;
225 
226         heartbeat = t;
227         wd_heartbeat = t * 100;
228         return 0;
229 }
230 
231 /**
232  *      wdtpci_get_status:
233  *      @status:                the new status.
234  *
235  *      Extract the status information from a WDT watchdog device. There are
236  *      several board variants so we have to know which bits are valid. Some
237  *      bits default to one and some to zero in order to be maximally painful.
238  *
239  *      we then map the bits onto the status ioctl flags.
240  */
241 
242 static int wdtpci_get_status(int *status)
243 {
244         unsigned char new_status;
245         unsigned long flags;
246 
247         spin_lock_irqsave(&wdtpci_lock, flags);
248         new_status = inb(WDT_SR);
249         spin_unlock_irqrestore(&wdtpci_lock, flags);
250 
251         *status = 0;
252         if (new_status & WDC_SR_ISOI0)
253                 *status |= WDIOF_EXTERN1;
254         if (new_status & WDC_SR_ISII1)
255                 *status |= WDIOF_EXTERN2;
256         if (type == 501) {
257                 if (!(new_status & WDC_SR_TGOOD))
258                         *status |= WDIOF_OVERHEAT;
259                 if (!(new_status & WDC_SR_PSUOVER))
260                         *status |= WDIOF_POWEROVER;
261                 if (!(new_status & WDC_SR_PSUUNDR))
262                         *status |= WDIOF_POWERUNDER;
263                 if (tachometer) {
264                         if (!(new_status & WDC_SR_FANGOOD))
265                                 *status |= WDIOF_FANFAULT;
266                 }
267         }
268         return 0;
269 }
270 
271 /**
272  *      wdtpci_get_temperature:
273  *
274  *      Reports the temperature in degrees Fahrenheit. The API is in
275  *      farenheit. It was designed by an imperial measurement luddite.
276  */
277 
278 static int wdtpci_get_temperature(int *temperature)
279 {
280         unsigned short c;
281         unsigned long flags;
282         spin_lock_irqsave(&wdtpci_lock, flags);
283         c = inb(WDT_RT);
284         udelay(8);
285         spin_unlock_irqrestore(&wdtpci_lock, flags);
286         *temperature = (c * 11 / 15) + 7;
287         return 0;
288 }
289 
290 /**
291  *      wdtpci_interrupt:
292  *      @irq:           Interrupt number
293  *      @dev_id:        Unused as we don't allow multiple devices.
294  *
295  *      Handle an interrupt from the board. These are raised when the status
296  *      map changes in what the board considers an interesting way. That means
297  *      a failure condition occurring.
298  */
299 
300 static irqreturn_t wdtpci_interrupt(int irq, void *dev_id)
301 {
302         /*
303          *      Read the status register see what is up and
304          *      then printk it.
305          */
306         unsigned char status;
307 
308         spin_lock(&wdtpci_lock);
309 
310         status = inb(WDT_SR);
311         udelay(8);
312 
313         pr_crit("status %d\n", status);
314 
315         if (type == 501) {
316                 if (!(status & WDC_SR_TGOOD)) {
317                         pr_crit("Overheat alarm (%d)\n", inb(WDT_RT));
318                         udelay(8);
319                 }
320                 if (!(status & WDC_SR_PSUOVER))
321                         pr_crit("PSU over voltage\n");
322                 if (!(status & WDC_SR_PSUUNDR))
323                         pr_crit("PSU under voltage\n");
324                 if (tachometer) {
325                         if (!(status & WDC_SR_FANGOOD))
326                                 pr_crit("Possible fan fault\n");
327                 }
328         }
329         if (!(status & WDC_SR_WCCR)) {
330 #ifdef SOFTWARE_REBOOT
331 #ifdef ONLY_TESTING
332                 pr_crit("Would Reboot\n");
333 #else
334                 pr_crit("Initiating system reboot\n");
335                 emergency_restart(NULL);
336 #endif
337 #else
338                 pr_crit("Reset in 5ms\n");
339 #endif
340         }
341         spin_unlock(&wdtpci_lock);
342         return IRQ_HANDLED;
343 }
344 
345 
346 /**
347  *      wdtpci_write:
348  *      @file: file handle to the watchdog
349  *      @buf: buffer to write (unused as data does not matter here
350  *      @count: count of bytes
351  *      @ppos: pointer to the position to write. No seeks allowed
352  *
353  *      A write to a watchdog device is defined as a keepalive signal. Any
354  *      write of data will do, as we we don't define content meaning.
355  */
356 
357 static ssize_t wdtpci_write(struct file *file, const char __user *buf,
358                                                 size_t count, loff_t *ppos)
359 {
360         if (count) {
361                 if (!nowayout) {
362                         size_t i;
363 
364                         /* In case it was set long ago */
365                         expect_close = 0;
366 
367                         for (i = 0; i != count; i++) {
368                                 char c;
369                                 if (get_user(c, buf + i))
370                                         return -EFAULT;
371                                 if (c == 'V')
372                                         expect_close = 42;
373                         }
374                 }
375                 wdtpci_ping();
376         }
377         return count;
378 }
379 
380 /**
381  *      wdtpci_ioctl:
382  *      @file: file handle to the device
383  *      @cmd: watchdog command
384  *      @arg: argument pointer
385  *
386  *      The watchdog API defines a common set of functions for all watchdogs
387  *      according to their available features. We only actually usefully support
388  *      querying capabilities and current status.
389  */
390 
391 static long wdtpci_ioctl(struct file *file, unsigned int cmd,
392                                                         unsigned long arg)
393 {
394         void __user *argp = (void __user *)arg;
395         int __user *p = argp;
396         int new_heartbeat;
397         int status;
398 
399         struct watchdog_info ident = {
400                 .options =              WDIOF_SETTIMEOUT|
401                                         WDIOF_MAGICCLOSE|
402                                         WDIOF_KEEPALIVEPING,
403                 .firmware_version =     1,
404                 .identity =             "PCI-WDT500/501",
405         };
406 
407         /* Add options according to the card we have */
408         ident.options |= (WDIOF_EXTERN1|WDIOF_EXTERN2);
409         if (type == 501) {
410                 ident.options |= (WDIOF_OVERHEAT|WDIOF_POWERUNDER|
411                                                         WDIOF_POWEROVER);
412                 if (tachometer)
413                         ident.options |= WDIOF_FANFAULT;
414         }
415 
416         switch (cmd) {
417         case WDIOC_GETSUPPORT:
418                 return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
419         case WDIOC_GETSTATUS:
420                 wdtpci_get_status(&status);
421                 return put_user(status, p);
422         case WDIOC_GETBOOTSTATUS:
423                 return put_user(0, p);
424         case WDIOC_KEEPALIVE:
425                 wdtpci_ping();
426                 return 0;
427         case WDIOC_SETTIMEOUT:
428                 if (get_user(new_heartbeat, p))
429                         return -EFAULT;
430                 if (wdtpci_set_heartbeat(new_heartbeat))
431                         return -EINVAL;
432                 wdtpci_ping();
433                 /* Fall */
434         case WDIOC_GETTIMEOUT:
435                 return put_user(heartbeat, p);
436         default:
437                 return -ENOTTY;
438         }
439 }
440 
441 /**
442  *      wdtpci_open:
443  *      @inode: inode of device
444  *      @file: file handle to device
445  *
446  *      The watchdog device has been opened. The watchdog device is single
447  *      open and on opening we load the counters. Counter zero is a 100Hz
448  *      cascade, into counter 1 which downcounts to reboot. When the counter
449  *      triggers counter 2 downcounts the length of the reset pulse which
450  *      set set to be as long as possible.
451  */
452 
453 static int wdtpci_open(struct inode *inode, struct file *file)
454 {
455         if (test_and_set_bit(0, &open_lock))
456                 return -EBUSY;
457 
458         if (nowayout)
459                 __module_get(THIS_MODULE);
460         /*
461          *      Activate
462          */
463         wdtpci_start();
464         return nonseekable_open(inode, file);
465 }
466 
467 /**
468  *      wdtpci_release:
469  *      @inode: inode to board
470  *      @file: file handle to board
471  *
472  *      The watchdog has a configurable API. There is a religious dispute
473  *      between people who want their watchdog to be able to shut down and
474  *      those who want to be sure if the watchdog manager dies the machine
475  *      reboots. In the former case we disable the counters, in the latter
476  *      case you have to open it again very soon.
477  */
478 
479 static int wdtpci_release(struct inode *inode, struct file *file)
480 {
481         if (expect_close == 42) {
482                 wdtpci_stop();
483         } else {
484                 pr_crit("Unexpected close, not stopping timer!\n");
485                 wdtpci_ping();
486         }
487         expect_close = 0;
488         clear_bit(0, &open_lock);
489         return 0;
490 }
491 
492 /**
493  *      wdtpci_temp_read:
494  *      @file: file handle to the watchdog board
495  *      @buf: buffer to write 1 byte into
496  *      @count: length of buffer
497  *      @ptr: offset (no seek allowed)
498  *
499  *      Read reports the temperature in degrees Fahrenheit. The API is in
500  *      fahrenheit. It was designed by an imperial measurement luddite.
501  */
502 
503 static ssize_t wdtpci_temp_read(struct file *file, char __user *buf,
504                                                 size_t count, loff_t *ptr)
505 {
506         int temperature;
507 
508         if (wdtpci_get_temperature(&temperature))
509                 return -EFAULT;
510 
511         if (copy_to_user(buf, &temperature, 1))
512                 return -EFAULT;
513 
514         return 1;
515 }
516 
517 /**
518  *      wdtpci_temp_open:
519  *      @inode: inode of device
520  *      @file: file handle to device
521  *
522  *      The temperature device has been opened.
523  */
524 
525 static int wdtpci_temp_open(struct inode *inode, struct file *file)
526 {
527         return nonseekable_open(inode, file);
528 }
529 
530 /**
531  *      wdtpci_temp_release:
532  *      @inode: inode to board
533  *      @file: file handle to board
534  *
535  *      The temperature device has been closed.
536  */
537 
538 static int wdtpci_temp_release(struct inode *inode, struct file *file)
539 {
540         return 0;
541 }
542 
543 /**
544  *      notify_sys:
545  *      @this: our notifier block
546  *      @code: the event being reported
547  *      @unused: unused
548  *
549  *      Our notifier is called on system shutdowns. We want to turn the card
550  *      off at reboot otherwise the machine will reboot again during memory
551  *      test or worse yet during the following fsck. This would suck, in fact
552  *      trust me - if it happens it does suck.
553  */
554 
555 static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code,
556                                                         void *unused)
557 {
558         if (code == SYS_DOWN || code == SYS_HALT)
559                 wdtpci_stop();
560         return NOTIFY_DONE;
561 }
562 
563 /*
564  *      Kernel Interfaces
565  */
566 
567 
568 static const struct file_operations wdtpci_fops = {
569         .owner          = THIS_MODULE,
570         .llseek         = no_llseek,
571         .write          = wdtpci_write,
572         .unlocked_ioctl = wdtpci_ioctl,
573         .open           = wdtpci_open,
574         .release        = wdtpci_release,
575 };
576 
577 static struct miscdevice wdtpci_miscdev = {
578         .minor  = WATCHDOG_MINOR,
579         .name   = "watchdog",
580         .fops   = &wdtpci_fops,
581 };
582 
583 static const struct file_operations wdtpci_temp_fops = {
584         .owner          = THIS_MODULE,
585         .llseek         = no_llseek,
586         .read           = wdtpci_temp_read,
587         .open           = wdtpci_temp_open,
588         .release        = wdtpci_temp_release,
589 };
590 
591 static struct miscdevice temp_miscdev = {
592         .minor  = TEMP_MINOR,
593         .name   = "temperature",
594         .fops   = &wdtpci_temp_fops,
595 };
596 
597 /*
598  *      The WDT card needs to learn about soft shutdowns in order to
599  *      turn the timebomb registers off.
600  */
601 
602 static struct notifier_block wdtpci_notifier = {
603         .notifier_call = wdtpci_notify_sys,
604 };
605 
606 
607 static int wdtpci_init_one(struct pci_dev *dev,
608                                         const struct pci_device_id *ent)
609 {
610         int ret = -EIO;
611 
612         dev_count++;
613         if (dev_count > 1) {
614                 pr_err("This driver only supports one device\n");
615                 return -ENODEV;
616         }
617 
618         if (type != 500 && type != 501) {
619                 pr_err("unknown card type '%d'\n", type);
620                 return -ENODEV;
621         }
622 
623         if (pci_enable_device(dev)) {
624                 pr_err("Not possible to enable PCI Device\n");
625                 return -ENODEV;
626         }
627 
628         if (pci_resource_start(dev, 2) == 0x0000) {
629                 pr_err("No I/O-Address for card detected\n");
630                 ret = -ENODEV;
631                 goto out_pci;
632         }
633 
634         if (pci_request_region(dev, 2, "wdt_pci")) {
635                 pr_err("I/O address 0x%llx already in use\n",
636                        (unsigned long long)pci_resource_start(dev, 2));
637                 goto out_pci;
638         }
639 
640         irq = dev->irq;
641         io = pci_resource_start(dev, 2);
642 
643         if (request_irq(irq, wdtpci_interrupt, IRQF_SHARED,
644                          "wdt_pci", &wdtpci_miscdev)) {
645                 pr_err("IRQ %d is not free\n", irq);
646                 goto out_reg;
647         }
648 
649         pr_info("PCI-WDT500/501 (PCI-WDG-CSM) driver 0.10 at 0x%llx (Interrupt %d)\n",
650                 (unsigned long long)io, irq);
651 
652         /* Check that the heartbeat value is within its range;
653            if not reset to the default */
654         if (wdtpci_set_heartbeat(heartbeat)) {
655                 wdtpci_set_heartbeat(WD_TIMO);
656                 pr_info("heartbeat value must be 0 < heartbeat < 65536, using %d\n",
657                         WD_TIMO);
658         }
659 
660         ret = register_reboot_notifier(&wdtpci_notifier);
661         if (ret) {
662                 pr_err("cannot register reboot notifier (err=%d)\n", ret);
663                 goto out_irq;
664         }
665 
666         if (type == 501) {
667                 ret = misc_register(&temp_miscdev);
668                 if (ret) {
669                         pr_err("cannot register miscdev on minor=%d (err=%d)\n",
670                                TEMP_MINOR, ret);
671                         goto out_rbt;
672                 }
673         }
674 
675         ret = misc_register(&wdtpci_miscdev);
676         if (ret) {
677                 pr_err("cannot register miscdev on minor=%d (err=%d)\n",
678                        WATCHDOG_MINOR, ret);
679                 goto out_misc;
680         }
681 
682         pr_info("initialized. heartbeat=%d sec (nowayout=%d)\n",
683                 heartbeat, nowayout);
684         if (type == 501)
685                 pr_info("Fan Tachometer is %s\n",
686                         tachometer ? "Enabled" : "Disabled");
687 
688         ret = 0;
689 out:
690         return ret;
691 
692 out_misc:
693         if (type == 501)
694                 misc_deregister(&temp_miscdev);
695 out_rbt:
696         unregister_reboot_notifier(&wdtpci_notifier);
697 out_irq:
698         free_irq(irq, &wdtpci_miscdev);
699 out_reg:
700         pci_release_region(dev, 2);
701 out_pci:
702         pci_disable_device(dev);
703         goto out;
704 }
705 
706 
707 static void wdtpci_remove_one(struct pci_dev *pdev)
708 {
709         /* here we assume only one device will ever have
710          * been picked up and registered by probe function */
711         misc_deregister(&wdtpci_miscdev);
712         if (type == 501)
713                 misc_deregister(&temp_miscdev);
714         unregister_reboot_notifier(&wdtpci_notifier);
715         free_irq(irq, &wdtpci_miscdev);
716         pci_release_region(pdev, 2);
717         pci_disable_device(pdev);
718         dev_count--;
719 }
720 
721 
722 static const struct pci_device_id wdtpci_pci_tbl[] = {
723         {
724                 .vendor    = PCI_VENDOR_ID_ACCESSIO,
725                 .device    = PCI_DEVICE_ID_ACCESSIO_WDG_CSM,
726                 .subvendor = PCI_ANY_ID,
727                 .subdevice = PCI_ANY_ID,
728         },
729         { 0, }, /* terminate list */
730 };
731 MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl);
732 
733 
734 static struct pci_driver wdtpci_driver = {
735         .name           = "wdt_pci",
736         .id_table       = wdtpci_pci_tbl,
737         .probe          = wdtpci_init_one,
738         .remove         = wdtpci_remove_one,
739 };
740 
741 module_pci_driver(wdtpci_driver);
742 
743 MODULE_AUTHOR("JP Nollmann, Alan Cox");
744 MODULE_DESCRIPTION("Driver for the ICS PCI-WDT500/501 watchdog cards");
745 MODULE_LICENSE("GPL");
746 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us