Fix the watchdog timeout calculation to prevent wrap. The RPi hardware

can't do a timeout bigger than 15 seconds.  The code wasn't checking for
this and because bitmasking was involved the requested timeout was
basically adjusted modulo-16.  That led to things like a 128 second
timeout actually being a 9 second timeout, which accidentally worked fine
until watchdogd was changed to only pet the dog once every 10 seconds.
This commit is contained in:
Ian Lepore 2014-12-10 04:54:43 +00:00
parent cb92abb49c
commit 7f353dddc8

View File

@ -142,14 +142,13 @@ bcmwd_watchdog_fn(void *private, u_int cmd, int *error)
if (cmd > 0) {
sec = ((uint64_t)1 << (cmd & WD_INTERVAL)) / 1000000000;
ticks = (sec << 16) & BCM2835_WDOG_TIME_MASK;
if (ticks == 0) {
if (sec == 0 || sec > 15) {
/*
* Can't arm
* disable watchdog as watchdog(9) requires
*/
device_printf(sc->dev,
"Can't arm, timeout is less than 1 second\n");
"Can't arm, timeout must be between 1-15 seconds\n");
WRITE(sc, BCM2835_RSTC_REG,
(BCM2835_PASWORD << BCM2835_PASSWORD_SHIFT) |
BCM2835_RSTC_RESET);
@ -157,6 +156,7 @@ bcmwd_watchdog_fn(void *private, u_int cmd, int *error)
return;
}
ticks = (sec << 16) & BCM2835_WDOG_TIME_MASK;
reg = (BCM2835_PASWORD << BCM2835_PASSWORD_SHIFT) | ticks;
WRITE(sc, BCM2835_WDOG_REG, reg);