Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/watchdog/watchdog.c
Show First 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | |||||
SYSCTL_UINT(_hw_watchdog, OID_AUTO, wd_last_u, CTLFLAG_RD, | SYSCTL_UINT(_hw_watchdog, OID_AUTO, wd_last_u, CTLFLAG_RD, | ||||
&wd_last_u_sysctl, 0, "Watchdog last update time"); | &wd_last_u_sysctl, 0, "Watchdog last update time"); | ||||
SYSCTL_UINT(_hw_watchdog, OID_AUTO, wd_last_u_secs, CTLFLAG_RD, | SYSCTL_UINT(_hw_watchdog, OID_AUTO, wd_last_u_secs, CTLFLAG_RD, | ||||
&wd_last_u_sysctl_secs, 0, "Watchdog last update time"); | &wd_last_u_sysctl_secs, 0, "Watchdog last update time"); | ||||
static int wd_lastpat_valid = 0; | static int wd_lastpat_valid = 0; | ||||
static time_t wd_lastpat = 0; /* when the watchdog was last patted */ | static time_t wd_lastpat = 0; /* when the watchdog was last patted */ | ||||
/* Hook for external software watchdog to register for use if needed */ | |||||
void (*wdog_software_attach)(void); | |||||
static void | static void | ||||
pow2ns_to_ts(int pow2ns, struct timespec *ts) | pow2ns_to_ts(int pow2ns, struct timespec *ts) | ||||
{ | { | ||||
uint64_t ns; | uint64_t ns; | ||||
ns = 1ULL << pow2ns; | ns = 1ULL << pow2ns; | ||||
ts->tv_sec = ns / 1000000000ULL; | ts->tv_sec = ns / 1000000000ULL; | ||||
ts->tv_nsec = ns % 1000000000ULL; | ts->tv_nsec = ns % 1000000000ULL; | ||||
Show All 26 Lines | seconds_to_pow2ns(int seconds) | ||||
return (power); | return (power); | ||||
} | } | ||||
int | int | ||||
wdog_kern_pat(u_int utim) | wdog_kern_pat(u_int utim) | ||||
{ | { | ||||
int error; | int error; | ||||
static int first = 1; | |||||
if ((utim & WD_LASTVAL) != 0 && (utim & WD_INTERVAL) > 0) | if ((utim & WD_LASTVAL) != 0 && (utim & WD_INTERVAL) > 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
if ((utim & WD_LASTVAL) != 0) { | if ((utim & WD_LASTVAL) != 0) { | ||||
/* | /* | ||||
* if WD_LASTVAL is set, fill in the bits for timeout | * if WD_LASTVAL is set, fill in the bits for timeout | ||||
* from the saved value in wd_last_u. | * from the saved value in wd_last_u. | ||||
Show All 25 Lines | if (wd_softtimer) { | ||||
} else { | } else { | ||||
(void) callout_reset(&wd_softtimeo_handle, | (void) callout_reset(&wd_softtimeo_handle, | ||||
pow2ns_to_ticks(utim), wd_timeout_cb, "soft"); | pow2ns_to_ticks(utim), wd_timeout_cb, "soft"); | ||||
} | } | ||||
error = 0; | error = 0; | ||||
} else { | } else { | ||||
EVENTHANDLER_INVOKE(watchdog_list, utim, &error); | EVENTHANDLER_INVOKE(watchdog_list, utim, &error); | ||||
} | } | ||||
/* | |||||
* If we no hardware watchdog responded, we have not tried to | |||||
* attach an external software watchdog, and one is available, | |||||
* attach it now and retry. | |||||
*/ | |||||
if (error == EOPNOTSUPP && first && *wdog_software_attach != NULL) { | |||||
(*wdog_software_attach)(); | |||||
EVENTHANDLER_INVOKE(watchdog_list, utim, &error); | |||||
} | |||||
first = 0; | |||||
wd_set_pretimeout(wd_pretimeout, true); | wd_set_pretimeout(wd_pretimeout, true); | ||||
/* | /* | ||||
* If we were able to arm/strobe the watchdog, then | * If we were able to arm/strobe the watchdog, then | ||||
* update the last time it was strobed for WDIOC_GETTIMELEFT | * update the last time it was strobed for WDIOC_GETTIMELEFT | ||||
*/ | */ | ||||
if (!error) { | if (!error) { | ||||
struct timespec ts; | struct timespec ts; | ||||
▲ Show 20 Lines • Show All 241 Lines • Show Last 20 Lines |