summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMichael Knudsen <mk@cvs.openbsd.org>2006-05-31 01:40:41 +0000
committerMichael Knudsen <mk@cvs.openbsd.org>2006-05-31 01:40:41 +0000
commitb7a544bacd1e13f77af031c22f573b6f8995964f (patch)
tree4f88621c170d12f8ccee505b7a27bf2254dffe09 /sys
parent175c420c443c6a97db79a10d70be637f7cff641d (diff)
Use the watchdog(4) framework for watchdog services instead of rolling
more or less the same code. This means that all our watchdog drivers use the framework, and that they all can be configured using sysctl kern.watchdog.{period,auto}, and they can all use watchdogd. At least for now we still support the /dev/wdt0 char device and userland poking using ioctl. Testing by < jg ! rilk , com >, many thanks! ok deraadt
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/wdt.c137
1 files changed, 36 insertions, 101 deletions
diff --git a/sys/dev/pci/wdt.c b/sys/dev/pci/wdt.c
index 6c032f191c0..2a6a31a51a9 100644
--- a/sys/dev/pci/wdt.c
+++ b/sys/dev/pci/wdt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdt.c,v 1.7 2006/03/15 20:03:07 miod Exp $ */
+/* $OpenBSD: wdt.c,v 1.8 2006/05/31 01:40:40 mk Exp $ */
/*-
* Copyright (c) 1998,1999 Alex Nash
@@ -33,7 +33,6 @@
#include <sys/malloc.h>
#include <sys/systm.h>
#include <sys/kernel.h>
-#include <sys/timeout.h>
#include <sys/proc.h>
#include <machine/bus.h>
@@ -59,7 +58,6 @@ struct wdt_softc {
/* watchdog timeout */
unsigned timeout_secs;
- struct timeout timeout;
/* device access through bus space */
bus_space_tag_t iot;
@@ -77,18 +75,15 @@ int wdtioctl(dev_t, u_long, caddr_t, int, struct proc *);
static int wdt_is501(struct wdt_softc *wdt);
static void wdt_8254_count(struct wdt_softc *wdt, int counter, u_int16_t v);
static void wdt_8254_mode(struct wdt_softc *wdt, int counter, int mode);
-static void wdt_set_timeout(struct wdt_softc *wdt, unsigned seconds);
-static void wdt_timeout(void *arg);
+static int wdt_set_timeout(void *wdt, int seconds);
static void wdt_init_timer(struct wdt_softc *wdt);
static void wdt_buzzer_off(struct wdt_softc *wdt);
static int wdt_read_temperature(struct wdt_softc *wdt);
static int wdt_read_status(struct wdt_softc *wdt);
static void wdt_display_status(struct wdt_softc *wdt);
static int wdt_get_state(struct wdt_softc *wdt, struct wdt_state *state);
-static void wdt_shutdown(void *arg);
static int wdt_sched(struct wdt_softc *wdt, struct proc *p);
static void wdt_timer_disable(struct wdt_softc *wdt);
-static void wdt_timer_enable(struct wdt_softc *wdt, unsigned seconds);
#if WDT_DISABLE_BUZZER
static void wdt_buzzer_disable(struct wdt_softc *wdt);
#else
@@ -170,6 +165,7 @@ wdtattach (parent, self, aux)
/* initialize the watchdog timer structure */
wdt->unit = unit;
wdt->procs = 0;
+ wdt->timeout_secs = 0;
/* check the feature set available */
if (wdt_is501(wdt))
@@ -177,13 +173,6 @@ wdtattach (parent, self, aux)
else
wdt->features = 0;
- /*
- * register a callback for system shutdown
- * (we need to disable the watchdog timer during shutdown)
- */
- if (shutdownhook_establish(wdt_shutdown, wdt) == NULL)
- return;
-
if (wdt->features) {
/*
* turn off the buzzer, it may have been activated
@@ -202,13 +191,14 @@ wdtattach (parent, self, aux)
wdt_init_timer(wdt);
/*
- * it appears the timeout queue isn't processed until the
- * kernel has fully booted, so we set the first timeout
- * far in advance, and subsequent timeouts at the normal
- * 30 second interval
+ * ensure that the watchdog is disabled
*/
- wdt_timer_enable(wdt, 90/*seconds*/);
- wdt->timeout_secs = 30;
+ wdt_timer_disable(wdt);
+
+ /*
+ * register with the watchdog framework
+ */
+ wdog_register(wdt, wdt_set_timeout);
printf("\n");
wdt_display_status(wdt);
@@ -307,52 +297,43 @@ wdt_8254_mode (struct wdt_softc *wdt, int counter, int mode)
* wdt_set_timeout
*
* Load the watchdog timer with the specified number of seconds.
+ * Clamp seconds to be in the interval [2; 1800].
*/
-static void
-wdt_set_timeout (struct wdt_softc *wdt, unsigned seconds)
+static int
+wdt_set_timeout (void *self, int seconds)
{
- /* 8254 has been programmed with a 2ms period */
- u_int16_t v = (u_int16_t)seconds * 50;
+ struct wdt_softc *wdt = (struct wdt_softc *)self;
- /* disable the timer */
- (void)bus_space_read_1(wdt->iot, wdt->ioh, WDT_DISABLE_TIMER);
+ u_int16_t v;
+ int s;
+
+ s = splclock();
+
+ wdt_timer_disable(wdt);
+
+ if (seconds == 0) {
+ wdt->timeout_secs = 0;
+ splx(s);
+ return (0);
+ } else if (seconds < 2)
+ seconds = 2;
+ else if (seconds > 1800)
+ seconds = 1800;
+
+ /* 8254 has been programmed with a 2ms period */
+ v = (u_int16_t)seconds * 50;
/* load the new timeout count */
wdt_8254_count(wdt, WDT_8254_TC_HI, v);
/* enable the timer */
bus_space_write_1(wdt->iot, wdt->ioh, WDT_ENABLE_TIMER, 0);
-}
-/*
- * wdt_timeout
- *
- * Kernel timeout handler. This function is called every
- * wdt->timeout_secs / 2 seconds. It reloads the watchdog
- * counters in one of two ways:
- *
- * - If there are one or more processes sleeping in a
- * WIOCSCHED ioctl(), they are woken up to perform
- * the counter reload.
- * - If no processes are sleeping in WIOCSCHED, the
- * counters are reloaded from here.
- *
- * Finally, another timeout is scheduled for wdt->timeout_secs
- * from now.
- */
-static void
-wdt_timeout (void *arg)
-{
- struct wdt_softc *wdt = (struct wdt_softc *)arg;
+ wdt->timeout_secs = seconds;
- /* reload counters from proc in WIOCSCHED ioctl()? */
- if (wdt->procs)
- wakeup(wdt);
- else
- wdt_set_timeout(wdt, wdt->timeout_secs);
+ splx(s);
- /* schedule another timeout in half the countdown time */
- timeout_add(&wdt->timeout, wdt->timeout_secs * hz / 2);
+ return (seconds);
}
/*
@@ -365,40 +346,6 @@ static void
wdt_timer_disable (struct wdt_softc *wdt)
{
(void)bus_space_read_1(wdt->iot, wdt->ioh, WDT_DISABLE_TIMER);
- timeout_del(&wdt->timeout);
-}
-
-/*
- * wdt_timer_enable
- *
- * Enables the watchdog timer to expire in the specified number
- * of seconds. If 'seconds' is outside the range 2-1800, it
- * is silently clamped to be within range.
- */
-static void
-wdt_timer_enable (struct wdt_softc *wdt, unsigned seconds)
-{
- int s;
-
- /* clamp range */
- if (seconds < 2)
- seconds = 2;
-
- if (seconds > 1800)
- seconds = 1800;
-
- /* block out the timeout handler */
- s = splclock();
-
- wdt_timer_disable(wdt);
- wdt->timeout_secs = seconds;
-
- timeout_set(&wdt->timeout, wdt_timeout, wdt);
- timeout_add(&wdt->timeout, hz * seconds / 2);
- wdt_set_timeout(wdt, seconds);
-
- /* re-enable clock interrupts */
- splx(s);
}
/*
@@ -529,19 +476,6 @@ wdt_get_state (struct wdt_softc *wdt, struct wdt_state *state)
}
/*
- * wdt_shutdown
- *
- * Disables the watchdog timer at system shutdown time.
- */
-static void
-wdt_shutdown (void *arg)
-{
- struct wdt_softc *wdt = (struct wdt_softc *)arg;
-
- wdt_timer_disable(wdt);
-}
-
-/*
* wdt_sched
*
* Put the process into an infinite loop in which:
@@ -597,3 +531,4 @@ wdt_sched (struct wdt_softc *wdt, struct proc *p)
return(error);
}
+