This patch has been approved by the maintainer, Rodolfo Giometti.
Regards,
Rob Radez
--- linux-2.4.19-pre7/drivers/char/eurotechwdt.c Tue Apr 16 13:18:17 2002
+++ watchdog-tree/drivers/char/eurotechwdt.c Thu Apr 25 02:07:08 2002
@@ -3,6 +3,7 @@
*
* (c) Copyright 2001 Ascensit <support@ascensit.com>
* (c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com>
+ * (c) Copyright 2002 Rob Radez <rob@osinvestor.com>
*
* Based on wdt.c.
* Original copyright messages:
@@ -22,17 +23,27 @@
* (c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>*
*/
+/* Changelog:
+ *
+ * 2002/04/25 - Rob Radez
+ * clean up #includes
+ * clean up locking
+ * make __setup param unique
+ * proper options in watchdog_info
+ * add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls
+ * add expect_close support
+ *
+ * 2001 - Rodolfo Giometti
+ * Initial release
+ */
+
#include <linux/config.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
-#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/fcntl.h>
#include <asm/io.h>
@@ -41,12 +52,10 @@
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-static int eurwdt_is_open;
+static unsigned long eurwdt_is_open;
static int eurwdt_timeout;
-static spinlock_t eurwdt_lock;
+static char eur_expect_close;
/*
* You must set these - there is no sane way to probe for this board.
@@ -100,7 +109,7 @@
return 1;
}
-__setup("wdt=", eurwdt_setup);
+__setup("eurwdt=", eurwdt_setup);
#endif /* !MODULE */
@@ -109,7 +118,7 @@
MODULE_PARM(irq, "i");
MODULE_PARM_DESC(irq, "Eurotech WDT irq (default=10)");
MODULE_PARM(ev, "s");
-MODULE_PARM_DESC(ev, "Eurotech WDT event type (default is `reboot')");
+MODULE_PARM_DESC(ev, "Eurotech WDT event type (default is `int')");
/*
@@ -211,11 +220,20 @@
return -ESPIPE;
if (count) {
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+ size_t i;
+
+ eur_expect_close = 0;
+
+ for (i = 0; i != count; i++) {
+ if (buf[i] == 'V')
+ eur_expect_close = 42;
+ }
+#endif
eurwdt_ping(); /* the default timeout */
- return 1;
}
- return 0;
+ return count;
}
/**
@@ -233,8 +251,8 @@
unsigned int cmd, unsigned long arg)
{
static struct watchdog_info ident = {
- options : WDIOF_CARDRESET | WDIOF_SETTIMEOUT,
- firmware_version : 1,
+ options : WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
+ firmware_version : 0,
identity : "WDT Eurotech CPU-1220/1410"
};
@@ -248,6 +266,7 @@
return copy_to_user((struct watchdog_info *)arg, &ident,
sizeof(ident)) ? -EFAULT : 0;
+ case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
return put_user(0, (int *) arg);
@@ -269,6 +288,27 @@
case WDIOC_GETTIMEOUT:
return put_user(eurwdt_timeout, (int *)arg);
+
+ case WDIOC_SETOPTIONS:
+ {
+ int options, retval = -EINVAL;
+
+ if (get_user(options, (int *)arg))
+ return -EFAULT;
+
+ if (options & WDIOS_DISABLECARD) {
+ eurwdt_disable_timer();
+ retval = 0;
+ }
+
+ if (options & WDIOS_ENABLECARD) {
+ eurwdt_activate_timer();
+ eurwdt_ping();
+ retval = 0;
+ }
+
+ return retval;
+ }
}
}
@@ -283,32 +323,15 @@
static int eurwdt_open(struct inode *inode, struct file *file)
{
- switch (MINOR(inode->i_rdev)) {
- case WATCHDOG_MINOR:
- spin_lock(&eurwdt_lock);
- if (eurwdt_is_open) {
- spin_unlock(&eurwdt_lock);
- return -EBUSY;
- }
-
- eurwdt_is_open = 1;
- eurwdt_timeout = WDT_TIMEOUT; /* initial timeout */
-
- /* Activate the WDT */
- eurwdt_activate_timer();
-
- spin_unlock(&eurwdt_lock);
-
- MOD_INC_USE_COUNT;
+ if (test_and_set_bit(0, &eurwdt_is_open))
+ return -EBUSY;
- return 0;
+ eurwdt_timeout = WDT_TIMEOUT; /* initial timeout */
- case TEMP_MINOR:
- return 0;
+ /* Activate the WDT */
+ eurwdt_activate_timer();
- default:
- return -ENODEV;
- }
+ return 0;
}
/**
@@ -325,14 +348,14 @@
static int eurwdt_release(struct inode *inode, struct file *file)
{
- if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
-#ifndef CONFIG_WATCHDOG_NOWAYOUT
+ if (eur_expect_close == 42) {
eurwdt_disable_timer();
-#endif
- eurwdt_is_open = 0;
-
- MOD_DEC_USE_COUNT;
+ } else {
+ printk(KERN_CRIT "eurwdt: Unexpected close, not stopping watchdog!\n");
+ eurwdt_ping();
}
+ clear_bit(0, &eurwdt_is_open);
+ eur_expect_close = 0;
return 0;
}
@@ -376,9 +399,9 @@
static struct miscdevice eurwdt_miscdev =
{
- WATCHDOG_MINOR,
- "watchdog",
- &eurwdt_fops
+ minor: WATCHDOG_MINOR,
+ name: "watchdog",
+ fops: &eurwdt_fops,
};
/*
@@ -457,8 +480,6 @@
printk(KERN_INFO "Eurotech WDT driver 0.01 at %X (Interrupt %d)"
" - timeout event: %s\n",
io, irq, (!strcmp("int", ev) ? "int" : "reboot"));
-
- spin_lock_init(&eurwdt_lock);
out:
return ret;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/