diff options
Diffstat (limited to 'hw/ipmi')
-rw-r--r-- | hw/ipmi/ipmi-watchdog.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/hw/ipmi/ipmi-watchdog.c b/hw/ipmi/ipmi-watchdog.c index 201e9d1..1a638c8 100644 --- a/hw/ipmi/ipmi-watchdog.c +++ b/hw/ipmi/ipmi-watchdog.c @@ -48,27 +48,18 @@ static struct timer wdt_timer; static bool wdt_stopped; static bool wdt_ticking; -static void ipmi_wdt_complete(struct ipmi_msg *msg) -{ - if (msg->cmd == IPMI_CMD(IPMI_RESET_WDT) && wdt_ticking) - schedule_timer(&wdt_timer, msecs_to_tb( - (WDT_TIMEOUT - WDT_MARGIN)*100)); - - ipmi_free_msg(msg); -} - static void set_wdt(uint8_t action, uint16_t count, uint8_t pretimeout, bool dont_stop) { struct ipmi_msg *ipmi_msg; ipmi_msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_SET_WDT, - ipmi_wdt_complete, NULL, NULL, 6, 0); + ipmi_free_msg, NULL, NULL, 6, 0); if (!ipmi_msg) { prerror("Unable to allocate set wdt message\n"); return; } - ipmi_msg->error = ipmi_wdt_complete; + ipmi_msg->error = ipmi_free_msg; ipmi_msg->data[0] = TIMER_USE_POST | TIMER_USE_DONT_LOG | (dont_stop ? TIMER_USE_DONT_STOP : 0); @@ -80,12 +71,24 @@ static void set_wdt(uint8_t action, uint16_t count, uint8_t pretimeout, ipmi_queue_msg(ipmi_msg); } +static void reset_wdt_complete(struct ipmi_msg *msg) +{ + const uint64_t reset_delay_ms = (WDT_TIMEOUT - WDT_MARGIN) * 100; + + /* If we are inside of skiboot we need to periodically restart the + * timer. Reschedule a reset so it happens before the timeout. */ + if (wdt_ticking) + schedule_timer(&wdt_timer, msecs_to_tb(reset_delay_ms)); + + ipmi_free_msg(msg); +} + static struct ipmi_msg *wdt_reset_mkmsg(void) { struct ipmi_msg *ipmi_msg; ipmi_msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_RESET_WDT, - ipmi_wdt_complete, NULL, NULL, 0, 0); + reset_wdt_complete, NULL, NULL, 0, 0); if (!ipmi_msg) { prerror("Unable to allocate reset wdt message\n"); return NULL; |