aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorNick Hibma <n_hibma@FreeBSD.org>2006-12-15 21:44:49 +0000
committerNick Hibma <n_hibma@FreeBSD.org>2006-12-15 21:44:49 +0000
commit9079fff5504650793319895e16f3f9cd431c5ec5 (patch)
tree787bbfce7ce18dfa578e01e209a342d73f933983 /sys
parent2cd19db26a49002206f71dfa91a0278aa7b43977 (diff)
downloadsrc-9079fff5504650793319895e16f3f9cd431c5ec5.tar.gz
src-9079fff5504650793319895e16f3f9cd431c5ec5.zip
Align the interfaces for the various watchdogs and make the interface
behave as expected. Also: - Return an error if WD_PASSIVE is passed in to the ioctl as only WD_ACTIVE is implemented at the moment. See sys/watchdog.h for an explanation of the difference between WD_ACTIVE and WD_PASSIVE. - Remove the I_HAVE_TOTALLY_LOST_MY_SENSE_OF_HUMOR define. If you've lost your sense of humor, than don't add a define. Specific changes: i80321_wdog.c Don't roll your own passive watchdog tickle as this would defeat the purpose of an active (userland) watchdog tickle. ichwd.c / ipmi.c: WD_ACTIVE means active patting of the watchdog by a userland process, not whether the watchdog is active. See sys/watchdog.h. kern_clock.c: (software watchdog) Remove a check for WD_ACTIVE as this does not make sense here. This reverts r1.181.
Notes
Notes: svn path=/head/; revision=165260
Diffstat (limited to 'sys')
-rw-r--r--sys/arm/at91/at91_st.c9
-rw-r--r--sys/arm/xscale/i80321/i80321_wdog.c26
-rw-r--r--sys/dev/ichwd/ichwd.c42
-rw-r--r--sys/dev/ipmi/ipmi.c25
-rw-r--r--sys/dev/mk48txx/mk48txx.c4
-rw-r--r--sys/dev/watchdog/watchdog.c5
-rw-r--r--sys/i386/i386/elan-mmcr.c18
-rw-r--r--sys/kern/kern_clock.c6
-rw-r--r--sys/sys/watchdog.h4
9 files changed, 61 insertions, 78 deletions
diff --git a/sys/arm/at91/at91_st.c b/sys/arm/at91/at91_st.c
index 7b63af1fa76e..8b61c789653d 100644
--- a/sys/arm/at91/at91_st.c
+++ b/sys/arm/at91/at91_st.c
@@ -170,10 +170,15 @@ at91st_watchdog(void *argp, u_int cmd, int *error)
uint32_t wdog;
int t;
- wdog = 0;
t = cmd & WD_INTERVAL;
- if (cmd != 0 && t >= 22 && t <= 37)
+ if (cmd > 0 && t >= 22 && t <= 37) {
wdog = (1 << (t - 22)) | ST_WDMR_RSTEN;
+ *error = 0;
+ } else {
+ wdog = 0;
+ if (cmd > 0)
+ *error = EINVAL;
+ }
WR4(ST_WDMR, wdog);
WR4(ST_CR, ST_CR_WDRST);
}
diff --git a/sys/arm/xscale/i80321/i80321_wdog.c b/sys/arm/xscale/i80321/i80321_wdog.c
index a33812cc71c5..c6c749c2ce2c 100644
--- a/sys/arm/xscale/i80321/i80321_wdog.c
+++ b/sys/arm/xscale/i80321/i80321_wdog.c
@@ -62,7 +62,6 @@ struct iopwdog_softc {
device_t dev;
int armed;
int wdog_period;
- struct callout_handle wdog_callout;
};
static __inline void
@@ -83,8 +82,6 @@ iopwdog_tickle(void *arg)
return;
wdtcr_write(WDTCR_ENABLE1);
wdtcr_write(WDTCR_ENABLE2);
- sc->wdog_callout = timeout(iopwdog_tickle, sc,
- hz * (sc->wdog_period - 1));
}
static int
@@ -112,14 +109,21 @@ iopwdog_watchdog_fn(void *private, u_int cmd, int *error)
{
struct iopwdog_softc *sc = private;
- if (cmd == 0)
- return;
- if ((((uint64_t)1 << (cmd & WD_INTERVAL))) >
- (uint64_t)sc->wdog_period * 1000000000)
- return;
- sc->armed = 1;
- iopwdog_tickle(sc);
- *error = 0;
+ cmd &= WD_INTERVAL;
+ if (cmd > 0 && cmd <= 63
+ && (uint64_t)1 << (cmd & WD_INTERVAL) <=
+ (uint64_t)sc->wdog_period * 1000000000) {
+ /* Valid value -> Enable watchdog */
+ iopwdog_tickle(sc);
+ sc->armed = 1;
+ *error = 0;
+ } else {
+ /* XXX Can't disable this watchdog? */
+ if (sc->armed)
+ *error = EOPNOTSUPP;
+ else if (cmd > 0)
+ *error = EINVAL;
+ }
}
static int
diff --git a/sys/dev/ichwd/ichwd.c b/sys/dev/ichwd/ichwd.c
index 8ddeb8ce3c5b..f878d39f9339 100644
--- a/sys/dev/ichwd/ichwd.c
+++ b/sys/dev/ichwd/ichwd.c
@@ -178,38 +178,22 @@ ichwd_event(void *arg, unsigned int cmd, int *error)
struct ichwd_softc *sc = arg;
unsigned int timeout;
+ /* convert from power-of-two-ns to WDT ticks */
+ cmd &= WD_INTERVAL;
+ timeout = ((uint64_t)1 << cmd) / ICHWD_TICK;
+ if (cmd > 0 && cmd <= 63
+ && timeout >= ICHWD_MIN_TIMEOUT && timeout <= ICHWD_MAX_TIMEOUT) {
+ if (timeout != sc->timeout)
+ ichwd_tmr_set(sc, timeout);
- /* disable / enable */
- if (!(cmd & WD_ACTIVE)) {
+ ichwd_tmr_reload(sc);
+ *error = 0;
+ } else {
if (sc->active)
ichwd_tmr_disable(sc);
- *error = 0;
- return;
- }
- if (!sc->active)
- ichwd_tmr_enable(sc);
-
- cmd &= WD_INTERVAL;
- /* convert from power-of-to-ns to WDT ticks */
- if (cmd >= 64) {
- *error = EINVAL;
- return;
- }
- timeout = ((uint64_t)1 << cmd) / ICHWD_TICK;
- if (timeout < ICHWD_MIN_TIMEOUT || timeout > ICHWD_MAX_TIMEOUT) {
- *error = EINVAL;
- return;
+ if (cmd > 0)
+ *error = EINVAL;
}
-
- /* set new initial value */
- if (timeout != sc->timeout)
- ichwd_tmr_set(sc, timeout);
-
- /* reload */
- ichwd_tmr_reload(sc);
-
- *error = 0;
- return;
}
static unsigned int pmbase = 0;
@@ -332,8 +316,6 @@ ichwd_detach(device_t dev)
{
struct ichwd_softc *sc;
- device_printf(dev, "detaching\n");
-
sc = device_get_softc(dev);
/* halt the watchdog timer */
diff --git a/sys/dev/ipmi/ipmi.c b/sys/dev/ipmi/ipmi.c
index 194f9d1ea9a1..a82299c7afc9 100644
--- a/sys/dev/ipmi/ipmi.c
+++ b/sys/dev/ipmi/ipmi.c
@@ -649,25 +649,16 @@ ipmi_wd_event(void *arg, unsigned int cmd, int *error)
struct ipmi_softc *sc = arg;
unsigned int timeout;
- /* disable / enable */
- if (!(cmd & WD_ACTIVE)) {
- ipmi_set_watchdog(sc, 0);
- *error = 0;
- return;
- }
-
cmd &= WD_INTERVAL;
- /* convert from power-of-to-ns to WDT ticks */
- if (cmd >= 64) {
- *error = EINVAL;
- return;
+ if (cmd > 0 && cmd <= 63) {
+ timeout = ((uint64_t)1 << cmd) / 1800000000;
+ ipmi_set_watchdog(sc, timeout);
+ *error = 0;
+ } else {
+ ipmi_set_watchdog(sc, 0);
+ if (cmd > 0)
+ *error = 0;
}
- timeout = ((uint64_t)1 << cmd) / 1800000000;
-
- /* reload */
- ipmi_set_watchdog(sc, timeout);
-
- *error = 0;
}
#ifdef CLONING
diff --git a/sys/dev/mk48txx/mk48txx.c b/sys/dev/mk48txx/mk48txx.c
index 00afc90e067a..fbc03c440da1 100644
--- a/sys/dev/mk48txx/mk48txx.c
+++ b/sys/dev/mk48txx/mk48txx.c
@@ -297,7 +297,7 @@ mk48txx_watchdog(void *arg, u_int cmd, int *error)
wdog = 0;
t = cmd & WD_INTERVAL;
- if (cmd != 0 && t >= 26 && t <= 37) {
+ if (cmd > 0 && t >= 26 && t <= 37) {
if (t <= WD_TO_2SEC) {
wdog |= MK48TXX_WDOG_RB_1_16;
t -= 26;
@@ -317,6 +317,8 @@ mk48txx_watchdog(void *arg, u_int cmd, int *error)
if (sc->sc_flag & MK48TXX_WDOG_ENABLE_WDS)
wdog |= MK48TXX_WDOG_WDS;
*error = 0;
+ } else if (cmd > 0) {
+ *error = EINVAL;
}
mtx_lock(&sc->sc_mtx);
(*sc->sc_nvwr)(dev, sc->sc_clkoffset + MK48TXX_WDOG, wdog);
diff --git a/sys/dev/watchdog/watchdog.c b/sys/dev/watchdog/watchdog.c
index 907324a036c2..a1d8d88167d7 100644
--- a/sys/dev/watchdog/watchdog.c
+++ b/sys/dev/watchdog/watchdog.c
@@ -55,11 +55,14 @@ wd_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t data,
return (EINVAL);
if ((u & (WD_ACTIVE | WD_PASSIVE)) == (WD_ACTIVE | WD_PASSIVE))
return (EINVAL);
-
+ if (u & WD_PASSIVE)
+ return (ENOSYS); /* XXX Not implemented yet */
if ((u & WD_INTERVAL) == WD_TO_NEVER) {
u = 0;
+ /* Assume all is well; watchdog signals failure. */
error = 0;
} else {
+ /* Assume no watchdog available; watchdog flags success */
error = EOPNOTSUPP;
}
EVENTHANDLER_INVOKE(watchdog_list, u, &error);
diff --git a/sys/i386/i386/elan-mmcr.c b/sys/i386/i386/elan-mmcr.c
index 66c218f2ee4b..be3e2a45c9a3 100644
--- a/sys/i386/i386/elan-mmcr.c
+++ b/sys/i386/i386/elan-mmcr.c
@@ -367,11 +367,11 @@ init_AMD_Elan_sc520(void)
static void
elan_watchdog(void *foo __unused, u_int spec, int *error)
{
- u_int u, v;
+ u_int u, v, w;
static u_int cur;
u = spec & WD_INTERVAL;
- if (spec && u <= 35) {
+ if (u > 0 && u <= 35) {
u = imax(u - 5, 24);
v = 2 << (u - 24);
v |= 0xc000;
@@ -383,7 +383,7 @@ elan_watchdog(void *foo __unused, u_int spec, int *error)
* for other reasons. Save and restore the GP echo mode
* around our hardware tom-foolery.
*/
- u = elan_mmcr->GPECHO;
+ w = elan_mmcr->GPECHO;
elan_mmcr->GPECHO = 0;
if (v != cur) {
/* Clear the ENB bit */
@@ -401,19 +401,19 @@ elan_watchdog(void *foo __unused, u_int spec, int *error)
elan_mmcr->WDTMRCTL = 0xaaaa;
elan_mmcr->WDTMRCTL = 0x5555;
}
- elan_mmcr->GPECHO = u;
+ elan_mmcr->GPECHO = w;
*error = 0;
- return;
} else {
- u = elan_mmcr->GPECHO;
+ w = elan_mmcr->GPECHO;
elan_mmcr->GPECHO = 0;
elan_mmcr->WDTMRCTL = 0x3333;
elan_mmcr->WDTMRCTL = 0xcccc;
elan_mmcr->WDTMRCTL = 0x4080;
- elan_mmcr->WDTMRCTL = u;
- elan_mmcr->GPECHO = u;
+ elan_mmcr->WDTMRCTL = w; /* XXX What does this statement do? */
+ elan_mmcr->GPECHO = w;
cur = 0;
- return;
+ if (u > 0)
+ *error = 0;
}
}
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index a3732a81e595..dbc6d2084ea8 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -536,15 +536,15 @@ SYSCTL_PROC(_kern, KERN_CLOCKRATE, clockrate, CTLTYPE_STRUCT|CTLFLAG_RD,
#ifdef SW_WATCHDOG
static void
-watchdog_config(void *unused __unused, u_int cmd, int *err)
+watchdog_config(void *unused __unused, u_int cmd, int *error)
{
u_int u;
u = cmd & WD_INTERVAL;
- if ((cmd & WD_ACTIVE) && u >= WD_TO_1SEC) {
+ if (u >= WD_TO_1SEC) {
watchdog_ticks = (1 << (u - WD_TO_1SEC)) * hz;
watchdog_enabled = 1;
- *err = 0;
+ *error = 0;
} else {
watchdog_enabled = 0;
}
diff --git a/sys/sys/watchdog.h b/sys/sys/watchdog.h
index a67b68b4392d..941077593384 100644
--- a/sys/sys/watchdog.h
+++ b/sys/sys/watchdog.h
@@ -30,11 +30,7 @@
#include <sys/ioccom.h>
-#ifdef I_HAVE_TOTALLY_LOST_MY_SENSE_OF_HUMOUR
-#define _PATH_WATCHDOG "watchdog"
-#else
#define _PATH_WATCHDOG "fido"
-#endif
#define WDIOCPATPAT _IOW('W', 42, u_int)