From: Corey Minyard <cminyard@xxxxxxxxxx> The new API has the capability, and so do the IPMI interface, so do it. Signed-off-by: Corey Minyard <cminyard@xxxxxxxxxx> --- drivers/watchdog/ipmi_watchdog.c | 57 ++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/drivers/watchdog/ipmi_watchdog.c b/drivers/watchdog/ipmi_watchdog.c index c8c11a61ebb9..218c01707c0b 100644 --- a/drivers/watchdog/ipmi_watchdog.c +++ b/drivers/watchdog/ipmi_watchdog.c @@ -757,6 +757,62 @@ static int _ipmi_heartbeat(struct ipmi_wdt *iwd) return rv; } +static unsigned int ipmi_wdt_get_timeleft(struct watchdog_device *wdd) +{ + struct ipmi_wdt *iwd = wdd_to_ipmi_wdt(wdd); + struct kernel_ipmi_msg msg; + int rv = 0; + struct ipmi_system_interface_addr addr; + + mutex_lock(&iwd->lock); + if (iwd->state == WDOG_TIMEOUT_NONE) + goto out_unlock; + + addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + addr.channel = IPMI_BMC_CHANNEL; + addr.lun = 0; + + atomic_set(&iwd->msg_tofree, 2); + + msg.netfn = 0x06; + msg.cmd = IPMI_WDOG_GET_TIMER; + msg.data = NULL; + msg.data_len = 0; + rv = ipmi_request_supply_msgs(iwd->user, + (struct ipmi_addr *) &addr, + 0, + &msg, + NULL, + &iwd->smi_msg, + &iwd->recv_msg, + 1); + if (rv) { + pr_warn("get timeout error: %d\n", rv); + goto out_unlock; + } + + wait_msg_done(iwd, false); + + if (iwd->recv_msg.msg.data[0] != 0) { + pr_warn("get timeout IPMI error: %d\n", + iwd->recv_msg.msg.data[0]); + goto out_unlock; + } + + if (iwd->recv_msg.msg.data_len < 9) { + pr_warn("get timeout IPMI response too short: %d\n", + iwd->recv_msg.msg.data_len); + goto out_unlock; + } + + rv = iwd->recv_msg.msg.data[8] << 8 | iwd->recv_msg.msg.data[7]; + rv /= 10; /* IPMI time is in 100s of milliseconds. */ + +out_unlock: + mutex_unlock(&iwd->lock); + return rv; +} + static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg, void *handler_data) { @@ -880,6 +936,7 @@ static const struct watchdog_ops ipmi_wdt_ops = { .ping = ipmi_wdt_ping, .set_timeout = ipmi_wdt_set_timeout, .set_pretimeout = ipmi_wdt_set_pretimeout, + .get_timeleft = ipmi_wdt_get_timeleft, }; static const struct ipmi_user_hndl ipmi_hndlrs = { -- 2.17.1