Commit a5ab05a5 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-watchdog.bkbits.net/linux-2.6-watchdog

into home.osdl.org:/home/torvalds/v2.5/linux
parents 0010bc50 30cbd07c
...@@ -100,7 +100,7 @@ static ssize_t acq_write(struct file *file, const char *buf, size_t count, loff_ ...@@ -100,7 +100,7 @@ static ssize_t acq_write(struct file *file, const char *buf, size_t count, loff_
* five months ago... */ * five months ago... */
expect_close = 0; expect_close = 0;
/* scan to see wether or not we got the magic character */ /* scan to see whether or not we got the magic character */
for (i = 0; i != count; i++) { for (i = 0; i != count; i++) {
char c; char c;
if (get_user(c, buf + i)) if (get_user(c, buf + i))
...@@ -263,33 +263,33 @@ static int __init acq_init(void) ...@@ -263,33 +263,33 @@ static int __init acq_init(void)
goto unreg_stop; goto unreg_stop;
} }
ret = register_reboot_notifier(&acq_notifier); ret = register_reboot_notifier(&acq_notifier);
if (ret != 0) { if (ret != 0) {
printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
ret); ret);
goto unreg_regions; goto unreg_regions;
} }
ret = misc_register(&acq_miscdev); ret = misc_register(&acq_miscdev);
if (ret != 0) { if (ret != 0) {
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); WATCHDOG_MINOR, ret);
goto unreg_reboot; goto unreg_reboot;
} }
printk (KERN_INFO PFX "initialized. (nowayout=%d)\n", printk (KERN_INFO PFX "initialized. (nowayout=%d)\n",
nowayout); nowayout);
out: out:
return ret; return ret;
unreg_reboot: unreg_reboot:
unregister_reboot_notifier(&acq_notifier); unregister_reboot_notifier(&acq_notifier);
unreg_regions: unreg_regions:
release_region(wdt_start, 1); release_region(wdt_start, 1);
unreg_stop: unreg_stop:
if (wdt_stop != wdt_start) if (wdt_stop != wdt_start)
release_region(wdt_stop, 1); release_region(wdt_stop, 1);
goto out; goto out;
} }
static void __exit acq_exit(void) static void __exit acq_exit(void)
......
...@@ -183,7 +183,7 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -183,7 +183,7 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
} }
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
} }
return 0; return 0;
} }
......
...@@ -153,7 +153,7 @@ static ssize_t ali_write(struct file *file, const char *data, ...@@ -153,7 +153,7 @@ static ssize_t ali_write(struct file *file, const char *data,
* five months ago... */ * five months ago... */
ali_expect_release = 0; ali_expect_release = 0;
/* scan to see wether or not we got the magic character */ /* scan to see whether or not we got the magic character */
for (i = 0; i != len; i++) { for (i = 0; i != len; i++) {
char c; char c;
if(get_user(c, data+i)) if(get_user(c, data+i))
...@@ -402,7 +402,7 @@ static int __init watchdog_init(void) ...@@ -402,7 +402,7 @@ static int __init watchdog_init(void)
spin_lock_init(&ali_lock); spin_lock_init(&ali_lock);
/* Check wether or not the hardware watchdog is there */ /* Check whether or not the hardware watchdog is there */
if (ali_find_watchdog() != 0) { if (ali_find_watchdog() != 0) {
return -ENODEV; return -ENODEV;
} }
......
...@@ -374,7 +374,7 @@ static int __init alim7101_wdt_init(void) ...@@ -374,7 +374,7 @@ static int __init alim7101_wdt_init(void)
err_out_miscdev: err_out_miscdev:
misc_deregister(&wdt_miscdev); misc_deregister(&wdt_miscdev);
err_out: err_out:
return rc; return rc;
} }
module_init(alim7101_wdt_init); module_init(alim7101_wdt_init);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/watchdog.h> #include <linux/watchdog.h>
...@@ -45,7 +46,7 @@ ...@@ -45,7 +46,7 @@
#define TCO_TIMEOUT_MASK 0x3f #define TCO_TIMEOUT_MASK 0x3f
#define TCO_STATUS1_REG 0x44 #define TCO_STATUS1_REG 0x44
#define TCO_STATUS2_REG 0x46 #define TCO_STATUS2_REG 0x46
#define NDTO_STS2 (1 << 1) /* we're interested in the second timeout */ #define NDTO_STS2 (1 << 1) /* we're interested in the second timeout */
#define BOOT_STS (1 << 2) /* will be set if NDTO_STS2 was set before reboot */ #define BOOT_STS (1 << 2) /* will be set if NDTO_STS2 was set before reboot */
#define TCO_CTRL1_REG 0x48 #define TCO_CTRL1_REG 0x48
#define TCO_HALT (1 << 11) #define TCO_HALT (1 << 11)
...@@ -57,11 +58,20 @@ static u32 pmbase; /* PMxx I/O base */ ...@@ -57,11 +58,20 @@ static u32 pmbase; /* PMxx I/O base */
static struct pci_dev *dev; static struct pci_dev *dev;
static struct semaphore open_sem; static struct semaphore open_sem;
static spinlock_t amdtco_lock; /* only for device access */ static spinlock_t amdtco_lock; /* only for device access */
static int expect_close = 0; static char expect_close;
MODULE_PARM(timeout, "i"); module_param(timeout, int, 0);
MODULE_PARM_DESC(timeout, "range is 0-38 seconds, default is 38"); MODULE_PARM_DESC(timeout, "range is 0-38 seconds, default is 38");
#ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1;
#else
static int nowayout = 0;
#endif
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
static inline u8 seconds_to_ticks(int seconds) static inline u8 seconds_to_ticks(int seconds)
{ {
/* the internal timer is stored as ticks which decrement /* the internal timer is stored as ticks which decrement
...@@ -124,7 +134,7 @@ static inline void amdtco_global_enable(void) ...@@ -124,7 +134,7 @@ static inline void amdtco_global_enable(void)
static inline void amdtco_enable(void) static inline void amdtco_enable(void)
{ {
u16 reg; u16 reg;
spin_lock(&amdtco_lock); spin_lock(&amdtco_lock);
reg = inw(pmbase+TCO_CTRL1_REG); reg = inw(pmbase+TCO_CTRL1_REG);
reg &= ~TCO_HALT; reg &= ~TCO_HALT;
...@@ -152,13 +162,13 @@ static int amdtco_fop_open(struct inode *inode, struct file *file) ...@@ -152,13 +162,13 @@ static int amdtco_fop_open(struct inode *inode, struct file *file)
timeout = MAX_TIMEOUT; timeout = MAX_TIMEOUT;
amdtco_disable(); amdtco_disable();
amdtco_settimeout(timeout); amdtco_settimeout(timeout);
amdtco_global_enable(); amdtco_global_enable();
amdtco_enable(); amdtco_enable();
amdtco_ping(); amdtco_ping();
printk(KERN_INFO PFX "Watchdog enabled, timeout = %ds of %ds\n", printk(KERN_INFO PFX "Watchdog enabled, timeout = %ds of %ds\n",
amdtco_gettimeout(), timeout); amdtco_gettimeout(), timeout);
return 0; return 0;
} }
...@@ -170,12 +180,12 @@ static int amdtco_fop_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -170,12 +180,12 @@ static int amdtco_fop_ioctl(struct inode *inode, struct file *file, unsigned int
static struct watchdog_info ident = { static struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT | WDIOF_CARDRESET, .options = WDIOF_SETTIMEOUT | WDIOF_CARDRESET,
.identity = "AMD 766/768" .identity = "AMD 766/768",
}; };
switch (cmd) { switch (cmd) {
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT: case WDIOC_GETSUPPORT:
if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof ident)) if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof ident))
...@@ -184,7 +194,7 @@ static int amdtco_fop_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -184,7 +194,7 @@ static int amdtco_fop_ioctl(struct inode *inode, struct file *file, unsigned int
case WDIOC_GETSTATUS: case WDIOC_GETSTATUS:
return put_user(amdtco_status(), (int *)arg); return put_user(amdtco_status(), (int *)arg);
case WDIOC_KEEPALIVE: case WDIOC_KEEPALIVE:
amdtco_ping(); amdtco_ping();
return 0; return 0;
...@@ -192,10 +202,10 @@ static int amdtco_fop_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -192,10 +202,10 @@ static int amdtco_fop_ioctl(struct inode *inode, struct file *file, unsigned int
case WDIOC_SETTIMEOUT: case WDIOC_SETTIMEOUT:
if (get_user(new_timeout, (int *)arg)) if (get_user(new_timeout, (int *)arg))
return -EFAULT; return -EFAULT;
if (new_timeout < 0) if (new_timeout < 0)
return -EINVAL; return -EINVAL;
if (new_timeout > MAX_TIMEOUT) if (new_timeout > MAX_TIMEOUT)
new_timeout = MAX_TIMEOUT; new_timeout = MAX_TIMEOUT;
...@@ -205,17 +215,17 @@ static int amdtco_fop_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -205,17 +215,17 @@ static int amdtco_fop_ioctl(struct inode *inode, struct file *file, unsigned int
case WDIOC_GETTIMEOUT: case WDIOC_GETTIMEOUT:
return put_user(amdtco_gettimeout(), (int *)arg); return put_user(amdtco_gettimeout(), (int *)arg);
case WDIOC_SETOPTIONS: case WDIOC_SETOPTIONS:
if (copy_from_user(&tmp, (int *)arg, sizeof tmp)) if (copy_from_user(&tmp, (int *)arg, sizeof tmp))
return -EFAULT; return -EFAULT;
if (tmp & WDIOS_DISABLECARD) if (tmp & WDIOS_DISABLECARD)
amdtco_disable(); amdtco_disable();
if (tmp & WDIOS_ENABLECARD) if (tmp & WDIOS_ENABLECARD)
amdtco_enable(); amdtco_enable();
return 0; return 0;
} }
} }
...@@ -223,14 +233,15 @@ static int amdtco_fop_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -223,14 +233,15 @@ static int amdtco_fop_ioctl(struct inode *inode, struct file *file, unsigned int
static int amdtco_fop_release(struct inode *inode, struct file *file) static int amdtco_fop_release(struct inode *inode, struct file *file)
{ {
if (expect_close) { if (expect_close == 42) {
amdtco_disable(); amdtco_disable();
printk(KERN_INFO PFX "Watchdog disabled\n"); printk(KERN_INFO PFX "Watchdog disabled\n");
} else { } else {
amdtco_ping(); amdtco_ping();
printk(KERN_CRIT PFX "Unexpected close!, timeout in %d seconds\n", timeout); printk(KERN_CRIT PFX "Unexpected close!, timeout in %d seconds\n", timeout);
} }
expect_close = 0;
up(&open_sem); up(&open_sem);
return 0; return 0;
} }
...@@ -240,21 +251,21 @@ static ssize_t amdtco_fop_write(struct file *file, const char *data, size_t len, ...@@ -240,21 +251,21 @@ static ssize_t amdtco_fop_write(struct file *file, const char *data, size_t len,
{ {
if (ppos != &file->f_pos) if (ppos != &file->f_pos)
return -ESPIPE; return -ESPIPE;
if (len) {
#ifndef CONFIG_WATCHDOG_NOWAYOUT
size_t i;
char c;
expect_close = 0;
for (i = 0; i != len; i++) {
if (get_user(c, data + i))
return -EFAULT;
if (c == 'V') if (len) {
expect_close = 1; if (!nowayout) {
size_t i;
char c;
expect_close = 0;
for (i = 0; i != len; i++) {
if (get_user(c, data + i))
return -EFAULT;
if (c == 'V')
expect_close = 42;
}
} }
#endif
amdtco_ping(); amdtco_ping();
} }
...@@ -273,7 +284,7 @@ static int amdtco_notify_sys(struct notifier_block *this, unsigned long code, vo ...@@ -273,7 +284,7 @@ static int amdtco_notify_sys(struct notifier_block *this, unsigned long code, vo
static struct notifier_block amdtco_notifier = static struct notifier_block amdtco_notifier =
{ {
.notifier_call = amdtco_notify_sys .notifier_call = amdtco_notify_sys,
}; };
static struct file_operations amdtco_fops = static struct file_operations amdtco_fops =
...@@ -282,20 +293,20 @@ static struct file_operations amdtco_fops = ...@@ -282,20 +293,20 @@ static struct file_operations amdtco_fops =
.write = amdtco_fop_write, .write = amdtco_fop_write,
.ioctl = amdtco_fop_ioctl, .ioctl = amdtco_fop_ioctl,
.open = amdtco_fop_open, .open = amdtco_fop_open,
.release = amdtco_fop_release .release = amdtco_fop_release,
}; };
static struct miscdevice amdtco_miscdev = static struct miscdevice amdtco_miscdev =
{ {
.minor = WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
.name = "watchdog", .name = "watchdog",
.fops = &amdtco_fops .fops = &amdtco_fops,
}; };
static struct pci_device_id amdtco_pci_tbl[] = { static struct pci_device_id amdtco_pci_tbl[] = {
/* AMD 766 PCI_IDs here */ /* AMD 766 PCI_IDs here */
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7443, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7443, PCI_ANY_ID, PCI_ANY_ID, },
{ 0, } { 0, },
}; };
MODULE_DEVICE_TABLE (pci, amdtco_pci_tbl); MODULE_DEVICE_TABLE (pci, amdtco_pci_tbl);
...@@ -316,7 +327,7 @@ static int __init amdtco_init(void) ...@@ -316,7 +327,7 @@ static int __init amdtco_init(void)
return -ENODEV; return -ENODEV;
found_one: found_one:
if ((ret = register_reboot_notifier(&amdtco_notifier))) { if ((ret = register_reboot_notifier(&amdtco_notifier))) {
printk(KERN_ERR PFX "Unable to register reboot notifier err = %d\n", ret); printk(KERN_ERR PFX "Unable to register reboot notifier err = %d\n", ret);
goto out_clean; goto out_clean;
......
...@@ -105,8 +105,8 @@ static void cpu5wdt_start(void) ...@@ -105,8 +105,8 @@ static void cpu5wdt_start(void)
{ {
if ( !cpu5wdt_device.queue ) { if ( !cpu5wdt_device.queue ) {
cpu5wdt_device.queue = 1; cpu5wdt_device.queue = 1;
outb(0, port + CPU5WDT_TIME_A_REG); outb(0, port + CPU5WDT_TIME_A_REG);
outb(0, port + CPU5WDT_TIME_B_REG); outb(0, port + CPU5WDT_TIME_B_REG);
outb(1, port + CPU5WDT_MODE_REG); outb(1, port + CPU5WDT_MODE_REG);
outb(0, port + CPU5WDT_RESET_REG); outb(0, port + CPU5WDT_RESET_REG);
outb(0, port + CPU5WDT_ENABLE_REG); outb(0, port + CPU5WDT_ENABLE_REG);
...@@ -134,23 +134,15 @@ static int cpu5wdt_stop(void) ...@@ -134,23 +134,15 @@ static int cpu5wdt_stop(void)
static int cpu5wdt_open(struct inode *inode, struct file *file) static int cpu5wdt_open(struct inode *inode, struct file *file)
{ {
switch(iminor(inode)) { if ( test_and_set_bit(0, &cpu5wdt_device.inuse) )
case WATCHDOG_MINOR: return -EBUSY;
if ( test_and_set_bit(0, &cpu5wdt_device.inuse) )
return -EBUSY;
break;
default:
return -ENODEV;
}
return 0; return 0;
} }
static int cpu5wdt_release(struct inode *inode, struct file *file) static int cpu5wdt_release(struct inode *inode, struct file *file)
{ {
if(iminor(inode)==WATCHDOG_MINOR) { clear_bit(0, &cpu5wdt_device.inuse);
clear_bit(0, &cpu5wdt_device.inuse);
}
return 0; return 0;
} }
...@@ -160,15 +152,15 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm ...@@ -160,15 +152,15 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm
static struct watchdog_info ident = static struct watchdog_info ident =
{ {
.options = WDIOF_CARDRESET, .options = WDIOF_CARDRESET,
.identity = "CPU5 WDT" .identity = "CPU5 WDT",
}; };
switch(cmd) { switch(cmd) {
case WDIOC_KEEPALIVE: case WDIOC_KEEPALIVE:
cpu5wdt_reset(); cpu5wdt_reset();
break; break;
case WDIOC_GETSTATUS: case WDIOC_GETSTATUS:
value = inb(port + CPU5WDT_STATUS_REG); value = inb(port + CPU5WDT_STATUS_REG);
value = (value >> 2) & 1; value = (value >> 2) & 1;
if ( copy_to_user((int *)arg, (int *)&value, sizeof(int)) ) if ( copy_to_user((int *)arg, (int *)&value, sizeof(int)) )
return -EFAULT; return -EFAULT;
...@@ -191,7 +183,7 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm ...@@ -191,7 +183,7 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm
} }
break; break;
default: default:
return -EINVAL; return -ENOIOCTLCMD;
} }
return 0; return 0;
} }
...@@ -200,7 +192,7 @@ static ssize_t cpu5wdt_write(struct file *file, const char *buf, size_t count, l ...@@ -200,7 +192,7 @@ static ssize_t cpu5wdt_write(struct file *file, const char *buf, size_t count, l
{ {
if ( !count ) if ( !count )
return -EIO; return -EIO;
cpu5wdt_reset(); cpu5wdt_reset();
return count; return count;
...@@ -217,7 +209,7 @@ static struct file_operations cpu5wdt_fops = { ...@@ -217,7 +209,7 @@ static struct file_operations cpu5wdt_fops = {
static struct miscdevice cpu5wdt_misc = { static struct miscdevice cpu5wdt_misc = {
.minor = WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
.name = "watchdog", .name = "watchdog",
.fops = &cpu5wdt_fops .fops = &cpu5wdt_fops,
}; };
/* init/exit function */ /* init/exit function */
...@@ -242,7 +234,7 @@ static int __devinit cpu5wdt_init(void) ...@@ -242,7 +234,7 @@ static int __devinit cpu5wdt_init(void)
} }
/* watchdog reboot? */ /* watchdog reboot? */
val = inb(port + CPU5WDT_STATUS_REG); val = inb(port + CPU5WDT_STATUS_REG);
val = (val >> 2) & 1; val = (val >> 2) & 1;
if ( !val ) if ( !val )
printk(KERN_INFO PFX "sorry, was my fault\n"); printk(KERN_INFO PFX "sorry, was my fault\n");
......
/* /*
* Eurotech CPU-1220/1410 on board WDT driver for Linux 2.4.x * Eurotech CPU-1220/1410 on board WDT driver
* *
* (c) Copyright 2001 Ascensit <support@ascensit.com> * (c) Copyright 2001 Ascensit <support@ascensit.com>
* (c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com> * (c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com>
...@@ -64,11 +64,11 @@ static char eur_expect_close; ...@@ -64,11 +64,11 @@ static char eur_expect_close;
* You must set these - there is no sane way to probe for this board. * You must set these - there is no sane way to probe for this board.
* You can use eurwdt=x,y to set these now. * You can use eurwdt=x,y to set these now.
*/ */
static int io = 0x3f0; static int io = 0x3f0;
static int irq = 10; static int irq = 10;
static char *ev = "int"; static char *ev = "int";
#define WDT_TIMEOUT 60 /* 1 minute */ #define WDT_TIMEOUT 60 /* 1 minute */
#ifdef CONFIG_WATCHDOG_NOWAYOUT #ifdef CONFIG_WATCHDOG_NOWAYOUT
...@@ -81,7 +81,7 @@ MODULE_PARM(nowayout,"i"); ...@@ -81,7 +81,7 @@ MODULE_PARM(nowayout,"i");
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
/* /*
* Some symbolic names * Some symbolic names
*/ */
#define WDT_CTRL_REG 0x30 #define WDT_CTRL_REG 0x30
...@@ -92,7 +92,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON ...@@ -92,7 +92,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
#define WDT_UNIT_SECS 0x80 #define WDT_UNIT_SECS 0x80
#define WDT_TIMEOUT_VAL 0xf2 #define WDT_TIMEOUT_VAL 0xf2
#define WDT_TIMER_CFG 0xf3 #define WDT_TIMER_CFG 0xf3
#ifndef MODULE #ifndef MODULE
...@@ -104,26 +104,26 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON ...@@ -104,26 +104,26 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
* get the user to tell us the configuration. Sane people build it * get the user to tell us the configuration. Sane people build it
* modular but the others come here. * modular but the others come here.
*/ */
static int __init eurwdt_setup(char *str) static int __init eurwdt_setup(char *str)
{ {
int ints[4]; int ints[4];
str = get_options (str, ARRAY_SIZE(ints), ints); str = get_options (str, ARRAY_SIZE(ints), ints);
if (ints[0] > 0) { if (ints[0] > 0) {
io = ints[1]; io = ints[1];
if (ints[0] > 1) if (ints[0] > 1)
irq = ints[2]; irq = ints[2];
} }
return 1; return 1;
} }
__setup("eurwdt=", eurwdt_setup); __setup("eurwdt=", eurwdt_setup);
#endif /* !MODULE */ #endif /* !MODULE */
MODULE_PARM(io, "i"); MODULE_PARM(io, "i");
MODULE_PARM_DESC(io, "Eurotech WDT io port (default=0x3f0)"); MODULE_PARM_DESC(io, "Eurotech WDT io port (default=0x3f0)");
MODULE_PARM(irq, "i"); MODULE_PARM(irq, "i");
...@@ -162,7 +162,7 @@ static inline void eurwdt_disable_timer(void) ...@@ -162,7 +162,7 @@ static inline void eurwdt_disable_timer(void)
{ {
eurwdt_set_timeout(0); eurwdt_set_timeout(0);
} }
static void eurwdt_activate_timer(void) static void eurwdt_activate_timer(void)
{ {
eurwdt_disable_timer(); eurwdt_disable_timer();
...@@ -180,18 +180,18 @@ static void eurwdt_activate_timer(void) ...@@ -180,18 +180,18 @@ static void eurwdt_activate_timer(void)
eurwdt_write_reg(WDT_TIMER_CFG, irq<<4); eurwdt_write_reg(WDT_TIMER_CFG, irq<<4);
eurwdt_write_reg(WDT_UNIT_SEL, WDT_UNIT_SECS); /* we use seconds */ eurwdt_write_reg(WDT_UNIT_SEL, WDT_UNIT_SECS); /* we use seconds */
eurwdt_set_timeout(0); /* the default timeout */ eurwdt_set_timeout(0); /* the default timeout */
} }
/* /*
* Kernel methods. * Kernel methods.
*/ */
static irqreturn_t eurwdt_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t eurwdt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
printk(KERN_CRIT "timeout WDT timeout\n"); printk(KERN_CRIT "timeout WDT timeout\n");
#ifdef ONLY_TESTING #ifdef ONLY_TESTING
printk(KERN_CRIT "Would Reboot.\n"); printk(KERN_CRIT "Would Reboot.\n");
#else #else
...@@ -207,13 +207,13 @@ static irqreturn_t eurwdt_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -207,13 +207,13 @@ static irqreturn_t eurwdt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* *
* Reload counter one with the watchdog timeout. * Reload counter one with the watchdog timeout.
*/ */
static void eurwdt_ping(void) static void eurwdt_ping(void)
{ {
/* Write the watchdog default value */ /* Write the watchdog default value */
eurwdt_set_timeout(eurwdt_timeout); eurwdt_set_timeout(eurwdt_timeout);
} }
/** /**
* eurwdt_write: * eurwdt_write:
* @file: file handle to the watchdog * @file: file handle to the watchdog
...@@ -224,14 +224,14 @@ static void eurwdt_ping(void) ...@@ -224,14 +224,14 @@ static void eurwdt_ping(void)
* A write to a watchdog device is defined as a keepalive signal. Any * A write to a watchdog device is defined as a keepalive signal. Any
* write of data will do, as we we don't define content meaning. * write of data will do, as we we don't define content meaning.
*/ */
static ssize_t eurwdt_write(struct file *file, const char *buf, size_t count, static ssize_t eurwdt_write(struct file *file, const char *buf, size_t count,
loff_t *ppos) loff_t *ppos)
{ {
/* Can't seek (pwrite) on this device */ /* Can't seek (pwrite) on this device */
if (ppos != &file->f_pos) if (ppos != &file->f_pos)
return -ESPIPE; return -ESPIPE;
if (count) { if (count) {
if (!nowayout) { if (!nowayout) {
size_t i; size_t i;
...@@ -262,7 +262,7 @@ loff_t *ppos) ...@@ -262,7 +262,7 @@ loff_t *ppos)
* The watchdog API defines a common set of functions for all watchdogs * The watchdog API defines a common set of functions for all watchdogs
* according to their available features. * according to their available features.
*/ */
static int eurwdt_ioctl(struct inode *inode, struct file *file, static int eurwdt_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -274,15 +274,15 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file, ...@@ -274,15 +274,15 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
int time; int time;
int options, retval = -EINVAL; int options, retval = -EINVAL;
switch(cmd) { switch(cmd) {
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT: case WDIOC_GETSUPPORT:
return copy_to_user((struct watchdog_info *)arg, &ident, return copy_to_user((struct watchdog_info *)arg, &ident,
sizeof(ident)) ? -EFAULT : 0; sizeof(ident)) ? -EFAULT : 0;
case WDIOC_GETSTATUS: case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS: case WDIOC_GETBOOTSTATUS:
return put_user(0, (int *) arg); return put_user(0, (int *) arg);
...@@ -299,8 +299,8 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file, ...@@ -299,8 +299,8 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
if (time < 0 || time > 255) if (time < 0 || time > 255)
return -EINVAL; return -EINVAL;
eurwdt_timeout = time; eurwdt_timeout = time;
eurwdt_set_timeout(time); eurwdt_set_timeout(time);
/* Fall */ /* Fall */
case WDIOC_GETTIMEOUT: case WDIOC_GETTIMEOUT:
...@@ -330,7 +330,7 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file, ...@@ -330,7 +330,7 @@ static int eurwdt_ioctl(struct inode *inode, struct file *file,
* The misc device has been opened. The watchdog device is single * The misc device has been opened. The watchdog device is single
* open and on opening we load the counter. * open and on opening we load the counter.
*/ */
static int eurwdt_open(struct inode *inode, struct file *file) static int eurwdt_open(struct inode *inode, struct file *file)
{ {
if (test_and_set_bit(0, &eurwdt_is_open)) if (test_and_set_bit(0, &eurwdt_is_open))
...@@ -340,7 +340,7 @@ static int eurwdt_open(struct inode *inode, struct file *file) ...@@ -340,7 +340,7 @@ static int eurwdt_open(struct inode *inode, struct file *file)
eurwdt_activate_timer(); eurwdt_activate_timer();
return 0; return 0;
} }
/** /**
* eurwdt_release: * eurwdt_release:
* @inode: inode to board * @inode: inode to board
...@@ -352,7 +352,7 @@ static int eurwdt_open(struct inode *inode, struct file *file) ...@@ -352,7 +352,7 @@ static int eurwdt_open(struct inode *inode, struct file *file)
* reboots. In the former case we disable the counters, in the latter * reboots. In the former case we disable the counters, in the latter
* case you have to open it again very soon. * case you have to open it again very soon.
*/ */
static int eurwdt_release(struct inode *inode, struct file *file) static int eurwdt_release(struct inode *inode, struct file *file)
{ {
if (eur_expect_close == 42) { if (eur_expect_close == 42) {
...@@ -360,12 +360,12 @@ static int eurwdt_release(struct inode *inode, struct file *file) ...@@ -360,12 +360,12 @@ static int eurwdt_release(struct inode *inode, struct file *file)
} else { } else {
printk(KERN_CRIT "eurwdt: Unexpected close, not stopping watchdog!\n"); printk(KERN_CRIT "eurwdt: Unexpected close, not stopping watchdog!\n");
eurwdt_ping(); eurwdt_ping();
} }
clear_bit(0, &eurwdt_is_open); clear_bit(0, &eurwdt_is_open);
eur_expect_close = 0; eur_expect_close = 0;
return 0; return 0;
} }
/** /**
* eurwdt_notify_sys: * eurwdt_notify_sys:
* @this: our notifier block * @this: our notifier block
...@@ -377,7 +377,7 @@ static int eurwdt_release(struct inode *inode, struct file *file) ...@@ -377,7 +377,7 @@ static int eurwdt_release(struct inode *inode, struct file *file)
* test or worse yet during the following fsck. This would suck, in fact * test or worse yet during the following fsck. This would suck, in fact
* trust me - if it happens it does suck. * trust me - if it happens it does suck.
*/ */
static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code, static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code,
void *unused) void *unused)
{ {
...@@ -388,12 +388,12 @@ static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code, ...@@ -388,12 +388,12 @@ static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code,
return NOTIFY_DONE; return NOTIFY_DONE;
} }
/* /*
* Kernel Interfaces * Kernel Interfaces
*/ */
static struct file_operations eurwdt_fops = { static struct file_operations eurwdt_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.llseek = no_llseek, .llseek = no_llseek,
...@@ -406,18 +406,18 @@ static struct file_operations eurwdt_fops = { ...@@ -406,18 +406,18 @@ static struct file_operations eurwdt_fops = {
static struct miscdevice eurwdt_miscdev = { static struct miscdevice eurwdt_miscdev = {
.minor = WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
.name = "watchdog", .name = "watchdog",
.fops = &eurwdt_fops .fops = &eurwdt_fops,
}; };
/* /*
* The WDT card needs to learn about soft shutdowns in order to * The WDT card needs to learn about soft shutdowns in order to
* turn the timebomb registers off. * turn the timebomb registers off.
*/ */
static struct notifier_block eurwdt_notifier = { static struct notifier_block eurwdt_notifier = {
.notifier_call = eurwdt_notify_sys, .notifier_call = eurwdt_notify_sys,
}; };
/** /**
* cleanup_module: * cleanup_module:
* *
...@@ -427,7 +427,7 @@ static struct notifier_block eurwdt_notifier = { ...@@ -427,7 +427,7 @@ static struct notifier_block eurwdt_notifier = {
* will not touch PC memory so all is fine. You just have to load a new * will not touch PC memory so all is fine. You just have to load a new
* module in 60 seconds or reboot. * module in 60 seconds or reboot.
*/ */
static void __exit eurwdt_exit(void) static void __exit eurwdt_exit(void)
{ {
eurwdt_lock_chip(); eurwdt_lock_chip();
...@@ -438,15 +438,15 @@ static void __exit eurwdt_exit(void) ...@@ -438,15 +438,15 @@ static void __exit eurwdt_exit(void)
release_region(io, 2); release_region(io, 2);
free_irq(irq, NULL); free_irq(irq, NULL);
} }
/** /**
* eurwdt_init: * eurwdt_init:
* *
* Set up the WDT watchdog board. After grabbing the resources * Set up the WDT watchdog board. After grabbing the resources
* we require we need also to unlock the device. * we require we need also to unlock the device.
* The open() function will actually kick the board off. * The open() function will actually kick the board off.
*/ */
static int __init eurwdt_init(void) static int __init eurwdt_init(void)
{ {
int ret; int ret;
...@@ -477,15 +477,15 @@ static int __init eurwdt_init(void) ...@@ -477,15 +477,15 @@ static int __init eurwdt_init(void)
} }
eurwdt_unlock_chip(); eurwdt_unlock_chip();
ret = 0; ret = 0;
printk(KERN_INFO "Eurotech WDT driver 0.01 at %X (Interrupt %d)" printk(KERN_INFO "Eurotech WDT driver 0.01 at %X (Interrupt %d)"
" - timeout event: %s\n", " - timeout event: %s\n",
io, irq, (!strcmp("int", ev) ? "int" : "reboot")); io, irq, (!strcmp("int", ev) ? "int" : "reboot"));
out: out:
return ret; return ret;
outreg: outreg:
release_region(io, 2); release_region(io, 2);
...@@ -496,10 +496,10 @@ static int __init eurwdt_init(void) ...@@ -496,10 +496,10 @@ static int __init eurwdt_init(void)
misc_deregister(&eurwdt_miscdev); misc_deregister(&eurwdt_miscdev);
goto out; goto out;
} }
module_init(eurwdt_init); module_init(eurwdt_init);
module_exit(eurwdt_exit); module_exit(eurwdt_exit);
MODULE_AUTHOR("Rodolfo Giometti"); MODULE_AUTHOR("Rodolfo Giometti");
MODULE_DESCRIPTION("Driver for Eurotech CPU-1220/1410 on board watchdog"); MODULE_DESCRIPTION("Driver for Eurotech CPU-1220/1410 on board watchdog");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
* *
* Neither kernel concepts nor Nils Faerber admit liability nor provide * Neither kernel concepts nor Nils Faerber admit liability nor provide
* warranty for any of this software. This material is provided * warranty for any of this software. This material is provided
* "AS-IS" and at no charge. * "AS-IS" and at no charge.
...@@ -112,7 +112,7 @@ static int tco_timer_start (void) ...@@ -112,7 +112,7 @@ static int tco_timer_start (void)
outb (val, TCO1_CNT + 1); outb (val, TCO1_CNT + 1);
val = inb (TCO1_CNT + 1); val = inb (TCO1_CNT + 1);
spin_unlock(&tco_lock); spin_unlock(&tco_lock);
if (val & 0x08) if (val & 0x08)
return -1; return -1;
return 0; return 0;
...@@ -131,7 +131,7 @@ static int tco_timer_stop (void) ...@@ -131,7 +131,7 @@ static int tco_timer_stop (void)
outb (val, TCO1_CNT + 1); outb (val, TCO1_CNT + 1);
val = inb (TCO1_CNT + 1); val = inb (TCO1_CNT + 1);
spin_unlock(&tco_lock); spin_unlock(&tco_lock);
if ((val & 0x08) == 0) if ((val & 0x08) == 0)
return -1; return -1;
return 0; return 0;
...@@ -148,7 +148,7 @@ static int tco_timer_settimer (unsigned char tmrval) ...@@ -148,7 +148,7 @@ static int tco_timer_settimer (unsigned char tmrval)
/* "Values of 0h-3h are ignored and should not be attempted" */ /* "Values of 0h-3h are ignored and should not be attempted" */
if (tmrval > 0x3f || tmrval < 0x04) if (tmrval > 0x3f || tmrval < 0x04)
return -1; return -1;
spin_lock(&tco_lock); spin_lock(&tco_lock);
val = inb (TCO1_TMR); val = inb (TCO1_TMR);
val &= 0xc0; val &= 0xc0;
...@@ -156,7 +156,7 @@ static int tco_timer_settimer (unsigned char tmrval) ...@@ -156,7 +156,7 @@ static int tco_timer_settimer (unsigned char tmrval)
outb (val, TCO1_TMR); outb (val, TCO1_TMR);
val = inb (TCO1_TMR); val = inb (TCO1_TMR);
spin_unlock(&tco_lock); spin_unlock(&tco_lock);
if ((val & 0x3f) != tmrval) if ((val & 0x3f) != tmrval)
return -1; return -1;
...@@ -197,7 +197,7 @@ static int i810tco_release (struct inode *inode, struct file *file) ...@@ -197,7 +197,7 @@ static int i810tco_release (struct inode *inode, struct file *file)
/* /*
* Shut off the timer. * Shut off the timer.
*/ */
if (tco_expect_close == 42 && !nowayout) { if (tco_expect_close == 42) {
tco_timer_stop (); tco_timer_stop ();
} else { } else {
tco_timer_reload (); tco_timer_reload ();
...@@ -217,17 +217,21 @@ static ssize_t i810tco_write (struct file *file, const char *data, ...@@ -217,17 +217,21 @@ static ssize_t i810tco_write (struct file *file, const char *data,
/* See if we got the magic character 'V' and reload the timer */ /* See if we got the magic character 'V' and reload the timer */
if (len) { if (len) {
size_t i; if (!nowayout) {
size_t i;
tco_expect_close = 0;
/* note: just in case someone wrote the magic character
/* scan to see whether or not we got the magic character */ * five months ago... */
for (i = 0; i != len; i++) { tco_expect_close = 0;
u8 c;
if(get_user(c, data+i)) /* scan to see whether or not we got the magic character */
return -EFAULT; for (i = 0; i != len; i++) {
if (c == 'V') u8 c;
tco_expect_close = 42; if(get_user(c, data+i))
return -EFAULT;
if (c == 'V')
tco_expect_close = 42;
}
} }
/* someone wrote to us, we should reload the timer */ /* someone wrote to us, we should reload the timer */
...@@ -251,7 +255,7 @@ static int i810tco_ioctl (struct inode *inode, struct file *file, ...@@ -251,7 +255,7 @@ static int i810tco_ioctl (struct inode *inode, struct file *file,
}; };
switch (cmd) { switch (cmd) {
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT: case WDIOC_GETSUPPORT:
if (copy_to_user if (copy_to_user
((struct watchdog_info *) arg, &ident, sizeof (ident))) ((struct watchdog_info *) arg, &ident, sizeof (ident)))
......
/* /*
* IB700 Single Board Computer WDT driver for Linux 2.4.x * IB700 Single Board Computer WDT driver
* *
* (c) Copyright 2001 Charles Howes <chowes@vsol.net> * (c) Copyright 2001 Charles Howes <chowes@vsol.net>
* *
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
* 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com> * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
* Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
* Added timeout module option to override default * Added timeout module option to override default
* *
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -48,9 +48,9 @@ ...@@ -48,9 +48,9 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/system.h> #include <asm/system.h>
static int ibwdt_is_open; static unsigned long ibwdt_is_open;
static spinlock_t ibwdt_lock; static spinlock_t ibwdt_lock;
static int expect_close = 0; static char expect_close;
#define PFX "ib700wdt: " #define PFX "ib700wdt: "
...@@ -157,7 +157,7 @@ ibwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) ...@@ -157,7 +157,7 @@ ibwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
if (get_user(c, buf + i)) if (get_user(c, buf + i))
return -EFAULT; return -EFAULT;
if (c == 'V') if (c == 'V')
expect_close = 1; expect_close = 42;
} }
} }
ibwdt_ping(); ibwdt_ping();
...@@ -174,7 +174,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -174,7 +174,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static struct watchdog_info ident = { static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
.firmware_version = 1, .firmware_version = 1,
.identity = "IB700 WDT" .identity = "IB700 WDT",
}; };
switch (cmd) { switch (cmd) {
...@@ -184,9 +184,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -184,9 +184,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
break; break;
case WDIOC_GETSTATUS: case WDIOC_GETSTATUS:
if (copy_to_user((int *)arg, &ibwdt_is_open, sizeof(int))) return put_user(0, (int *) arg);
return -EFAULT;
break;
case WDIOC_KEEPALIVE: case WDIOC_KEEPALIVE:
ibwdt_ping(); ibwdt_ping();
...@@ -209,7 +207,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -209,7 +207,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
break; break;
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
} }
return 0; return 0;
} }
...@@ -217,38 +215,32 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -217,38 +215,32 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static int static int
ibwdt_open(struct inode *inode, struct file *file) ibwdt_open(struct inode *inode, struct file *file)
{ {
if (iminor(inode) == WATCHDOG_MINOR) { spin_lock(&ibwdt_lock);
spin_lock(&ibwdt_lock); if (test_and_set_bit(0, &ibwdt_is_open)) {
if (ibwdt_is_open) {
spin_unlock(&ibwdt_lock);
return -EBUSY;
}
if (nowayout)
__module_get(THIS_MODULE);
/* Activate */
ibwdt_is_open = 1;
ibwdt_ping();
spin_unlock(&ibwdt_lock); spin_unlock(&ibwdt_lock);
return 0; return -EBUSY;
} else {
return -ENODEV;
} }
if (nowayout)
__module_get(THIS_MODULE);
/* Activate */
ibwdt_ping();
spin_unlock(&ibwdt_lock);
return 0;
} }
static int static int
ibwdt_close(struct inode *inode, struct file *file) ibwdt_close(struct inode *inode, struct file *file)
{ {
if (iminor(inode) == WATCHDOG_MINOR) { spin_lock(&ibwdt_lock);
spin_lock(&ibwdt_lock); if (expect_close == 42)
if (expect_close) outb_p(wd_times[wd_margin], WDT_STOP);
outb_p(wd_times[wd_margin], WDT_STOP); else
else printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n");
printk(KERN_CRIT PFX "WDT device closed unexpectedly. WDT will not stop!\n");
clear_bit(0, &ibwdt_is_open);
ibwdt_is_open = 0; expect_close = 0;
spin_unlock(&ibwdt_lock); spin_unlock(&ibwdt_lock);
}
return 0; return 0;
} }
...@@ -282,7 +274,7 @@ static struct file_operations ibwdt_fops = { ...@@ -282,7 +274,7 @@ static struct file_operations ibwdt_fops = {
static struct miscdevice ibwdt_miscdev = { static struct miscdevice ibwdt_miscdev = {
.minor = WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
.name = "watchdog", .name = "watchdog",
.fops = &ibwdt_fops .fops = &ibwdt_fops,
}; };
/* /*
...@@ -293,7 +285,7 @@ static struct miscdevice ibwdt_miscdev = { ...@@ -293,7 +285,7 @@ static struct miscdevice ibwdt_miscdev = {
static struct notifier_block ibwdt_notifier = { static struct notifier_block ibwdt_notifier = {
.notifier_call = ibwdt_notify_sys, .notifier_call = ibwdt_notify_sys,
.next = NULL, .next = NULL,
.priority = 0 .priority = 0,
}; };
static int __init ibwdt_init(void) static int __init ibwdt_init(void)
......
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
* *
* based on softdog.c by Alan Cox <alan@redhat.com> * based on softdog.c by Alan Cox <alan@redhat.com>
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/config.h> #include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
#include <asm/sgi/sgimc.h> #include <asm/sgi/sgimc.h>
static unsigned long indydog_alive; static unsigned long indydog_alive;
static struct sgimc_misc_ctrl *mcmisc_regs; static struct sgimc_misc_ctrl *mcmisc_regs;
static int expect_close = 0; static char expect_close;
#ifdef CONFIG_WATCHDOG_NOWAYOUT #ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1; static int nowayout = 1;
...@@ -50,7 +50,7 @@ static void indydog_ping() ...@@ -50,7 +50,7 @@ static void indydog_ping()
static int indydog_open(struct inode *inode, struct file *file) static int indydog_open(struct inode *inode, struct file *file)
{ {
u32 mc_ctrl0; u32 mc_ctrl0;
if( test_and_set_bit(0,&indydog_alive) ) if( test_and_set_bit(0,&indydog_alive) )
return -EBUSY; return -EBUSY;
...@@ -65,7 +65,7 @@ static int indydog_open(struct inode *inode, struct file *file) ...@@ -65,7 +65,7 @@ static int indydog_open(struct inode *inode, struct file *file)
mc_ctrl0 = mcmisc_regs->cpuctrl0 | SGIMC_CCTRL0_WDOG; mc_ctrl0 = mcmisc_regs->cpuctrl0 | SGIMC_CCTRL0_WDOG;
mcmisc_regs->cpuctrl0 = mc_ctrl0; mcmisc_regs->cpuctrl0 = mc_ctrl0;
indydog_ping(); indydog_ping();
printk("Started watchdog timer.\n"); printk("Started watchdog timer.\n");
return 0; return 0;
} }
...@@ -77,8 +77,8 @@ static int indydog_release(struct inode *inode, struct file *file) ...@@ -77,8 +77,8 @@ static int indydog_release(struct inode *inode, struct file *file)
* Lock it in if it's a module and we set nowayout * Lock it in if it's a module and we set nowayout
*/ */
if (expect_close) { if (expect_close == 42) {
u32 mc_ctrl0 = mcmisc_regs->cpuctrl0; u32 mc_ctrl0 = mcmisc_regs->cpuctrl0;
mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG; mc_ctrl0 &= ~SGIMC_CCTRL0_WDOG;
mcmisc_regs->cpuctrl0 = mc_ctrl0; mcmisc_regs->cpuctrl0 = mc_ctrl0;
printk("Stopped watchdog timer.\n"); printk("Stopped watchdog timer.\n");
...@@ -86,6 +86,7 @@ static int indydog_release(struct inode *inode, struct file *file) ...@@ -86,6 +86,7 @@ static int indydog_release(struct inode *inode, struct file *file)
printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n"); printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n");
} }
clear_bit(0,&indydog_alive); clear_bit(0,&indydog_alive);
expect_close = 0;
return 0; return 0;
} }
...@@ -109,7 +110,7 @@ static ssize_t indydog_write(struct file *file, const char *data, size_t len, lo ...@@ -109,7 +110,7 @@ static ssize_t indydog_write(struct file *file, const char *data, size_t len, lo
if (get_user(c, data + i)) if (get_user(c, data + i))
return -EFAULT; return -EFAULT;
if (c == 'V') if (c == 'V')
expect_close = 1; expect_close = 42;
} }
} }
indydog_ping(); indydog_ping();
......
/* /*
* MachZ ZF-Logic Watchdog Timer driver for Linux * MachZ ZF-Logic Watchdog Timer driver for Linux
* *
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
...@@ -14,14 +14,14 @@ ...@@ -14,14 +14,14 @@
* Author: Fernando Fuganti <fuganti@conectiva.com.br> * Author: Fernando Fuganti <fuganti@conectiva.com.br>
* *
* Based on sbc60xxwdt.c by Jakob Oestergaard * Based on sbc60xxwdt.c by Jakob Oestergaard
*
* *
* We have two timers (wd#1, wd#2) driven by a 32 KHz clock with the *
* We have two timers (wd#1, wd#2) driven by a 32 KHz clock with the
* following periods: * following periods:
* wd#1 - 2 seconds; * wd#1 - 2 seconds;
* wd#2 - 7.2 ms; * wd#2 - 7.2 ms;
* After the expiration of wd#1, it can generate a NMI, SCI, SMI, or * After the expiration of wd#1, it can generate a NMI, SCI, SMI, or
* a system RESET and it starts wd#2 that unconditionaly will RESET * a system RESET and it starts wd#2 that unconditionaly will RESET
* the system when the counter reaches zero. * the system when the counter reaches zero.
* *
* 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com> * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
/* indexes */ /* size */ /* indexes */ /* size */
#define ZFL_VERSION 0x02 /* 16 */ #define ZFL_VERSION 0x02 /* 16 */
#define CONTROL 0x10 /* 16 */ #define CONTROL 0x10 /* 16 */
#define STATUS 0x12 /* 8 */ #define STATUS 0x12 /* 8 */
#define COUNTER_1 0x0C /* 16 */ #define COUNTER_1 0x0C /* 16 */
#define COUNTER_2 0x0E /* 8 */ #define COUNTER_2 0x0E /* 8 */
...@@ -111,9 +111,9 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON ...@@ -111,9 +111,9 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
#define PFX "machzwd" #define PFX "machzwd"
static struct watchdog_info zf_info = { static struct watchdog_info zf_info = {
.options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
.firmware_version = 1, .firmware_version = 1,
.identity = "ZF-Logic watchdog" .identity = "ZF-Logic watchdog",
}; };
...@@ -130,8 +130,8 @@ module_param(action, int, 0); ...@@ -130,8 +130,8 @@ module_param(action, int, 0);
MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI"); MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*) 1 = SMI 2 = NMI 3 = SCI");
static int zf_action = GEN_RESET; static int zf_action = GEN_RESET;
static int zf_is_open = 0; static unsigned long zf_is_open;
static int zf_expect_close = 0; static char zf_expect_close;
static spinlock_t zf_lock; static spinlock_t zf_lock;
static spinlock_t zf_port_lock; static spinlock_t zf_port_lock;
static struct timer_list zf_timer; static struct timer_list zf_timer;
...@@ -225,7 +225,7 @@ static void zf_timer_off(void) ...@@ -225,7 +225,7 @@ static void zf_timer_off(void)
del_timer_sync(&zf_timer); del_timer_sync(&zf_timer);
spin_lock_irqsave(&zf_port_lock, flags); spin_lock_irqsave(&zf_port_lock, flags);
/* stop watchdog timer */ /* stop watchdog timer */
ctrl_reg = zf_get_control(); ctrl_reg = zf_get_control();
ctrl_reg |= (ENABLE_WD1|ENABLE_WD2); /* disable wd1 and wd2 */ ctrl_reg |= (ENABLE_WD1|ENABLE_WD2); /* disable wd1 and wd2 */
ctrl_reg &= ~(ENABLE_WD1|ENABLE_WD2); ctrl_reg &= ~(ENABLE_WD1|ENABLE_WD2);
...@@ -237,13 +237,13 @@ static void zf_timer_off(void) ...@@ -237,13 +237,13 @@ static void zf_timer_off(void)
/* /*
* start hardware timer * start hardware timer
*/ */
static void zf_timer_on(void) static void zf_timer_on(void)
{ {
unsigned int ctrl_reg = 0; unsigned int ctrl_reg = 0;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&zf_port_lock, flags); spin_lock_irqsave(&zf_port_lock, flags);
zf_writeb(PULSE_LEN, 0xff); zf_writeb(PULSE_LEN, 0xff);
...@@ -272,26 +272,26 @@ static void zf_ping(unsigned long data) ...@@ -272,26 +272,26 @@ static void zf_ping(unsigned long data)
{ {
unsigned int ctrl_reg = 0; unsigned int ctrl_reg = 0;
unsigned long flags; unsigned long flags;
zf_writeb(COUNTER_2, 0xff); zf_writeb(COUNTER_2, 0xff);
if(time_before(jiffies, next_heartbeat)){ if(time_before(jiffies, next_heartbeat)){
dprintk("time_before: %ld\n", next_heartbeat - jiffies); dprintk("time_before: %ld\n", next_heartbeat - jiffies);
/* /*
* reset event is activated by transition from 0 to 1 on * reset event is activated by transition from 0 to 1 on
* RESET_WD1 bit and we assume that it is already zero... * RESET_WD1 bit and we assume that it is already zero...
*/ */
spin_lock_irqsave(&zf_port_lock, flags); spin_lock_irqsave(&zf_port_lock, flags);
ctrl_reg = zf_get_control(); ctrl_reg = zf_get_control();
ctrl_reg |= RESET_WD1; ctrl_reg |= RESET_WD1;
zf_set_control(ctrl_reg); zf_set_control(ctrl_reg);
/* ...and nothing changes until here */ /* ...and nothing changes until here */
ctrl_reg &= ~(RESET_WD1); ctrl_reg &= ~(RESET_WD1);
zf_set_control(ctrl_reg); zf_set_control(ctrl_reg);
spin_unlock_irqrestore(&zf_port_lock, flags); spin_unlock_irqrestore(&zf_port_lock, flags);
zf_timer.expires = jiffies + ZF_HW_TIMEO; zf_timer.expires = jiffies + ZF_HW_TIMEO;
...@@ -301,7 +301,7 @@ static void zf_ping(unsigned long data) ...@@ -301,7 +301,7 @@ static void zf_ping(unsigned long data)
} }
} }
static ssize_t zf_write(struct file *file, const char *buf, size_t count, static ssize_t zf_write(struct file *file, const char *buf, size_t count,
loff_t *ppos) loff_t *ppos)
{ {
/* Can't seek (pwrite) on this device */ /* Can't seek (pwrite) on this device */
...@@ -317,21 +317,21 @@ static ssize_t zf_write(struct file *file, const char *buf, size_t count, ...@@ -317,21 +317,21 @@ static ssize_t zf_write(struct file *file, const char *buf, size_t count,
*/ */
if (!nowayout) { if (!nowayout) {
size_t ofs; size_t ofs;
/* /*
* note: just in case someone wrote the magic character * note: just in case someone wrote the magic character
* five months ago... * five months ago...
*/ */
zf_expect_close = 0; zf_expect_close = 0;
/* now scan */ /* now scan */
for (ofs = 0; ofs != count; ofs++){ for (ofs = 0; ofs != count; ofs++){
char c; char c;
if (get_user(c, buf + ofs)) if (get_user(c, buf + ofs))
return -EFAULT; return -EFAULT;
if (c == 'V'){ if (c == 'V'){
zf_expect_close = 1; zf_expect_close = 42;
dprintk("zf_expect_close 1\n"); dprintk("zf_expect_close = 42\n");
} }
} }
} }
...@@ -342,7 +342,7 @@ static ssize_t zf_write(struct file *file, const char *buf, size_t count, ...@@ -342,7 +342,7 @@ static ssize_t zf_write(struct file *file, const char *buf, size_t count,
*/ */
next_heartbeat = jiffies + ZF_USER_TIMEO; next_heartbeat = jiffies + ZF_USER_TIMEO;
dprintk("user ping at %ld\n", jiffies); dprintk("user ping at %ld\n", jiffies);
} }
return count; return count;
...@@ -353,22 +353,20 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -353,22 +353,20 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
{ {
switch(cmd){ switch(cmd){
case WDIOC_GETSUPPORT: case WDIOC_GETSUPPORT:
if (copy_to_user((struct watchdog_info *)arg, if (copy_to_user((struct watchdog_info *)arg,
&zf_info, sizeof(zf_info))) &zf_info, sizeof(zf_info)))
return -EFAULT; return -EFAULT;
break; break;
case WDIOC_GETSTATUS: case WDIOC_GETSTATUS:
if (copy_to_user((int *)arg, &zf_is_open, sizeof(int))) return put_user(0, (int *) arg);
return -EFAULT;
break;
case WDIOC_KEEPALIVE: case WDIOC_KEEPALIVE:
zf_ping(0); zf_ping(0);
break; break;
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
} }
return 0; return 0;
...@@ -376,47 +374,37 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -376,47 +374,37 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static int zf_open(struct inode *inode, struct file *file) static int zf_open(struct inode *inode, struct file *file)
{ {
switch(iminor(inode)){ spin_lock(&zf_lock);
case WATCHDOG_MINOR: if(test_and_set_bit(0, &zf_is_open)) {
spin_lock(&zf_lock); spin_unlock(&zf_lock);
if(zf_is_open){ return -EBUSY;
spin_unlock(&zf_lock); }
return -EBUSY;
}
if (nowayout)
__module_get(THIS_MODULE);
zf_is_open = 1; if (nowayout)
__module_get(THIS_MODULE);
spin_unlock(&zf_lock); spin_unlock(&zf_lock);
zf_timer_on(); zf_timer_on();
return 0; return 0;
default:
return -ENODEV;
}
} }
static int zf_close(struct inode *inode, struct file *file) static int zf_close(struct inode *inode, struct file *file)
{ {
if(iminor(inode) == WATCHDOG_MINOR){ if(zf_expect_close == 42){
zf_timer_off();
} else {
del_timer(&zf_timer);
printk(KERN_ERR PFX ": device file closed unexpectedly. Will not stop the WDT!\n");
}
if(zf_expect_close){ spin_lock(&zf_lock);
zf_timer_off(); clear_bit(0, &zf_is_open);
} else { spin_unlock(&zf_lock);
del_timer(&zf_timer);
printk(KERN_ERR PFX ": device file closed unexpectedly. Will not stop the WDT!\n"); zf_expect_close = 0;
}
spin_lock(&zf_lock);
zf_is_open = 0;
spin_unlock(&zf_lock);
zf_expect_close = 0;
}
return 0; return 0;
} }
...@@ -428,9 +416,9 @@ static int zf_notify_sys(struct notifier_block *this, unsigned long code, ...@@ -428,9 +416,9 @@ static int zf_notify_sys(struct notifier_block *this, unsigned long code,
void *unused) void *unused)
{ {
if(code == SYS_DOWN || code == SYS_HALT){ if(code == SYS_DOWN || code == SYS_HALT){
zf_timer_off(); zf_timer_off();
} }
return NOTIFY_DONE; return NOTIFY_DONE;
} }
...@@ -448,9 +436,9 @@ static struct file_operations zf_fops = { ...@@ -448,9 +436,9 @@ static struct file_operations zf_fops = {
static struct miscdevice zf_miscdev = { static struct miscdevice zf_miscdev = {
.minor = WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
.name = "watchdog", .name = "watchdog",
.fops = &zf_fops .fops = &zf_fops,
}; };
/* /*
* The device needs to learn about soft shutdowns in order to * The device needs to learn about soft shutdowns in order to
...@@ -459,20 +447,20 @@ static struct miscdevice zf_miscdev = { ...@@ -459,20 +447,20 @@ static struct miscdevice zf_miscdev = {
static struct notifier_block zf_notifier = { static struct notifier_block zf_notifier = {
.notifier_call = zf_notify_sys, .notifier_call = zf_notify_sys,
.next = NULL, .next = NULL,
.priority = 0 .priority = 0,
}; };
static void __init zf_show_action(int act) static void __init zf_show_action(int act)
{ {
char *str[] = { "RESET", "SMI", "NMI", "SCI" }; char *str[] = { "RESET", "SMI", "NMI", "SCI" };
printk(KERN_INFO PFX ": Watchdog using action = %s\n", str[act]); printk(KERN_INFO PFX ": Watchdog using action = %s\n", str[act]);
} }
static int __init zf_init(void) static int __init zf_init(void)
{ {
int ret; int ret;
printk(KERN_INFO PFX ": MachZ ZF-Logic Watchdog driver initializing.\n"); printk(KERN_INFO PFX ": MachZ ZF-Logic Watchdog driver initializing.\n");
ret = zf_get_ZFL_version(); ret = zf_get_ZFL_version();
...@@ -486,12 +474,12 @@ static int __init zf_init(void) ...@@ -486,12 +474,12 @@ static int __init zf_init(void)
zf_action = zf_action>>action; zf_action = zf_action>>action;
} else } else
action = 0; action = 0;
zf_show_action(action); zf_show_action(action);
spin_lock_init(&zf_lock); spin_lock_init(&zf_lock);
spin_lock_init(&zf_port_lock); spin_lock_init(&zf_port_lock);
ret = misc_register(&zf_miscdev); ret = misc_register(&zf_miscdev);
if (ret){ if (ret){
printk(KERN_ERR "can't misc_register on minor=%d\n", printk(KERN_ERR "can't misc_register on minor=%d\n",
...@@ -512,7 +500,7 @@ static int __init zf_init(void) ...@@ -512,7 +500,7 @@ static int __init zf_init(void)
ret); ret);
goto no_reboot; goto no_reboot;
} }
zf_set_status(0); zf_set_status(0);
zf_set_control(0); zf_set_control(0);
...@@ -520,7 +508,7 @@ static int __init zf_init(void) ...@@ -520,7 +508,7 @@ static int __init zf_init(void)
init_timer(&zf_timer); init_timer(&zf_timer);
zf_timer.function = zf_ping; zf_timer.function = zf_ping;
zf_timer.data = 0; zf_timer.data = 0;
return 0; return 0;
no_reboot: no_reboot:
...@@ -531,11 +519,11 @@ static int __init zf_init(void) ...@@ -531,11 +519,11 @@ static int __init zf_init(void)
return ret; return ret;
} }
void __exit zf_exit(void) void __exit zf_exit(void)
{ {
zf_timer_off(); zf_timer_off();
misc_deregister(&zf_miscdev); misc_deregister(&zf_miscdev);
unregister_reboot_notifier(&zf_notifier); unregister_reboot_notifier(&zf_notifier);
release_region(ZF_IOBASE, 3); release_region(ZF_IOBASE, 3);
......
...@@ -30,11 +30,11 @@ ...@@ -30,11 +30,11 @@
* *
* Version 0.5 (2001/12/14) Matt Domsch <Matt_Domsch@dell.com> * Version 0.5 (2001/12/14) Matt Domsch <Matt_Domsch@dell.com>
* - added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT * - added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
* *
*/ */
#define VERSION "0.5" #define VERSION "0.5"
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/config.h> #include <linux/config.h>
...@@ -55,12 +55,12 @@ static int mixcomwd_ioports[] = { 0x180, 0x280, 0x380, 0x000 }; ...@@ -55,12 +55,12 @@ static int mixcomwd_ioports[] = { 0x180, 0x280, 0x380, 0x000 };
#define FLASHCOM_WATCHDOG_OFFSET 0x4 #define FLASHCOM_WATCHDOG_OFFSET 0x4
#define FLASHCOM_ID 0x18 #define FLASHCOM_ID 0x18
static long mixcomwd_opened; /* long req'd for setbit --RR */ static unsigned long mixcomwd_opened; /* long req'd for setbit --RR */
static int watchdog_port; static int watchdog_port;
static int mixcomwd_timer_alive; static int mixcomwd_timer_alive;
static struct timer_list mixcomwd_timer = TIMER_INITIALIZER(NULL, 0, 0); static struct timer_list mixcomwd_timer = TIMER_INITIALIZER(NULL, 0, 0);
static int expect_close = 0; static char expect_close;
#ifdef CONFIG_WATCHDOG_NOWAYOUT #ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1; static int nowayout = 1;
...@@ -80,21 +80,21 @@ static void mixcomwd_ping(void) ...@@ -80,21 +80,21 @@ static void mixcomwd_ping(void)
static void mixcomwd_timerfun(unsigned long d) static void mixcomwd_timerfun(unsigned long d)
{ {
mixcomwd_ping(); mixcomwd_ping();
mod_timer(&mixcomwd_timer,jiffies+ 5*HZ); mod_timer(&mixcomwd_timer,jiffies+ 5*HZ);
} }
/* /*
* Allow only one person to hold it open * Allow only one person to hold it open
*/ */
static int mixcomwd_open(struct inode *inode, struct file *file) static int mixcomwd_open(struct inode *inode, struct file *file)
{ {
if(test_and_set_bit(0,&mixcomwd_opened)) { if(test_and_set_bit(0,&mixcomwd_opened)) {
return -EBUSY; return -EBUSY;
} }
mixcomwd_ping(); mixcomwd_ping();
if (nowayout) { if (nowayout) {
/* /*
* fops_get() code via open() has already done * fops_get() code via open() has already done
...@@ -113,7 +113,7 @@ static int mixcomwd_open(struct inode *inode, struct file *file) ...@@ -113,7 +113,7 @@ static int mixcomwd_open(struct inode *inode, struct file *file)
static int mixcomwd_release(struct inode *inode, struct file *file) static int mixcomwd_release(struct inode *inode, struct file *file)
{ {
if (expect_close) { if (expect_close == 42) {
if(mixcomwd_timer_alive) { if(mixcomwd_timer_alive) {
printk(KERN_ERR "mixcomwd: release called while internal timer alive"); printk(KERN_ERR "mixcomwd: release called while internal timer alive");
return -EBUSY; return -EBUSY;
...@@ -129,6 +129,7 @@ static int mixcomwd_release(struct inode *inode, struct file *file) ...@@ -129,6 +129,7 @@ static int mixcomwd_release(struct inode *inode, struct file *file)
} }
clear_bit(0,&mixcomwd_opened); clear_bit(0,&mixcomwd_opened);
expect_close=0;
return 0; return 0;
} }
...@@ -152,7 +153,7 @@ static ssize_t mixcomwd_write(struct file *file, const char *data, size_t len, l ...@@ -152,7 +153,7 @@ static ssize_t mixcomwd_write(struct file *file, const char *data, size_t len, l
if (get_user(c, data + i)) if (get_user(c, data + i))
return -EFAULT; return -EFAULT;
if (c == 'V') if (c == 'V')
expect_close = 1; expect_close = 42;
} }
} }
mixcomwd_ping(); mixcomwd_ping();
...@@ -167,9 +168,9 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file, ...@@ -167,9 +168,9 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
static struct watchdog_info ident = { static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
.firmware_version = 1, .firmware_version = 1,
.identity = "MixCOM watchdog" .identity = "MixCOM watchdog",
}; };
switch(cmd) switch(cmd)
{ {
case WDIOC_GETSTATUS: case WDIOC_GETSTATUS:
...@@ -182,7 +183,7 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file, ...@@ -182,7 +183,7 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
} }
break; break;
case WDIOC_GETSUPPORT: case WDIOC_GETSUPPORT:
if (copy_to_user((struct watchdog_info *)arg, &ident, if (copy_to_user((struct watchdog_info *)arg, &ident,
sizeof(ident))) { sizeof(ident))) {
return -EFAULT; return -EFAULT;
} }
...@@ -191,7 +192,7 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file, ...@@ -191,7 +192,7 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
mixcomwd_ping(); mixcomwd_ping();
break; break;
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
} }
return 0; return 0;
} }
...@@ -207,9 +208,9 @@ static struct file_operations mixcomwd_fops= ...@@ -207,9 +208,9 @@ static struct file_operations mixcomwd_fops=
static struct miscdevice mixcomwd_miscdev= static struct miscdevice mixcomwd_miscdev=
{ {
WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
"watchdog", .name = "watchdog",
&mixcomwd_fops .fops = &mixcomwd_fops,
}; };
static int __init mixcomwd_checkcard(int port) static int __init mixcomwd_checkcard(int port)
...@@ -220,7 +221,7 @@ static int __init mixcomwd_checkcard(int port) ...@@ -220,7 +221,7 @@ static int __init mixcomwd_checkcard(int port)
if (!request_region(port, 1, "MixCOM watchdog")) { if (!request_region(port, 1, "MixCOM watchdog")) {
return 0; return 0;
} }
id=inb_p(port) & 0x3f; id=inb_p(port) & 0x3f;
if(id!=MIXCOM_ID) { if(id!=MIXCOM_ID) {
release_region(port, 1); release_region(port, 1);
...@@ -232,12 +233,12 @@ static int __init mixcomwd_checkcard(int port) ...@@ -232,12 +233,12 @@ static int __init mixcomwd_checkcard(int port)
static int __init flashcom_checkcard(int port) static int __init flashcom_checkcard(int port)
{ {
int id; int id;
port += FLASHCOM_WATCHDOG_OFFSET; port += FLASHCOM_WATCHDOG_OFFSET;
if (!request_region(port, 1, "MixCOM watchdog")) { if (!request_region(port, 1, "MixCOM watchdog")) {
return 0; return 0;
} }
id=inb_p(port); id=inb_p(port);
if(id!=FLASHCOM_ID) { if(id!=FLASHCOM_ID) {
release_region(port, 1); release_region(port, 1);
...@@ -245,7 +246,7 @@ static int __init flashcom_checkcard(int port) ...@@ -245,7 +246,7 @@ static int __init flashcom_checkcard(int port)
} }
return port; return port;
} }
static int __init mixcomwd_init(void) static int __init mixcomwd_init(void)
{ {
int i; int i;
...@@ -258,7 +259,7 @@ static int __init mixcomwd_init(void) ...@@ -258,7 +259,7 @@ static int __init mixcomwd_init(void)
found = 1; found = 1;
} }
} }
/* The FlashCOM card can be set up at 0x300 -> 0x378, in 0x8 jumps */ /* The FlashCOM card can be set up at 0x300 -> 0x378, in 0x8 jumps */
for (i = 0x300; !found && i < 0x380; i+=0x8) { for (i = 0x300; !found && i < 0x380; i+=0x8) {
watchdog_port = flashcom_checkcard(i); watchdog_port = flashcom_checkcard(i);
...@@ -266,7 +267,7 @@ static int __init mixcomwd_init(void) ...@@ -266,7 +267,7 @@ static int __init mixcomwd_init(void)
found = 1; found = 1;
} }
} }
if (!found) { if (!found) {
printk("mixcomwd: No card detected, or port not available.\n"); printk("mixcomwd: No card detected, or port not available.\n");
return -ENODEV; return -ENODEV;
...@@ -278,11 +279,11 @@ static int __init mixcomwd_init(void) ...@@ -278,11 +279,11 @@ static int __init mixcomwd_init(void)
release_region(watchdog_port, 1); release_region(watchdog_port, 1);
return ret; return ret;
} }
printk(KERN_INFO "MixCOM watchdog driver v%s, watchdog port at 0x%3x\n",VERSION,watchdog_port); printk(KERN_INFO "MixCOM watchdog driver v%s, watchdog port at 0x%3x\n",VERSION,watchdog_port);
return 0; return 0;
} }
static void __exit mixcomwd_exit(void) static void __exit mixcomwd_exit(void)
{ {
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
* 971222 Changed open/close for temperature handling * 971222 Changed open/close for temperature handling
* Michael Meskes <meskes@debian.org>. * Michael Meskes <meskes@debian.org>.
* 980112 Used minor numbers from include/linux/miscdevice.h * 980112 Used minor numbers from include/linux/miscdevice.h
* 990403 Clear reset status after reading control status register in * 990403 Clear reset status after reading control status register in
* pcwd_showprevstate(). [Marc Boucher <marc@mbsi.ca>] * pcwd_showprevstate(). [Marc Boucher <marc@mbsi.ca>]
* 990605 Made changes to code to support Firmware 1.22a, added * 990605 Made changes to code to support Firmware 1.22a, added
* fairly useless proc entry. * fairly useless proc entry.
...@@ -86,10 +86,10 @@ static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 }; ...@@ -86,10 +86,10 @@ static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 };
#define WD_TIMEOUT 4 /* 2 seconds for a timeout */ #define WD_TIMEOUT 4 /* 2 seconds for a timeout */
static int timeout_val = WD_TIMEOUT; static int timeout_val = WD_TIMEOUT;
static int timeout = 2; static int timeout = 2;
static int expect_close = 0; static char expect_close;
module_param(timeout, int, 0); module_param(timeout, int, 0);
MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=2)"); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=2)");
#ifdef CONFIG_WATCHDOG_NOWAYOUT #ifdef CONFIG_WATCHDOG_NOWAYOUT
static int nowayout = 1; static int nowayout = 1;
...@@ -248,14 +248,14 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, ...@@ -248,14 +248,14 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
int cdat, rv; int cdat, rv;
static struct watchdog_info ident= static struct watchdog_info ident=
{ {
WDIOF_OVERHEAT|WDIOF_CARDRESET, .options = WDIOF_OVERHEAT|WDIOF_CARDRESET,
1, .firmware_version = 1,
"PCWD" .identity = "PCWD",
}; };
switch(cmd) { switch(cmd) {
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT: case WDIOC_GETSUPPORT:
if(copy_to_user((void*)arg, &ident, sizeof(ident))) if(copy_to_user((void*)arg, &ident, sizeof(ident)))
...@@ -264,19 +264,19 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, ...@@ -264,19 +264,19 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
case WDIOC_GETSTATUS: case WDIOC_GETSTATUS:
spin_lock(&io_lock); spin_lock(&io_lock);
if (revision == PCWD_REVISION_A) if (revision == PCWD_REVISION_A)
cdat = inb(current_readport); cdat = inb(current_readport);
else else
cdat = inb(current_readport + 1 ); cdat = inb(current_readport + 1 );
spin_unlock(&io_lock); spin_unlock(&io_lock);
rv = WDIOF_MAGICCLOSE; rv = WDIOF_MAGICCLOSE;
if (revision == PCWD_REVISION_A) if (revision == PCWD_REVISION_A)
{ {
if (cdat & WD_WDRST) if (cdat & WD_WDRST)
rv |= WDIOF_CARDRESET; rv |= WDIOF_CARDRESET;
if (cdat & WD_T110) if (cdat & WD_T110)
{ {
rv |= WDIOF_OVERHEAT; rv |= WDIOF_OVERHEAT;
...@@ -286,12 +286,12 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, ...@@ -286,12 +286,12 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
} }
} }
} }
else else
{ {
if (cdat & 0x01) if (cdat & 0x01)
rv |= WDIOF_CARDRESET; rv |= WDIOF_CARDRESET;
if (cdat & 0x04) if (cdat & 0x04)
{ {
rv |= WDIOF_OVERHEAT; rv |= WDIOF_OVERHEAT;
...@@ -309,7 +309,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, ...@@ -309,7 +309,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
case WDIOC_GETBOOTSTATUS: case WDIOC_GETBOOTSTATUS:
rv = 0; rv = 0;
if (revision == PCWD_REVISION_A) if (revision == PCWD_REVISION_A)
{ {
if (initial_status & WD_WDRST) if (initial_status & WD_WDRST)
rv |= WDIOF_CARDRESET; rv |= WDIOF_CARDRESET;
...@@ -333,7 +333,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, ...@@ -333,7 +333,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
case WDIOC_GETTEMP: case WDIOC_GETTEMP:
rv = 0; rv = 0;
if ((supports_temp) && (mode_debug == 0)) if ((supports_temp) && (mode_debug == 0))
{ {
spin_lock(&io_lock); spin_lock(&io_lock);
rv = inb(current_readport); rv = inb(current_readport);
...@@ -345,19 +345,19 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, ...@@ -345,19 +345,19 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
return 0; return 0;
case WDIOC_SETOPTIONS: case WDIOC_SETOPTIONS:
if (revision == PCWD_REVISION_C) if (revision == PCWD_REVISION_C)
{ {
if(copy_from_user(&rv, (int*) arg, sizeof(int))) if(copy_from_user(&rv, (int*) arg, sizeof(int)))
return -EFAULT; return -EFAULT;
if (rv & WDIOS_DISABLECARD) if (rv & WDIOS_DISABLECARD)
{ {
spin_lock(&io_lock); spin_lock(&io_lock);
outb_p(0xA5, current_readport + 3); outb_p(0xA5, current_readport + 3);
outb_p(0xA5, current_readport + 3); outb_p(0xA5, current_readport + 3);
cdat = inb_p(current_readport + 2); cdat = inb_p(current_readport + 2);
spin_unlock(&io_lock); spin_unlock(&io_lock);
if ((cdat & 0x10) == 0) if ((cdat & 0x10) == 0)
{ {
printk(KERN_INFO "pcwd: Could not disable card.\n"); printk(KERN_INFO "pcwd: Could not disable card.\n");
return -EIO; return -EIO;
...@@ -366,13 +366,13 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, ...@@ -366,13 +366,13 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
return 0; return 0;
} }
if (rv & WDIOS_ENABLECARD) if (rv & WDIOS_ENABLECARD)
{ {
spin_lock(&io_lock); spin_lock(&io_lock);
outb_p(0x00, current_readport + 3); outb_p(0x00, current_readport + 3);
cdat = inb_p(current_readport + 2); cdat = inb_p(current_readport + 2);
spin_unlock(&io_lock); spin_unlock(&io_lock);
if (cdat & 0x10) if (cdat & 0x10)
{ {
printk(KERN_INFO "pcwd: Could not enable card.\n"); printk(KERN_INFO "pcwd: Could not enable card.\n");
return -EIO; return -EIO;
...@@ -380,13 +380,13 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, ...@@ -380,13 +380,13 @@ static int pcwd_ioctl(struct inode *inode, struct file *file,
return 0; return 0;
} }
if (rv & WDIOS_TEMPPANIC) if (rv & WDIOS_TEMPPANIC)
{ {
temp_panic = 1; temp_panic = 1;
} }
} }
return -EINVAL; return -EINVAL;
case WDIOC_KEEPALIVE: case WDIOC_KEEPALIVE:
pcwd_send_heartbeat(); pcwd_send_heartbeat();
return 0; return 0;
...@@ -415,7 +415,7 @@ static ssize_t pcwd_write(struct file *file, const char *buf, size_t len, ...@@ -415,7 +415,7 @@ static ssize_t pcwd_write(struct file *file, const char *buf, size_t len,
if (get_user(c, buf + i)) if (get_user(c, buf + i))
return -EFAULT; return -EFAULT;
if (c == 'V') if (c == 'V')
expect_close = 1; expect_close = 42;
} }
} }
pcwd_send_heartbeat(); pcwd_send_heartbeat();
...@@ -456,14 +456,14 @@ static ssize_t pcwd_read(struct file *file, char *buf, size_t count, ...@@ -456,14 +456,14 @@ static ssize_t pcwd_read(struct file *file, char *buf, size_t count,
/* Can't seek (pread) on this device */ /* Can't seek (pread) on this device */
if (ppos != &file->f_pos) if (ppos != &file->f_pos)
return -ESPIPE; return -ESPIPE;
switch(iminor(file->f_dentry->d_inode)) switch(iminor(file->f_dentry->d_inode))
{ {
case TEMP_MINOR: case TEMP_MINOR:
/* /*
* Convert metric to Fahrenheit, since this was * Convert metric to Fahrenheit, since this was
* the decided 'standard' for this return value. * the decided 'standard' for this return value.
*/ */
c = inb(current_readport); c = inb(current_readport);
cp = (c * 9 / 5) + 32; cp = (c * 9 / 5) + 32;
if(copy_to_user(buf, &cp, 1)) if(copy_to_user(buf, &cp, 1))
...@@ -477,7 +477,7 @@ static ssize_t pcwd_read(struct file *file, char *buf, size_t count, ...@@ -477,7 +477,7 @@ static ssize_t pcwd_read(struct file *file, char *buf, size_t count,
static int pcwd_close(struct inode *ino, struct file *filep) static int pcwd_close(struct inode *ino, struct file *filep)
{ {
if (iminor(ino)==WATCHDOG_MINOR) { if (iminor(ino)==WATCHDOG_MINOR) {
if (expect_close) { if (expect_close == 42) {
/* Disable the board */ /* Disable the board */
if (revision == PCWD_REVISION_C) { if (revision == PCWD_REVISION_C) {
spin_lock(&io_lock); spin_lock(&io_lock);
...@@ -488,6 +488,7 @@ static int pcwd_close(struct inode *ino, struct file *filep) ...@@ -488,6 +488,7 @@ static int pcwd_close(struct inode *ino, struct file *filep)
atomic_inc( &open_allowed ); atomic_inc( &open_allowed );
} }
} }
expect_close = 0;
return 0; return 0;
} }
...@@ -500,7 +501,7 @@ static inline void get_support(void) ...@@ -500,7 +501,7 @@ static inline void get_support(void)
static inline int get_revision(void) static inline int get_revision(void)
{ {
int r = PCWD_REVISION_C; int r = PCWD_REVISION_C;
spin_lock(&io_lock); spin_lock(&io_lock);
if ((inb(current_readport + 2) == 0xFF) || if ((inb(current_readport + 2) == 0xFF) ||
(inb(current_readport + 3) == 0xFF)) (inb(current_readport + 3) == 0xFF))
...@@ -576,29 +577,29 @@ static struct file_operations pcwd_fops = { ...@@ -576,29 +577,29 @@ static struct file_operations pcwd_fops = {
}; };
static struct miscdevice pcwd_miscdev = { static struct miscdevice pcwd_miscdev = {
WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
"watchdog", .name = "watchdog",
&pcwd_fops .fops = &pcwd_fops,
}; };
static struct miscdevice temp_miscdev = { static struct miscdevice temp_miscdev = {
TEMP_MINOR, .minor = TEMP_MINOR,
"temperature", .name = "temperature",
&pcwd_fops .fops = &pcwd_fops,
}; };
static void __init pcwd_validate_timeout(void) static void __init pcwd_validate_timeout(void)
{ {
timeout_val = timeout * 2; timeout_val = timeout * 2;
} }
static int __init pcwatchdog_init(void) static int __init pcwatchdog_init(void)
{ {
char *firmware; char *firmware;
int i, found = 0; int i, found = 0;
pcwd_validate_timeout(); pcwd_validate_timeout();
spin_lock_init(&io_lock); spin_lock_init(&io_lock);
revision = PCWD_REVISION_A; revision = PCWD_REVISION_A;
printk(KERN_INFO "pcwd: v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER); printk(KERN_INFO "pcwd: v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER);
...@@ -660,11 +661,11 @@ static int __init pcwatchdog_init(void) ...@@ -660,11 +661,11 @@ static int __init pcwatchdog_init(void)
if (misc_register(&pcwd_miscdev)) if (misc_register(&pcwd_miscdev))
return -ENODEV; return -ENODEV;
if (supports_temp) if (supports_temp)
if (misc_register(&temp_miscdev)) { if (misc_register(&temp_miscdev)) {
misc_deregister(&pcwd_miscdev); misc_deregister(&pcwd_miscdev);
return -ENODEV; return -ENODEV;
} }
...@@ -673,10 +674,10 @@ static int __init pcwatchdog_init(void) ...@@ -673,10 +674,10 @@ static int __init pcwatchdog_init(void)
misc_deregister(&pcwd_miscdev); misc_deregister(&pcwd_miscdev);
if (supports_temp) if (supports_temp)
misc_deregister(&pcwd_miscdev); misc_deregister(&pcwd_miscdev);
return -EIO; return -EIO;
} }
} }
else else
if (!request_region(current_readport, 4, "PCWD Rev.C (Berkshire)")) { if (!request_region(current_readport, 4, "PCWD Rev.C (Berkshire)")) {
misc_deregister(&pcwd_miscdev); misc_deregister(&pcwd_miscdev);
if (supports_temp) if (supports_temp)
......
...@@ -77,6 +77,7 @@ static int sa1100dog_release(struct inode *inode, struct file *file) ...@@ -77,6 +77,7 @@ static int sa1100dog_release(struct inode *inode, struct file *file)
} }
clear_bit(1, &sa1100wdt_users); clear_bit(1, &sa1100wdt_users);
expect_close = 0;
return 0; return 0;
} }
......
...@@ -183,7 +183,7 @@ static ssize_t fop_write(struct file * file, const char * buf, size_t count, lof ...@@ -183,7 +183,7 @@ static ssize_t fop_write(struct file * file, const char * buf, size_t count, lof
* five months ago... */ * five months ago... */
wdt_expect_close = 0; wdt_expect_close = 0;
/* scan to see wether or not we got the magic character */ /* scan to see whether or not we got the magic character */
for(ofs = 0; ofs != count; ofs++) for(ofs = 0; ofs != count; ofs++)
{ {
char c; char c;
......
...@@ -175,12 +175,12 @@ static int sc1200wdt_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -175,12 +175,12 @@ static int sc1200wdt_ioctl(struct inode *inode, struct file *file, unsigned int
static struct watchdog_info ident = { static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
.firmware_version = 0, .firmware_version = 0,
.identity = "PC87307/PC97307" .identity = "PC87307/PC97307",
}; };
switch (cmd) { switch (cmd) {
default: default:
return -ENOTTY; /* Keep Pavel Machek amused ;) */ return -ENOIOCTLCMD; /* Keep Pavel Machek amused ;) */
case WDIOC_GETSUPPORT: case WDIOC_GETSUPPORT:
if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof ident)) if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof ident))
...@@ -256,7 +256,7 @@ static ssize_t sc1200wdt_write(struct file *file, const char *data, size_t len, ...@@ -256,7 +256,7 @@ static ssize_t sc1200wdt_write(struct file *file, const char *data, size_t len,
{ {
if (ppos != &file->f_pos) if (ppos != &file->f_pos)
return -ESPIPE; return -ESPIPE;
if (len) { if (len) {
if (!nowayout) { if (!nowayout) {
size_t i; size_t i;
...@@ -292,7 +292,7 @@ static int sc1200wdt_notify_sys(struct notifier_block *this, unsigned long code, ...@@ -292,7 +292,7 @@ static int sc1200wdt_notify_sys(struct notifier_block *this, unsigned long code,
static struct notifier_block sc1200wdt_notifier = static struct notifier_block sc1200wdt_notifier =
{ {
notifier_call: sc1200wdt_notify_sys .notifier_call = sc1200wdt_notify_sys,
}; };
static struct file_operations sc1200wdt_fops = static struct file_operations sc1200wdt_fops =
...@@ -301,7 +301,7 @@ static struct file_operations sc1200wdt_fops = ...@@ -301,7 +301,7 @@ static struct file_operations sc1200wdt_fops =
.write = sc1200wdt_write, .write = sc1200wdt_write,
.ioctl = sc1200wdt_ioctl, .ioctl = sc1200wdt_ioctl,
.open = sc1200wdt_open, .open = sc1200wdt_open,
.release = sc1200wdt_release .release = sc1200wdt_release,
}; };
static struct miscdevice sc1200wdt_miscdev = static struct miscdevice sc1200wdt_miscdev =
...@@ -320,7 +320,7 @@ static int __init sc1200wdt_probe(void) ...@@ -320,7 +320,7 @@ static int __init sc1200wdt_probe(void)
* Nb. This could be done with accuracy by reading the SID registers, but * Nb. This could be done with accuracy by reading the SID registers, but
* we don't have access to those io regions. * we don't have access to those io regions.
*/ */
unsigned char reg; unsigned char reg;
sc1200wdt_read_data(PMC3, &reg); sc1200wdt_read_data(PMC3, &reg);
...@@ -334,7 +334,7 @@ static int __init sc1200wdt_probe(void) ...@@ -334,7 +334,7 @@ static int __init sc1200wdt_probe(void)
struct pnp_device_id scl200wdt_pnp_devices[] = { struct pnp_device_id scl200wdt_pnp_devices[] = {
/* National Semiconductor PC87307/PC97307 watchdog component */ /* National Semiconductor PC87307/PC97307 watchdog component */
{.id = "NSC0800", .driver_data = 0}, {.id = "NSC0800", .driver_data = 0},
{.id = ""} {.id = ""},
}; };
static int scl200wdt_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) static int scl200wdt_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
...@@ -409,7 +409,7 @@ static int __init sc1200wdt_init(void) ...@@ -409,7 +409,7 @@ static int __init sc1200wdt_init(void)
ret = -EBUSY; ret = -EBUSY;
goto out_clean; goto out_clean;
} }
ret = sc1200wdt_probe(); ret = sc1200wdt_probe();
if (ret) if (ret)
goto out_io; goto out_io;
...@@ -438,7 +438,7 @@ static int __init sc1200wdt_init(void) ...@@ -438,7 +438,7 @@ static int __init sc1200wdt_init(void)
release_region(io, io_len); release_region(io, io_len);
goto out_clean; goto out_clean;
} }
static void __exit sc1200wdt_exit(void) static void __exit sc1200wdt_exit(void)
......
/* linux/drivers/char/scx200_wdt.c /* drivers/char/watchdog/scx200_wdt.c
National Semiconductor SCx200 Watchdog support National Semiconductor SCx200 Watchdog support
...@@ -51,7 +51,7 @@ MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); ...@@ -51,7 +51,7 @@ MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
static u16 wdto_restart; static u16 wdto_restart;
static struct semaphore open_semaphore; static struct semaphore open_semaphore;
static unsigned expect_close; static char expect_close;
/* Bits of the WDCNFG register */ /* Bits of the WDCNFG register */
#define W_ENABLE 0x00fa /* Enable watchdog */ #define W_ENABLE 0x00fa /* Enable watchdog */
...@@ -73,7 +73,7 @@ static void scx200_wdt_update_margin(void) ...@@ -73,7 +73,7 @@ static void scx200_wdt_update_margin(void)
static void scx200_wdt_enable(void) static void scx200_wdt_enable(void)
{ {
printk(KERN_DEBUG NAME ": enabling watchdog timer, wdto_restart = %d\n", printk(KERN_DEBUG NAME ": enabling watchdog timer, wdto_restart = %d\n",
wdto_restart); wdto_restart);
outw(0, SCx200_CB_BASE + SCx200_WDT_WDTO); outw(0, SCx200_CB_BASE + SCx200_WDT_WDTO);
...@@ -86,7 +86,7 @@ static void scx200_wdt_enable(void) ...@@ -86,7 +86,7 @@ static void scx200_wdt_enable(void)
static void scx200_wdt_disable(void) static void scx200_wdt_disable(void)
{ {
printk(KERN_DEBUG NAME ": disabling watchdog timer\n"); printk(KERN_DEBUG NAME ": disabling watchdog timer\n");
outw(0, SCx200_CB_BASE + SCx200_WDT_WDTO); outw(0, SCx200_CB_BASE + SCx200_WDT_WDTO);
outb(SCx200_WDT_WDSTS_WDOVF, SCx200_CB_BASE + SCx200_WDT_WDSTS); outb(SCx200_WDT_WDSTS_WDOVF, SCx200_CB_BASE + SCx200_WDT_WDSTS);
outw(W_DISABLE, SCx200_CB_BASE + SCx200_WDT_WDCNFG); outw(W_DISABLE, SCx200_CB_BASE + SCx200_WDT_WDCNFG);
...@@ -94,50 +94,50 @@ static void scx200_wdt_disable(void) ...@@ -94,50 +94,50 @@ static void scx200_wdt_disable(void)
static int scx200_wdt_open(struct inode *inode, struct file *file) static int scx200_wdt_open(struct inode *inode, struct file *file)
{ {
/* only allow one at a time */ /* only allow one at a time */
if (down_trylock(&open_semaphore)) if (down_trylock(&open_semaphore))
return -EBUSY; return -EBUSY;
scx200_wdt_enable(); scx200_wdt_enable();
expect_close = 0;
return 0; return 0;
} }
static int scx200_wdt_release(struct inode *inode, struct file *file) static int scx200_wdt_release(struct inode *inode, struct file *file)
{ {
if (!expect_close) { if (expect_close != 42) {
printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n"); printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n");
} else if (!nowayout) { } else if (!nowayout) {
scx200_wdt_disable(); scx200_wdt_disable();
} }
up(&open_semaphore); expect_close = 0;
up(&open_semaphore);
return 0; return 0;
} }
static int scx200_wdt_notify_sys(struct notifier_block *this, static int scx200_wdt_notify_sys(struct notifier_block *this,
unsigned long code, void *unused) unsigned long code, void *unused)
{ {
if (code == SYS_HALT || code == SYS_POWER_OFF) if (code == SYS_HALT || code == SYS_POWER_OFF)
if (!nowayout) if (!nowayout)
scx200_wdt_disable(); scx200_wdt_disable();
return NOTIFY_DONE; return NOTIFY_DONE;
} }
static struct notifier_block scx200_wdt_notifier = static struct notifier_block scx200_wdt_notifier =
{ {
.notifier_call = scx200_wdt_notify_sys .notifier_call = scx200_wdt_notify_sys,
}; };
static ssize_t scx200_wdt_write(struct file *file, const char *data, static ssize_t scx200_wdt_write(struct file *file, const char *data,
size_t len, loff_t *ppos) size_t len, loff_t *ppos)
{ {
if (ppos != &file->f_pos) if (ppos != &file->f_pos)
return -ESPIPE; return -ESPIPE;
/* check for a magic close character */ /* check for a magic close character */
if (len) if (len)
{ {
size_t i; size_t i;
...@@ -149,7 +149,7 @@ static ssize_t scx200_wdt_write(struct file *file, const char *data, ...@@ -149,7 +149,7 @@ static ssize_t scx200_wdt_write(struct file *file, const char *data,
if (get_user(c, data+i)) if (get_user(c, data+i))
return -EFAULT; return -EFAULT;
if (c == 'V') if (c == 'V')
expect_close = 1; expect_close = 42;
} }
return len; return len;
...@@ -163,16 +163,16 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file, ...@@ -163,16 +163,16 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file,
{ {
static struct watchdog_info ident = { static struct watchdog_info ident = {
.identity = "NatSemi SCx200 Watchdog", .identity = "NatSemi SCx200 Watchdog",
.firmware_version = 1, .firmware_version = 1,
.options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING), .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING),
}; };
int new_margin; int new_margin;
switch (cmd) { switch (cmd) {
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT: case WDIOC_GETSUPPORT:
if(copy_to_user((struct watchdog_info *)arg, &ident, if(copy_to_user((struct watchdog_info *)arg, &ident,
sizeof(ident))) sizeof(ident)))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -220,7 +220,7 @@ static int __init scx200_wdt_init(void) ...@@ -220,7 +220,7 @@ static int __init scx200_wdt_init(void)
printk(KERN_DEBUG NAME ": NatSemi SCx200 Watchdog Driver\n"); printk(KERN_DEBUG NAME ": NatSemi SCx200 Watchdog Driver\n");
/* First check that this really is a NatSemi SCx200 CPU */ /* First check that this really is a NatSemi SCx200 CPU */
if ((pci_find_device(PCI_VENDOR_ID_NS, if ((pci_find_device(PCI_VENDOR_ID_NS,
PCI_DEVICE_ID_NS_SCx200_BRIDGE, PCI_DEVICE_ID_NS_SCx200_BRIDGE,
NULL)) == NULL) NULL)) == NULL)
return -ENODEV; return -ENODEV;
...@@ -231,8 +231,8 @@ static int __init scx200_wdt_init(void) ...@@ -231,8 +231,8 @@ static int __init scx200_wdt_init(void)
return -ENODEV; return -ENODEV;
} }
if (!request_region(SCx200_CB_BASE + SCx200_WDT_OFFSET, if (!request_region(SCx200_CB_BASE + SCx200_WDT_OFFSET,
SCx200_WDT_SIZE, SCx200_WDT_SIZE,
"NatSemi SCx200 Watchdog")) { "NatSemi SCx200 Watchdog")) {
printk(KERN_WARNING NAME ": watchdog I/O region busy\n"); printk(KERN_WARNING NAME ": watchdog I/O region busy\n");
return -EBUSY; return -EBUSY;
...@@ -251,20 +251,20 @@ static int __init scx200_wdt_init(void) ...@@ -251,20 +251,20 @@ static int __init scx200_wdt_init(void)
} }
r = register_reboot_notifier(&scx200_wdt_notifier); r = register_reboot_notifier(&scx200_wdt_notifier);
if (r) { if (r) {
printk(KERN_ERR NAME ": unable to register reboot notifier"); printk(KERN_ERR NAME ": unable to register reboot notifier");
misc_deregister(&scx200_wdt_miscdev); misc_deregister(&scx200_wdt_miscdev);
release_region(SCx200_CB_BASE + SCx200_WDT_OFFSET, release_region(SCx200_CB_BASE + SCx200_WDT_OFFSET,
SCx200_WDT_SIZE); SCx200_WDT_SIZE);
return r; return r;
} }
return 0; return 0;
} }
static void __exit scx200_wdt_cleanup(void) static void __exit scx200_wdt_cleanup(void)
{ {
unregister_reboot_notifier(&scx200_wdt_notifier); unregister_reboot_notifier(&scx200_wdt_notifier);
misc_deregister(&scx200_wdt_miscdev); misc_deregister(&scx200_wdt_miscdev);
release_region(SCx200_CB_BASE + SCx200_WDT_OFFSET, release_region(SCx200_CB_BASE + SCx200_WDT_OFFSET,
SCx200_WDT_SIZE); SCx200_WDT_SIZE);
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
/* /*
* Default clock division ratio is 5.25 msecs. For an additional table of * Default clock division ratio is 5.25 msecs. For an additional table of
* values, consult the asm-sh/watchdog.h. Overload this at module load * values, consult the asm-sh/watchdog.h. Overload this at module load
* time. * time.
* *
* In order for this to work reliably we need to have HZ set to 1000 or * In order for this to work reliably we need to have HZ set to 1000 or
* something quite higher than 100 (or we need a proper high-res timer * something quite higher than 100 (or we need a proper high-res timer
...@@ -122,7 +122,7 @@ static void sh_wdt_start(void) ...@@ -122,7 +122,7 @@ static void sh_wdt_start(void)
csr = sh_wdt_read_rstcsr(); csr = sh_wdt_read_rstcsr();
csr &= ~RSTCSR_RSTS; csr &= ~RSTCSR_RSTS;
sh_wdt_write_rstcsr(csr); sh_wdt_write_rstcsr(csr);
#endif #endif
} }
/** /**
...@@ -202,7 +202,7 @@ static int sh_wdt_close(struct inode *inode, struct file *file) ...@@ -202,7 +202,7 @@ static int sh_wdt_close(struct inode *inode, struct file *file)
clear_bit(0, &shwdt_is_open); clear_bit(0, &shwdt_is_open);
shwdt_expect_close = 0; shwdt_expect_close = 0;
return 0; return 0;
} }
...@@ -264,7 +264,7 @@ static int sh_wdt_ioctl(struct inode *inode, struct file *file, ...@@ -264,7 +264,7 @@ static int sh_wdt_ioctl(struct inode *inode, struct file *file,
sizeof(sh_wdt_info))) { sizeof(sh_wdt_info))) {
return -EFAULT; return -EFAULT;
} }
break; break;
case WDIOC_GETSTATUS: case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS: case WDIOC_GETBOOTSTATUS:
...@@ -299,11 +299,11 @@ static int sh_wdt_ioctl(struct inode *inode, struct file *file, ...@@ -299,11 +299,11 @@ static int sh_wdt_ioctl(struct inode *inode, struct file *file,
sh_wdt_start(); sh_wdt_start();
retval = 0; retval = 0;
} }
return retval; return retval;
} }
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
} }
return 0; return 0;
...@@ -311,7 +311,7 @@ static int sh_wdt_ioctl(struct inode *inode, struct file *file, ...@@ -311,7 +311,7 @@ static int sh_wdt_ioctl(struct inode *inode, struct file *file,
/** /**
* sh_wdt_notify_sys - Notifier Handler * sh_wdt_notify_sys - Notifier Handler
* *
* @this: notifier block * @this: notifier block
* @code: notifier event * @code: notifier event
* @unused: unused * @unused: unused
......
...@@ -8,10 +8,10 @@ ...@@ -8,10 +8,10 @@
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
* *
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided * warranty for any of this software. This material is provided
* "AS-IS" and at no charge. * "AS-IS" and at no charge.
* *
* (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk> * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
* *
...@@ -28,14 +28,14 @@ ...@@ -28,14 +28,14 @@
* Made SMP safe for 2.3.x * Made SMP safe for 2.3.x
* *
* 20011127 Joel Becker (jlbec@evilplan.org> * 20011127 Joel Becker (jlbec@evilplan.org>
* Added soft_noboot; Allows testing the softdog trigger without * Added soft_noboot; Allows testing the softdog trigger without
* requiring a recompile. * requiring a recompile.
* Added WDIOC_GETTIMEOUT and WDIOC_SETTIMOUT. * Added WDIOC_GETTIMEOUT and WDIOC_SETTIMOUT.
* *
* 20020530 Joel Becker <joel.becker@oracle.com> * 20020530 Joel Becker <joel.becker@oracle.com>
* Added Matt Domsch's nowayout module option. * Added Matt Domsch's nowayout module option.
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/config.h> #include <linux/config.h>
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
#define TIMER_MARGIN 60 /* (secs) Default is 1 minute */ #define TIMER_MARGIN 60 /* (secs) Default is 1 minute */
static int expect_close = 0; static char expect_close;
static int soft_margin = TIMER_MARGIN; /* in seconds */ static int soft_margin = TIMER_MARGIN; /* in seconds */
#ifdef ONLY_TESTING #ifdef ONLY_TESTING
static int soft_noboot = 1; static int soft_noboot = 1;
...@@ -73,7 +73,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON ...@@ -73,7 +73,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
/* /*
* Our timer * Our timer
*/ */
static void watchdog_fire(unsigned long); static void watchdog_fire(unsigned long);
static struct timer_list watchdog_ticktock = static struct timer_list watchdog_ticktock =
...@@ -84,7 +84,7 @@ static unsigned long timer_alive; ...@@ -84,7 +84,7 @@ static unsigned long timer_alive;
/* /*
* If the timer expires.. * If the timer expires..
*/ */
static void watchdog_fire(unsigned long data) static void watchdog_fire(unsigned long data)
{ {
if (soft_noboot) if (soft_noboot)
...@@ -100,12 +100,12 @@ static void watchdog_fire(unsigned long data) ...@@ -100,12 +100,12 @@ static void watchdog_fire(unsigned long data)
/* /*
* Allow only one person to hold it open * Allow only one person to hold it open
*/ */
static int softdog_open(struct inode *inode, struct file *file) static int softdog_open(struct inode *inode, struct file *file)
{ {
if(test_and_set_bit(0, &timer_alive)) if(test_and_set_bit(0, &timer_alive))
return -EBUSY; return -EBUSY;
if (nowayout) if (nowayout)
__module_get(THIS_MODULE); __module_get(THIS_MODULE);
/* /*
* Activate timer * Activate timer
...@@ -120,12 +120,13 @@ static int softdog_release(struct inode *inode, struct file *file) ...@@ -120,12 +120,13 @@ static int softdog_release(struct inode *inode, struct file *file)
* Shut off the timer. * Shut off the timer.
* Lock it in if it's a module and we set nowayout * Lock it in if it's a module and we set nowayout
*/ */
if (expect_close) { if (expect_close == 42) {
del_timer(&watchdog_ticktock); del_timer(&watchdog_ticktock);
} else { } else {
printk(KERN_CRIT "SOFTDOG: WDT device closed unexpectedly. WDT will not stop!\n"); printk(KERN_CRIT "SOFTDOG: WDT device closed unexpectedly. WDT will not stop!\n");
} }
clear_bit(0, &timer_alive); clear_bit(0, &timer_alive);
expect_close = 0;
return 0; return 0;
} }
...@@ -151,7 +152,7 @@ static ssize_t softdog_write(struct file *file, const char *data, size_t len, lo ...@@ -151,7 +152,7 @@ static ssize_t softdog_write(struct file *file, const char *data, size_t len, lo
if (get_user(c, data + i)) if (get_user(c, data + i))
return -EFAULT; return -EFAULT;
if (c == 'V') if (c == 'V')
expect_close = 1; expect_close = 42;
} }
} }
mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ)); mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
...@@ -169,7 +170,7 @@ static int softdog_ioctl(struct inode *inode, struct file *file, ...@@ -169,7 +170,7 @@ static int softdog_ioctl(struct inode *inode, struct file *file,
}; };
switch (cmd) { switch (cmd) {
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT: case WDIOC_GETSUPPORT:
if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))) if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
return -EFAULT; return -EFAULT;
......
...@@ -184,7 +184,7 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -184,7 +184,7 @@ wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
} }
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
} }
return 0; return 0;
} }
......
...@@ -205,7 +205,7 @@ static ssize_t fop_write(struct file * file, const char * buf, size_t count, lof ...@@ -205,7 +205,7 @@ static ssize_t fop_write(struct file * file, const char * buf, size_t count, lof
* five months ago... */ * five months ago... */
wdt_expect_close = 0; wdt_expect_close = 0;
/* scan to see wether or not we got the magic character */ /* scan to see whether or not we got the magic character */
for(ofs = 0; ofs != count; ofs++) for(ofs = 0; ofs != count; ofs++)
{ {
char c; char c;
......
...@@ -109,7 +109,7 @@ static ssize_t wafwdt_write(struct file *file, const char *buf, size_t count, lo ...@@ -109,7 +109,7 @@ static ssize_t wafwdt_write(struct file *file, const char *buf, size_t count, lo
/* In case it was set long ago */ /* In case it was set long ago */
expect_close = 0; expect_close = 0;
/* scan to see wether or not we got the magic character */ /* scan to see whether or not we got the magic character */
for (i = 0; i != count; i++) { for (i = 0; i != count; i++) {
char c; char c;
if (get_user(c, buf + i)) if (get_user(c, buf + i))
...@@ -182,7 +182,7 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -182,7 +182,7 @@ static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd
} }
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
} }
return 0; return 0;
} }
......
...@@ -8,10 +8,10 @@ ...@@ -8,10 +8,10 @@
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
* *
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided * warranty for any of this software. This material is provided
* "AS-IS" and at no charge. * "AS-IS" and at no charge.
* *
* (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk> * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
* *
...@@ -49,13 +49,13 @@ ...@@ -49,13 +49,13 @@
#include "wd501p.h" #include "wd501p.h"
static unsigned long wdt_is_open; static unsigned long wdt_is_open;
static int expect_close; static char expect_close;
/* /*
* You must set these - there is no sane way to probe for this board. * You must set these - there is no sane way to probe for this board.
* You can use wdt=x,y to set these now. * You can use wdt=x,y to set these now.
*/ */
static int io=0x240; static int io=0x240;
static int irq=11; static int irq=11;
...@@ -80,10 +80,10 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON ...@@ -80,10 +80,10 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
* @str: command line string * @str: command line string
* *
* Setup options. The board isn't really probe-able so we have to * Setup options. The board isn't really probe-able so we have to
* get the user to tell us the configuration. Sane people build it * get the user to tell us the configuration. Sane people build it
* modular but the others come here. * modular but the others come here.
*/ */
static int __init wdt_setup(char *str) static int __init wdt_setup(char *str)
{ {
int ints[4]; int ints[4];
...@@ -108,11 +108,11 @@ MODULE_PARM(io, "i"); ...@@ -108,11 +108,11 @@ MODULE_PARM(io, "i");
MODULE_PARM_DESC(io, "WDT io port (default=0x240)"); MODULE_PARM_DESC(io, "WDT io port (default=0x240)");
MODULE_PARM(irq, "i"); MODULE_PARM(irq, "i");
MODULE_PARM_DESC(irq, "WDT irq (default=11)"); MODULE_PARM_DESC(irq, "WDT irq (default=11)");
/* /*
* Programming support * Programming support
*/ */
static void wdt_ctr_mode(int ctr, int mode) static void wdt_ctr_mode(int ctr, int mode)
{ {
ctr<<=6; ctr<<=6;
...@@ -130,29 +130,29 @@ static void wdt_ctr_load(int ctr, int val) ...@@ -130,29 +130,29 @@ static void wdt_ctr_load(int ctr, int val)
/* /*
* Kernel methods. * Kernel methods.
*/ */
/** /**
* wdt_status: * wdt_status:
* *
* Extract the status information from a WDT watchdog device. There are * Extract the status information from a WDT watchdog device. There are
* several board variants so we have to know which bits are valid. Some * several board variants so we have to know which bits are valid. Some
* bits default to one and some to zero in order to be maximally painful. * bits default to one and some to zero in order to be maximally painful.
* *
* we then map the bits onto the status ioctl flags. * we then map the bits onto the status ioctl flags.
*/ */
static int wdt_status(void) static int wdt_status(void)
{ {
/* /*
* Status register to bit flags * Status register to bit flags
*/ */
int flag=0; int flag=0;
unsigned char status=inb_p(WDT_SR); unsigned char status=inb_p(WDT_SR);
status|=FEATUREMAP1; status|=FEATUREMAP1;
status&=~FEATUREMAP2; status&=~FEATUREMAP2;
if(!(status&WDC_SR_TGOOD)) if(!(status&WDC_SR_TGOOD))
flag|=WDIOF_OVERHEAT; flag|=WDIOF_OVERHEAT;
if(!(status&WDC_SR_PSUOVER)) if(!(status&WDC_SR_PSUOVER))
...@@ -178,21 +178,21 @@ static int wdt_status(void) ...@@ -178,21 +178,21 @@ static int wdt_status(void)
* map changes in what the board considers an interesting way. That means * map changes in what the board considers an interesting way. That means
* a failure condition occurring. * a failure condition occurring.
*/ */
static irqreturn_t wdt_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t wdt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
/* /*
* Read the status register see what is up and * Read the status register see what is up and
* then printk it. * then printk it.
*/ */
unsigned char status=inb_p(WDT_SR); unsigned char status=inb_p(WDT_SR);
status|=FEATUREMAP1; status|=FEATUREMAP1;
status&=~FEATUREMAP2; status&=~FEATUREMAP2;
printk(KERN_CRIT "WDT status %d\n", status); printk(KERN_CRIT "WDT status %d\n", status);
if(!(status&WDC_SR_TGOOD)) if(!(status&WDC_SR_TGOOD))
printk(KERN_CRIT "Overheat alarm.(%d)\n",inb_p(WDT_RT)); printk(KERN_CRIT "Overheat alarm.(%d)\n",inb_p(WDT_RT));
if(!(status&WDC_SR_PSUOVER)) if(!(status&WDC_SR_PSUOVER))
...@@ -205,10 +205,10 @@ static irqreturn_t wdt_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -205,10 +205,10 @@ static irqreturn_t wdt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#ifdef SOFTWARE_REBOOT #ifdef SOFTWARE_REBOOT
#ifdef ONLY_TESTING #ifdef ONLY_TESTING
printk(KERN_CRIT "Would Reboot.\n"); printk(KERN_CRIT "Would Reboot.\n");
#else #else
printk(KERN_CRIT "Initiating system reboot.\n"); printk(KERN_CRIT "Initiating system reboot.\n");
machine_restart(NULL); machine_restart(NULL);
#endif #endif
#else #else
printk(KERN_CRIT "Reset in 5ms.\n"); printk(KERN_CRIT "Reset in 5ms.\n");
#endif #endif
...@@ -220,9 +220,9 @@ static irqreturn_t wdt_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -220,9 +220,9 @@ static irqreturn_t wdt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* wdt_ping: * wdt_ping:
* *
* Reload counter one with the watchdog timeout. We don't bother reloading * Reload counter one with the watchdog timeout. We don't bother reloading
* the cascade counter. * the cascade counter.
*/ */
static void wdt_ping(void) static void wdt_ping(void)
{ {
/* Write a watchdog value */ /* Write a watchdog value */
...@@ -235,14 +235,14 @@ static void wdt_ping(void) ...@@ -235,14 +235,14 @@ static void wdt_ping(void)
/** /**
* wdt_write: * wdt_write:
* @file: file handle to the watchdog * @file: file handle to the watchdog
* @buf: buffer to write (unused as data does not matter here * @buf: buffer to write (unused as data does not matter here
* @count: count of bytes * @count: count of bytes
* @ppos: pointer to the position to write. No seeks allowed * @ppos: pointer to the position to write. No seeks allowed
* *
* A write to a watchdog device is defined as a keepalive signal. Any * A write to a watchdog device is defined as a keepalive signal. Any
* write of data will do, as we we don't define content meaning. * write of data will do, as we we don't define content meaning.
*/ */
static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{ {
/* Can't seek (pwrite) on this device */ /* Can't seek (pwrite) on this device */
...@@ -261,7 +261,7 @@ static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_ ...@@ -261,7 +261,7 @@ static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_
if (get_user(c, buf + i)) if (get_user(c, buf + i))
return -EFAULT; return -EFAULT;
if (c == 'V') if (c == 'V')
expect_close = 1; expect_close = 42;
} }
} }
wdt_ping(); wdt_ping();
...@@ -279,12 +279,12 @@ static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_ ...@@ -279,12 +279,12 @@ static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_
* Read reports the temperature in degrees Fahrenheit. The API is in * Read reports the temperature in degrees Fahrenheit. The API is in
* farenheit. It was designed by an imperial measurement luddite. * farenheit. It was designed by an imperial measurement luddite.
*/ */
static ssize_t wdt_read(struct file *file, char *buf, size_t count, loff_t *ptr) static ssize_t wdt_read(struct file *file, char *buf, size_t count, loff_t *ptr)
{ {
unsigned short c=inb_p(WDT_RT); unsigned short c=inb_p(WDT_RT);
unsigned char cp; unsigned char cp;
/* Can't seek (pread) on this device */ /* Can't seek (pread) on this device */
if (ptr != &file->f_pos) if (ptr != &file->f_pos)
return -ESPIPE; return -ESPIPE;
...@@ -312,9 +312,9 @@ static ssize_t wdt_read(struct file *file, char *buf, size_t count, loff_t *ptr) ...@@ -312,9 +312,9 @@ static ssize_t wdt_read(struct file *file, char *buf, size_t count, loff_t *ptr)
* *
* The watchdog API defines a common set of functions for all watchdogs * The watchdog API defines a common set of functions for all watchdogs
* according to their available features. We only actually usefully support * according to their available features. We only actually usefully support
* querying capabilities and current status. * querying capabilities and current status.
*/ */
static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
...@@ -326,14 +326,14 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -326,14 +326,14 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
|WDIOF_EXTERN1|WDIOF_EXTERN2|WDIOF_FANFAULT |WDIOF_EXTERN1|WDIOF_EXTERN2|WDIOF_FANFAULT
|WDIOF_SETTIMEOUT|WDIOF_MAGICCLOSE, |WDIOF_SETTIMEOUT|WDIOF_MAGICCLOSE,
.firmware_version = 1, .firmware_version = 1,
.identity = "WDT500/501" .identity = "WDT500/501",
}; };
ident.options&=WDT_OPTION_MASK; /* Mask down to the card we have */ ident.options&=WDT_OPTION_MASK; /* Mask down to the card we have */
switch(cmd) switch(cmd)
{ {
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT: case WDIOC_GETSUPPORT:
return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
...@@ -364,12 +364,12 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -364,12 +364,12 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
* @file: file handle to device * @file: file handle to device
* *
* One of our two misc devices has been opened. The watchdog device is * One of our two misc devices has been opened. The watchdog device is
* single open and on opening we load the counters. Counter zero is a * single open and on opening we load the counters. Counter zero is a
* 100Hz cascade, into counter 1 which downcounts to reboot. When the * 100Hz cascade, into counter 1 which downcounts to reboot. When the
* counter triggers counter 2 downcounts the length of the reset pulse * counter triggers counter 2 downcounts the length of the reset pulse
* which set set to be as long as possible. * which set set to be as long as possible.
*/ */
static int wdt_open(struct inode *inode, struct file *file) static int wdt_open(struct inode *inode, struct file *file)
{ {
switch(iminor(inode)) switch(iminor(inode))
...@@ -378,9 +378,9 @@ static int wdt_open(struct inode *inode, struct file *file) ...@@ -378,9 +378,9 @@ static int wdt_open(struct inode *inode, struct file *file)
if(test_and_set_bit(0, &wdt_is_open)) if(test_and_set_bit(0, &wdt_is_open))
return -EBUSY; return -EBUSY;
/* /*
* Activate * Activate
*/ */
wdt_is_open=1; wdt_is_open=1;
inb_p(WDT_DC); /* Disable */ inb_p(WDT_DC); /* Disable */
wdt_ctr_mode(0,3); wdt_ctr_mode(0,3);
...@@ -403,24 +403,25 @@ static int wdt_open(struct inode *inode, struct file *file) ...@@ -403,24 +403,25 @@ static int wdt_open(struct inode *inode, struct file *file)
* @inode: inode to board * @inode: inode to board
* @file: file handle to board * @file: file handle to board
* *
* The watchdog has a configurable API. There is a religious dispute * The watchdog has a configurable API. There is a religious dispute
* between people who want their watchdog to be able to shut down and * between people who want their watchdog to be able to shut down and
* those who want to be sure if the watchdog manager dies the machine * those who want to be sure if the watchdog manager dies the machine
* reboots. In the former case we disable the counters, in the latter * reboots. In the former case we disable the counters, in the latter
* case you have to open it again very soon. * case you have to open it again very soon.
*/ */
static int wdt_release(struct inode *inode, struct file *file) static int wdt_release(struct inode *inode, struct file *file)
{ {
if(iminor(inode)==WATCHDOG_MINOR) if(iminor(inode)==WATCHDOG_MINOR)
{ {
if (expect_close) { if (expect_close == 42) {
inb_p(WDT_DC); /* Disable counters */ inb_p(WDT_DC); /* Disable counters */
wdt_ctr_load(2,0); /* 0 length reset pulses now */ wdt_ctr_load(2,0); /* 0 length reset pulses now */
} else { } 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");
} }
clear_bit(0, &wdt_is_open); clear_bit(0, &wdt_is_open);
expect_close = 0;
} }
return 0; return 0;
} }
...@@ -448,12 +449,12 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, ...@@ -448,12 +449,12 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
} }
return NOTIFY_DONE; return NOTIFY_DONE;
} }
/* /*
* Kernel Interfaces * Kernel Interfaces
*/ */
static struct file_operations wdt_fops = { static struct file_operations wdt_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.llseek = no_llseek, .llseek = no_llseek,
...@@ -468,7 +469,7 @@ static struct miscdevice wdt_miscdev= ...@@ -468,7 +469,7 @@ static struct miscdevice wdt_miscdev=
{ {
.minor = WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
.name = "watchdog", .name = "watchdog",
.fops = &wdt_fops .fops = &wdt_fops,
}; };
#ifdef CONFIG_WDT_501 #ifdef CONFIG_WDT_501
...@@ -476,20 +477,20 @@ static struct miscdevice temp_miscdev= ...@@ -476,20 +477,20 @@ static struct miscdevice temp_miscdev=
{ {
.minor = TEMP_MINOR, .minor = TEMP_MINOR,
.name = "temperature", .name = "temperature",
.fops = &wdt_fops .fops = &wdt_fops,
}; };
#endif #endif
/* /*
* The WDT card needs to learn about soft shutdowns in order to * The WDT card needs to learn about soft shutdowns in order to
* turn the timebomb registers off. * turn the timebomb registers off.
*/ */
static struct notifier_block wdt_notifier= static struct notifier_block wdt_notifier=
{ {
.notifier_call = wdt_notify_sys, .notifier_call = wdt_notify_sys,
.next = NULL, .next = NULL,
.priority = 0 .priority = 0,
}; };
/** /**
...@@ -501,13 +502,13 @@ static struct notifier_block wdt_notifier= ...@@ -501,13 +502,13 @@ static struct notifier_block wdt_notifier=
* will not touch PC memory so all is fine. You just have to load a new * will not touch PC memory so all is fine. You just have to load a new
* module in 60 seconds or reboot. * module in 60 seconds or reboot.
*/ */
static void __exit wdt_exit(void) static void __exit wdt_exit(void)
{ {
misc_deregister(&wdt_miscdev); misc_deregister(&wdt_miscdev);
#ifdef CONFIG_WDT_501 #ifdef CONFIG_WDT_501
misc_deregister(&temp_miscdev); misc_deregister(&temp_miscdev);
#endif #endif
unregister_reboot_notifier(&wdt_notifier); unregister_reboot_notifier(&wdt_notifier);
release_region(io,8); release_region(io,8);
free_irq(irq, NULL); free_irq(irq, NULL);
...@@ -520,7 +521,7 @@ static void __exit wdt_exit(void) ...@@ -520,7 +521,7 @@ static void __exit wdt_exit(void)
* resources we require and bitch if anyone beat us to them. * resources we require and bitch if anyone beat us to them.
* The open() function will actually kick the board off. * The open() function will actually kick the board off.
*/ */
static int __init wdt_init(void) static int __init wdt_init(void)
{ {
int ret; int ret;
......
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
* *
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -79,7 +79,7 @@ static int watchdog_open(struct inode *inode, struct file *file) ...@@ -79,7 +79,7 @@ static int watchdog_open(struct inode *inode, struct file *file)
*CSR_TIMER4_CLR = 0; *CSR_TIMER4_CLR = 0;
watchdog_ping(); watchdog_ping();
*CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD *CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD
| TIMER_CNTL_DIV256; | TIMER_CNTL_DIV256;
#ifdef ONLY_TESTING #ifdef ONLY_TESTING
...@@ -132,7 +132,7 @@ watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos) ...@@ -132,7 +132,7 @@ watchdog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
static struct watchdog_info ident = { static struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT, .options = WDIOF_SETTIMEOUT,
.identity = "Footbridge Watchdog" .identity = "Footbridge Watchdog",
}; };
static int static int
...@@ -192,7 +192,7 @@ static struct file_operations watchdog_fops = { ...@@ -192,7 +192,7 @@ static struct file_operations watchdog_fops = {
static struct miscdevice watchdog_miscdev = { static struct miscdevice watchdog_miscdev = {
.minor = WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
.name = "watchdog", .name = "watchdog",
.fops = &watchdog_fops .fops = &watchdog_fops,
}; };
static int __init footbridge_watchdog_init(void) static int __init footbridge_watchdog_init(void)
...@@ -206,7 +206,7 @@ static int __init footbridge_watchdog_init(void) ...@@ -206,7 +206,7 @@ static int __init footbridge_watchdog_init(void)
if (retval < 0) if (retval < 0)
return retval; return retval;
printk("Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n", printk("Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n",
soft_margin); soft_margin);
if (machine_is_cats()) if (machine_is_cats())
......
...@@ -43,7 +43,7 @@ static int timeout = DEFAULT_TIMEOUT*60; /* TO in seconds from user */ ...@@ -43,7 +43,7 @@ static int timeout = DEFAULT_TIMEOUT*60; /* TO in seconds from user */
static int timeoutM = DEFAULT_TIMEOUT; /* timeout in minutes */ static int timeoutM = DEFAULT_TIMEOUT; /* timeout in minutes */
static unsigned long timer_alive; static unsigned long timer_alive;
static int testmode; static int testmode;
static int expect_close = 0; static char expect_close;
module_param(timeout, int, 0); module_param(timeout, int, 0);
MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (60..15300), default=60"); MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (60..15300), default=60");
...@@ -165,7 +165,7 @@ static int wdt977_release(struct inode *inode, struct file *file) ...@@ -165,7 +165,7 @@ static int wdt977_release(struct inode *inode, struct file *file)
* Shut off the timer. * Shut off the timer.
* Lock it in if it's a module and we set nowayout * Lock it in if it's a module and we set nowayout
*/ */
if (!nowayout) if (expect_close == 42)
{ {
/* unlock the SuperIO chip */ /* unlock the SuperIO chip */
outb(0x87,0x370); outb(0x87,0x370);
...@@ -202,6 +202,7 @@ static int wdt977_release(struct inode *inode, struct file *file) ...@@ -202,6 +202,7 @@ static int wdt977_release(struct inode *inode, struct file *file)
} else { } else {
printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n"); printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n");
} }
expect_close = 0;
return 0; return 0;
} }
...@@ -235,7 +236,7 @@ static ssize_t wdt977_write(struct file *file, const char *buf, size_t count, lo ...@@ -235,7 +236,7 @@ static ssize_t wdt977_write(struct file *file, const char *buf, size_t count, lo
if (get_user(c, buf + i)) if (get_user(c, buf + i))
return -EFAULT; return -EFAULT;
if (c == 'V') if (c == 'V')
expect_close = 1; expect_close = 42;
} }
} }
...@@ -257,18 +258,18 @@ static ssize_t wdt977_write(struct file *file, const char *buf, size_t count, lo ...@@ -257,18 +258,18 @@ static ssize_t wdt977_write(struct file *file, const char *buf, size_t count, lo
static struct watchdog_info ident = { static struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT, .options = WDIOF_SETTIMEOUT,
.identity = "Winbond 83977" .identity = "Winbond 83977",
}; };
static int wdt977_ioctl(struct inode *inode, struct file *file, static int wdt977_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
int temp; int temp;
switch(cmd) switch(cmd)
{ {
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT: case WDIOC_GETSUPPORT:
return copy_to_user((struct watchdog_info *)arg, &ident, return copy_to_user((struct watchdog_info *)arg, &ident,
...@@ -341,7 +342,7 @@ static struct miscdevice wdt977_miscdev= ...@@ -341,7 +342,7 @@ static struct miscdevice wdt977_miscdev=
{ {
.minor = WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
.name = "watchdog", .name = "watchdog",
.fops = &wdt977_fops .fops = &wdt977_fops,
}; };
static int __init nwwatchdog_init(void) static int __init nwwatchdog_init(void)
......
...@@ -8,10 +8,10 @@ ...@@ -8,10 +8,10 @@
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
* *
* Neither Alan Cox nor CymruNet Ltd. admit liability nor provide * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
* warranty for any of this software. This material is provided * warranty for any of this software. This material is provided
* "AS-IS" and at no charge. * "AS-IS" and at no charge.
* *
* (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk> * (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
* *
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
static struct semaphore open_sem; static struct semaphore open_sem;
static spinlock_t wdtpci_lock; static spinlock_t wdtpci_lock;
static int expect_close = 0; static char expect_close;
static int io; static int io;
static int irq; static int irq;
...@@ -95,7 +95,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON ...@@ -95,7 +95,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
/* /*
* Programming support * Programming support
*/ */
static void wdtpci_ctr_mode(int ctr, int mode) static void wdtpci_ctr_mode(int ctr, int mode)
{ {
ctr<<=6; ctr<<=6;
...@@ -113,29 +113,29 @@ static void wdtpci_ctr_load(int ctr, int val) ...@@ -113,29 +113,29 @@ static void wdtpci_ctr_load(int ctr, int val)
/* /*
* Kernel methods. * Kernel methods.
*/ */
/** /**
* wdtpci_status: * wdtpci_status:
* *
* Extract the status information from a WDT watchdog device. There are * Extract the status information from a WDT watchdog device. There are
* several board variants so we have to know which bits are valid. Some * several board variants so we have to know which bits are valid. Some
* bits default to one and some to zero in order to be maximally painful. * bits default to one and some to zero in order to be maximally painful.
* *
* we then map the bits onto the status ioctl flags. * we then map the bits onto the status ioctl flags.
*/ */
static int wdtpci_status(void) static int wdtpci_status(void)
{ {
/* /*
* Status register to bit flags * Status register to bit flags
*/ */
int flag=0; int flag=0;
unsigned char status=inb_p(WDT_SR); unsigned char status=inb_p(WDT_SR);
status|=FEATUREMAP1; status|=FEATUREMAP1;
status&=~FEATUREMAP2; status&=~FEATUREMAP2;
if(!(status&WDC_SR_TGOOD)) if(!(status&WDC_SR_TGOOD))
flag|=WDIOF_OVERHEAT; flag|=WDIOF_OVERHEAT;
if(!(status&WDC_SR_PSUOVER)) if(!(status&WDC_SR_PSUOVER))
...@@ -161,21 +161,21 @@ static int wdtpci_status(void) ...@@ -161,21 +161,21 @@ static int wdtpci_status(void)
* map changes in what the board considers an interesting way. That means * map changes in what the board considers an interesting way. That means
* a failure condition occurring. * a failure condition occurring.
*/ */
static irqreturn_t wdtpci_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t wdtpci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
/* /*
* Read the status register see what is up and * Read the status register see what is up and
* then printk it. * then printk it.
*/ */
unsigned char status=inb_p(WDT_SR); unsigned char status=inb_p(WDT_SR);
status|=FEATUREMAP1; status|=FEATUREMAP1;
status&=~FEATUREMAP2; status&=~FEATUREMAP2;
printk(KERN_CRIT "WDT status %d\n", status); printk(KERN_CRIT "WDT status %d\n", status);
if(!(status&WDC_SR_TGOOD)) if(!(status&WDC_SR_TGOOD))
printk(KERN_CRIT "Overheat alarm.(%d)\n",inb_p(WDT_RT)); printk(KERN_CRIT "Overheat alarm.(%d)\n",inb_p(WDT_RT));
if(!(status&WDC_SR_PSUOVER)) if(!(status&WDC_SR_PSUOVER))
...@@ -188,10 +188,10 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -188,10 +188,10 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#ifdef SOFTWARE_REBOOT #ifdef SOFTWARE_REBOOT
#ifdef ONLY_TESTING #ifdef ONLY_TESTING
printk(KERN_CRIT "Would Reboot.\n"); printk(KERN_CRIT "Would Reboot.\n");
#else #else
printk(KERN_CRIT "Initiating system reboot.\n"); printk(KERN_CRIT "Initiating system reboot.\n");
machine_restart(NULL); machine_restart(NULL);
#endif #endif
#else #else
printk(KERN_CRIT "Reset in 5ms.\n"); printk(KERN_CRIT "Reset in 5ms.\n");
#endif #endif
...@@ -203,9 +203,9 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -203,9 +203,9 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* wdtpci_ping: * wdtpci_ping:
* *
* Reload counter one with the watchdog timeout. We don't bother reloading * Reload counter one with the watchdog timeout. We don't bother reloading
* the cascade counter. * the cascade counter.
*/ */
static void wdtpci_ping(void) static void wdtpci_ping(void)
{ {
unsigned long flags; unsigned long flags;
...@@ -222,14 +222,14 @@ static void wdtpci_ping(void) ...@@ -222,14 +222,14 @@ static void wdtpci_ping(void)
/** /**
* wdtpci_write: * wdtpci_write:
* @file: file handle to the watchdog * @file: file handle to the watchdog
* @buf: buffer to write (unused as data does not matter here * @buf: buffer to write (unused as data does not matter here
* @count: count of bytes * @count: count of bytes
* @ppos: pointer to the position to write. No seeks allowed * @ppos: pointer to the position to write. No seeks allowed
* *
* A write to a watchdog device is defined as a keepalive signal. Any * A write to a watchdog device is defined as a keepalive signal. Any
* write of data will do, as we we don't define content meaning. * write of data will do, as we we don't define content meaning.
*/ */
static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, loff_t *ppos) static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{ {
/* Can't seek (pwrite) on this device */ /* Can't seek (pwrite) on this device */
...@@ -247,7 +247,7 @@ static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, lo ...@@ -247,7 +247,7 @@ static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, lo
if(get_user(c, buf+i)) if(get_user(c, buf+i))
return -EFAULT; return -EFAULT;
if (c == 'V') if (c == 'V')
expect_close = 1; expect_close = 42;
} }
} }
wdtpci_ping(); wdtpci_ping();
...@@ -266,12 +266,12 @@ static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, lo ...@@ -266,12 +266,12 @@ static ssize_t wdtpci_write(struct file *file, const char *buf, size_t count, lo
* Read reports the temperature in degrees Fahrenheit. The API is in * Read reports the temperature in degrees Fahrenheit. The API is in
* fahrenheit. It was designed by an imperial measurement luddite. * fahrenheit. It was designed by an imperial measurement luddite.
*/ */
static ssize_t wdtpci_read(struct file *file, char *buf, size_t count, loff_t *ptr) static ssize_t wdtpci_read(struct file *file, char *buf, size_t count, loff_t *ptr)
{ {
unsigned short c=inb_p(WDT_RT); unsigned short c=inb_p(WDT_RT);
unsigned char cp; unsigned char cp;
/* Can't seek (pread) on this device */ /* Can't seek (pread) on this device */
if (ptr != &file->f_pos) if (ptr != &file->f_pos)
return -ESPIPE; return -ESPIPE;
...@@ -299,9 +299,9 @@ static ssize_t wdtpci_read(struct file *file, char *buf, size_t count, loff_t *p ...@@ -299,9 +299,9 @@ static ssize_t wdtpci_read(struct file *file, char *buf, size_t count, loff_t *p
* *
* The watchdog API defines a common set of functions for all watchdogs * The watchdog API defines a common set of functions for all watchdogs
* according to their available features. We only actually usefully support * according to their available features. We only actually usefully support
* querying capabilities and current status. * querying capabilities and current status.
*/ */
static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd, static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
...@@ -314,12 +314,12 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -314,12 +314,12 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd
.firmware_version = 1, .firmware_version = 1,
.identity = "WDT500/501PCI", .identity = "WDT500/501PCI",
}; };
ident.options&=WDT_OPTION_MASK; /* Mask down to the card we have */ ident.options&=WDT_OPTION_MASK; /* Mask down to the card we have */
switch(cmd) switch(cmd)
{ {
default: default:
return -ENOTTY; return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT: case WDIOC_GETSUPPORT:
return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0; return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
...@@ -351,12 +351,12 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -351,12 +351,12 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd
* @file: file handle to device * @file: file handle to device
* *
* One of our two misc devices has been opened. The watchdog device is * One of our two misc devices has been opened. The watchdog device is
* single open and on opening we load the counters. Counter zero is a * single open and on opening we load the counters. Counter zero is a
* 100Hz cascade, into counter 1 which downcounts to reboot. When the * 100Hz cascade, into counter 1 which downcounts to reboot. When the
* counter triggers counter 2 downcounts the length of the reset pulse * counter triggers counter 2 downcounts the length of the reset pulse
* which set set to be as long as possible. * which set set to be as long as possible.
*/ */
static int wdtpci_open(struct inode *inode, struct file *file) static int wdtpci_open(struct inode *inode, struct file *file)
{ {
unsigned long flags; unsigned long flags;
...@@ -371,17 +371,17 @@ static int wdtpci_open(struct inode *inode, struct file *file) ...@@ -371,17 +371,17 @@ static int wdtpci_open(struct inode *inode, struct file *file)
__module_get(THIS_MODULE); __module_get(THIS_MODULE);
} }
/* /*
* Activate * Activate
*/ */
spin_lock_irqsave(&wdtpci_lock, flags); spin_lock_irqsave(&wdtpci_lock, flags);
inb_p(WDT_DC); /* Disable */ inb_p(WDT_DC); /* Disable */
/* /*
* "pet" the watchdog, as Access says. * "pet" the watchdog, as Access says.
* This resets the clock outputs. * This resets the clock outputs.
*/ */
wdtpci_ctr_mode(2,0); wdtpci_ctr_mode(2,0);
outb_p(0, WDT_DC); outb_p(0, WDT_DC);
...@@ -413,19 +413,19 @@ static int wdtpci_open(struct inode *inode, struct file *file) ...@@ -413,19 +413,19 @@ static int wdtpci_open(struct inode *inode, struct file *file)
* @inode: inode to board * @inode: inode to board
* @file: file handle to board * @file: file handle to board
* *
* The watchdog has a configurable API. There is a religious dispute * The watchdog has a configurable API. There is a religious dispute
* between people who want their watchdog to be able to shut down and * between people who want their watchdog to be able to shut down and
* those who want to be sure if the watchdog manager dies the machine * those who want to be sure if the watchdog manager dies the machine
* reboots. In the former case we disable the counters, in the latter * reboots. In the former case we disable the counters, in the latter
* case you have to open it again very soon. * case you have to open it again very soon.
*/ */
static int wdtpci_release(struct inode *inode, struct file *file) static int wdtpci_release(struct inode *inode, struct file *file)
{ {
if (iminor(inode)==WATCHDOG_MINOR) { if (iminor(inode)==WATCHDOG_MINOR) {
unsigned long flags; unsigned long flags;
if (expect_close) { if (expect_close == 42) {
spin_lock_irqsave(&wdtpci_lock, flags); spin_lock_irqsave(&wdtpci_lock, flags);
inb_p(WDT_DC); /* Disable counters */ inb_p(WDT_DC); /* Disable counters */
wdtpci_ctr_load(2,0); /* 0 length reset pulses now */ wdtpci_ctr_load(2,0); /* 0 length reset pulses now */
...@@ -434,6 +434,7 @@ static int wdtpci_release(struct inode *inode, struct file *file) ...@@ -434,6 +434,7 @@ static int wdtpci_release(struct inode *inode, struct file *file)
printk(KERN_CRIT PFX "Unexpected close, not stopping timer!"); printk(KERN_CRIT PFX "Unexpected close, not stopping timer!");
wdtpci_ping(); wdtpci_ping();
} }
expect_close = 0;
up(&open_sem); up(&open_sem);
} }
return 0; return 0;
...@@ -465,12 +466,12 @@ static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code, ...@@ -465,12 +466,12 @@ static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code,
} }
return NOTIFY_DONE; return NOTIFY_DONE;
} }
/* /*
* Kernel Interfaces * Kernel Interfaces
*/ */
static struct file_operations wdtpci_fops = { static struct file_operations wdtpci_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.llseek = no_llseek, .llseek = no_llseek,
...@@ -497,9 +498,9 @@ static struct miscdevice temp_miscdev = { ...@@ -497,9 +498,9 @@ static struct miscdevice temp_miscdev = {
/* /*
* The WDT card needs to learn about soft shutdowns in order to * The WDT card needs to learn about soft shutdowns in order to
* turn the timebomb registers off. * turn the timebomb registers off.
*/ */
static struct notifier_block wdtpci_notifier = { static struct notifier_block wdtpci_notifier = {
.notifier_call = wdtpci_notify_sys, .notifier_call = wdtpci_notify_sys,
}; };
...@@ -584,7 +585,7 @@ static void __devexit wdtpci_remove_one (struct pci_dev *pdev) ...@@ -584,7 +585,7 @@ static void __devexit wdtpci_remove_one (struct pci_dev *pdev)
unregister_reboot_notifier(&wdtpci_notifier); unregister_reboot_notifier(&wdtpci_notifier);
#ifdef CONFIG_WDT_501_PCI #ifdef CONFIG_WDT_501_PCI
misc_deregister(&temp_miscdev); misc_deregister(&temp_miscdev);
#endif #endif
misc_deregister(&wdtpci_miscdev); misc_deregister(&wdtpci_miscdev);
free_irq(irq, &wdtpci_miscdev); free_irq(irq, &wdtpci_miscdev);
release_region(io, 16); release_region(io, 16);
...@@ -620,7 +621,7 @@ static struct pci_driver wdtpci_driver = { ...@@ -620,7 +621,7 @@ static struct pci_driver wdtpci_driver = {
* will not touch PC memory so all is fine. You just have to load a new * will not touch PC memory so all is fine. You just have to load a new
* module in 60 seconds or reboot. * module in 60 seconds or reboot.
*/ */
static void __exit wdtpci_cleanup(void) static void __exit wdtpci_cleanup(void)
{ {
pci_unregister_driver (&wdtpci_driver); pci_unregister_driver (&wdtpci_driver);
...@@ -634,14 +635,14 @@ static void __exit wdtpci_cleanup(void) ...@@ -634,14 +635,14 @@ static void __exit wdtpci_cleanup(void)
* resources we require and bitch if anyone beat us to them. * resources we require and bitch if anyone beat us to them.
* The open() function will actually kick the board off. * The open() function will actually kick the board off.
*/ */
static int __init wdtpci_init(void) static int __init wdtpci_init(void)
{ {
int rc = pci_register_driver (&wdtpci_driver); int rc = pci_register_driver (&wdtpci_driver);
if (rc < 1) if (rc < 1)
return -ENODEV; return -ENODEV;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment