From e245e4e932279a112325dae06d7c12cf9e8ed833 Mon Sep 17 00:00:00 2001 From: Dhruvaraj Subhashchandran Date: Tue, 3 Oct 2017 03:58:05 -0500 Subject: IPMI changes to mark non present as non functional When marking a unit as functional, both functional state and presence need to be checked to avoid marking non-present units as functional. Change-Id: If7b710c39f1c2590b82378ebdb7014dc924599ff Signed-off-by: Dhruvaraj Subhashchandran --- scripts/sensor-example.yaml | 57 +++++++++++++++++++++++++++++--------------- scripts/writesensor.mako.cpp | 29 ++++++++++++++++++---- sensordatahandler.cpp | 32 ++++++++++++++++++------- types.hpp | 18 ++++++++++++-- 4 files changed, 103 insertions(+), 33 deletions(-) diff --git a/scripts/sensor-example.yaml b/scripts/sensor-example.yaml index 98e9ff6..c4ff4d5 100755 --- a/scripts/sensor-example.yaml +++ b/scripts/sensor-example.yaml @@ -17,13 +17,14 @@ # One or more interface dict entries org.open_power.OCC.Status: OccActive: - # Sensor type specific offset - 0x06: - # OccActive is a boolean - type: "bool" - # If offset 0x06 is asserted, set OccActive as false. - assert: "false" - deassert: "true" + Offsets: + # Sensor type specific offset + 0x06: + # OccActive is a boolean + type: "bool" + # If offset 0x06 is asserted, set OccActive as false. + assert: "false" + deassert: "true" 0x61: sensorType: 0x04 @@ -35,14 +36,23 @@ serviceInterface: xyz.openbmc_project.Inventory.Manager readingType: assertion interfaces: - xyz.openbmc_project.Inventory.Item: - Present: - 0x06: - assert: true - deassert: false - type: bool xyz.openbmc_project.State.Decorator.OperationalStatus: Functional: + #Offsets contain the offsets in the sensor data. + Offsets: + 0x06: + assert: true + deassert: false + type: bool + #Prereqs are pre-requisites for this property value to be true. + Prereqs: + 0x04: + assert: false + deassert: true + type: bool + xyz.openbmc_project.Inventory.Item: + Present: + Offsets: 0x04: assert: false deassert: true @@ -52,8 +62,9 @@ interfaces: xyz.openbmc_project.Control.Boot.RebootAttempts: AttemptsLeft: - 0xFF: - type: uint32_t + Offsets: + 0xFF: + type: uint32_t path: /xyz/openbmc_project/state/host0 # A special case of assertion, where the entire assert bitfield # serves as the value, or reading. Hence, the offset above is intentionally @@ -67,8 +78,9 @@ interfaces: xyz.openbmc_project.Control.Boot.RebootAttempts: AttemptsLeft: - 0xFF: - type: uint32_t + Offsets: + 0xFF: + type: uint32_t path: /xyz/openbmc_project/state/host1 readingType: readingAssertion sensorReadingType: 0x6F @@ -88,8 +100,9 @@ interfaces: xyz.openbmc_project.Sensor.Value: Value: - 0xFF: - type: int64_t + Offsets: + 0xFF: + type: int64_t 0x54: sensorType: 0x07 @@ -100,12 +113,18 @@ interfaces: xyz.openbmc_project.State.Decorator.OperationalStatus: Functional: + Offsets: 0x08: assert: false deassert: true type: bool + Prereqs: + 0x07: + assert: true + deassert: false xyz.openbmc_project.Inventory.Item: Present: + Offsets: 0x07: assert: true deassert: false diff --git a/scripts/writesensor.mako.cpp b/scripts/writesensor.mako.cpp index 9cd4e48..c5db13a 100644 --- a/scripts/writesensor.mako.cpp +++ b/scripts/writesensor.mako.cpp @@ -51,7 +51,7 @@ extern const IdInfoMap sensors = { if "readingAssertion" == valueReadingType or "readingData" == valueReadingType: for interface,properties in interfaces.items(): for dbus_property,property_value in properties.items(): - for offset,values in property_value.items(): + for offset,values in property_value["Offsets"].items(): valueType = values["type"] updateFunc = "set::" + valueReadingType + "<" + valueType + ">" getFunc = "get::" + valueReadingType + "<" + valueType + ">" @@ -66,7 +66,28 @@ extern const IdInfoMap sensors = { {"${interface}",{ % for dbus_property,property_value in properties.items(): {"${dbus_property}",{ - % for offset,values in property_value.items(): +<% +try: + preReq = property_value["Prereqs"] +except KeyError, e: + preReq = dict() +%>\ + { + % for preOffset,preValues in preReq.items(): + { ${preOffset},{ + % for name,value in preValues.items(): + % if name == "type": +<% continue %>\ + % endif +<% value = str(value).lower() %>\ + ${value}, + % endfor + } + }, + % endfor + }, + { + % for offset,values in property_value["Offsets"].items(): { ${offset},{ % if offset == 0xFF: }}, @@ -102,11 +123,11 @@ except KeyError, e: } }, % endfor - }}, + }}}, % endfor }}, % endfor - }, + } }}, % endif % endfor diff --git a/sensordatahandler.cpp b/sensordatahandler.cpp index c8d4fbf..8240108 100644 --- a/sensordatahandler.cpp +++ b/sensordatahandler.cpp @@ -132,7 +132,7 @@ GetSensorResponse mapDbusToAssertion(const Info& sensorInfo, interface.first, property.first); - for (const auto& value : property.second) + for (const auto& value : std::get(property.second)) { if (propValue == value.second.assert) { @@ -176,7 +176,7 @@ GetSensorResponse eventdata2(const Info& sensorInfo) interface.first, property.first); - for (const auto& value : property.second) + for (const auto& value : std::get(property.second)) { if (propValue == value.second.assert) { @@ -230,8 +230,8 @@ ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData, for (const auto& property : interface->second) { msg.append(property.first); - const auto& iter = property.second.find(data); - if (iter == property.second.end()) + const auto& iter = std::get(property.second).find(data); + if (iter == std::get(property.second).end()) { log("Invalid event data"); return IPMI_CC_PARM_OUT_OF_RANGE; @@ -258,7 +258,7 @@ ipmi_ret_t assertion(const SetSensorReadingReq& cmdData, for (const auto& property : interface->second) { msg.append(property.first); - for (const auto& value : property.second) + for (const auto& value : std::get(property.second)) { if (assertionSet.test(value.first)) { @@ -310,11 +310,14 @@ ipmi_ret_t assertion(const SetSensorReadingReq& cmdData, ipmi::sensor::InterfaceMap interfaces; for (const auto& interface : sensorInfo.propertyInterfaces) { + //For a property like functional state the result will be + //calculated based on the true value of all conditions. for (const auto& property : interface.second) { ipmi::sensor::PropertyMap props; bool valid = false; - for (const auto& value : property.second) + auto result = true; + for (const auto& value : std::get(property.second)) { if (assertionSet.test(value.first)) { @@ -323,7 +326,7 @@ ipmi_ret_t assertion(const SetSensorReadingReq& cmdData, { return IPMI_CC_OK; } - props.emplace(property.first, value.second.assert); + result = result && value.second.assert.get(); valid = true; } else if (deassertionSet.test(value.first)) @@ -333,12 +336,25 @@ ipmi_ret_t assertion(const SetSensorReadingReq& cmdData, { return IPMI_CC_OK; } - props.emplace(property.first, value.second.deassert); + result = result && value.second.deassert.get(); valid = true; } } + for (const auto& value : + std::get(property.second)) + { + if (assertionSet.test(value.first)) + { + result = result && value.second.assert.get(); + } + else if (deassertionSet.test(value.first)) + { + result = result && value.second.deassert.get(); + } + } if (valid) { + props.emplace(property.first, result); interfaces.emplace(interface.first, std::move(props)); } } diff --git a/types.hpp b/types.hpp index d3be704..0177c8f 100644 --- a/types.hpp +++ b/types.hpp @@ -50,6 +50,18 @@ struct Values Value deassert; }; +/** + * @enum PreReqValues + * Pre-req conditions for a property. + */ +struct PreReqValues +{ + Value assert; //Value in case of assert. + Value deassert; //Value in case of deassert. +}; + +using PreReqOffsetValueMap = std::map; + /** * @struct SetSensorReadingReq * @@ -88,9 +100,11 @@ using GetSensorResponse = std::array; using OffsetValueMap = std::map; -using DbusPropertyMap = std::map; +using DbusPropertyValues = std::pair; + +using DbusPropertyMap = std::map; -using DbusInterfaceMap = std::map; +using DbusInterfaceMap = std::map; using InstancePath = std::string; using Type = uint8_t; -- cgit v1.2.1