Module Name:    src
Committed By:   pgoyette
Date:           Thu Jul 22 14:10:15 UTC 2010

Modified Files:
        src/share/man/man4: swwdog.4
        src/sys/dev/sysmon: files.sysmon swwdog.c
        src/sys/rump/dev/lib/libsysmon: Makefile
Added Files:
        src/sys/rump/dev/lib/libsysmon: SYSMON.ioconf

Log Message:
Convert swwdog(4) from a simple defpseudo device to a defpseudodev so
that we can attach a power management handler.  The handler prevents
a suspend if the watchdog is active, to be consistent with other
watchdog drivers.

As discussed on tech-kern.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/share/man/man4/swwdog.4
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/sysmon/files.sysmon
cvs rdiff -u -r1.9 -r1.10 src/sys/dev/sysmon/swwdog.c
cvs rdiff -u -r1.2 -r1.3 src/sys/rump/dev/lib/libsysmon/Makefile
cvs rdiff -u -r0 -r1.1 src/sys/rump/dev/lib/libsysmon/SYSMON.ioconf

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/share/man/man4/swwdog.4
diff -u src/share/man/man4/swwdog.4:1.4 src/share/man/man4/swwdog.4:1.5
--- src/share/man/man4/swwdog.4:1.4	Sat Jan 30 21:55:28 2010
+++ src/share/man/man4/swwdog.4	Thu Jul 22 14:10:14 2010
@@ -1,4 +1,4 @@
-.\"	$NetBSD: swwdog.4,v 1.4 2010/01/30 21:55:28 pooka Exp $
+.\"	$NetBSD: swwdog.4,v 1.5 2010/07/22 14:10:14 pgoyette Exp $
 .\"
 .\" Copyright (c) 2004, 2005 Steven M. Bellovin
 .\" All rights reserved.
@@ -31,7 +31,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd January 30, 2010
+.Dd July 21, 2010
 .\" Written by Steven M. Bellovin
 .Dt SWWDOG 4
 .Os
@@ -45,14 +45,26 @@
 .Nm
 driver provides a software watchdog timer that works with
 .Xr wdogctl 8 .
-If the timer expires, the system reboots unless the variable
+If the timer expires, the system reboots unless the boolean variable
 .Va swwdog_panic
-is non-zero; if it is, the system will panic instead.
+is
+.Dv true ;
+if it is, the system will panic instead.
+.Va swwdog_reboot
+is accessible as a
+.Xr sysctl 8
+variable, machdep.swwdog0.reboot and defaults to
+.Dv false .
 .Pp
 The default period of
 .Nm
 is 60 seconds.
+.Pp
+As with other watchdog timers, the
+.Nm
+driver prevents a system from suspending when the watchdog is armed.
 .Sh SEE ALSO
+.Xr sysctl 8
 .Xr wdogctl 8
 .Sh HISTORY
 The
@@ -61,7 +73,10 @@
 .An Steven M. Bellovin .
 .Sh BUGS
 Only one watchdog timer can be active at any given time.
-Arguably, this is a bug in the watchdog timer framework.
+(Arguably, this is a bug in the watchdog timer framework.)
+Therefore, only a single instance of the
+.Nm
+device can be created.
 .Pp
 Kernel tickle mode is useless with
 .Nm

Index: src/sys/dev/sysmon/files.sysmon
diff -u src/sys/dev/sysmon/files.sysmon:1.11 src/sys/dev/sysmon/files.sysmon:1.12
--- src/sys/dev/sysmon/files.sysmon:1.11	Sat Jan 30 21:55:28 2010
+++ src/sys/dev/sysmon/files.sysmon	Thu Jul 22 14:10:15 2010
@@ -1,4 +1,4 @@
-#	$NetBSD: files.sysmon,v 1.11 2010/01/30 21:55:28 pooka Exp $
+#	$NetBSD: files.sysmon,v 1.12 2010/07/22 14:10:15 pgoyette Exp $
 
 define	sysmon_taskq
 file	dev/sysmon/sysmon_taskq.c	sysmon_taskq 		needs-flag
@@ -18,5 +18,5 @@
 file	dev/sysmon/sysmon.c		sysmon_envsys | sysmon_wdog |
 					sysmon_power
 
-defpseudo swwdog: sysmon_wdog
+defpseudodev swwdog: sysmon_wdog
 file    dev/sysmon/swwdog.c            swwdog

