summaryrefslogtreecommitdiffstats
path: root/src/usr/ipmi
diff options
context:
space:
mode:
authorRichard J. Knight <rjknight@us.ibm.com>2015-01-13 09:59:14 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2015-02-16 14:56:50 -0600
commit83420f9f902fe439747dd291034ad0df26187e99 (patch)
tree531971b2a8a1dd071c7bd3adc2050a9135506241 /src/usr/ipmi
parent7ff96947e3424a8d8909f7de37c1442b6e8d7a18 (diff)
downloadtalos-hostboot-83420f9f902fe439747dd291034ad0df26187e99.tar.gz
talos-hostboot-83420f9f902fe439747dd291034ad0df26187e99.zip
Make OCC_Active sensor readable
- add support to base sensor object to read sensors - add is_active method to OCC_Active sensor - add static method to get sensor number from base object - add write support to Boot_count sensor Change-Id: I82685207e374766f56a4788607c71a93be5d976e RTC:120588 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/15149 Tested-by: Jenkins Server Reviewed-by: Brian Silver <bsilver@us.ibm.com> Reviewed-by: WILLIAM G. HOFFA <wghoffa@us.ibm.com> Reviewed-by: Brian H. Horton <brianh@linux.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/ipmi')
-rw-r--r--src/usr/ipmi/ipmisensor.C211
1 files changed, 159 insertions, 52 deletions
diff --git a/src/usr/ipmi/ipmisensor.C b/src/usr/ipmi/ipmisensor.C
index 4e6a03973..84a7d31de 100644
--- a/src/usr/ipmi/ipmisensor.C
+++ b/src/usr/ipmi/ipmisensor.C
@@ -35,7 +35,6 @@
#include <targeting/common/utilFilter.H>
#include <ipmi/ipmi_reasoncodes.H>
#include <endian.h>
-
extern trace_desc_t * g_trac_ipmi;
namespace SENSOR
@@ -115,9 +114,9 @@ namespace SENSOR
* @devdesc Set sensor reading command failed.
*/
l_reasonCode = IPMI::RC_EVENT_DATA_NOT_SETTABLE;
- TRACFCOMP(g_trac_ipmi,"Attempted to set event data bytes but"
- "setting event data bytes is not supported for"
- " this sensor");
+ TRACFCOMP(g_trac_ipmi,"Attempted to set event data bytes "
+ "but setting event data bytes is not supported for"
+ " this sensor");
break;
}
@@ -249,12 +248,20 @@ namespace SENSOR
// Helper function to set the bit in the assertion/deassertion mask
// associated with the desired sensor specific offset
//
- uint16_t SensorBase::setMask( const uint8_t offset )
+ uint16_t SensorBase::setMask( const uint8_t offset, bool swap )
{
const uint16_t mask = (0x0001 << offset);
- // need to byte swap the mask (see set sensor reading in spec)
- return le16toh(mask);
+ if(swap)
+ {
+ // need to byte swap the mask (see set sensor reading in spec)
+ return le16toh(mask);
+ }
+ else
+ {
+ return mask;
+ }
+
};
//
@@ -268,7 +275,7 @@ namespace SENSOR
};
// read data from the sensor.
- errlHndl_t SensorBase::readSensorData(uint8_t *& o_data)
+ errlHndl_t SensorBase::readSensorData( getSensorReadingData& o_data)
{
// get sensor reading command only requires one byte of extra data,
@@ -276,26 +283,88 @@ namespace SENSOR
// 3 and 5 bytes of data.
size_t len = 1;
- // need to allocate some me to hold the sensor number this will be
+ // need to allocate some mem to hold the sensor number this will be
// deleted by the IPMI transport layer
- o_data = new uint8_t[len];
+ uint8_t * l_data = new uint8_t[len];
- o_data[0] = getSensorNumber();
+ l_data[0] = getSensorNumber();
IPMI::completion_code cc = IPMI::CC_UNKBAD;
// o_data will hold the response when this returns
errlHndl_t l_err = sendrecv(IPMI::get_sensor_reading(), cc, len,
- (uint8_t *&)o_data);
+ l_data);
// if we didn't get an error back from the BT interface, but see a
// bad completion code from the BMC, process the CC to see if we
// need to create a PEL
- if( (l_err == NULL ) && (cc != IPMI::CC_OK) )
+ if( l_err == NULL )
{
l_err = processCompletionCode( cc );
- }
+ // $TODO RTC:123045 - Remove when SDR is finalized
+ if( l_err == NULL && (cc != IPMI::CC_BADSENSOR) )
+ {
+ // populate the output structure with the sensor data
+ o_data.completion_code = cc;
+
+ o_data.sensor_status = l_data[0];
+
+ o_data.sensor_reading = l_data[1];
+
+ // bytes 3-5 of the reading are optional and will be dependent
+ // on the value of the sensor status byte.
+ if( !( o_data.sensor_status &
+ ( SENSOR::SENSOR_DISABLED |
+ SENSOR::SENSOR_SCANNING_DISABLED )) ||
+ ( o_data.sensor_status & SENSOR::READING_UNAVAILABLE ))
+ {
+ // sensor reading is available
+ o_data.event_status =
+ (( (uint16_t) l_data[3]) << 8 | l_data[2] );
+
+ // spec indicates that the high order bit should be
+ // ignored on a read, so lets mask it off now.
+ o_data.event_status &= 0x7FFFF;
+ }
+ else
+ {
+ uint32_t l_sensorNumber = getSensorNumber();
+
+ TRACFCOMP(g_trac_ipmi,"Sensor reading not available: status = 0x%x",o_data.sensor_status);
+ TRACFCOMP(g_trac_ipmi,"sensor number 0x%x, huid 0x%x",l_sensorNumber ,get_huid(iv_target));
+
+ // something happened log an error to indicate the request
+ // failed
+ /* @errorlog tag
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid IPMI::MOD_IPMISENSOR
+ * @reasoncode IPMI::RC_SENSOR_READING_NOT_AVAIL
+ * @userdata1 sensor status indicating reason for
+ * reading not available
+ * @userdata2[0:31] sensor number
+ * @userdata2[32:64] HUID of target
+ *
+ * @devdesc Set sensor reading command failed.
+ * @custdesc Request to get sensor reading
+ * IPMI completion code can be seen
+ * in userdata1 field of the log.
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ IPMI::MOD_IPMISENSOR,
+ IPMI::RC_SENSOR_READING_NOT_AVAIL,
+ o_data.sensor_status,
+ TWO_UINT32_TO_UINT64( l_sensorNumber,
+ TARGETING::get_huid(iv_target)), true);
+
+ l_err->collectTrace(IPMI_COMP_NAME);
+
+ }
+
+ delete[] l_data;
+ }
+ }
return l_err;
};
@@ -399,29 +468,32 @@ namespace SENSOR
return getMajorType(i_sensorRecord[0]) == getMajorType(i_sensorName);
}
+ // $TODO RTC:123035 investigate pre-populating some info if we end up
+ // doing this multiple times per sensor
//
// Helper function to search the sensor data for the correct sensor number
// based on the sensor name.
//
- uint8_t SensorBase::getSensorNumber()
+ uint8_t SensorBase::getSensorNumber( TARGETING::Target * i_targ,
+ TARGETING::SENSOR_NAME i_name )
{
uint8_t l_sensor_number = INVALID_SENSOR;
- if( iv_target == NULL )
+ if( i_targ == NULL )
{
// use the system target
- TARGETING::targetService().getTopLevelTarget(iv_target);
+ TARGETING::targetService().getTopLevelTarget(i_targ);
// die if there is no system target
- assert(iv_target);
+ assert(i_targ);
}
TARGETING::AttributeTraits<TARGETING::ATTR_IPMI_SENSORS>::Type
l_sensors;
- if( iv_target->tryGetAttr<TARGETING::ATTR_IPMI_SENSORS>(l_sensors) )
+ if( i_targ->tryGetAttr<TARGETING::ATTR_IPMI_SENSORS>(l_sensors) )
{
// get the number of rows by dividing the total size by the size of
@@ -437,27 +509,27 @@ namespace SENSOR
uint16_t (*end)[2] = &l_sensors[array_rows];
uint16_t (*ptr)[2] =
- std::lower_bound(begin, end, iv_name, &compare_it);
+ std::lower_bound(begin, end, i_name, &compare_it);
// we have not reached the end of the array and the iterator
// returned from lower_bound is pointing to an entry which equals
// the one we are searching for.
if( ( ptr != end ) &&
- ( (*ptr)[TARGETING::IPMI_SENSOR_ARRAY_NAME_OFFSET] == iv_name ) )
+ ( (*ptr)[TARGETING::IPMI_SENSOR_ARRAY_NAME_OFFSET] == i_name ) )
{
// found it
l_sensor_number =
(*ptr)[TARGETING::IPMI_SENSOR_ARRAY_NUMBER_OFFSET];
TRACFCOMP(g_trac_ipmi,"Found sensor number %d for HUID=0x%x",
- l_sensor_number, TARGETING::get_huid(iv_target));
+ l_sensor_number, TARGETING::get_huid(i_targ));
}
}
else
{
// bug here...
assert(0,"no IPMI_SENSOR attribute check target HUID=0x%x",
- TARGETING::get_huid(iv_target));
+ TARGETING::get_huid(i_targ));
}
return l_sensor_number;
@@ -512,18 +584,41 @@ namespace SENSOR
//
// setRebootCount - send a new value for the reboot count to the BMC.
//
- errlHndl_t RebootCountSensor::setRebootCount( rebootCount_t i_count )
+ errlHndl_t RebootCountSensor::setRebootCount( uint16_t i_count )
{
- // put the reboot count into the sensor
- // reading byte of the message
- iv_msg->iv_sensor_reading = i_count;
+ // the Reboot_count sensor is defined as a discrete sensor
+ // but the assertion bytes are being used to transfer the count
+ // to the bmc, will need to byte swap the data
+ iv_msg->iv_assertion_mask = le16toh(i_count);
return writeSensorData();
}
//
+ // getRebootCount - get the reboot count from the BMC
+ //
+ errlHndl_t RebootCountSensor::getRebootCount( uint16_t &o_rebootCount )
+ {
+
+ // the Reboot_count sensor is defined as a discrete sensor
+ // but the assertion bytes are being used to transfer the count
+ // from the BMC
+ getSensorReadingData l_data;
+
+ errlHndl_t l_err = readSensorData( l_data );
+
+ if( l_err == NULL )
+ {
+ // this value is already byteswapped
+ o_rebootCount = l_data.event_status;
+ }
+ return l_err;
+
+ }
+
+ //
// StatusSensor constructor - uses system DIMM/CORE/PROC target
//
StatusSensor::StatusSensor( TARGETING::Target * i_target )
@@ -702,10 +797,8 @@ namespace SENSOR
//
//
OCCActiveSensor::OCCActiveSensor( TARGETING::Target * i_pTarget )
- :SensorBase(TARGETING::SENSOR_NAME_OCC_ACTIVE, i_pTarget ),
- iv_functionalOffset(PROC_DISABLED)
+ :SensorBase(TARGETING::SENSOR_NAME_OCC_ACTIVE, i_pTarget )
{
-
};
//
@@ -718,36 +811,50 @@ namespace SENSOR
// send the message to the BMC to update the event status for this sensor.
errlHndl_t OCCActiveSensor::setState( OccStateEnum i_state )
{
-
errlHndl_t l_err = NULL;
- uint16_t func_mask = setMask( iv_functionalOffset );
+ // assert the specified state
+ iv_msg->iv_assertion_mask = setMask(i_state);
- switch ( i_state )
- {
+ l_err = writeSensorData();
- case OCC_ACTIVE:
- // turn off the disabled bit
- iv_msg->iv_deassertion_mask = func_mask;
- break;
+ return l_err;
- case OCC_NOT_ACTIVE:
- // assert the disabled bit
- iv_msg->iv_assertion_mask = func_mask;
- break;
+ };
- default:
- // assert that it is non-functional
- iv_msg->iv_assertion_mask = func_mask;
- break;
- }
+ // send the message to the BMC to read the event status for this sensor,
+ // will return true if the "disabled" state of the sensor is not
+ // asserted
+ bool OCCActiveSensor::isActive( )
+ {
+ getSensorReadingData l_data;
- l_err = writeSensorData();
+ bool is_active = false;
+ // set the mask, but dont swap the bytes since we are using it locally
+ // not passing it in the set sensor cmd
+ uint16_t mask = setMask( OCC_ACTIVE, false );
- return l_err;
+ errlHndl_t l_err = readSensorData( l_data );
+
+ if( l_err == NULL )
+ {
+ // check if "disabled" offset has been asserted -
+ // this would indicate that the OCC was not yet enabled
+ if( l_data.event_status & mask )
+ {
+ is_active = true;
+ }
+ }
+ else
+ {
+ // commit the error and return "not active" by default
+ errlCommit( l_err, IPMI_COMP_ID );
+ }
+
+ return is_active;
+ }
- };
//
// HostStausSensor constructor - uses system target
@@ -845,9 +952,9 @@ namespace SENSOR
{
errlCommit( l_err, IPMI_COMP_ID );
}
- }
+ }
- }
+ }
void updateBMCFaultSensorStatus(void)
{
OpenPOWER on IntegriCloud