summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci')
-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);
}
+