diff options
author | Doug Gilbert <dgilbert@us.ibm.com> | 2015-01-26 14:41:54 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2015-02-28 05:49:51 -0600 |
commit | 29581aca6a1ed02d3374e5688e5f32fcb6f104bc (patch) | |
tree | 11f3ef76e83a0e18b313e2aa67b45292190e4b2a /src/usr/htmgt | |
parent | 9ca7f528d22e488c53d2dfbad32423806b47ddb0 (diff) | |
download | talos-hostboot-29581aca6a1ed02d3374e5688e5f32fcb6f104bc.tar.gz talos-hostboot-29581aca6a1ed02d3374e5688e5f32fcb6f104bc.zip |
HTMGT: Implement OCC Reset
Change-Id: Icb713497d662d1ab55718409675bf4b23ac2c3ec
RTC: 121721
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/15530
Tested-by: Jenkins Server
Reviewed-by: Christopher Cain <cjcain@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/htmgt')
-rw-r--r-- | src/usr/htmgt/htmgt.C | 93 | ||||
-rw-r--r-- | src/usr/htmgt/htmgt_activate.C | 22 | ||||
-rw-r--r-- | src/usr/htmgt/htmgt_activate.H | 4 | ||||
-rw-r--r-- | src/usr/htmgt/htmgt_cfgdata.C | 2 | ||||
-rw-r--r-- | src/usr/htmgt/htmgt_occ.C | 184 | ||||
-rw-r--r-- | src/usr/htmgt/htmgt_occ.H | 103 | ||||
-rw-r--r-- | src/usr/htmgt/htmgt_occcmd.C | 6 | ||||
-rw-r--r-- | src/usr/htmgt/htmgt_occcmd.H | 10 | ||||
-rw-r--r-- | src/usr/htmgt/htmgt_poll.C | 170 | ||||
-rw-r--r-- | src/usr/htmgt/htmgt_poll.H | 16 |
10 files changed, 497 insertions, 113 deletions
diff --git a/src/usr/htmgt/htmgt.C b/src/usr/htmgt/htmgt.C index b6498ca05..33d4f16c2 100644 --- a/src/usr/htmgt/htmgt.C +++ b/src/usr/htmgt/htmgt.C @@ -43,6 +43,9 @@ #include <targeting/common/attributes.H> #include <targeting/common/targetservice.H> +// HBOCC support +#include <hwpf/hwp/occ/occ_common.H> + #include <sys/time.h> @@ -92,10 +95,16 @@ namespace HTMGT // Make sure OCCs are ready for communication occMgr::instance().waitForOccCheckpoint(); +#ifdef __HOSTBOOT_RUNTIME + // TODO RTC 124738 Final solution TBD + // Perhapse POLL scom 0x6a214 until bit 31 is set? + nanosleep(1,0); +#endif + // Send poll to establish comm TMGT_INF("Send initial poll to all OCCs to" " establish comm"); - l_err = sendOccPoll(); + l_err = OccManager::sendOccPoll(); if (l_err) { // Continue even if failed (poll will be retried) @@ -121,7 +130,7 @@ namespace HTMGT // Set active sensors for all OCCs, // so BMC can start communication with OCCs - l_err = setOccActiveSensors(); + l_err = setOccActiveSensors(true); if (l_err) { // Continue even if failed to update sensor @@ -137,7 +146,7 @@ namespace HTMGT // Poll the OCCs to retrieve any errors that may // have been created TMGT_INF("Send final poll to all OCCs"); - l_err = sendOccPoll(true); + l_err = OccManager::sendOccPoll(true); if (l_err) { ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID); @@ -235,10 +244,20 @@ namespace HTMGT // Notify HTMGT that an OCC has an error to report - void processOccError(TARGETING::Target * i_occTarget) + void processOccError(TARGETING::Target * i_proc) { - const uint32_t l_huid = i_occTarget->getAttr<TARGETING::ATTR_HUID>(); + const uint32_t l_huid = i_proc->getAttr<TARGETING::ATTR_HUID>(); TMGT_INF("processOccError(HUID=0x%08X) called", l_huid); + + //TARGETING::Target * failedOccTarget = NULL; + // Get OCC target (one per proc) + TARGETING::TargetHandleList pOccs; + getChildChiplets(pOccs, i_proc, TARGETING::TYPE_OCC); + if (pOccs.size() > 0) + { + // failedOccTarget = pOccs[0]; + } + // TODO RTC 109224 } // end processOccError() @@ -246,13 +265,67 @@ namespace HTMGT // Notify HTMGT that an OCC has failed and needs to be reset - void processOccReset(TARGETING::Target * i_failedOccTarget) + void processOccReset(TARGETING::Target * i_proc) { - const uint32_t l_huid = - i_failedOccTarget->getAttr<TARGETING::ATTR_HUID>(); - TMGT_INF("processOccReset(HUID=0x%08X) called", l_huid); - // TODO RTC 115296 + errlHndl_t errl = NULL; + TARGETING::Target * failedOccTarget = NULL; + + TARGETING::Target* sys = NULL; + TARGETING::targetService().getTopLevelTarget(sys); + uint8_t safeMode = 0; + // If the system is in safemode then ignore request to reset OCCs + if(sys && + sys->tryGetAttr<TARGETING::ATTR_HTMGT_SAFEMODE>(safeMode) && + safeMode) + { + return; + } + + // Get functional OCC (one per proc) + TARGETING::TargetHandleList pOccs; + getChildChiplets(pOccs, i_proc, TARGETING::TYPE_OCC); + if (pOccs.size() > 0) + { + failedOccTarget = pOccs[0]; + } + + if(NULL != failedOccTarget) + { + uint32_t huid = failedOccTarget->getAttr<TARGETING::ATTR_HUID>(); + TMGT_INF("processOccReset(HUID=0x%08X) called", huid); + } + else + { + uint32_t huid = i_proc->getAttr<TARGETING::ATTR_HUID>(); + TMGT_INF("processOccReset: Invalid OCC target (proc huid=0x08X)" + "resetting OCCs anyway", + huid); + + /*@ + * @errortype + * @reasoncode HTMGT_RC_INVALID_PARAMETER + * @moduleid HTMGT_MOD_PROCESS_OCC_RESET + * @userdata1[0:7] Processor HUID + * @devdesc No OCC target found for proc Target, + */ + bldErrLog(errl, + HTMGT_MOD_PROCESS_OCC_RESET, + HTMGT_RC_INVALID_PARAMETER, + huid, 0, 0, 1, + ERRORLOG::ERRL_SEV_INFORMATIONAL); + + // Add HB firmware callout + errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_MED); + ERRORLOG::errlCommit(errl, HTMGT_COMP_ID); // sets errl to NULL + } + + errl = OccManager::resetOccs(failedOccTarget); + if(errl) + { + ERRORLOG::errlCommit(errl, HTMGT_COMP_ID); // sets errl to NULL + } } // end processOccReset() diff --git a/src/usr/htmgt/htmgt_activate.C b/src/usr/htmgt/htmgt_activate.C index a18d5039e..c23e8b0a4 100644 --- a/src/usr/htmgt/htmgt_activate.C +++ b/src/usr/htmgt/htmgt_activate.C @@ -73,7 +73,7 @@ namespace HTMGT do { // Poll all OCCs - l_err = sendOccPoll(); + l_err = OccManager::sendOccPoll(); ++numPolls; if (NULL != l_err) { @@ -148,13 +148,25 @@ namespace HTMGT - // Set active sensors for all OCCs so BMC can start communication - errlHndl_t setOccActiveSensors() + // Set active/inactive sensors for all OCCs so BMC can start communication + errlHndl_t setOccActiveSensors(bool i_activate) { errlHndl_t l_err = NULL; - TMGT_INF("setOccActiveSensors: STUB"); - // TODO RTC 119073 + TMGT_INF("setOccActiveSensors:"); + std::vector<Occ*> occList = occMgr::instance().getOccArray(); + for (std::vector<Occ*>::iterator itr = occList.begin(); + (itr < occList.end()); + ++itr) + { + Occ * occ = (*itr); + l_err = occ->ipmiSensor(i_activate); + if( l_err ) + { + ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID); + } + } + return l_err; } diff --git a/src/usr/htmgt/htmgt_activate.H b/src/usr/htmgt/htmgt_activate.H index 74bf8ee70..7e2480f54 100644 --- a/src/usr/htmgt/htmgt_activate.H +++ b/src/usr/htmgt/htmgt_activate.H @@ -49,9 +49,11 @@ namespace HTMGT /** * @brief Set active sensors for all OCCs so BMC can start communication * + * @param[in] i_activate [true - set active | false - set inactive] * @return NULL if all sensors were updated, else error handle + * */ - errlHndl_t setOccActiveSensors(); + errlHndl_t setOccActiveSensors(bool i_activate); /** diff --git a/src/usr/htmgt/htmgt_cfgdata.C b/src/usr/htmgt/htmgt_cfgdata.C index 66a1a237c..338e29efa 100644 --- a/src/usr/htmgt/htmgt_cfgdata.C +++ b/src/usr/htmgt/htmgt_cfgdata.C @@ -211,7 +211,7 @@ namespace HTMGT } // Send poll between config packets to flush errors - l_err = sendOccPoll(); + l_err = OccManager::sendOccPoll(); if (l_err) { ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID); diff --git a/src/usr/htmgt/htmgt_occ.C b/src/usr/htmgt/htmgt_occ.C index d31694c6d..237df3e16 100644 --- a/src/usr/htmgt/htmgt_occ.C +++ b/src/usr/htmgt/htmgt_occ.C @@ -40,6 +40,8 @@ #include <ecmdDataBufferBase.H> #include <hwpf/hwp/occ/occAccess.H> +#include <hwpf/hwp/occ/occ.H> +#include <hwpf/hwp/occ/occ_common.H> namespace HTMGT { @@ -61,6 +63,7 @@ namespace HTMGT iv_target(i_target), iv_lastPollValid(false), iv_occsPresent(1 << i_instance), + iv_resetCount(0), iv_version(0x01) { } @@ -172,6 +175,52 @@ namespace HTMGT }; + // Reset OCC + bool Occ::resetPrep() + { + errlHndl_t err = NULL; + bool atThreshold = false; + + // Send resetPrep command + uint8_t cmdData[2]; + cmdData[0] = OCC_RESET_CMD_VERSION; + + if(iv_failed) + { + cmdData[1] = OCC_RESET_FAIL_THIS_OCC; + ++iv_resetCount; + if(iv_resetCount > OCC_RESET_COUNT_THRESHOLD) + { + atThreshold = true; + } + } + else + { + cmdData[1] = OCC_RESET_FAIL_OTHER_OCC; + } + + OccCmd cmd(this, OCC_CMD_RESET_PREP, sizeof(cmdData), cmdData); + err = cmd.sendOccCmd(); + if(err) + { + // log error and keep going + TMGT_ERR("OCC::resetPrep: OCC%d resetPrep failed with rc = 0x%04x", + iv_instance, + err->reasonCode()); + + ERRORLOG::errlCommit(err, HTMGT_COMP_ID); + } + + // poll and flush error logs from OCC - Check Ex return code + err = pollForErrors(true); + if(err) + { + ERRORLOG::errlCommit(err, HTMGT_COMP_ID); + } + + return atThreshold; + } + ///////////////////////////////////////////////////////////////// @@ -187,6 +236,7 @@ namespace HTMGT OccManager::~OccManager() { + _removeAllOccs(); } @@ -214,6 +264,15 @@ namespace HTMGT { TMGT_INF("buildOccs called"); +#if defined(__HOSTBOOT_RUNTIME) + // At runtime need to keep occ state, only build OCC objects once. + if(iv_occArray.size() > 0 && iv_occMaster != NULL) + { + TMGT_INF("buildOccs: Existing OCC Targets kept = %d", + iv_occArray.size()); + return iv_occArray.size(); + } +#endif // Remove existing OCC objects _removeAllOccs(); @@ -480,6 +539,125 @@ namespace HTMGT } // end OccManager::_setOccState() + errlHndl_t OccManager::_resetOccs(TARGETING::Target * i_failedOccTarget) + { + errlHndl_t err = NULL; + bool atThreshold = false; + + _buildOccs(); // if not a already built. + err = setOccActiveSensors(false); // Set OCC sensor to inactive + if( err ) + { + TMGT_ERR("_resetOccs: Set OCC sensors to inactive failed."); + // log and continue + ERRORLOG::errlCommit(err, HTMGT_COMP_ID); + } + + // Send poll cmd to all OCCs to establish comm + err = _sendOccPoll(false,NULL); + if (err) + { + TMGT_ERR("_resetOccs: Poll OCCs failed."); + // Proceed with reset even if failed + ERRORLOG::errlCommit(err, HTMGT_COMP_ID); + } + + for(occList_t::const_iterator occ = iv_occArray.begin(); + occ != iv_occArray.end(); + ++occ) + { + if((*occ)->getTarget() == i_failedOccTarget) + { + (*occ)->failed(true); + } + + if((*occ)->resetPrep()) + { + atThreshold = true; + } + } + + uint64_t retryCount = OCC_RESET_COUNT_THRESHOLD; + while(retryCount) + { + // Reset all OCCs + TMGT_INF("Calling HBOCC::stopAllOCCs"); + err = HBOCC::stopAllOCCs(); + if(!err) + { + break; + } + --retryCount; + + if(retryCount) + { + // log if not last retry + ERRORLOG::errlCommit(err, HTMGT_COMP_ID); + } + else + { + TMGT_ERR("_resetOCCs: stopAllOCCs failed. " + "Leaving OCCs in reset state"); + // pass err handle back + err->collectTrace("HTMGT"); + } + } + + if(!atThreshold && !err) + { + for(occList_t::const_iterator occ = iv_occArray.begin(); + occ != iv_occArray.end(); + ++occ) + { + (*occ)->failed(false); + } + + TMGT_INF("Calling HBOCC::activateOCCs"); + + err = HBOCC::activateOCCs(); + if(err) + { + TMGT_ERR("_resetOCCs: activateOCCs failed. "); + err->collectTrace("HTMGT"); + } + } + else if (!err) // Reset Threshold reached and no other err + { + // Create threshold error + TMGT_ERR("_resetOCCs: Retry Threshold reached. " + "Leaving OCCs in reset state"); + /*@ + * @errortype + * @moduleid HTMTG_MOD_OCC_RESET + * @reasoncode HTMGT_RC_OCC_RESET_THREHOLD + * @devdesc OCC reset threshold reached. + * Leaving OCCs in reset state + */ + bldErrLog(err, + HTMTG_MOD_OCC_RESET, + HTMGT_RC_OCC_RESET_THREHOLD, + 0, 0, 0, 0, + ERRORLOG::ERRL_SEV_UNRECOVERABLE); + } + + // Any error at this point means OCCs were not reactivated + if(err) + { + err->setSev(ERRORLOG::ERRL_SEV_UNRECOVERABLE); + + TARGETING::Target* sys = NULL; + TARGETING::targetService().getTopLevelTarget(sys); + uint8_t safeMode = 1; + + // Put into safemode + if(sys) + { + sys->setAttr<TARGETING::ATTR_HTMGT_SAFEMODE>(safeMode); + } + } + + return err; + } // Wait for all OCCs to reach communications checkpoint void OccManager::_waitForOccCheckpoint() @@ -592,6 +770,12 @@ namespace HTMGT return Singleton<OccManager>::instance()._setOccState(i_state); } + errlHndl_t OccManager::resetOccs(TARGETING::Target * i_failedOccTarget) + { + return + Singleton<OccManager>::instance()._resetOccs(i_failedOccTarget); + } + occStateId OccManager::getTargetState() { diff --git a/src/usr/htmgt/htmgt_occ.H b/src/usr/htmgt/htmgt_occ.H index 72834346d..13d17a1a5 100644 --- a/src/usr/htmgt/htmgt_occ.H +++ b/src/usr/htmgt/htmgt_occ.H @@ -28,6 +28,9 @@ #include <stdint.h> #include <vector> +#if defined(CONFIG_BMC_IPMI) +#include <ipmi/ipmisensor.H> +#endif namespace HTMGT @@ -59,6 +62,11 @@ namespace HTMGT OCC_ROLE_FIR_MASTER = 0x80 }; + enum + { + OCC_RESET_COUNT_THRESHOLD = 3, + }; + /** @@ -129,13 +137,17 @@ namespace HTMGT /** - * @brief Process an OCC poll response + * @brief Poll for Errors * - * @param[in] i_pollResponse pointer to the response - * @param[in] i_pollResponseSize length of the poll response + * @param[in] i_flushAllErrors: + * If set to true, HTMGT will send poll cmds + * to the OCC as long as the OCC continues + * to report errors. If false, only one + * poll will be sent. + * + * @return NULL on success, else error handle */ - void pollRspHandler(const uint8_t * i_pollResponse, - const uint16_t i_pollResponseSize); + errlHndl_t pollForErrors(const bool i_flushAllErrors = false); /** @@ -175,6 +187,36 @@ namespace HTMGT */ occStateId getState() { return iv_state; }; + /** + * @brief Prepare this OCC for reset + * @return return true if at threshold otherwise false + */ + bool resetPrep(); + + /** + * @brief Set IPMI OCC sensor state + * @param i_activate: true - set active + * false - set inactive + * + * @return error log on error + */ + errlHndl_t ipmiSensor(bool i_activate) + { +#if !defined(CONFIG_BMC_IPMI) + return NULL; +#else + return SENSOR::OCCActiveSensor(iv_target).setState + (i_activate ? SENSOR::OCCActiveSensor::OCC_ACTIVE : + SENSOR::OCCActiveSensor::OCC_NOT_ACTIVE); +#endif + } + + /** + * @brief Set failed state + * @param[in] failed state + */ + void failed(bool i_state) { iv_failed = i_state; } + /** * @brief Return OCCs present bits @@ -195,6 +237,17 @@ namespace HTMGT */ void updateOccPresentBits(uint8_t i_slavePresent); + private: // functions + + /** + * @brief Process an OCC poll response + * + * @param[in] i_pollResponse pointer to the response + * @param[in] i_pollResponseSize length of the poll response + */ + void pollRspHandler(const uint8_t * i_pollResponse, + const uint16_t i_pollResponseSize); + protected: // Instance number of this OCC: 0 = first physical OCC @@ -226,6 +279,8 @@ namespace HTMGT private: + // Reset count + uint8_t iv_resetCount; // Version of data stored (0 = not written) uint8_t iv_version; @@ -298,6 +353,14 @@ namespace HTMGT */ static Occ * getMasterOcc(); + /** + * @brief Reset the OCCs + * + * @param[in] Failing occ target + * @return Error Log | NULL + */ + static errlHndl_t resetOccs(TARGETING::Target * i_failedOccTarget); + /** * @brief Set the state of the OCCs. If i_state is @@ -336,9 +399,29 @@ namespace HTMGT void waitForOccCheckpoint(); + /** + * @brief Send a poll command to one or all OCCs + * + * @param[in] i_flushAllErrors: + * If set to true, HTMGT will send poll cmds + * to each OCC that is selected as long as that OCC + * continues to report errors. If false, only one + * poll will be send to each OCC. + * @param[in] i_occTarget: The Selected OCC or NULL for all OCCs + * + * @return NULL on success, else error handle + */ + static errlHndl_t + sendOccPoll(const bool i_flushAllErrors = false, + TARGETING::Target * i_occTarget = NULL); + + private: + + typedef std::vector<Occ*> occList_t; + Occ * iv_occMaster; - std::vector<Occ*> iv_occArray; + occList_t iv_occArray; occStateId iv_state; occStateId iv_targetState; @@ -388,6 +471,14 @@ namespace HTMGT void _waitForOccCheckpoint(); + /** See resetOccs() above */ + errlHndl_t _resetOccs(TARGETING::Target * i_failedOccTarget); + + /** See sendOccPoll() above */ + errlHndl_t + _sendOccPoll(const bool i_flushAllErrors, + TARGETING::Target * i_occTarget); + }; typedef Singleton<OccManager> occMgr; diff --git a/src/usr/htmgt/htmgt_occcmd.C b/src/usr/htmgt/htmgt_occcmd.C index 579b6d7d5..3e60c5775 100644 --- a/src/usr/htmgt/htmgt_occcmd.C +++ b/src/usr/htmgt/htmgt_occcmd.C @@ -77,7 +77,7 @@ namespace HTMGT {OCC_CMD_SET_POWER_CAP, 0x80, OCC_CHECK_RSP_LENGTH_NONE, 0x0000, TO_20SEC, 0x0090, OCC_TRACE_EXTENDED}, {OCC_CMD_RESET_PREP, 0x80, OCC_CHECK_RSP_LENGTH_GREATER, - 0x0006, TO_20SEC, 0x0190, OCC_TRACE_ALWAYS}, + 0x0000, TO_20SEC, 0x0190, OCC_TRACE_ALWAYS}, {OCC_CMD_GET_FIELD_DEBUG_DATA, 0x80, OCC_CHECK_RSP_LENGTH_GREATER, 0x0001, TO_20SEC, RD_MAX, OCC_TRACE_NEVER}, @@ -814,7 +814,7 @@ namespace HTMGT bldErrLog(l_excErr, HTMGT_MOD_HANLDE_OCC_EXCEPTION, (htmgtReasonCode)(OCCC_COMP_ID | iv_OccRsp.returnStatus), iv_OccRsp.returnStatus, iv_OccRsp.dataLength, 0, 0, - ERRORLOG::ERRL_SEV_INFORMATIONAL); + ERRORLOG::ERRL_SEV_UNRECOVERABLE); const uint8_t * const exceptionData = iv_Occ->iv_homer + OCC_RSP_ADDR; l_excErr->addFFDC(OCCC_COMP_ID, exceptionData, @@ -861,6 +861,8 @@ namespace HTMGT { TMGT_ERR("writeOccCmd: Error writing to OCC Circular Buffer," " rc=0x%04X", l_err->reasonCode()); + + ERRORLOG::errlCommit(l_err, HTMGT_COMP_ID); } #endif diff --git a/src/usr/htmgt/htmgt_occcmd.H b/src/usr/htmgt/htmgt_occcmd.H index 252fc3852..a75dd5528 100644 --- a/src/usr/htmgt/htmgt_occcmd.H +++ b/src/usr/htmgt/htmgt_occcmd.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014 */ +/* Contributors Listed Below - COPYRIGHT 2014,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -80,6 +80,14 @@ namespace HTMGT OCC_CMD_END_OF_TABLE = 0xFF }; + enum occResetReasonType + { + OCC_RESET_CMD_VERSION = 0x00, + OCC_RESET_NON_FAILURE = 0x00, + OCC_RESET_FAIL_THIS_OCC = 0x01, + OCC_RESET_FAIL_OTHER_OCC = 0x02, + }; + enum occCheckRspLengthType { OCC_CHECK_RSP_LENGTH_NONE = 0x00, diff --git a/src/usr/htmgt/htmgt_poll.C b/src/usr/htmgt/htmgt_poll.C index 29ca416cc..6729b652c 100644 --- a/src/usr/htmgt/htmgt_poll.C +++ b/src/usr/htmgt/htmgt_poll.C @@ -42,100 +42,126 @@ namespace HTMGT { - // Send a poll command to all OCCs - errlHndl_t sendOccPoll(const bool i_flushAllErrors) + errlHndl_t OccManager::_sendOccPoll(const bool i_flushAllErrors, + TARGETING::Target * i_occTarget) { - errlHndl_t l_err = NULL; - uint8_t * l_poll_rsp = NULL; + errlHndl_t err = NULL; TMGT_INF("sendOccPoll(flush=%c)", i_flushAllErrors?'y':'n'); - // Loop through all functional OCCs - std::vector<Occ*> occList = occMgr::instance().getOccArray(); - for (std::vector<Occ*>::iterator itr = occList.begin(); - (itr < occList.end()) && (NULL == l_err); - ++itr) + for(occList_t::const_iterator occ_itr = iv_occArray.begin(); + (occ_itr != iv_occArray.end()) && (NULL == err); + ++occ_itr) { - Occ * occ = (*itr); - const uint8_t occInstance = occ->getInstance(); + Occ * occ = *occ_itr; + if(NULL == i_occTarget || occ->iv_target == i_occTarget) + { + err = occ->pollForErrors(i_flushAllErrors); + } + } + + return err; + } + + + errlHndl_t OccManager::sendOccPoll(const bool i_flushAllErrors, + TARGETING::Target * i_occTarget) + { + return + Singleton<OccManager>::instance()._sendOccPoll(i_flushAllErrors, + i_occTarget); + } + + + errlHndl_t Occ::pollForErrors(const bool i_flushAllErrors) + { + errlHndl_t err = NULL; + uint8_t * poll_rsp = NULL; - TMGT_INF("sendOccPoll: Polling OCC%d", occInstance); - bool continuePolling = false; - size_t elogCount = 10; - do + TMGT_INF("sendOccPoll: Polling OCC%d", iv_instance); + bool continuePolling = false; + size_t elogCount = 10; + + do + { + // create 1 byte buffer for poll command data + const uint8_t l_cmdData[1] = { 0x10 /*version*/ }; + + OccCmd cmd(this, + OCC_CMD_POLL, + sizeof(l_cmdData), + l_cmdData); + + err = cmd.sendOccCmd(); + if (err != NULL) { - // create 1 byte buffer for poll command data - const uint8_t l_cmdData[1] = { 0x10 /*version*/ }; + // Poll failed + TMGT_ERR("sendOccPoll: OCC%d poll failed with rc=0x%04X", + iv_instance, + err->reasonCode()); - OccCmd cmd(occ, OCC_CMD_POLL, sizeof(l_cmdData), l_cmdData); - l_err = cmd.sendOccCmd(); - if (l_err != NULL) - { - // Poll failed - TMGT_ERR("sendOccPoll: OCC%d poll failed with rc=0x%04X", - occInstance, l_err->reasonCode()); - } - else + continuePolling = false; + } + else + { + // Poll succeeded, check response + uint32_t poll_rsp_size = cmd.getResponseData(poll_rsp); + if (poll_rsp_size >= OCC_POLL_DATA_MIN_SIZE) { - // Poll succeeded, check response - uint32_t l_poll_rsp_size = cmd.getResponseData(l_poll_rsp); - if (l_poll_rsp_size >= OCC_POLL_DATA_MIN_SIZE) + if (i_flushAllErrors) { - if (i_flushAllErrors) + const occPollRspStruct_t *currentPollRsp = + (occPollRspStruct_t *) poll_rsp; + if (currentPollRsp->errorId != 0) { - const occPollRspStruct_t *currentPollRsp = - (occPollRspStruct_t *) l_poll_rsp; - if (currentPollRsp->errorId != 0) + if (--elogCount > 0) { - if (--elogCount > 0) - { - // An error was returned, keep polling OCC - continuePolling = true; - } - else - { - // Limit number of elogs retrieved so - // we do not get stuck in loop - TMGT_INF("sendOccPoll: OCC%d still has" - "more errors to report.", - occInstance); - continuePolling = false; - } + // An error was returned, keep polling OCC + continuePolling = true; } else { + // Limit number of elogs retrieved so + // we do not get stuck in loop + TMGT_INF("sendOccPoll: OCC%d still has" + "more errors to report.", + iv_instance); continuePolling = false; } } - occ->pollRspHandler(l_poll_rsp, l_poll_rsp_size); - } - else - { - TMGT_ERR("sendOccPoll: OCC%d poll command response " - "failed with invalid data length %d", - occInstance, l_poll_rsp_size); - /*@ - * @errortype - * @reasoncode HTMGT_RC_INVALID_LENGTH - * @moduleid HTMGT_MOD_OCC_POLL - * @userdata1 OCC instance - * @devdesc Invalid POLL response length - */ - bldErrLog(l_err, HTMGT_MOD_OCC_POLL, - HTMGT_RC_INVALID_LENGTH, - occInstance, 0, 0, 0, - ERRORLOG::ERRL_SEV_INFORMATIONAL); + else + { + continuePolling = false; + } } + pollRspHandler(poll_rsp, poll_rsp_size); } - } - while (continuePolling); - - } // for each OCC - - return l_err; + else + { + TMGT_ERR("sendOccPoll: OCC%d poll command response " + "failed with invalid data length %d", + iv_instance, poll_rsp_size); + /*@ + * @errortype + * @reasoncode HTMGT_RC_INVALID_LENGTH + * @moduleid HTMGT_MOD_OCC_POLL + * @userdata1 OCC instance + * @devdesc Invalid POLL response length + */ + bldErrLog(err, + HTMGT_MOD_OCC_POLL, + HTMGT_RC_INVALID_LENGTH, + iv_instance, 0, 0, 0, + ERRORLOG::ERRL_SEV_INFORMATIONAL); - } // end sendOccPoll() + continuePolling = false; + } + } + } + while (continuePolling); + return err; + } // Handle OCC poll response diff --git a/src/usr/htmgt/htmgt_poll.H b/src/usr/htmgt/htmgt_poll.H index 631a1d365..faf133028 100644 --- a/src/usr/htmgt/htmgt_poll.H +++ b/src/usr/htmgt/htmgt_poll.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014 */ +/* Contributors Listed Below - COPYRIGHT 2014,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -69,19 +69,5 @@ namespace HTMGT const uint32_t HTMGT_OCC_POLL_DATA_SIZE = sizeof(occPollRspStruct_t); - /** - * @brief Send a poll command to each OCC - * - * @param[in] i_flushAllErrors If set to true, TMGT will send poll cmds - * to each OCC as long as that OCC continues - * to report errors. If false, only one - * poll will be send to each OCC. - * - * @return NULL on success, else error handle - */ - errlHndl_t sendOccPoll(const bool i_flushAllErrors = false); - - - } // end namespace #endif |