1 /* $NetBSD: swwdog.c,v 1.6 2007/01/29 01:52:45 hubertf Exp $ */
4 * Copyright (c) 2004, 2005 Steven M. Bellovin
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Steven M. Bellovin
18 * 4. The name of the author contributors may not be used to endorse or
19 * promote products derived from this software without specific prior
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
35 #include <sys/cdefs.h>
36 __KERNEL_RCSID(0, "$NetBSD: swwdog.c,v 1.6 2007/01/29 01:52:45 hubertf Exp $");
40 * Software watchdog timer
43 #include <sys/param.h>
44 #include <sys/callout.h>
45 #include <sys/device.h>
46 #include <sys/kernel.h>
47 #include <sys/reboot.h>
48 #include <sys/systm.h>
50 #include <dev/sysmon/sysmonvar.h>
55 struct sysmon_wdog sc_smw
;
61 void swwdogattach(int);
63 static int swwdog_setmode(struct sysmon_wdog
*);
64 static int swwdog_tickle(struct sysmon_wdog
*);
66 static int swwdog_arm(struct swwdog_softc
*);
67 static int swwdog_disarm(struct swwdog_softc
*);
69 static void swwdog_panic(void *);
71 int swwdog_reboot
= 0; /* set for panic instead of reboot */
73 #define SWDOG_DEFAULT 60 /* 60-second default period */
76 swwdogattach(int count __unused
)
80 for (i
= 0; i
< NSWWDOG
; i
++) {
81 struct swwdog_softc
*sc
= &sc_wdog
[i
];
83 snprintf(sc
->sc_name
, sizeof sc
->sc_name
, "swwdog%d", i
);
84 printf("%s: ", sc
->sc_name
);
85 sc
->sc_smw
.smw_name
= sc
->sc_name
;
86 sc
->sc_smw
.smw_cookie
= sc
;
87 sc
->sc_smw
.smw_setmode
= swwdog_setmode
;
88 sc
->sc_smw
.smw_tickle
= swwdog_tickle
;
89 sc
->sc_smw
.smw_period
= SWDOG_DEFAULT
;
90 callout_init(&sc
->sc_c
, 0);
91 callout_setfunc(&sc
->sc_c
, swwdog_panic
, sc
);
93 if (sysmon_wdog_register(&sc
->sc_smw
) == 0)
94 printf("software watchdog initialized\n");
96 printf("unable to register software watchdog "
102 swwdog_setmode(struct sysmon_wdog
*smw
)
104 struct swwdog_softc
*sc
= smw
->smw_cookie
;
107 if ((smw
->smw_mode
& WDOG_MODE_MASK
) == WDOG_MODE_DISARMED
) {
108 error
= swwdog_disarm(sc
);
110 if (smw
->smw_period
== 0)
112 else if (smw
->smw_period
== WDOG_PERIOD_DEFAULT
)
113 sc
->sc_smw
.smw_period
= SWDOG_DEFAULT
;
115 sc
->sc_smw
.smw_period
= smw
->smw_period
;
116 error
= swwdog_arm(sc
);
122 swwdog_tickle(struct sysmon_wdog
*smw
)
125 return swwdog_arm(smw
->smw_cookie
);
129 swwdog_arm(struct swwdog_softc
*sc
)
132 callout_schedule(&sc
->sc_c
, sc
->sc_smw
.smw_period
* hz
);
137 swwdog_disarm(struct swwdog_softc
*sc
)
140 callout_stop(&sc
->sc_c
);
145 swwdog_panic(void *vsc
)
147 struct swwdog_softc
*sc
= vsc
;
150 do_panic
= swwdog_reboot
;
152 callout_schedule(&sc
->sc_c
, 60 * hz
); /* deliberate double-panic */
154 printf("%s: %d second timer expired", sc
->sc_name
,
155 sc
->sc_smw
.smw_period
);
158 panic("watchdog timer expired");