Loading drivers/watchdog/wdt.c +94 −82 Original line number Diff line number Diff line Loading @@ -24,9 +24,10 @@ * Matt Crocker). * Alan Cox : Added wdt= boot option * Alan Cox : Cleaned up copy/user stuff * Tim Hockin : Added insmod parameters, comment cleanup * Parameterized timeout * Tigran Aivazian : Restructured wdt_init() to handle failures * Tim Hockin : Added insmod parameters, comment * cleanup, parameterized timeout * Tigran Aivazian : Restructured wdt_init() to handle * failures * Joel Becker : Added WDIOC_GET/SETTIMEOUT * Matt Domsch : Added nowayout module option */ Loading @@ -42,9 +43,9 @@ #include <linux/notifier.h> #include <linux/reboot.h> #include <linux/init.h> #include <linux/io.h> #include <linux/uaccess.h> #include <asm/io.h> #include <asm/uaccess.h> #include <asm/system.h> #include "wd501p.h" Loading @@ -60,11 +61,15 @@ static char expect_close; static int heartbeat = WD_TIMO; static int wd_heartbeat; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")"); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0 < heartbeat < 65536, default=" __MODULE_STRING(WD_TIMO) ")"); static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); /* You must set these - there is no sane way to probe for this board. */ static int io = 0x240; Loading @@ -82,7 +87,8 @@ MODULE_PARM_DESC(irq, "WDT irq (default=11)"); static int tachometer; module_param(tachometer, int, 0); MODULE_PARM_DESC(tachometer, "WDT501-P Fan Tachometer support (0=disable, default=0)"); MODULE_PARM_DESC(tachometer, "WDT501-P Fan Tachometer support (0=disable, default=0)"); #endif /* CONFIG_WDT_501 */ /* Loading Loading @@ -114,9 +120,12 @@ static int wdt_start(void) unsigned long flags; spin_lock_irqsave(&wdt_lock, flags); inb_p(WDT_DC); /* Disable watchdog */ wdt_ctr_mode(0,3); /* Program CTR0 for Mode 3: Square Wave Generator */ wdt_ctr_mode(1,2); /* Program CTR1 for Mode 2: Rate Generator */ wdt_ctr_mode(2,0); /* Program CTR2 for Mode 0: Pulse on Terminal Count */ wdt_ctr_mode(0, 3); /* Program CTR0 for Mode 3: Square Wave Generator */ wdt_ctr_mode(1, 2); /* Program CTR1 for Mode 2: Rate Generator */ wdt_ctr_mode(2, 0); /* Program CTR2 for Mode 0: Pulse on Terminal Count */ wdt_ctr_load(0, 8948); /* Count at 100Hz */ wdt_ctr_load(1, wd_heartbeat); /* Heartbeat */ wdt_ctr_load(2, 65535); /* Length of reset pulse */ Loading Loading @@ -145,8 +154,8 @@ static int wdt_stop (void) /** * wdt_ping: * * Reload counter one with the watchdog heartbeat. We don't bother reloading * the cascade counter. * Reload counter one with the watchdog heartbeat. We don't bother * reloading the cascade counter. */ static int wdt_ping(void) Loading @@ -155,7 +164,8 @@ static int wdt_ping(void) spin_lock_irqsave(&wdt_lock, flags); /* Write a watchdog value */ inb_p(WDT_DC); /* Disable watchdog */ wdt_ctr_mode(1,2); /* Re-Program CTR1 for Mode 2: Rate Generator */ wdt_ctr_mode(1, 2); /* Re-Program CTR1 for Mode 2: Rate Generator */ wdt_ctr_load(1, wd_heartbeat); /* Heartbeat */ outb_p(0, WDT_DC); /* Enable watchdog */ spin_unlock_irqrestore(&wdt_lock, flags); Loading @@ -166,13 +176,14 @@ static int wdt_ping(void) * wdt_set_heartbeat: * @t: the new heartbeat value that needs to be set. * * Set a new heartbeat value for the watchdog device. If the heartbeat value is * incorrect we keep the old value and return -EINVAL. If successfull we * return 0. * Set a new heartbeat value for the watchdog device. If the heartbeat * value is incorrect we keep the old value and return -EINVAL. If * successful we return 0. */ static int wdt_set_heartbeat(int t) { if ((t < 1) || (t > 65535)) if (t < 1 || t > 65535) return -EINVAL; heartbeat = t; Loading Loading @@ -304,7 +315,8 @@ static irqreturn_t wdt_interrupt(int irq, void *dev_id) * write of data will do, as we we don't define content meaning. */ static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { if (count) { if (!nowayout) { Loading @@ -328,7 +340,6 @@ static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count /** * wdt_ioctl: * @inode: inode of the device * @file: file handle to the device * @cmd: watchdog command * @arg: argument pointer Loading @@ -338,8 +349,7 @@ static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count * querying capabilities and current status. */ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; Loading @@ -362,13 +372,11 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ident.options |= WDIOF_FANFAULT; #endif /* CONFIG_WDT_501 */ switch(cmd) { switch (cmd) { default: return -ENOTTY; case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: wdt_get_status(&status); return put_user(status, p); Loading @@ -380,10 +388,8 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, case WDIOC_SETTIMEOUT: if (get_user(new_heartbeat, p)) return -EFAULT; if (wdt_set_heartbeat(new_heartbeat)) return -EINVAL; wdt_ping(); /* Fall */ case WDIOC_GETTIMEOUT: Loading Loading @@ -432,7 +438,8 @@ static int wdt_release(struct inode *inode, struct file *file) wdt_stop(); clear_bit(0, &wdt_is_open); } else { printk(KERN_CRIT "wdt: WDT device closed unexpectedly. WDT will not stop!\n"); printk(KERN_CRIT "wdt: WDT device closed unexpectedly. WDT will not stop!\n"); wdt_ping(); } expect_close = 0; Loading @@ -451,7 +458,8 @@ static int wdt_release(struct inode *inode, struct file *file) * farenheit. It was designed by an imperial measurement luddite. */ static ssize_t wdt_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) static ssize_t wdt_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) { int temperature; Loading Loading @@ -506,10 +514,8 @@ static int wdt_temp_release(struct inode *inode, struct file *file) static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if(code==SYS_DOWN || code==SYS_HALT) { /* Turn the card off */ if (code == SYS_DOWN || code == SYS_HALT) wdt_stop(); } return NOTIFY_DONE; } Loading @@ -522,7 +528,7 @@ static const struct file_operations wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = wdt_write, .ioctl = wdt_ioctl, .unlocked_ioctl = wdt_ioctl, .open = wdt_open, .release = wdt_release, }; Loading Loading @@ -591,7 +597,8 @@ static int __init wdt_init(void) { int ret; /* Check that the heartbeat value is within it's range ; if not reset to the default */ /* Check that the heartbeat value is within it's range; if not reset to the default */ if (wdt_set_heartbeat(heartbeat)) { wdt_set_heartbeat(WD_TIMO); printk(KERN_INFO "wdt: heartbeat value must be 0 < heartbeat < 65536, using %d\n", Loading @@ -599,7 +606,8 @@ static int __init wdt_init(void) } if (!request_region(io, 8, "wdt501p")) { printk(KERN_ERR "wdt: I/O address 0x%04x already in use\n", io); printk(KERN_ERR "wdt: I/O address 0x%04x already in use\n", io); ret = -EBUSY; goto out; } Loading @@ -612,14 +620,16 @@ static int __init wdt_init(void) ret = register_reboot_notifier(&wdt_notifier); if (ret) { printk(KERN_ERR "wdt: cannot register reboot notifier (err=%d)\n", ret); printk(KERN_ERR "wdt: cannot register reboot notifier (err=%d)\n", ret); goto outirq; } #ifdef CONFIG_WDT_501 ret = misc_register(&temp_miscdev); if (ret) { printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n", printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n", TEMP_MINOR, ret); goto outrbt; } Loading @@ -627,7 +637,8 @@ static int __init wdt_init(void) ret = misc_register(&wdt_miscdev); if (ret) { printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n", printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); goto outmisc; } Loading @@ -636,7 +647,8 @@ static int __init wdt_init(void) printk(KERN_INFO "WDT500/501-P driver 0.10 at 0x%04x (Interrupt %d). heartbeat=%d sec (nowayout=%d)\n", io, irq, heartbeat, nowayout); #ifdef CONFIG_WDT_501 printk(KERN_INFO "wdt: Fan Tachometer is %s\n", (tachometer ? "Enabled" : "Disabled")); printk(KERN_INFO "wdt: Fan Tachometer is %s\n", (tachometer ? "Enabled" : "Disabled")); #endif /* CONFIG_WDT_501 */ out: Loading drivers/watchdog/wdt_pci.c +171 −129 Original line number Diff line number Diff line Loading @@ -29,9 +29,11 @@ * JP Nollmann : Added support for PCI wdt501p * Alan Cox : Split ISA and PCI cards into two drivers * Jeff Garzik : PCI cleanups * Tigran Aivazian : Restructured wdtpci_init_one() to handle failures * Tigran Aivazian : Restructured wdtpci_init_one() to handle * failures * Joel Becker : Added WDIOC_GET/SETTIMEOUT * Zwane Mwaikambo : Magic char closing, locking changes, cleanups * Zwane Mwaikambo : Magic char closing, locking changes, * cleanups * Matt Domsch : nowayout module option */ Loading @@ -47,9 +49,9 @@ #include <linux/init.h> #include <linux/fs.h> #include <linux/pci.h> #include <linux/io.h> #include <linux/uaccess.h> #include <asm/io.h> #include <asm/uaccess.h> #include <asm/system.h> #define WDT_IS_PCI Loading @@ -73,7 +75,7 @@ /* We can only use 1 card due to the /dev/watchdog restriction */ static int dev_count; static struct semaphore open_sem; static unsigned long open_lock; static DEFINE_SPINLOCK(wdtpci_lock); static char expect_close; Loading @@ -86,18 +88,23 @@ static int irq; static int heartbeat = WD_TIMO; static int wd_heartbeat; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")"); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")"); static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); #ifdef CONFIG_WDT_501_PCI /* Support for the Fan Tachometer on the PCI-WDT501 */ static int tachometer; module_param(tachometer, int, 0); MODULE_PARM_DESC(tachometer, "PCI-WDT501 Fan Tachometer support (0=disable, default=0)"); MODULE_PARM_DESC(tachometer, "PCI-WDT501 Fan Tachometer support (0=disable, default=0)"); #endif /* CONFIG_WDT_501_PCI */ /* Loading @@ -109,13 +116,16 @@ static void wdtpci_ctr_mode(int ctr, int mode) ctr <<= 6; ctr |= 0x30; ctr |= (mode << 1); outb_p(ctr, WDT_CR); outb(ctr, WDT_CR); udelay(8); } static void wdtpci_ctr_load(int ctr, int val) { outb_p(val&0xFF, WDT_COUNT0+ctr); outb_p(val>>8, WDT_COUNT0+ctr); outb(val & 0xFF, WDT_COUNT0 + ctr); udelay(8); outb(val >> 8, WDT_COUNT0 + ctr); udelay(8); } /** Loading @@ -134,23 +144,35 @@ static int wdtpci_start(void) * "pet" the watchdog, as Access says. * This resets the clock outputs. */ inb_p(WDT_DC); /* Disable watchdog */ wdtpci_ctr_mode(2,0); /* Program CTR2 for Mode 0: Pulse on Terminal Count */ outb_p(0, WDT_DC); /* Enable watchdog */ inb_p(WDT_DC); /* Disable watchdog */ outb_p(0, WDT_CLOCK); /* 2.0833MHz clock */ inb_p(WDT_BUZZER); /* disable */ inb_p(WDT_OPTONOTRST); /* disable */ inb_p(WDT_OPTORST); /* disable */ inb_p(WDT_PROGOUT); /* disable */ wdtpci_ctr_mode(0,3); /* Program CTR0 for Mode 3: Square Wave Generator */ wdtpci_ctr_mode(1,2); /* Program CTR1 for Mode 2: Rate Generator */ wdtpci_ctr_mode(2,1); /* Program CTR2 for Mode 1: Retriggerable One-Shot */ inb(WDT_DC); /* Disable watchdog */ udelay(8); wdtpci_ctr_mode(2, 0); /* Program CTR2 for Mode 0: Pulse on Terminal Count */ outb(0, WDT_DC); /* Enable watchdog */ udelay(8); inb(WDT_DC); /* Disable watchdog */ udelay(8); outb(0, WDT_CLOCK); /* 2.0833MHz clock */ udelay(8); inb(WDT_BUZZER); /* disable */ udelay(8); inb(WDT_OPTONOTRST); /* disable */ udelay(8); inb(WDT_OPTORST); /* disable */ udelay(8); inb(WDT_PROGOUT); /* disable */ udelay(8); wdtpci_ctr_mode(0, 3); /* Program CTR0 for Mode 3: Square Wave Generator */ wdtpci_ctr_mode(1, 2); /* Program CTR1 for Mode 2: Rate Generator */ wdtpci_ctr_mode(2, 1); /* Program CTR2 for Mode 1: Retriggerable One-Shot */ wdtpci_ctr_load(0, 20833); /* count at 100Hz */ wdtpci_ctr_load(1, wd_heartbeat);/* Heartbeat */ /* DO NOT LOAD CTR2 on PCI card! -- JPN */ outb_p(0, WDT_DC); /* Enable watchdog */ outb(0, WDT_DC); /* Enable watchdog */ udelay(8); spin_unlock_irqrestore(&wdtpci_lock, flags); return 0; Loading @@ -168,7 +190,8 @@ static int wdtpci_stop (void) /* Turn the card off */ spin_lock_irqsave(&wdtpci_lock, flags); inb_p(WDT_DC); /* Disable watchdog */ inb(WDT_DC); /* Disable watchdog */ udelay(8); wdtpci_ctr_load(2, 0); /* 0 length reset pulses now */ spin_unlock_irqrestore(&wdtpci_lock, flags); return 0; Loading @@ -177,20 +200,23 @@ static int wdtpci_stop (void) /** * wdtpci_ping: * * Reload counter one with the watchdog heartbeat. We don't bother reloading * the cascade counter. * Reload counter one with the watchdog heartbeat. We don't bother * reloading the cascade counter. */ static int wdtpci_ping(void) { unsigned long flags; /* Write a watchdog value */ spin_lock_irqsave(&wdtpci_lock, flags); inb_p(WDT_DC); /* Disable watchdog */ wdtpci_ctr_mode(1,2); /* Re-Program CTR1 for Mode 2: Rate Generator */ /* Write a watchdog value */ inb(WDT_DC); /* Disable watchdog */ udelay(8); wdtpci_ctr_mode(1, 2); /* Re-Program CTR1 for Mode 2: Rate Generator */ wdtpci_ctr_load(1, wd_heartbeat);/* Heartbeat */ outb_p(0, WDT_DC); /* Enable watchdog */ outb(0, WDT_DC); /* Enable watchdog */ udelay(8); spin_unlock_irqrestore(&wdtpci_lock, flags); return 0; } Loading @@ -199,14 +225,14 @@ static int wdtpci_ping(void) * wdtpci_set_heartbeat: * @t: the new heartbeat value that needs to be set. * * Set a new heartbeat value for the watchdog device. If the heartbeat value is * incorrect we keep the old value and return -EINVAL. If successfull we * return 0. * Set a new heartbeat value for the watchdog device. If the heartbeat * value is incorrect we keep the old value and return -EINVAL. * If successful we return 0. */ static int wdtpci_set_heartbeat(int t) { /* Arbitrary, can't find the card's limits */ if ((t < 1) || (t > 65535)) if (t < 1 || t > 65535) return -EINVAL; heartbeat = t; Loading @@ -227,7 +253,12 @@ static int wdtpci_set_heartbeat(int t) static int wdtpci_get_status(int *status) { unsigned char new_status=inb_p(WDT_SR); unsigned char new_status; unsigned long flags; spin_lock_irqsave(&wdtpci_lock, flags); new_status = inb(WDT_SR); spin_unlock_irqrestore(&wdtpci_lock, flags); *status = 0; if (new_status & WDC_SR_ISOI0) Loading Loading @@ -259,8 +290,12 @@ static int wdtpci_get_status(int *status) static int wdtpci_get_temperature(int *temperature) { unsigned short c=inb_p(WDT_RT); unsigned short c; unsigned long flags; spin_lock_irqsave(&wdtpci_lock, flags); c = inb(WDT_RT); udelay(8); spin_unlock_irqrestore(&wdtpci_lock, flags); *temperature = (c * 11 / 15) + 7; return 0; } Loading @@ -282,13 +317,21 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id) * Read the status register see what is up and * then printk it. */ unsigned char status=inb_p(WDT_SR); unsigned char status; spin_lock(&wdtpci_lock); status = inb(WDT_SR); udelay(8); printk(KERN_CRIT PFX "status %d\n", status); #ifdef CONFIG_WDT_501_PCI if (!(status & WDC_SR_TGOOD)) printk(KERN_CRIT PFX "Overheat alarm.(%d)\n",inb_p(WDT_RT)); if (!(status & WDC_SR_TGOOD)) { u8 alarm = inb(WDT_RT); printk(KERN_CRIT PFX "Overheat alarm.(%d)\n", alarm); udelay(8); } if (!(status & WDC_SR_PSUOVER)) printk(KERN_CRIT PFX "PSU over voltage.\n"); if (!(status & WDC_SR_PSUUNDR)) Loading @@ -310,6 +353,7 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id) printk(KERN_CRIT PFX "Reset in 5ms.\n"); #endif } spin_unlock(&wdtpci_lock); return IRQ_HANDLED; } Loading @@ -325,7 +369,8 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id) * write of data will do, as we we don't define content meaning. */ static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { if (count) { if (!nowayout) { Loading @@ -343,13 +388,11 @@ static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t co } wdtpci_ping(); } return count; } /** * wdtpci_ioctl: * @inode: inode of the device * @file: file handle to the device * @cmd: watchdog command * @arg: argument pointer Loading @@ -359,7 +402,7 @@ static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t co * querying capabilities and current status. */ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd, static long wdtpci_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int new_heartbeat; Loading @@ -383,13 +426,11 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd ident.options |= WDIOF_FANFAULT; #endif /* CONFIG_WDT_501_PCI */ switch(cmd) { switch (cmd) { default: return -ENOTTY; case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: wdtpci_get_status(&status); return put_user(status, p); Loading @@ -401,10 +442,8 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd case WDIOC_SETTIMEOUT: if (get_user(new_heartbeat, p)) return -EFAULT; if (wdtpci_set_heartbeat(new_heartbeat)) return -EINVAL; wdtpci_ping(); /* Fall */ case WDIOC_GETTIMEOUT: Loading @@ -426,12 +465,11 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd static int wdtpci_open(struct inode *inode, struct file *file) { if (down_trylock(&open_sem)) if (test_and_set_bit(0, &open_lock)) return -EBUSY; if (nowayout) { if (nowayout) __module_get(THIS_MODULE); } /* * Activate */ Loading Loading @@ -460,7 +498,7 @@ static int wdtpci_release(struct inode *inode, struct file *file) wdtpci_ping(); } expect_close = 0; up(&open_sem); clear_bit(0, &open_lock); return 0; } Loading @@ -476,7 +514,8 @@ static int wdtpci_release(struct inode *inode, struct file *file) * fahrenheit. It was designed by an imperial measurement luddite. */ static ssize_t wdtpci_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) static ssize_t wdtpci_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) { int temperature; Loading Loading @@ -531,10 +570,8 @@ static int wdtpci_temp_release(struct inode *inode, struct file *file) static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code==SYS_DOWN || code==SYS_HALT) { /* Turn the card off */ if (code == SYS_DOWN || code == SYS_HALT) wdtpci_stop(); } return NOTIFY_DONE; } Loading @@ -547,7 +584,7 @@ static const struct file_operations wdtpci_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = wdtpci_write, .ioctl = wdtpci_ioctl, .unlocked_ioctl = wdtpci_ioctl, .open = wdtpci_open, .release = wdtpci_release, }; Loading Loading @@ -591,7 +628,7 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev, dev_count++; if (dev_count > 1) { printk (KERN_ERR PFX "this driver only supports 1 device\n"); printk(KERN_ERR PFX "This driver only supports one device\n"); return -ENODEV; } Loading @@ -606,8 +643,6 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev, goto out_pci; } sema_init(&open_sem, 1); irq = dev->irq; io = pci_resource_start(dev, 2); Loading @@ -622,26 +657,31 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev, goto out_reg; } printk ("PCI-WDT500/501 (PCI-WDG-CSM) driver 0.10 at 0x%04x (Interrupt %d)\n", printk(KERN_INFO "PCI-WDT500/501 (PCI-WDG-CSM) driver 0.10 at 0x%04x (Interrupt %d)\n", io, irq); /* Check that the heartbeat value is within it's range ; if not reset to the default */ /* Check that the heartbeat value is within its range; if not reset to the default */ if (wdtpci_set_heartbeat(heartbeat)) { wdtpci_set_heartbeat(WD_TIMO); printk(KERN_INFO PFX "heartbeat value must be 0<heartbeat<65536, using %d\n", printk(KERN_INFO PFX "heartbeat value must be 0 < heartbeat < 65536, using %d\n", WD_TIMO); } ret = register_reboot_notifier(&wdtpci_notifier); if (ret) { printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); goto out_irq; } #ifdef CONFIG_WDT_501_PCI ret = misc_register(&temp_miscdev); if (ret) { printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", TEMP_MINOR, ret); goto out_rbt; } Loading @@ -649,7 +689,8 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev, ret = misc_register(&wdtpci_miscdev); if (ret) { printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); goto out_misc; } Loading @@ -657,7 +698,8 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev, printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", heartbeat, nowayout); #ifdef CONFIG_WDT_501_PCI printk(KERN_INFO "wdt: Fan Tachometer is %s\n", (tachometer ? "Enabled" : "Disabled")); printk(KERN_INFO "wdt: Fan Tachometer is %s\n", (tachometer ? "Enabled" : "Disabled")); #endif /* CONFIG_WDT_501_PCI */ ret = 0; Loading Loading
drivers/watchdog/wdt.c +94 −82 Original line number Diff line number Diff line Loading @@ -24,9 +24,10 @@ * Matt Crocker). * Alan Cox : Added wdt= boot option * Alan Cox : Cleaned up copy/user stuff * Tim Hockin : Added insmod parameters, comment cleanup * Parameterized timeout * Tigran Aivazian : Restructured wdt_init() to handle failures * Tim Hockin : Added insmod parameters, comment * cleanup, parameterized timeout * Tigran Aivazian : Restructured wdt_init() to handle * failures * Joel Becker : Added WDIOC_GET/SETTIMEOUT * Matt Domsch : Added nowayout module option */ Loading @@ -42,9 +43,9 @@ #include <linux/notifier.h> #include <linux/reboot.h> #include <linux/init.h> #include <linux/io.h> #include <linux/uaccess.h> #include <asm/io.h> #include <asm/uaccess.h> #include <asm/system.h> #include "wd501p.h" Loading @@ -60,11 +61,15 @@ static char expect_close; static int heartbeat = WD_TIMO; static int wd_heartbeat; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")"); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0 < heartbeat < 65536, default=" __MODULE_STRING(WD_TIMO) ")"); static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); /* You must set these - there is no sane way to probe for this board. */ static int io = 0x240; Loading @@ -82,7 +87,8 @@ MODULE_PARM_DESC(irq, "WDT irq (default=11)"); static int tachometer; module_param(tachometer, int, 0); MODULE_PARM_DESC(tachometer, "WDT501-P Fan Tachometer support (0=disable, default=0)"); MODULE_PARM_DESC(tachometer, "WDT501-P Fan Tachometer support (0=disable, default=0)"); #endif /* CONFIG_WDT_501 */ /* Loading Loading @@ -114,9 +120,12 @@ static int wdt_start(void) unsigned long flags; spin_lock_irqsave(&wdt_lock, flags); inb_p(WDT_DC); /* Disable watchdog */ wdt_ctr_mode(0,3); /* Program CTR0 for Mode 3: Square Wave Generator */ wdt_ctr_mode(1,2); /* Program CTR1 for Mode 2: Rate Generator */ wdt_ctr_mode(2,0); /* Program CTR2 for Mode 0: Pulse on Terminal Count */ wdt_ctr_mode(0, 3); /* Program CTR0 for Mode 3: Square Wave Generator */ wdt_ctr_mode(1, 2); /* Program CTR1 for Mode 2: Rate Generator */ wdt_ctr_mode(2, 0); /* Program CTR2 for Mode 0: Pulse on Terminal Count */ wdt_ctr_load(0, 8948); /* Count at 100Hz */ wdt_ctr_load(1, wd_heartbeat); /* Heartbeat */ wdt_ctr_load(2, 65535); /* Length of reset pulse */ Loading Loading @@ -145,8 +154,8 @@ static int wdt_stop (void) /** * wdt_ping: * * Reload counter one with the watchdog heartbeat. We don't bother reloading * the cascade counter. * Reload counter one with the watchdog heartbeat. We don't bother * reloading the cascade counter. */ static int wdt_ping(void) Loading @@ -155,7 +164,8 @@ static int wdt_ping(void) spin_lock_irqsave(&wdt_lock, flags); /* Write a watchdog value */ inb_p(WDT_DC); /* Disable watchdog */ wdt_ctr_mode(1,2); /* Re-Program CTR1 for Mode 2: Rate Generator */ wdt_ctr_mode(1, 2); /* Re-Program CTR1 for Mode 2: Rate Generator */ wdt_ctr_load(1, wd_heartbeat); /* Heartbeat */ outb_p(0, WDT_DC); /* Enable watchdog */ spin_unlock_irqrestore(&wdt_lock, flags); Loading @@ -166,13 +176,14 @@ static int wdt_ping(void) * wdt_set_heartbeat: * @t: the new heartbeat value that needs to be set. * * Set a new heartbeat value for the watchdog device. If the heartbeat value is * incorrect we keep the old value and return -EINVAL. If successfull we * return 0. * Set a new heartbeat value for the watchdog device. If the heartbeat * value is incorrect we keep the old value and return -EINVAL. If * successful we return 0. */ static int wdt_set_heartbeat(int t) { if ((t < 1) || (t > 65535)) if (t < 1 || t > 65535) return -EINVAL; heartbeat = t; Loading Loading @@ -304,7 +315,8 @@ static irqreturn_t wdt_interrupt(int irq, void *dev_id) * write of data will do, as we we don't define content meaning. */ static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { if (count) { if (!nowayout) { Loading @@ -328,7 +340,6 @@ static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count /** * wdt_ioctl: * @inode: inode of the device * @file: file handle to the device * @cmd: watchdog command * @arg: argument pointer Loading @@ -338,8 +349,7 @@ static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count * querying capabilities and current status. */ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; Loading @@ -362,13 +372,11 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ident.options |= WDIOF_FANFAULT; #endif /* CONFIG_WDT_501 */ switch(cmd) { switch (cmd) { default: return -ENOTTY; case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: wdt_get_status(&status); return put_user(status, p); Loading @@ -380,10 +388,8 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, case WDIOC_SETTIMEOUT: if (get_user(new_heartbeat, p)) return -EFAULT; if (wdt_set_heartbeat(new_heartbeat)) return -EINVAL; wdt_ping(); /* Fall */ case WDIOC_GETTIMEOUT: Loading Loading @@ -432,7 +438,8 @@ static int wdt_release(struct inode *inode, struct file *file) wdt_stop(); clear_bit(0, &wdt_is_open); } else { printk(KERN_CRIT "wdt: WDT device closed unexpectedly. WDT will not stop!\n"); printk(KERN_CRIT "wdt: WDT device closed unexpectedly. WDT will not stop!\n"); wdt_ping(); } expect_close = 0; Loading @@ -451,7 +458,8 @@ static int wdt_release(struct inode *inode, struct file *file) * farenheit. It was designed by an imperial measurement luddite. */ static ssize_t wdt_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) static ssize_t wdt_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) { int temperature; Loading Loading @@ -506,10 +514,8 @@ static int wdt_temp_release(struct inode *inode, struct file *file) static int wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if(code==SYS_DOWN || code==SYS_HALT) { /* Turn the card off */ if (code == SYS_DOWN || code == SYS_HALT) wdt_stop(); } return NOTIFY_DONE; } Loading @@ -522,7 +528,7 @@ static const struct file_operations wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = wdt_write, .ioctl = wdt_ioctl, .unlocked_ioctl = wdt_ioctl, .open = wdt_open, .release = wdt_release, }; Loading Loading @@ -591,7 +597,8 @@ static int __init wdt_init(void) { int ret; /* Check that the heartbeat value is within it's range ; if not reset to the default */ /* Check that the heartbeat value is within it's range; if not reset to the default */ if (wdt_set_heartbeat(heartbeat)) { wdt_set_heartbeat(WD_TIMO); printk(KERN_INFO "wdt: heartbeat value must be 0 < heartbeat < 65536, using %d\n", Loading @@ -599,7 +606,8 @@ static int __init wdt_init(void) } if (!request_region(io, 8, "wdt501p")) { printk(KERN_ERR "wdt: I/O address 0x%04x already in use\n", io); printk(KERN_ERR "wdt: I/O address 0x%04x already in use\n", io); ret = -EBUSY; goto out; } Loading @@ -612,14 +620,16 @@ static int __init wdt_init(void) ret = register_reboot_notifier(&wdt_notifier); if (ret) { printk(KERN_ERR "wdt: cannot register reboot notifier (err=%d)\n", ret); printk(KERN_ERR "wdt: cannot register reboot notifier (err=%d)\n", ret); goto outirq; } #ifdef CONFIG_WDT_501 ret = misc_register(&temp_miscdev); if (ret) { printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n", printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n", TEMP_MINOR, ret); goto outrbt; } Loading @@ -627,7 +637,8 @@ static int __init wdt_init(void) ret = misc_register(&wdt_miscdev); if (ret) { printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n", printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); goto outmisc; } Loading @@ -636,7 +647,8 @@ static int __init wdt_init(void) printk(KERN_INFO "WDT500/501-P driver 0.10 at 0x%04x (Interrupt %d). heartbeat=%d sec (nowayout=%d)\n", io, irq, heartbeat, nowayout); #ifdef CONFIG_WDT_501 printk(KERN_INFO "wdt: Fan Tachometer is %s\n", (tachometer ? "Enabled" : "Disabled")); printk(KERN_INFO "wdt: Fan Tachometer is %s\n", (tachometer ? "Enabled" : "Disabled")); #endif /* CONFIG_WDT_501 */ out: Loading
drivers/watchdog/wdt_pci.c +171 −129 Original line number Diff line number Diff line Loading @@ -29,9 +29,11 @@ * JP Nollmann : Added support for PCI wdt501p * Alan Cox : Split ISA and PCI cards into two drivers * Jeff Garzik : PCI cleanups * Tigran Aivazian : Restructured wdtpci_init_one() to handle failures * Tigran Aivazian : Restructured wdtpci_init_one() to handle * failures * Joel Becker : Added WDIOC_GET/SETTIMEOUT * Zwane Mwaikambo : Magic char closing, locking changes, cleanups * Zwane Mwaikambo : Magic char closing, locking changes, * cleanups * Matt Domsch : nowayout module option */ Loading @@ -47,9 +49,9 @@ #include <linux/init.h> #include <linux/fs.h> #include <linux/pci.h> #include <linux/io.h> #include <linux/uaccess.h> #include <asm/io.h> #include <asm/uaccess.h> #include <asm/system.h> #define WDT_IS_PCI Loading @@ -73,7 +75,7 @@ /* We can only use 1 card due to the /dev/watchdog restriction */ static int dev_count; static struct semaphore open_sem; static unsigned long open_lock; static DEFINE_SPINLOCK(wdtpci_lock); static char expect_close; Loading @@ -86,18 +88,23 @@ static int irq; static int heartbeat = WD_TIMO; static int wd_heartbeat; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")"); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")"); static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); #ifdef CONFIG_WDT_501_PCI /* Support for the Fan Tachometer on the PCI-WDT501 */ static int tachometer; module_param(tachometer, int, 0); MODULE_PARM_DESC(tachometer, "PCI-WDT501 Fan Tachometer support (0=disable, default=0)"); MODULE_PARM_DESC(tachometer, "PCI-WDT501 Fan Tachometer support (0=disable, default=0)"); #endif /* CONFIG_WDT_501_PCI */ /* Loading @@ -109,13 +116,16 @@ static void wdtpci_ctr_mode(int ctr, int mode) ctr <<= 6; ctr |= 0x30; ctr |= (mode << 1); outb_p(ctr, WDT_CR); outb(ctr, WDT_CR); udelay(8); } static void wdtpci_ctr_load(int ctr, int val) { outb_p(val&0xFF, WDT_COUNT0+ctr); outb_p(val>>8, WDT_COUNT0+ctr); outb(val & 0xFF, WDT_COUNT0 + ctr); udelay(8); outb(val >> 8, WDT_COUNT0 + ctr); udelay(8); } /** Loading @@ -134,23 +144,35 @@ static int wdtpci_start(void) * "pet" the watchdog, as Access says. * This resets the clock outputs. */ inb_p(WDT_DC); /* Disable watchdog */ wdtpci_ctr_mode(2,0); /* Program CTR2 for Mode 0: Pulse on Terminal Count */ outb_p(0, WDT_DC); /* Enable watchdog */ inb_p(WDT_DC); /* Disable watchdog */ outb_p(0, WDT_CLOCK); /* 2.0833MHz clock */ inb_p(WDT_BUZZER); /* disable */ inb_p(WDT_OPTONOTRST); /* disable */ inb_p(WDT_OPTORST); /* disable */ inb_p(WDT_PROGOUT); /* disable */ wdtpci_ctr_mode(0,3); /* Program CTR0 for Mode 3: Square Wave Generator */ wdtpci_ctr_mode(1,2); /* Program CTR1 for Mode 2: Rate Generator */ wdtpci_ctr_mode(2,1); /* Program CTR2 for Mode 1: Retriggerable One-Shot */ inb(WDT_DC); /* Disable watchdog */ udelay(8); wdtpci_ctr_mode(2, 0); /* Program CTR2 for Mode 0: Pulse on Terminal Count */ outb(0, WDT_DC); /* Enable watchdog */ udelay(8); inb(WDT_DC); /* Disable watchdog */ udelay(8); outb(0, WDT_CLOCK); /* 2.0833MHz clock */ udelay(8); inb(WDT_BUZZER); /* disable */ udelay(8); inb(WDT_OPTONOTRST); /* disable */ udelay(8); inb(WDT_OPTORST); /* disable */ udelay(8); inb(WDT_PROGOUT); /* disable */ udelay(8); wdtpci_ctr_mode(0, 3); /* Program CTR0 for Mode 3: Square Wave Generator */ wdtpci_ctr_mode(1, 2); /* Program CTR1 for Mode 2: Rate Generator */ wdtpci_ctr_mode(2, 1); /* Program CTR2 for Mode 1: Retriggerable One-Shot */ wdtpci_ctr_load(0, 20833); /* count at 100Hz */ wdtpci_ctr_load(1, wd_heartbeat);/* Heartbeat */ /* DO NOT LOAD CTR2 on PCI card! -- JPN */ outb_p(0, WDT_DC); /* Enable watchdog */ outb(0, WDT_DC); /* Enable watchdog */ udelay(8); spin_unlock_irqrestore(&wdtpci_lock, flags); return 0; Loading @@ -168,7 +190,8 @@ static int wdtpci_stop (void) /* Turn the card off */ spin_lock_irqsave(&wdtpci_lock, flags); inb_p(WDT_DC); /* Disable watchdog */ inb(WDT_DC); /* Disable watchdog */ udelay(8); wdtpci_ctr_load(2, 0); /* 0 length reset pulses now */ spin_unlock_irqrestore(&wdtpci_lock, flags); return 0; Loading @@ -177,20 +200,23 @@ static int wdtpci_stop (void) /** * wdtpci_ping: * * Reload counter one with the watchdog heartbeat. We don't bother reloading * the cascade counter. * Reload counter one with the watchdog heartbeat. We don't bother * reloading the cascade counter. */ static int wdtpci_ping(void) { unsigned long flags; /* Write a watchdog value */ spin_lock_irqsave(&wdtpci_lock, flags); inb_p(WDT_DC); /* Disable watchdog */ wdtpci_ctr_mode(1,2); /* Re-Program CTR1 for Mode 2: Rate Generator */ /* Write a watchdog value */ inb(WDT_DC); /* Disable watchdog */ udelay(8); wdtpci_ctr_mode(1, 2); /* Re-Program CTR1 for Mode 2: Rate Generator */ wdtpci_ctr_load(1, wd_heartbeat);/* Heartbeat */ outb_p(0, WDT_DC); /* Enable watchdog */ outb(0, WDT_DC); /* Enable watchdog */ udelay(8); spin_unlock_irqrestore(&wdtpci_lock, flags); return 0; } Loading @@ -199,14 +225,14 @@ static int wdtpci_ping(void) * wdtpci_set_heartbeat: * @t: the new heartbeat value that needs to be set. * * Set a new heartbeat value for the watchdog device. If the heartbeat value is * incorrect we keep the old value and return -EINVAL. If successfull we * return 0. * Set a new heartbeat value for the watchdog device. If the heartbeat * value is incorrect we keep the old value and return -EINVAL. * If successful we return 0. */ static int wdtpci_set_heartbeat(int t) { /* Arbitrary, can't find the card's limits */ if ((t < 1) || (t > 65535)) if (t < 1 || t > 65535) return -EINVAL; heartbeat = t; Loading @@ -227,7 +253,12 @@ static int wdtpci_set_heartbeat(int t) static int wdtpci_get_status(int *status) { unsigned char new_status=inb_p(WDT_SR); unsigned char new_status; unsigned long flags; spin_lock_irqsave(&wdtpci_lock, flags); new_status = inb(WDT_SR); spin_unlock_irqrestore(&wdtpci_lock, flags); *status = 0; if (new_status & WDC_SR_ISOI0) Loading Loading @@ -259,8 +290,12 @@ static int wdtpci_get_status(int *status) static int wdtpci_get_temperature(int *temperature) { unsigned short c=inb_p(WDT_RT); unsigned short c; unsigned long flags; spin_lock_irqsave(&wdtpci_lock, flags); c = inb(WDT_RT); udelay(8); spin_unlock_irqrestore(&wdtpci_lock, flags); *temperature = (c * 11 / 15) + 7; return 0; } Loading @@ -282,13 +317,21 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id) * Read the status register see what is up and * then printk it. */ unsigned char status=inb_p(WDT_SR); unsigned char status; spin_lock(&wdtpci_lock); status = inb(WDT_SR); udelay(8); printk(KERN_CRIT PFX "status %d\n", status); #ifdef CONFIG_WDT_501_PCI if (!(status & WDC_SR_TGOOD)) printk(KERN_CRIT PFX "Overheat alarm.(%d)\n",inb_p(WDT_RT)); if (!(status & WDC_SR_TGOOD)) { u8 alarm = inb(WDT_RT); printk(KERN_CRIT PFX "Overheat alarm.(%d)\n", alarm); udelay(8); } if (!(status & WDC_SR_PSUOVER)) printk(KERN_CRIT PFX "PSU over voltage.\n"); if (!(status & WDC_SR_PSUUNDR)) Loading @@ -310,6 +353,7 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id) printk(KERN_CRIT PFX "Reset in 5ms.\n"); #endif } spin_unlock(&wdtpci_lock); return IRQ_HANDLED; } Loading @@ -325,7 +369,8 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id) * write of data will do, as we we don't define content meaning. */ static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { if (count) { if (!nowayout) { Loading @@ -343,13 +388,11 @@ static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t co } wdtpci_ping(); } return count; } /** * wdtpci_ioctl: * @inode: inode of the device * @file: file handle to the device * @cmd: watchdog command * @arg: argument pointer Loading @@ -359,7 +402,7 @@ static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t co * querying capabilities and current status. */ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd, static long wdtpci_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int new_heartbeat; Loading @@ -383,13 +426,11 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd ident.options |= WDIOF_FANFAULT; #endif /* CONFIG_WDT_501_PCI */ switch(cmd) { switch (cmd) { default: return -ENOTTY; case WDIOC_GETSUPPORT: return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETSTATUS: wdtpci_get_status(&status); return put_user(status, p); Loading @@ -401,10 +442,8 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd case WDIOC_SETTIMEOUT: if (get_user(new_heartbeat, p)) return -EFAULT; if (wdtpci_set_heartbeat(new_heartbeat)) return -EINVAL; wdtpci_ping(); /* Fall */ case WDIOC_GETTIMEOUT: Loading @@ -426,12 +465,11 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd static int wdtpci_open(struct inode *inode, struct file *file) { if (down_trylock(&open_sem)) if (test_and_set_bit(0, &open_lock)) return -EBUSY; if (nowayout) { if (nowayout) __module_get(THIS_MODULE); } /* * Activate */ Loading Loading @@ -460,7 +498,7 @@ static int wdtpci_release(struct inode *inode, struct file *file) wdtpci_ping(); } expect_close = 0; up(&open_sem); clear_bit(0, &open_lock); return 0; } Loading @@ -476,7 +514,8 @@ static int wdtpci_release(struct inode *inode, struct file *file) * fahrenheit. It was designed by an imperial measurement luddite. */ static ssize_t wdtpci_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) static ssize_t wdtpci_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) { int temperature; Loading Loading @@ -531,10 +570,8 @@ static int wdtpci_temp_release(struct inode *inode, struct file *file) static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code, void *unused) { if (code==SYS_DOWN || code==SYS_HALT) { /* Turn the card off */ if (code == SYS_DOWN || code == SYS_HALT) wdtpci_stop(); } return NOTIFY_DONE; } Loading @@ -547,7 +584,7 @@ static const struct file_operations wdtpci_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = wdtpci_write, .ioctl = wdtpci_ioctl, .unlocked_ioctl = wdtpci_ioctl, .open = wdtpci_open, .release = wdtpci_release, }; Loading Loading @@ -591,7 +628,7 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev, dev_count++; if (dev_count > 1) { printk (KERN_ERR PFX "this driver only supports 1 device\n"); printk(KERN_ERR PFX "This driver only supports one device\n"); return -ENODEV; } Loading @@ -606,8 +643,6 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev, goto out_pci; } sema_init(&open_sem, 1); irq = dev->irq; io = pci_resource_start(dev, 2); Loading @@ -622,26 +657,31 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev, goto out_reg; } printk ("PCI-WDT500/501 (PCI-WDG-CSM) driver 0.10 at 0x%04x (Interrupt %d)\n", printk(KERN_INFO "PCI-WDT500/501 (PCI-WDG-CSM) driver 0.10 at 0x%04x (Interrupt %d)\n", io, irq); /* Check that the heartbeat value is within it's range ; if not reset to the default */ /* Check that the heartbeat value is within its range; if not reset to the default */ if (wdtpci_set_heartbeat(heartbeat)) { wdtpci_set_heartbeat(WD_TIMO); printk(KERN_INFO PFX "heartbeat value must be 0<heartbeat<65536, using %d\n", printk(KERN_INFO PFX "heartbeat value must be 0 < heartbeat < 65536, using %d\n", WD_TIMO); } ret = register_reboot_notifier(&wdtpci_notifier); if (ret) { printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); goto out_irq; } #ifdef CONFIG_WDT_501_PCI ret = misc_register(&temp_miscdev); if (ret) { printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", TEMP_MINOR, ret); goto out_rbt; } Loading @@ -649,7 +689,8 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev, ret = misc_register(&wdtpci_miscdev); if (ret) { printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret); goto out_misc; } Loading @@ -657,7 +698,8 @@ static int __devinit wdtpci_init_one (struct pci_dev *dev, printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", heartbeat, nowayout); #ifdef CONFIG_WDT_501_PCI printk(KERN_INFO "wdt: Fan Tachometer is %s\n", (tachometer ? "Enabled" : "Disabled")); printk(KERN_INFO "wdt: Fan Tachometer is %s\n", (tachometer ? "Enabled" : "Disabled")); #endif /* CONFIG_WDT_501_PCI */ ret = 0; Loading