public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Rusty Lynch <rusty@linux.co.intel.com>
To: Rusty Lynch <rusty@linux.co.intel.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>, lkml <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH][2.5] Sysfs enabling watchdog infrastructure
Date: 21 Feb 2003 15:31:44 -0800	[thread overview]
Message-ID: <1045870305.1014.11.camel@vmhack> (raw)
In-Reply-To: <1045869699.1037.6.camel@vmhack>

[-- Attachment #1: Type: text/plain, Size: 9338 bytes --]

The following is a patch against the 2.5.60 kernel that ports the
softdog driver to register as a watchdog_driver and allow the watchdog
infrastructure to take care of details like sysfs and presenting a miscdevice
for the watchdog minor.

There are enough changes to make the patch difficult to read so I am
also attaching softdog.c to make it easier to see what the file is doing.

    --rustyl

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1040  -> 1.1041 
#	drivers/char/watchdog/softdog.c	1.14    -> 1.15   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/02/21	rusty@penguin.co.intel.com	1.1041
# * ported driver to new sysfs based watchdog infrastructure
# * change from using old MODULE_PARM macro to the new module_param
#   function call
# --------------------------------------------
#
diff -Nru a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c
--- a/drivers/char/watchdog/softdog.c	Fri Feb 21 14:48:49 2003
+++ b/drivers/char/watchdog/softdog.c	Fri Feb 21 14:48:49 2003
@@ -1,5 +1,5 @@
 /*
- *	SoftDog	0.06:	A Software Watchdog Device
+ *	SoftDog	0.07:	A Software Watchdog Device
  *
  *	(c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
  *				http://www.redhat.com
@@ -34,52 +34,41 @@
  *
  *  20020530 Joel Becker <joel.becker@oracle.com>
  *  	Added Matt Domsch's nowayout module option.
+ * 
+ *  20030221 Rusty Lynch <rusty@linux.co.intel.com>
+ *      Moved implementation to use the new watchdog infrastructure.  This
+ *      adds the softdog to the sysfs topography and moves the common 
+ *      miscdevice functions to the infrastructure as well.
+ *       
  */
  
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/config.h>
 #include <linux/types.h>
-#include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
 
 #define TIMER_MARGIN	60		/* (secs) Default is 1 minute */
-
-static int expect_close = 0;
 static int soft_margin = TIMER_MARGIN;	/* in seconds */
-#ifdef ONLY_TESTING
-static int soft_noboot = 1;
-#else
-static int soft_noboot = 0;
-#endif  /* ONLY_TESTING */
+module_param(soft_margin,int,0);
+MODULE_PARM_DESC(soft_margin, "Watchdog timer margin (timeout) in seconds");
 
-MODULE_PARM(soft_margin,"i");
-MODULE_PARM(soft_noboot,"i");
-MODULE_LICENSE("GPL");
+static int soft_noboot = 0;
+module_param(soft_noboot,int,0);
+MODULE_PARM_DESC(soft_noboot, "Disable machine restarts on watchdog timeout");
 
 #ifdef CONFIG_WATCHDOG_NOWAYOUT
 static int nowayout = 1;
 #else
 static int nowayout = 0;
 #endif
-
-MODULE_PARM(nowayout,"i");
+module_param(nowayout,int,0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
 /*
- *	Our timer
- */
- 
-static void watchdog_fire(unsigned long);
-
-static struct timer_list watchdog_ticktock =
-		TIMER_INITIALIZER(watchdog_fire, 0, 0);
-static unsigned long timer_alive;
-
-
-/*
  *	If the timer expires..
  */
  
@@ -96,137 +85,154 @@
 }
 
 /*
- *	Allow only one person to hold it open
+ *	Software timer
  */
  
-static int softdog_open(struct inode *inode, struct file *file)
+static struct timer_list watchdog_ticktock =
+		TIMER_INITIALIZER(watchdog_fire, 0, 0);
+
+
+/* 
+ *       Watchdog ops callback functions
+ */
+
+static int softdog_start(struct watchdog_driver *d)
 {
-	if(test_and_set_bit(0, &timer_alive))
-		return -EBUSY;
-	if (nowayout) {
-		MOD_INC_USE_COUNT;
-	}
-	/*
-	 *	Activate timer
-	 */
 	mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
 	return 0;
 }
 
-static int softdog_release(struct inode *inode, struct file *file)
+static int softdog_stop(struct watchdog_driver *d)
 {
-	/*
-	 *	Shut off the timer.
-	 * 	Lock it in if it's a module and we set nowayout
-	 */
-	if (expect_close) {
-		del_timer(&watchdog_ticktock);
-	} else {
-		printk(KERN_CRIT "SOFTDOG: WDT device closed unexpectedly.  WDT will not stop!\n");
+	if (nowayout) {
+		printk(KERN_CRIT "SOFTDOG: WDT device closed unexpectedly.  "
+		       "WDT will not stop!\n");
+		return -1;
 	}
-	clear_bit(0, &timer_alive);
+
+	del_timer(&watchdog_ticktock);
 	return 0;
 }
 
-static ssize_t softdog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
+static int softdog_keepalive(struct watchdog_driver *d) 
 {
-	/*  Can't seek (pwrite) on this device  */
-	if (ppos != &file->f_pos)
-		return -ESPIPE;
+	mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
+	return 0;
+}
 
-	/*
-	 *	Refresh the timer.
-	 */
-	if(len) {
-		if (!nowayout) {
-			size_t i;
+static int softdog_get_timeout(struct watchdog_driver *d, int *timeout)
+{
+	*timeout = soft_margin;
+	return 0;
+}
 
-			/* In case it was set long ago */
-			expect_close = 0;
+static int softdog_set_timeout(struct watchdog_driver *d, int timeout)
+{
+	if (timeout < 1)
+		return -1;
 
-			for (i = 0; i != len; i++) {
-				char c;
+	soft_margin = timeout;
+	mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
+	return 0;
+}
 
-				if (get_user(c, data + i))
-					return -EFAULT;
-				if (c == 'V')
-					expect_close = 1;
-			}
-		}
-		mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
-		return 1;
-	}
+static int softdog_get_options(struct watchdog_driver *d, int *options)
+{
+	*options =  WDIOF_SETTIMEOUT;
 	return 0;
 }
 
-static int softdog_ioctl(struct inode *inode, struct file *file,
-	unsigned int cmd, unsigned long arg)
+static int softdog_get_nowayout(struct watchdog_driver *d, int *n)
 {
-	int new_margin;
-	static struct watchdog_info ident = {
-		.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
-		.identity = "Software Watchdog",
-	};
-	switch (cmd) {
-		default:
-			return -ENOTTY;
-		case WDIOC_GETSUPPORT:
-			if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
-				return -EFAULT;
-			return 0;
-		case WDIOC_GETSTATUS:
-		case WDIOC_GETBOOTSTATUS:
-			return put_user(0,(int *)arg);
-		case WDIOC_KEEPALIVE:
-			mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
-			return 0;
-		case WDIOC_SETTIMEOUT:
-			if (get_user(new_margin, (int *)arg))
-				return -EFAULT;
-			if (new_margin < 1)
-				return -EINVAL;
-			soft_margin = new_margin;
-			mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
-			/* Fall */
-		case WDIOC_GETTIMEOUT:
-			return put_user(soft_margin, (int *)arg);
-	}
+	*n = nowayout;
+	return 0;
 }
 
-static struct file_operations softdog_fops = {
-	.owner		= THIS_MODULE,
-	.write		= softdog_write,
-	.ioctl		= softdog_ioctl,
-	.open		= softdog_open,
-	.release	= softdog_release,
+static int softdog_set_nowayout(struct watchdog_driver *d, int n)
+{
+	if (n)
+		nowayout = 1;
+	else 
+		nowayout = 0;
+	return 0;
+}
+
+/*
+ *      Structures required to register as a watchdog driver
+ */
+
+static struct watchdog_ops softdog_ops = {
+	.start                 = softdog_start,
+	.stop                  = softdog_stop,
+	.keepalive             = softdog_keepalive,
+	.get_timeout           = softdog_get_timeout,
+	.set_timeout           = softdog_set_timeout,
+	.get_nowayout          = softdog_get_nowayout,
+	.set_nowayout          = softdog_set_nowayout,
+	.get_options           = softdog_get_options,
+	/* get_bootstatus not implemented */
+	/* get_status not implemented */
+	/* get/set_temppanic not implemented */
+	/* get_firmware_version not implemented */
 };
 
-static struct miscdevice softdog_miscdev = {
-	.minor		= WATCHDOG_MINOR,
-	.name		= "watchdog",
-	.fops		= &softdog_fops,
+static struct watchdog_driver softdog_driver = {
+	.ops = &softdog_ops,
+	.driver = {
+		.name		= "softdog",
+		.bus		= &system_bus_type,
+		.devclass       = &watchdog_devclass,
+	}
 };
 
-static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.06, soft_margin: %d sec, nowayout: %d\n";
+/* 
+ *      enable testing the of driver to not cause a machine restart 
+ */
+
+static ssize_t soft_noboot_show(struct device_driver * d, char * buf)
+{
+	return sprintf(buf, "%i\n",soft_noboot);
+}
+static ssize_t soft_noboot_store(struct device_driver *d,const char * buf, 
+				 size_t count)
+{
+	int tmp;
+
+	if (sscanf(buf,"%i",&tmp) != 1)
+		return -EINVAL;
+
+	if (tmp)
+		soft_noboot = 1;
+	else
+		soft_noboot = 0;
+	return count;
+}
+DRIVER_ATTR(soft_noboot,0644,soft_noboot_show,soft_noboot_store);
+
+static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.07, soft_margin: %d sec, nowayout: %d\n";
 
 static int __init watchdog_init(void)
 {
 	int ret;
 
-	ret = misc_register(&softdog_miscdev);
-
+	ret = watchdog_driver_register(&softdog_driver);
 	if (ret)
 		return ret;
 
+	driver_create_file(&softdog_driver.driver, &driver_attr_soft_noboot);
 	printk(banner, soft_margin, nowayout);
-
 	return 0;
 }
 
 static void __exit watchdog_exit(void)
-{
-	misc_deregister(&softdog_miscdev);
+{     
+	driver_remove_file(&softdog_driver.driver, &driver_attr_soft_noboot);
+	watchdog_driver_unregister(&softdog_driver);
+
+	/* ensure somebody didn't leave the watchdog ticking */
+	del_timer(&watchdog_ticktock);
 }
 
 module_init(watchdog_init);
 module_exit(watchdog_exit);
+MODULE_LICENSE("GPL");

[-- Attachment #2: softdog.c --]
[-- Type: text/x-c, Size: 6276 bytes --]

/*
 *	SoftDog	0.07:	A Software Watchdog Device
 *
 *	(c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
 *				http://www.redhat.com
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License
 *	as published by the Free Software Foundation; either version
 *	2 of the License, or (at your option) any later version.
 *	
 *	Neither Alan Cox nor CymruNet Ltd. admit liability nor provide 
 *	warranty for any of this software. This material is provided 
 *	"AS-IS" and at no charge.	
 *
 *	(c) Copyright 1995    Alan Cox <alan@lxorguk.ukuu.org.uk>
 *
 *	Software only watchdog driver. Unlike its big brother the WDT501P
 *	driver this won't always recover a failed machine.
 *
 *  03/96: Angelo Haritsis <ah@doc.ic.ac.uk> :
 *	Modularised.
 *	Added soft_margin; use upon insmod to change the timer delay.
 *	NB: uses same minor as wdt (WATCHDOG_MINOR); we could use separate
 *	    minors.
 *
 *  19980911 Alan Cox
 *	Made SMP safe for 2.3.x
 *
 *  20011127 Joel Becker (jlbec@evilplan.org>
 *	Added soft_noboot; Allows testing the softdog trigger without 
 *	requiring a recompile.
 *	Added WDIOC_GETTIMEOUT and WDIOC_SETTIMOUT.
 *
 *  20020530 Joel Becker <joel.becker@oracle.com>
 *  	Added Matt Domsch's nowayout module option.
 * 
 *  20030221 Rusty Lynch <rusty@linux.co.intel.com>
 *      Moved implementation to use the new watchdog infrastructure.  This
 *      adds the softdog to the sysfs topography and moves the common 
 *      miscdevice functions to the infrastructure as well.
 *       
 */
 
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <asm/uaccess.h>

#define TIMER_MARGIN	60		/* (secs) Default is 1 minute */
static int soft_margin = TIMER_MARGIN;	/* in seconds */
module_param(soft_margin,int,0);
MODULE_PARM_DESC(soft_margin, "Watchdog timer margin (timeout) in seconds");

static int soft_noboot = 0;
module_param(soft_noboot,int,0);
MODULE_PARM_DESC(soft_noboot, "Disable machine restarts on watchdog timeout");

#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)");

/*
 *	If the timer expires..
 */
 
static void watchdog_fire(unsigned long data)
{
	if (soft_noboot)
		printk(KERN_CRIT "SOFTDOG: Triggered - Reboot ignored.\n");
	else
	{
		printk(KERN_CRIT "SOFTDOG: Initiating system reboot.\n");
		machine_restart(NULL);
		printk("SOFTDOG: Reboot didn't ?????\n");
	}
}

/*
 *	Software timer
 */
 
static struct timer_list watchdog_ticktock =
		TIMER_INITIALIZER(watchdog_fire, 0, 0);


/* 
 *       Watchdog ops callback functions
 */

static int softdog_start(struct watchdog_driver *d)
{
	mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
	return 0;
}

static int softdog_stop(struct watchdog_driver *d)
{
	if (nowayout) {
		printk(KERN_CRIT "SOFTDOG: WDT device closed unexpectedly.  "
		       "WDT will not stop!\n");
		return -1;
	}

	del_timer(&watchdog_ticktock);
	return 0;
}

static int softdog_keepalive(struct watchdog_driver *d) 
{
	mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
	return 0;
}

static int softdog_get_timeout(struct watchdog_driver *d, int *timeout)
{
	*timeout = soft_margin;
	return 0;
}

static int softdog_set_timeout(struct watchdog_driver *d, int timeout)
{
	if (timeout < 1)
		return -1;

	soft_margin = timeout;
	mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
	return 0;
}

static int softdog_get_options(struct watchdog_driver *d, int *options)
{
	*options =  WDIOF_SETTIMEOUT;
	return 0;
}

static int softdog_get_nowayout(struct watchdog_driver *d, int *n)
{
	*n = nowayout;
	return 0;
}

static int softdog_set_nowayout(struct watchdog_driver *d, int n)
{
	if (n)
		nowayout = 1;
	else 
		nowayout = 0;
	return 0;
}

/*
 *      Structures required to register as a watchdog driver
 */

static struct watchdog_ops softdog_ops = {
	.start                 = softdog_start,
	.stop                  = softdog_stop,
	.keepalive             = softdog_keepalive,
	.get_timeout           = softdog_get_timeout,
	.set_timeout           = softdog_set_timeout,
	.get_nowayout          = softdog_get_nowayout,
	.set_nowayout          = softdog_set_nowayout,
	.get_options           = softdog_get_options,
	/* get_bootstatus not implemented */
	/* get_status not implemented */
	/* get/set_temppanic not implemented */
	/* get_firmware_version not implemented */
};

static struct watchdog_driver softdog_driver = {
	.ops = &softdog_ops,
	.driver = {
		.name		= "softdog",
		.bus		= &system_bus_type,
		.devclass       = &watchdog_devclass,
	}
};

/* 
 *      enable testing the of driver to not cause a machine restart 
 */

static ssize_t soft_noboot_show(struct device_driver * d, char * buf)
{
	return sprintf(buf, "%i\n",soft_noboot);
}
static ssize_t soft_noboot_store(struct device_driver *d,const char * buf, 
				 size_t count)
{
	int tmp;

	if (sscanf(buf,"%i",&tmp) != 1)
		return -EINVAL;

	if (tmp)
		soft_noboot = 1;
	else
		soft_noboot = 0;
	return count;
}
DRIVER_ATTR(soft_noboot,0644,soft_noboot_show,soft_noboot_store);

static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.07, soft_margin: %d sec, nowayout: %d\n";

static int __init watchdog_init(void)
{
	int ret;

	ret = watchdog_driver_register(&softdog_driver);
	if (ret)
		return ret;

	driver_create_file(&softdog_driver.driver, &driver_attr_soft_noboot);
	printk(banner, soft_margin, nowayout);
	return 0;
}

static void __exit watchdog_exit(void)
{     
	driver_remove_file(&softdog_driver.driver, &driver_attr_soft_noboot);
	watchdog_driver_unregister(&softdog_driver);

	/* ensure somebody didn't leave the watchdog ticking */
	del_timer(&watchdog_ticktock);
}

module_init(watchdog_init);
module_exit(watchdog_exit);
MODULE_LICENSE("GPL");

  reply	other threads:[~2003-02-21 23:34 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-02-21 23:21 [PATCH][2.5] Sysfs enabling watchdog infrastructure Rusty Lynch
2003-02-21 23:31 ` Rusty Lynch [this message]
2003-02-21 23:36 ` Rusty Lynch

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1045870305.1014.11.camel@vmhack \
    --to=rusty@linux.co.intel.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox