Add a software watchdog timer facility. Because this slightly

changes the "tickle" model of wdogctl(8), it was modified as well;
while I was in there, I cleaned up the argument parsing.

The code was reviewed by simonb@.
This commit is contained in:
smb 2005-01-09 22:51:32 +00:00
parent f26774eaee
commit ddd2ade252
9 changed files with 406 additions and 62 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.748 2005/01/09 05:53:16 snj Exp $
# $NetBSD: mi,v 1.749 2005/01/09 22:51:32 smb Exp $
./etc/mtree/set.man man-sys-root
./usr/share/info/am-utils.info man-amd-info info
./usr/share/info/as.info man-computil-info bfd,info
@ -1227,6 +1227,7 @@
./usr/share/man/cat4/sun3/ms.0 man-sys-catman .cat
./usr/share/man/cat4/sv.0 man-sys-catman .cat
./usr/share/man/cat4/sw.0 man-sys-catman .cat
./usr/share/man/cat4/swwdog.0 man-sys-catman .cat
./usr/share/man/cat4/sysbeep.0 man-sys-catman .cat
./usr/share/man/cat4/systrace.0 man-sys-catman .cat
./usr/share/man/cat4/tap.0 man-sys-catman .cat
@ -3411,6 +3412,7 @@
./usr/share/man/man4/sun3/ms.4 man-sys-man .man
./usr/share/man/man4/sv.4 man-sys-man .man
./usr/share/man/man4/sw.4 man-sys-man .man
./usr/share/man/man4/swwdog.4 man-sys-man .man
./usr/share/man/man4/sysbeep.4 man-sys-man .man
./usr/share/man/man4/systrace.4 man-sys-man .man
./usr/share/man/man4/tap.4 man-sys-man .man

View File

@ -1,4 +1,4 @@
.\" $NetBSD: wdogctl.8,v 1.8 2003/02/25 10:35:12 wiz Exp $
.\" $NetBSD: wdogctl.8,v 1.9 2005/01/09 22:51:32 smb Exp $
.\"
.\" Copyright (c) 2000 Zembu Labs, Inc.
.\" All rights reserved.
@ -50,6 +50,13 @@
.Op Fl p Ar seconds
.Ar timer
.Nm
.Fl e
.Op Fl A
.Op Fl p Ar seconds
.Ar timer
.Nm
.Fl t
.Nm
.Fl d
.Sh DESCRIPTION
.Nm
@ -67,8 +74,8 @@ something must refresh the timer to prevent it from expiring.
.Pp
The
.Nx
kernel provides two basic modes in which watchdog timers may
operate: kernel tickle mode and user tickle mode.
kernel provides three basic modes in which watchdog timers may
operate: kernel tickle mode, user tickle mode, and external tickle mode.
In kernel tickle mode, a timer in the kernel refreshes the watchdog timer.
In user tickle mode,
.Nm
@ -80,8 +87,15 @@ Note that user tickle mode must be used with caution;
on a heavily loaded system, the timer may
expire accidentally, even though user programs may be making
(very slow) progress.
A user-mode timer is disarmed (if possible) when the device is closed.
.Pp
In both modes, an attempt is made to refresh the watchdog timer
External-mode watchdogs are similar to user-mode watchdogs, except
that the tickle must be done explicitly by a separate invocation of
the program with the
.Fl t
option.
.Pp
In the first two modes, an attempt is made to refresh the watchdog timer
in one half the timer's configured period.
That is, if the watchdog timer has a period of 30 seconds, a refresh attempt
is made every 15 seconds.
@ -107,6 +121,10 @@ in kernel tickle mode.
Arm
.Ar timer
in user tickle mode.
.It Fl e
Arm
.Ar timer
in external tickle mode.
.It Fl A
When arming a timer, this flag indicates that an audible alarm is
to sound when the watchdog timer expires and resets the system.
@ -124,6 +142,8 @@ Note that not all watchdog timers can be disabled once armed.
If the selected timer can not be disabled,
an error message will be displayed and the
timer will remain armed.
.It Fl t
This flag tickles an external mode timer.
.El
.Sh FILES
.Pa /dev/watchdog

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdogctl.c,v 1.10 2004/01/05 23:23:34 jmmv Exp $ */
/* $NetBSD: wdogctl.c,v 1.11 2005/01/09 22:51:32 smb Exp $ */
/*-
* Copyright (c) 2000 Zembu Labs, Inc.
@ -35,7 +35,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: wdogctl.c,v 1.10 2004/01/05 23:23:34 jmmv Exp $");
__RCSID("$NetBSD: wdogctl.c,v 1.11 2005/01/09 22:51:32 smb Exp $");
#endif
@ -59,47 +59,74 @@ __RCSID("$NetBSD: wdogctl.c,v 1.10 2004/01/05 23:23:34 jmmv Exp $");
int main(int, char *[]);
void enable_kernel(const char *, u_int);
void enable_user(const char *, u_int);
void enable_ext(const char *, u_int);
void tickle_ext(void);
void disable(void);
void prep_wmode(struct wdog_mode *, int, const char *, u_int);
void list_timers(void);
void usage(void);
int Aflag;
/* Caution -- ordered list; entries >= CMD_EXT_TICKLE set timers */
enum cmd {
CMD_NONE, /* No verb given */
CMD_DISABLE,
CMD_DOTICKLE,
CMD_EXT_TICKLE,
CMD_KERN_TICKLE,
CMD_USER_TICKLE
};
int
main(int argc, char *argv[])
{
int cmds = 0, kflag = 0, uflag = 0, dflag = 0, ch;
enum cmd command = CMD_NONE;
int period_flag = 0;
int ch;
u_int period = WDOG_PERIOD_DEFAULT;
while ((ch = getopt(argc, argv, "Adkp:u")) != -1) {
while ((ch = getopt(argc, argv, "Adekp:ut")) != -1) {
switch (ch) {
case 'A':
if (cmds == 0 || dflag)
usage();
Aflag = 1;
break;
case 'd':
dflag = 1;
cmds++;
if (command != CMD_NONE)
usage();
command = CMD_DISABLE;
break;
case 'e':
if (command != CMD_NONE)
usage();
command = CMD_EXT_TICKLE;
break;
case 'k':
kflag = 1;
cmds++;
if (command != CMD_NONE)
usage();
command = CMD_KERN_TICKLE;
break;
case 't':
if (command != CMD_NONE)
usage();
command = CMD_DOTICKLE;
break;
case 'p':
if (cmds == 0 || dflag)
usage();
period_flag = 1;
period = atoi(optarg);
if (period == -1)
usage();
break;
case 'u':
uflag = 1;
cmds++;
if (command != CMD_NONE)
usage();
command = CMD_USER_TICKLE;
break;
default:
@ -110,41 +137,60 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
if (cmds > 1)
usage();
if (kflag) {
if (argc != 1)
if (command < CMD_EXT_TICKLE) {
if (Aflag || period_flag)
usage();
enable_kernel(argv[0], period);
} else if (uflag) {
if (argc != 1)
usage();
enable_user(argv[0], period);
} else if (dflag) {
if (argc != 0)
usage();
disable();
} else
list_timers();
}
else {
if (argc != 1)
usage();
}
switch (command) {
case CMD_NONE:
list_timers();
break;
case CMD_DISABLE:
disable();
break;
case CMD_DOTICKLE:
tickle_ext();
break;
case CMD_EXT_TICKLE:
enable_ext(argv[0], period);
break;
case CMD_KERN_TICKLE:
enable_kernel(argv[0], period);
break;
case CMD_USER_TICKLE:
enable_user(argv[0], period);
break;
}
exit(0);
}
void
prep_wmode(struct wdog_mode *wp, int mode, const char *name, u_int period)
{
if (strlen(name) >= WDOG_NAMESIZE)
errx(1, "invalid watchdog timer name: %s", name);
strlcpy(wp->wm_name, name, sizeof(wp->wm_name));
wp->wm_mode = mode;
wp->wm_period = period;
if (Aflag)
wp->wm_mode |= WDOG_FEATURE_ALARM;
}
void
enable_kernel(const char *name, u_int period)
{
struct wdog_mode wm;
int fd;
if (strlen(name) >= WDOG_NAMESIZE)
errx(1, "invalid watchdog timer name: %s", name);
strlcpy(wm.wm_name, name, sizeof(wm.wm_name));
wm.wm_mode = WDOG_MODE_KTICKLE;
wm.wm_period = period;
if (Aflag)
wm.wm_mode |= WDOG_FEATURE_ALARM;
prep_wmode(&wm, WDOG_MODE_KTICKLE, name, period);
fd = open(_PATH_WATCHDOG, O_RDWR, 0644);
if (fd == -1)
@ -154,6 +200,26 @@ enable_kernel(const char *name, u_int period)
err(1, "WDOGIOC_SMODE");
}
void
enable_ext(const char *name, u_int period)
{
struct wdog_mode wm;
int fd;
prep_wmode(&wm, WDOG_MODE_ETICKLE, name, period);
fd = open(_PATH_WATCHDOG, O_RDWR, 0644);
if (fd == -1)
err(1, "open %s", _PATH_WATCHDOG);
if (ioctl(fd, WDOGIOC_SMODE, &wm) == -1) {
err(1, "WDOGIOC_SMODE");
}
if (ioctl(fd, WDOGIOC_TICKLE) == -1)
syslog(LOG_EMERG, "unable to tickle watchdog timer %s: %m",
wm.wm_name);
return;
}
void
enable_user(const char *name, u_int period)
{
@ -162,14 +228,7 @@ enable_user(const char *name, u_int period)
pid_t tickler;
int fd, rv;
if (strlen(name) >= WDOG_NAMESIZE)
errx(1, "invalid watchdog timer name: %s", name);
strlcpy(wm.wm_name, name, sizeof(wm.wm_name));
wm.wm_mode = WDOG_MODE_UTICKLE;
wm.wm_period = period;
if (Aflag)
wm.wm_mode |= WDOG_FEATURE_ALARM;
prep_wmode(&wm, WDOG_MODE_UTICKLE, name, period);
fd = open(_PATH_WATCHDOG, O_RDWR, 0644);
if (fd == -1)
@ -243,6 +302,18 @@ enable_user(const char *name, u_int period)
/* NOTREACHED */
}
void
tickle_ext()
{
int fd;
fd = open(_PATH_WATCHDOG, O_RDWR, 0644);
if (fd == -1)
err(1, "open %s", _PATH_WATCHDOG);
if (ioctl(fd, WDOGIOC_TICKLE) == -1)
fprintf(stderr, "Cannot tickle timer\n");
}
void
disable(void)
{
@ -332,12 +403,19 @@ list_timers(void)
printf("\t%s, %u second period", cp, wm.wm_period);
if (wm.wm_mode != WDOG_MODE_DISARMED) {
printf(" [armed, %s tickle",
wm.wm_mode == WDOG_MODE_KTICKLE ?
"kernel" : "user");
if (wm.wm_mode == WDOG_MODE_UTICKLE &&
tickler != (pid_t) -1)
printf(", pid %d", tickler);
switch(wm.wm_mode) {
case WDOG_MODE_KTICKLE:
printf(" [armed, kernel tickle");
break;
case WDOG_MODE_UTICKLE:
printf(" [armed, user tickle");
if (tickler != (pid_t) -1)
printf(", pid %d", tickler);
break;
case WDOG_MODE_ETICKLE:
printf(" [armed, external tickle");
break;
}
printf("]");
}
printf("\n");
@ -350,10 +428,13 @@ void
usage(void)
{
fprintf(stderr, "usage: %s\n", getprogname());
fprintf(stderr, " %s -e [-A] [-p seconds] timer\n",
getprogname());
fprintf(stderr, " %s -k [-A] [-p seconds] timer\n",
getprogname());
fprintf(stderr, " %s -u [-A] [-p seconds] timer\n",
getprogname());
fprintf(stderr, " %s -t\n", getprogname());
fprintf(stderr, " %s -d\n", getprogname());
exit(1);

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.343 2005/01/08 22:29:38 cube Exp $
# $NetBSD: Makefile,v 1.344 2005/01/09 22:51:32 smb Exp $
# @(#)Makefile 8.1 (Berkeley) 6/18/93
MAN= aac.4 acardide.4 aceride.4 acphy.4 adc.4 adv.4 \
@ -33,8 +33,8 @@ MAN= aac.4 acardide.4 aceride.4 acphy.4 adc.4 adv.4 \
raid.4 ray.4 rcons.4 re.4 rnd.4 route.4 rtk.4 satalink.4 \
sbus.4 scc.4 scsi.4 sd.4 se.4 ses.4 sf.4 sfb.4 shb.4 \
siop.4 sip.4 siside.4 sk.4 sl.4 slide.4 \
sm.4 spc.4 speaker.4 spif.4 spp.4 sqphy.4 \
ss.4 st.4 ste.4 stge.4 sti.4 stpcide.4 sv.4 strip.4 systrace.4 \
sm.4 spc.4 speaker.4 spif.4 spp.4 sqphy.4 ss.4 \
st.4 ste.4 stge.4 sti.4 stpcide.4 sv.4 strip.4 swwdog.4 systrace.4 \
tap.4 tb.4 tc.4 tcds.4 tcp.4 termios.4 tfb.4 ti.4 \
tl.4 tlp.4 tlphy.4 tp.4 tr.4 trm.4 tty.4 tun.4 \
tqphy.4 twe.4 txp.4 ubsec.4 udp.4 uep.4 uha.4 uk.4 ukphy.4 \

76
share/man/man4/swwdog.4 Normal file
View File

@ -0,0 +1,76 @@
.\" $NetBSD: swwdog.4,v 1.1 2005/01/09 22:51:32 smb Exp $
.\"
.\" Copyright (c) 2004, 2005 Steven M. Bellovin
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the NetBSD
.\" Foundation, Inc. and its contributors.
.\" 4. Neither the name of the author nor the names of its
.\" contributors may be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd 6 January 2005
.\" Written by Steven M. Bellovin
.Dt SWDOG 4
.Os
.Sh NAME
.Nm swwdog
.Nd software watchdog timer
.Sh SYNOPSIS
.Cd "pseudo-device cgd" Op Ar count
.Sh DESCRIPTION
The
.Nm
driver provides a software watchdog timer that works with
.Xr wdogctl 8 .
If the timer expires, the system reboots unless the variable
.Va swwdog_panic
is non-zero; if it is, the system will panic instead.
.Pp
The default period of
.Nm
is 60 seconds.
.Sh SEE ALSO
.Xr wdogctl 8
.Sh HISTORY
The
.Nm
driver was written by Steven M. Bellovin
.Sh BUGS
Although more than one
.Nm
timer can be configured, it's a pointless thing to do, since only
one watchdog timer can be active at any given time. Arguably, this
is a bug in the watchdog timer framework.
.Pp
Kernel tickle mode is useless with
.Nm
and arguably should be rejected, since both it and
this driver rely on the same callout mechanism; if one is
blocked, almost certainly the other is as well.
.Pp
The alarm option to
.Xr wdogctl 8
isn't implemented.

View File

@ -1,4 +1,4 @@
# $NetBSD: files.sysmon,v 1.3 2003/04/20 20:20:35 thorpej Exp $
# $NetBSD: files.sysmon,v 1.4 2005/01/09 22:51:32 smb Exp $
define sysmon_envsys
file dev/sysmon/sysmon_envsys.c sysmon_envsys needs-flag
@ -14,3 +14,7 @@ file dev/sysmon/sysmon.c sysmon_envsys | sysmon_wdog |
define sysmon_taskq
file dev/sysmon/sysmon_taskq.c sysmon_taskq
defpseudo swwdog: sysmon_wdog
file dev/sysmon/swwdog.c swwdog needs-count

159
sys/dev/sysmon/swwdog.c Normal file
View File

@ -0,0 +1,159 @@
/* $NetBSD: swwdog.c,v 1.1 2005/01/09 22:51:32 smb Exp $ */
/*
* Copyright (c) 2004, 2005 Steven M. Bellovin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Steven M. Bellovin
* 4. The name of the author contributors may not be used to endorse or
* promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: swwdog.c,v 1.1 2005/01/09 22:51:32 smb Exp $");
/*
*
* Software watchdog timer
*
*/
#include <sys/param.h>
#include <sys/callout.h>
#include <sys/cdefs.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/reboot.h>
#include <sys/systm.h>
#include <sys/wdog.h>
#include <dev/sysmon/sysmonvar.h>
#include "swwdog.h"
struct swwdog_softc {
struct sysmon_wdog sc_smw;
struct callout sc_c;
char sc_name[20];
int sc_wdog_armed;
} sc_wdog[NSWWDOG];
void swwdogattach(int);
static int swwdog_setmode(struct sysmon_wdog *);
static int swwdog_tickle(struct sysmon_wdog *);
static int swwdog_arm(struct swwdog_softc *);
static int swwdog_disarm(struct swwdog_softc *);
static void swwdog_panic(void *);
int swwdog_reboot = 0; /* set for panic instead of reboot */
#define SWDOG_DEFAULT 60 /* 60-second default period */
void
swwdogattach(int count)
{
int i;
for (i = 0; i < NSWWDOG; i++) {
struct swwdog_softc *sc = &sc_wdog[i];
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);
callout_setfunc(&sc->sc_c, swwdog_panic, sc);
if (sysmon_wdog_register(&sc->sc_smw) == 0)
printf("software watchdog initialized\n");
else printf("unable to register software watchdog "
"with sysmon\n");
}
}
static int
swwdog_setmode(struct sysmon_wdog *smw)
{
struct swwdog_softc *sc = smw->smw_cookie;
int error = 0;
if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) {
error = swwdog_disarm(sc);
} else {
if (smw->smw_period == 0)
return EINVAL;
else if (smw->smw_period == WDOG_PERIOD_DEFAULT)
sc->sc_smw.smw_period = SWDOG_DEFAULT;
else sc->sc_smw.smw_period = smw->smw_period;
error = swwdog_arm(sc);
}
return error;
}
static int
swwdog_tickle(struct sysmon_wdog *smw)
{
return swwdog_arm(smw->smw_cookie);
}
static int
swwdog_arm(struct swwdog_softc *sc)
{
callout_schedule(&sc->sc_c, sc->sc_smw.smw_period * hz);
return 0;
}
static int
swwdog_disarm(struct swwdog_softc *sc)
{
callout_stop(&sc->sc_c);
return 0;
}
static void
swwdog_panic(void *vsc)
{
struct swwdog_softc *sc = vsc;
int 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", sc->sc_name,
sc->sc_smw.smw_period);
if (do_panic)
panic("watchdog timer expired");
else cpu_reboot(0, NULL);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: sysmon_wdog.c,v 1.9 2003/10/30 01:58:18 simonb Exp $ */
/* $NetBSD: sysmon_wdog.c,v 1.10 2005/01/09 22:51:32 smb Exp $ */
/*-
* Copyright (c) 2000 Zembu Labs, Inc.
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sysmon_wdog.c,v 1.9 2003/10/30 01:58:18 simonb Exp $");
__KERNEL_RCSID(0, "$NetBSD: sysmon_wdog.c,v 1.10 2005/01/09 22:51:32 smb Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@ -382,6 +382,7 @@ sysmon_wdog_setmode(struct sysmon_wdog *smw, int mode, u_int period)
case WDOG_MODE_KTICKLE:
case WDOG_MODE_UTICKLE:
case WDOG_MODE_ETICKLE:
if (sysmon_armed_wdog != NULL) {
error = EBUSY;
goto out;

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdog.h,v 1.1 2000/11/04 18:33:33 thorpej Exp $ */
/* $NetBSD: wdog.h,v 1.2 2005/01/09 22:55:35 smb Exp $ */
/*-
* Copyright (c) 2000 Zembu Labs, Inc.
@ -93,6 +93,7 @@ struct wdog_conf {
#define WDOG_MODE_DISARMED 0 /* watchdog is disarmed */
#define WDOG_MODE_KTICKLE 1 /* kernel tickles watchdog */
#define WDOG_MODE_UTICKLE 2 /* user tickles watchdog */
#define WDOG_MODE_ETICKLE 3 /* external program tickles watchdog */
#define WDOG_MODE_MASK 0x03