summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWilliam A. Kennington III <wak@google.com>2018-05-20 00:37:49 -0700
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-07-10 12:27:39 -0400
commit9a9bc342c9430ee335a948dc69702cadab48a83d (patch)
tree601de46d77895c1d67b55b87ac8d0a4eb7ed826e /src
parentb24deec9bad7834542ed0e03953789cb887f754d (diff)
downloadtalos-hostboot-9a9bc342c9430ee335a948dc69702cadab48a83d.tar.gz
talos-hostboot-9a9bc342c9430ee335a948dc69702cadab48a83d.zip
ipmiwatchdog: Handle uninitialized errors during reset
The IPMI spec allows for the IPMI watchdog to return an error if the watchdog was never initialized. This can happen if the daemon restarts or if the initial setWatchDog command fails for some reason. Instead of allowing the watchdog to remain uninitialized and disabled, use the values of the previously issued set command to re-initialize the watchdog. This is only attempted once per resetWatchDog call, but periodic calls to the resetWatchDog should eventually re-initialize it. Resolves #139 Signed-off-by: William A. Kennington III <wak@google.com> Change-Id: I7b777e2f3b75d5ce38888018c1b74c6ce12ffc19 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/59163 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/usr/ipmi/ipmiwatchdog.C61
1 files changed, 56 insertions, 5 deletions
diff --git a/src/usr/ipmi/ipmiwatchdog.C b/src/usr/ipmi/ipmiwatchdog.C
index 2f9f28f74..42da2a5ba 100644
--- a/src/usr/ipmi/ipmiwatchdog.C
+++ b/src/usr/ipmi/ipmiwatchdog.C
@@ -53,6 +53,14 @@ extern trace_desc_t * g_trac_ipmi;
namespace IPMIWATCHDOG
{
+// Needed for watchdog resets in case the BMC side becomes uninitialized and we
+// need to reinitialize it
+static bool g_set_once = false;
+static uint16_t g_countdown_secs;
+static uint8_t g_timer_use;
+static TIMER_ACTIONS g_timer_action;
+static TIMER_USE_CLR_FLAGS g_timer_clr_flag;
+
/******************************************************************************/
// Functions
/******************************************************************************/
@@ -63,6 +71,14 @@ errlHndl_t setWatchDogTimer( const uint16_t i_countdown_secs,
const TIMER_ACTIONS i_timer_action,
const TIMER_USE_CLR_FLAGS i_timer_clr_flag)
{
+ // Save the latest values so that reset actions can setup the timer
+ // if the BMC goes away.
+ g_set_once = true;
+ g_countdown_secs = i_countdown_secs;
+ g_timer_use = i_timer_use;
+ g_timer_action = i_timer_action;
+ g_timer_clr_flag = i_timer_clr_flag;
+
// Convert secs into lsb and msb values
// the ipmi spec uses the count which is 100ms/count
static const uint16_t ms_per_count = 100;
@@ -128,11 +144,9 @@ errlHndl_t resetWatchDogTimer()
{
IPMI_TRAC( "resetWatchDogTimer" );
- // Don't worry about the return just send the msg over
- // If there is an error during the reset
- // we don't care about it since the watchdog will trip
- //send ipmi command
- err_ipmi = IPMI::send(IPMI::reset_watchdog(), len, data);
+ IPMI::completion_code cc;
+ err_ipmi = IPMI::sendrecv(IPMI::reset_watchdog(), cc, len, data);
+ delete[] data;
if(err_ipmi)
{
@@ -141,6 +155,43 @@ errlHndl_t resetWatchDogTimer()
break;
}
+ // Make sure we don't have an uninitialized watchdog
+ // openbmc will always start the watchdog regardless of us
+ // initializing it. If we don't initialize it, it can eventually
+ // time out on us
+ if (g_set_once && cc == IPMI::CC_CMDSPC1)
+ {
+ err_ipmi = setWatchDogTimer(g_countdown_secs,
+ g_timer_use | DO_NOT_STOP,
+ g_timer_action, g_timer_clr_flag);
+
+ if (err_ipmi)
+ {
+ //got an error sending IPMI msg
+ //progate error upstream.
+ break;
+ }
+
+ // Make sure to issue a reset after initialization to start
+ // the timer if it isn't already. We don't care about the return
+ // value of this message since we can't recurse forever. If we
+ // fail here, later resets should handle reconfiguring the
+ // watchdog if it isn't critically broken.
+ len = 0;
+ data = NULL;
+ err_ipmi = IPMI::send(IPMI::reset_watchdog(), len, data);
+
+ if(err_ipmi)
+ {
+ //got an error sending IPMI msg
+ //progate error upstream.
+ break;
+ }
+ }
+
+ // We don't care about any other types of errors as the watchdog
+ // will just trip in these cases.
+ break;
}
while(0);
OpenPOWER on IntegriCloud