Add type 12h sdr records
This adds support for BMC and ME type 12 records.
Tested:
ipmitool sdr list mcloc
Device ID : �Basbrd Mgmt Ctl
Entity ID : 0.46 (Unspecified)
Device Slave Address : 20h
Channel Number : 0h
ACPI System P/S Notif : Not Required
ACPI Device P/S Notif : Not Required
Controller Presence : Dynamic
Logs Init Agent Errors : No
Event Message Gen : Enable
Device Capabilities
Chassis Device : Yes
Bridge : No
IPMB Event Generator : Yes
IPMB Event Receiver : Yes
FRU Inventory Device : Yes
SEL Device : Yes
SDR Repository : Yes
Sensor Device : Yes
Device ID : �Mgmt Engin
Entity ID : 0.46 (Unspecified)
Device Slave Address : 2Ch
Channel Number : 6h
ACPI System P/S Notif : Not Required
ACPI Device P/S Notif : Not Required
Controller Presence : Static
Logs Init Agent Errors : No
Event Message Gen : Enable
Device Capabilities
Chassis Device : No
Bridge : No
IPMB Event Generator : Yes
IPMB Event Receiver : No
FRU Inventory Device : No
SEL Device : No
SDR Repository : No
Sensor Device : Yes
Change-Id: I3d015ca2f61ab07be18ba46239c3d6a919f0298b
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/src/sensorcommands.cpp b/src/sensorcommands.cpp
index b24ac7e..28d68f4 100644
--- a/src/sensorcommands.cpp
+++ b/src/sensorcommands.cpp
@@ -1053,52 +1053,41 @@
/* storage commands */
-ipmi_ret_t ipmiStorageGetSDRRepositoryInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
- ipmi_request_t request,
- ipmi_response_t response,
- ipmi_data_len_t dataLen,
- ipmi_context_t context)
+ipmi::RspType<uint8_t, // sdr version
+ uint16_t, // record count
+ uint16_t, // free space
+ uint32_t, // most recent addition
+ uint32_t, // most recent erase
+ uint8_t // operationSupport
+ >
+ ipmiStorageGetSDRRepositoryInfo(void)
{
- printCommand(+netfn, +cmd);
-
- if (*dataLen)
- {
- *dataLen = 0;
- return IPMI_CC_REQ_DATA_LEN_INVALID;
- }
- *dataLen = 0; // default to 0 in case of an error
-
+ constexpr const uint16_t unspecifiedFreeSpace = 0xFFFF;
if (sensorTree.empty() && !getSensorSubtree(sensorTree))
{
- return IPMI_CC_RESPONSE_ERROR;
+ return ipmi::responseResponseError();
}
- // zero out response buff
- auto responseClear = static_cast<uint8_t *>(response);
- std::fill(responseClear, responseClear + sizeof(GetSDRInfoResp), 0);
+ size_t fruCount = 0;
+ ipmi::Cc ret = ipmi::storage::getFruSdrCount(fruCount);
+ if (ret != ipmi::ccSuccess)
+ {
+ return ipmi::response(ret);
+ }
- auto resp = static_cast<GetSDRInfoResp *>(response);
- resp->sdrVersion = ipmiSdrVersion;
- uint16_t recordCount = sensorTree.size();
+ uint16_t recordCount =
+ sensorTree.size() + fruCount + ipmi::storage::type12Count;
- // todo: for now, sdr count is number of sensors
- resp->recordCountLS = recordCount & 0xFF;
- resp->recordCountMS = recordCount >> 8;
-
- // free space unspcified
- resp->freeSpace[0] = 0xFF;
- resp->freeSpace[1] = 0xFF;
-
- resp->mostRecentAddition = sdrLastAdd;
- resp->mostRecentErase = sdrLastRemove;
- resp->operationSupport = static_cast<uint8_t>(
+ uint8_t operationSupport = static_cast<uint8_t>(
SdrRepositoryInfoOps::overflow); // write not supported
- resp->operationSupport |=
+
+ operationSupport |=
static_cast<uint8_t>(SdrRepositoryInfoOps::allocCommandSupported);
- resp->operationSupport |= static_cast<uint8_t>(
+ operationSupport |= static_cast<uint8_t>(
SdrRepositoryInfoOps::reserveSDRRepositoryCommandSupported);
- *dataLen = sizeof(GetSDRInfoResp);
- return IPMI_CC_OK;
+ return ipmi::responseSuccess(ipmiSdrVersion, recordCount,
+ unspecifiedFreeSpace, sdrLastAdd,
+ sdrLastRemove, operationSupport);
}
/** @brief implements the get SDR allocation info command
@@ -1166,13 +1155,14 @@
}
size_t fruCount = 0;
- ipmi_ret_t ret = ipmi::storage::getFruSdrCount(fruCount);
- if (ret != IPMI_CC_OK)
+ ipmi::Cc ret = ipmi::storage::getFruSdrCount(fruCount);
+ if (ret != ipmi::ccSuccess)
{
return ipmi::response(ret);
}
- size_t lastRecord = sensorTree.size() + fruCount - 1;
+ size_t lastRecord =
+ sensorTree.size() + fruCount + ipmi::storage::type12Count - 1;
if (recordID == lastRecordIndex)
{
recordID = lastRecord;
@@ -1186,30 +1176,51 @@
if (recordID >= sensorTree.size())
{
+ std::vector<uint8_t> recordData;
size_t fruIndex = recordID - sensorTree.size();
if (fruIndex >= fruCount)
{
- return ipmi::responseInvalidFieldRequest();
- }
- get_sdr::SensorDataFruRecord data;
- if (offset > sizeof(data))
- {
- return ipmi::responseInvalidFieldRequest();
- }
- ret = ipmi::storage::getFruSdrs(fruIndex, data);
- if (ret != IPMI_CC_OK)
- {
- return ipmi::response(ret);
- }
- data.header.record_id_msb = recordID << 8;
- data.header.record_id_lsb = recordID & 0xFF;
- if (sizeof(data) < (offset + bytesToRead))
- {
- bytesToRead = sizeof(data) - offset;
- }
+ // handle type 12 hardcoded records
+ size_t type12Index = fruIndex - fruCount;
+ if (type12Index >= ipmi::storage::type12Count ||
+ offset > sizeof(Type12Record))
+ {
+ return ipmi::responseInvalidFieldRequest();
+ }
+ std::vector<uint8_t> record =
+ ipmi::storage::getType12SDRs(type12Index, recordID);
+ if (record.size() < (offset + bytesToRead))
+ {
+ bytesToRead = record.size() - offset;
+ }
- uint8_t *respStart = reinterpret_cast<uint8_t *>(&data) + offset;
- std::vector<uint8_t> recordData(respStart, respStart + bytesToRead);
+ recordData.insert(recordData.end(), record.begin() + offset,
+ record.begin() + offset + bytesToRead);
+ }
+ else
+ {
+ // handle fru records
+ get_sdr::SensorDataFruRecord data;
+ if (offset > sizeof(data))
+ {
+ return ipmi::responseInvalidFieldRequest();
+ }
+ ret = ipmi::storage::getFruSdrs(fruIndex, data);
+ if (ret != IPMI_CC_OK)
+ {
+ return ipmi::response(ret);
+ }
+ data.header.record_id_msb = recordID << 8;
+ data.header.record_id_lsb = recordID & 0xFF;
+ if (sizeof(data) < (offset + bytesToRead))
+ {
+ bytesToRead = sizeof(data) - offset;
+ }
+
+ uint8_t *respStart = reinterpret_cast<uint8_t *>(&data) + offset;
+ recordData.insert(recordData.end(), respStart,
+ respStart + bytesToRead);
+ }
return ipmi::responseSuccess(nextRecordId, recordData);
}
@@ -1491,10 +1502,10 @@
// versions
// <Get SDR Repository Info>
- ipmiPrintAndRegister(
- NETFUN_STORAGE,
- static_cast<ipmi_cmd_t>(IPMINetfnStorageCmds::ipmiCmdGetRepositoryInfo),
- nullptr, ipmiStorageGetSDRRepositoryInfo, PRIVILEGE_USER);
+ ipmi::registerHandler(
+ ipmi::prioOemBase, NETFUN_STORAGE,
+ static_cast<ipmi::Cmd>(IPMINetfnStorageCmds::ipmiCmdGetRepositoryInfo),
+ ipmi::Privilege::User, ipmiStorageGetSDRRepositoryInfo);
// <Get SDR Allocation Info>
ipmi::registerHandler(