From 2d3657850d376bd7b73488fe885209084eddfcef Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Fri, 10 Jan 2003 00:45:22 -0100 Subject: [PATCH] [WATCHDOG] ib700wdt fixes from 2.4 --- drivers/char/watchdog/ib700wdt.c | 62 +++++++++++++++++++------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c index 448c7be4e717..983ae7a8c7fe 100644 --- a/drivers/char/watchdog/ib700wdt.c +++ b/drivers/char/watchdog/ib700wdt.c @@ -54,6 +54,7 @@ static int ibwdt_is_open; static spinlock_t ibwdt_lock; +static int expect_close = 0; /* * @@ -136,6 +137,21 @@ ibwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) return -ESPIPE; if (count) { + if (!nowayout) { + size_t i; + + /* In case it was set long ago */ + expect_close = 0; + + for (i = 0; i != count; i++) { + char c; + + if (get_user(c, buf + i)) + return -EFAULT; + if (c == 'V') + expect_close = 1; + } + } ibwdt_ping(); return 1; } @@ -153,7 +169,9 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { static struct watchdog_info ident = { - WDIOF_KEEPALIVEPING, 1, "IB700 WDT" + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, + .firmware_version = 1, + .identity = "IB700 WDT" }; switch (cmd) { @@ -180,42 +198,38 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, static int ibwdt_open(struct inode *inode, struct file *file) { - switch (minor(inode->i_rdev)) { - case WATCHDOG_MINOR: - spin_lock(&ibwdt_lock); - if (ibwdt_is_open) { - spin_unlock(&ibwdt_lock); - return -EBUSY; - } - if (nowayout) { - MOD_INC_USE_COUNT; - } - /* - * Activate - */ - - ibwdt_is_open = 1; - ibwdt_ping(); + if (minor(inode->i_rdev) == WATCHDOG_MINOR) { + spin_lock(&ibwdt_lock); + if (ibwdt_is_open) { spin_unlock(&ibwdt_lock); - return 0; - default: - return -ENODEV; + return -EBUSY; + } + if (nowayout) + MOD_INC_USE_COUNT; + + /* Activate */ + ibwdt_is_open = 1; + ibwdt_ping(); + spin_unlock(&ibwdt_lock); + return 0; + } else { + return -ENODEV; } } static int ibwdt_close(struct inode *inode, struct file *file) { - lock_kernel(); if (minor(inode->i_rdev) == WATCHDOG_MINOR) { spin_lock(&ibwdt_lock); - if (!nowayout) { + if (expect_close) outb_p(timeout_val, WDT_STOP); - } + else + printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n"); + ibwdt_is_open = 0; spin_unlock(&ibwdt_lock); } - unlock_kernel(); return 0; } -- 2.39.5