Index: src/sys/dev/sysmon/swwdog.c
diff -u src/sys/dev/sysmon/swwdog.c:1.9 src/sys/dev/sysmon/swwdog.c:1.10
--- src/sys/dev/sysmon/swwdog.c:1.9	Sun Jan 31 02:54:56 2010
+++ src/sys/dev/sysmon/swwdog.c	Thu Jul 22 14:10:15 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: swwdog.c,v 1.9 2010/01/31 02:54:56 pooka Exp $	*/
+/*	$NetBSD: swwdog.c,v 1.10 2010/07/22 14:10:15 pgoyette Exp $	*/
 
 /*
  * Copyright (c) 2004, 2005 Steven M. Bellovin
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: swwdog.c,v 1.9 2010/01/31 02:54:56 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: swwdog.c,v 1.10 2010/07/22 14:10:15 pgoyette Exp $");
 
 /*
  *
@@ -44,20 +44,28 @@
 #include <sys/callout.h>
 #include <sys/device.h>
 #include <sys/kernel.h>
+#include <sys/kmem.h>
 #include <sys/reboot.h>
 #include <sys/systm.h>
+#include <sys/sysctl.h>
 #include <sys/wdog.h>
 #include <dev/sysmon/sysmonvar.h>
 
-#define NSWWDOG 1
+#include "ioconf.h"
+
 struct swwdog_softc {
+	device_t sc_dev;
 	struct sysmon_wdog sc_smw;
 	struct callout sc_c;
-	char sc_name[20];
 	int sc_wdog_armed;
-} sc_wdog[NSWWDOG];
+};
+
+void		swwdogattach(int);
 
-void	swwdogattach(int);
+static int	swwdog_match(device_t, cfdata_t, void *);
+static void	swwdog_attach(device_t, device_t, void *);
+static int	swwdog_detach(device_t, int);
+static bool	swwdog_suspend(device_t, const pmf_qual_t *);
 
 static int swwdog_setmode(struct sysmon_wdog *);
 static int swwdog_tickle(struct sysmon_wdog *);
@@ -67,34 +75,87 @@
 
 static void swwdog_panic(void *);
 
-int swwdog_reboot = 0;		/* set for panic instead of reboot */
+bool swwdog_reboot = false;		/* set for panic instead of reboot */
 
 #define	SWDOG_DEFAULT	60		/* 60-second default period */
 
+CFATTACH_DECL_NEW(swwdog, sizeof(struct swwdog_softc),
+	swwdog_match, swwdog_attach, swwdog_detach, NULL);
+
 void
-swwdogattach(int count __unused)
+swwdogattach(int n __unused)
 {
-	int i;
+	int err;
+	static struct cfdata cf;
 
-	for (i = 0; i < NSWWDOG; i++) {
-		struct swwdog_softc *sc = &sc_wdog[i];
+	err = config_cfattach_attach(swwdog_cd.cd_name, &swwdog_ca);
+	if (err) {
+		aprint_error("%s: couldn't register cfattach: %d\n",
+		    swwdog_cd.cd_name, err);
+		config_cfdriver_detach(&swwdog_cd);
+		return;
+	}
 
-		snprintf(sc->sc_name, sizeof sc->sc_name, "swwdog%d", i);
-		printf("%s: ", sc->sc_name);
-		sc->sc_smw.smw_name = sc->sc_name;
-		sc->sc_smw.smw_cookie = sc;
-		sc->sc_smw.smw_setmode = swwdog_setmode;
-		sc->sc_smw.smw_tickle = swwdog_tickle;
-		sc->sc_smw.smw_period = SWDOG_DEFAULT;
-		callout_init(&sc->sc_c, 0);
-		callout_setfunc(&sc->sc_c, swwdog_panic, sc);
+	cf.cf_name = swwdog_cd.cd_name;
+	cf.cf_atname = swwdog_cd.cd_name;
+	cf.cf_unit = 0;
+	cf.cf_fstate = FSTATE_STAR;
 
-		if (sysmon_wdog_register(&sc->sc_smw) == 0)
-			printf("software watchdog initialized\n");
-		else
-			printf("unable to register software watchdog "
-			    "with sysmon\n");
-	}
+	(void)config_attach_pseudo(&cf);
+
+	return;
+}
+
+static int
+swwdog_match(device_t parent, cfdata_t data, void *aux)
+{
+	return 1;
+}
+
+static void
+swwdog_attach(device_t parent, device_t self, void *aux)
+{
+	struct swwdog_softc *sc = device_private(self);
+
+	sc->sc_dev = self;
+	sc->sc_smw.smw_name = device_xname(self);
+	sc->sc_smw.smw_cookie = sc;
+	sc->sc_smw.smw_setmode = swwdog_setmode;
+	sc->sc_smw.smw_tickle = swwdog_tickle;
+	sc->sc_smw.smw_period = SWDOG_DEFAULT;
+	callout_init(&sc->sc_c, 0);
+	callout_setfunc(&sc->sc_c, swwdog_panic, sc);
+
+	if (sysmon_wdog_register(&sc->sc_smw) == 0)
+		aprint_normal_dev(self, "software watchdog initialized\n");
+	else
+		aprint_error_dev(self, "unable to register software "
+		    "watchdog with sysmon\n");
+
+	if (!pmf_device_register(self, swwdog_suspend, NULL))
+		aprint_error_dev(self, "couldn't establish power handler\n");
+}
+
+static int
+swwdog_detach(device_t self, int flags)
+{
+	struct swwdog_softc *sc = device_private(self);
+
+	swwdog_disarm(sc);
+	callout_destroy(&sc->sc_c);
+
+	return 1;
+}
+
+static bool
+swwdog_suspend(device_t dev, const pmf_qual_t *qual)
+{
+	struct swwdog_softc *sc = device_private(dev);
+
+	/* Don't allow suspend if watchdog is armed */
+	if ((sc->sc_smw.smw_mode & WDOG_MODE_MASK) != WDOG_MODE_DISARMED)
+		return false;
+	return true;
 }
 
 static int
