Commit 2d365785 authored by Dave Jones's avatar Dave Jones Committed by Dave Jones

[WATCHDOG] ib700wdt fixes from 2.4

parent 924eeb20
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
static int ibwdt_is_open; static int ibwdt_is_open;
static spinlock_t ibwdt_lock; 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) ...@@ -136,6 +137,21 @@ ibwdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
return -ESPIPE; return -ESPIPE;
if (count) { 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(); ibwdt_ping();
return 1; return 1;
} }
...@@ -153,7 +169,9 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -153,7 +169,9 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
static struct watchdog_info ident = { 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) { switch (cmd) {
...@@ -180,42 +198,38 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -180,42 +198,38 @@ 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)
{ {
switch (minor(inode->i_rdev)) { if (minor(inode->i_rdev) == WATCHDOG_MINOR) {
case WATCHDOG_MINOR: spin_lock(&ibwdt_lock);
spin_lock(&ibwdt_lock); if (ibwdt_is_open) {
if (ibwdt_is_open) {
spin_unlock(&ibwdt_lock);
return -EBUSY;
}
if (nowayout) {
MOD_INC_USE_COUNT;
}
/*
* Activate
*/
ibwdt_is_open = 1;
ibwdt_ping();
spin_unlock(&ibwdt_lock); spin_unlock(&ibwdt_lock);
return 0; return -EBUSY;
default: }
return -ENODEV; if (nowayout)
MOD_INC_USE_COUNT;
/* Activate */
ibwdt_is_open = 1;
ibwdt_ping();
spin_unlock(&ibwdt_lock);
return 0;
} else {
return -ENODEV;
} }
} }
static int static int
ibwdt_close(struct inode *inode, struct file *file) ibwdt_close(struct inode *inode, struct file *file)
{ {
lock_kernel();
if (minor(inode->i_rdev) == WATCHDOG_MINOR) { if (minor(inode->i_rdev) == WATCHDOG_MINOR) {
spin_lock(&ibwdt_lock); spin_lock(&ibwdt_lock);
if (!nowayout) { if (expect_close)
outb_p(timeout_val, WDT_STOP); outb_p(timeout_val, WDT_STOP);
} else
printk(KERN_CRIT "WDT device closed unexpectedly. WDT will not stop!\n");
ibwdt_is_open = 0; ibwdt_is_open = 0;
spin_unlock(&ibwdt_lock); spin_unlock(&ibwdt_lock);
} }
unlock_kernel();
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