@@ -144,13 +205,13 @@
 swwdog_panic(void *vsc)
 {
 	struct swwdog_softc *sc = vsc;
-	int do_panic;
+	bool do_panic;
 
 	do_panic = swwdog_reboot;
 	swwdog_reboot = 1;
 	callout_schedule(&sc->sc_c, 60 * hz);	/* deliberate double-panic */
 
-	printf("%s: %d second timer expired\n", sc->sc_name,
+	printf("%s: %d second timer expired\n", device_xname(sc->sc_dev),
 	    sc->sc_smw.smw_period);
 
 	if (do_panic)
@@ -158,3 +219,26 @@
 	else
 		cpu_reboot(0, NULL);
 }
+
+SYSCTL_SETUP(sysctl_swwdog, "swwdog subtree setup")
+{
+	int err;
+	const struct sysctlnode *me;
+
+	err = sysctl_createv(NULL, 0, NULL, NULL, CTLFLAG_PERMANENT,
+	    CTLTYPE_NODE, "machdep", NULL,
+	    NULL, 0, NULL, 0,
+	    CTL_HW, CTL_EOL);
+
+	if (err == 0)
+		err = sysctl_createv(NULL, 0, NULL, &me, CTLFLAG_READWRITE,
+		    CTLTYPE_NODE, "swwdog", NULL,
+		    NULL, 0, NULL, 0,
+		    CTL_HW, CTL_CREATE, CTL_EOL);
+
+	if (err == 0)
+		err = sysctl_createv(NULL, 0, NULL, NULL, CTLFLAG_READWRITE,
+		    CTLTYPE_BOOL, "reboot", "reboot if timer expires",
+		    NULL, 0, &swwdog_reboot, sizeof(bool),
+		    CTL_HW, me->sysctl_num, CTL_CREATE, CTL_EOL);
+}

Index: src/sys/rump/dev/lib/libsysmon/Makefile
diff -u src/sys/rump/dev/lib/libsysmon/Makefile:1.2 src/sys/rump/dev/lib/libsysmon/Makefile:1.3
--- src/sys/rump/dev/lib/libsysmon/Makefile:1.2	Tue Feb 16 20:42:45 2010
+++ src/sys/rump/dev/lib/libsysmon/Makefile	Thu Jul 22 14:10:14 2010
@@ -1,9 +1,10 @@
-#	$NetBSD: Makefile,v 1.2 2010/02/16 20:42:45 pooka Exp $
+#	$NetBSD: Makefile,v 1.3 2010/07/22 14:10:14 pgoyette Exp $
 #
 
 .PATH:	${.CURDIR}/../../../../dev/sysmon
 
 LIB=	rumpdev_sysmon
+IOCONF=	SYSMON.ioconf
 
 SRCS=	sysmon_taskq.c sysmon_power.c sysmon_envsys.c sysmon_envsys_events.c \
 	sysmon_envsys_tables.c sysmon_envsys_util.c sysmon_wdog.c sysmon.c \

Added files:

Index: src/sys/rump/dev/lib/libsysmon/SYSMON.ioconf
diff -u /dev/null src/sys/rump/dev/lib/libsysmon/SYSMON.ioconf:1.1
--- /dev/null	Thu Jul 22 14:10:15 2010
+++ src/sys/rump/dev/lib/libsysmon/SYSMON.ioconf	Thu Jul 22 14:10:14 2010
@@ -0,0 +1,8 @@
+#	$NetBSD: SYSMON.ioconf,v 1.1 2010/07/22 14:10:14 pgoyette Exp $
+#
+
+ioconf swwdog
+
+include "conf/files"
+
+pseudo-device	swwdog

Reply via email to