summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--storagehandler.cpp67
-rw-r--r--storagehandler.h32
2 files changed, 96 insertions, 3 deletions
diff --git a/storagehandler.cpp b/storagehandler.cpp
index a1b3f03..36e1bb4 100644
--- a/storagehandler.cpp
+++ b/storagehandler.cpp
@@ -5,6 +5,7 @@
#include <mapper.h>
#include <chrono>
#include "selutility.hpp"
+#include <algorithm>
#include "storagehandler.h"
#include "storageaddsel.h"
#include "utils.hpp"
@@ -13,10 +14,11 @@
#include <phosphor-logging/log.hpp>
#include <sdbusplus/server.hpp>
#include "xyz/openbmc_project/Common/error.hpp"
+#include "read_fru_data.hpp"
+#include <phosphor-logging/elog-errors.hpp>
void register_netfn_storage_functions() __attribute__((constructor));
-
unsigned int g_sel_time = 0xFFFFFFFF;
extern unsigned short g_sel_reserve;
@@ -42,6 +44,17 @@ namespace cache
using InternalFailure =
sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
using namespace phosphor::logging;
+using namespace ipmi::fru;
+
+/**
+ * @enum Device access mode
+ */
+enum class AccessMode
+{
+ bytes, ///< Device is accessed by bytes
+ words ///< Device is accessed by words
+};
+
ipmi_ret_t ipmi_storage_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request, ipmi_response_t response,
@@ -579,6 +592,29 @@ ipmi_ret_t ipmi_storage_get_fru_inv_area_info(
ipmi_context_t context)
{
ipmi_ret_t rc = IPMI_CC_OK;
+ const FruInvenAreaInfoRequest* reqptr =
+ reinterpret_cast<const FruInvenAreaInfoRequest*>(request);
+ try
+ {
+ const auto& fruArea = getFruAreaData(reqptr->fruID);
+ auto size = static_cast<uint16_t>(fruArea.size());
+ FruInvenAreaInfoResponse resp;
+ resp.sizems = size >> 8;
+ resp.sizels = size;
+ resp.access = static_cast<uint8_t>(AccessMode::bytes);
+
+ *data_len = sizeof(resp);
+
+ // Pack the actual response
+ memcpy(response, &resp, *data_len);
+ }
+ catch(const InternalFailure& e)
+ {
+ rc = IPMI_CC_UNSPECIFIED_ERROR;
+ *data_len = 0;
+ log<level::ERR>(e.what());
+ report<InternalFailure>();
+ }
return rc;
}
@@ -589,11 +625,36 @@ ipmi_ret_t ipmi_storage_read_fru_data(
ipmi_context_t context)
{
ipmi_ret_t rc = IPMI_CC_OK;
+ const ReadFruDataRequest* reqptr =
+ reinterpret_cast<const ReadFruDataRequest*>(request);
+ auto offset =
+ static_cast<uint16_t>(reqptr->offsetMS << 8 | reqptr->offsetLS);
+ try
+ {
+ const auto& fruArea = getFruAreaData(reqptr->fruID);
+ auto size = fruArea.size();
+ if ((offset + reqptr->count) > size)
+ {
+ log<level::ERR>("Invalid offset and count",
+ entry("Offset=%d Count=%d SizeOfFruArea=%d",
+ offset, reqptr->count, size));
+ return IPMI_CC_INVALID;
+ }
+ std::copy((fruArea.begin() + offset), (fruArea.begin() + reqptr->count),
+ (static_cast<uint8_t*>(response)));
+ *data_len = reqptr->count;
+ }
+ catch (const InternalFailure& e)
+ {
+ rc = IPMI_CC_UNSPECIFIED_ERROR;
+ *data_len = 0;
+ log<level::ERR>(e.what());
+ report<InternalFailure>();
+ }
return rc;
}
-
void register_netfn_storage_functions()
{
// <Wildcard Command>
@@ -648,9 +709,9 @@ void register_netfn_storage_functions()
// <Add READ FRU Data
printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", NETFUN_STORAGE,
IPMI_CMD_READ_FRU_DATA);
-
ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_READ_FRU_DATA, NULL,
ipmi_storage_read_fru_data, PRIVILEGE_OPERATOR);
+
return;
}
diff --git a/storagehandler.h b/storagehandler.h
index 7f1b67d..a971f77 100644
--- a/storagehandler.h
+++ b/storagehandler.h
@@ -30,4 +30,36 @@ struct ipmi_add_sel_request_t {
uint8_t eventdir;
uint8_t eventdata[3];
};
+
+/**
+ * @struct Read FRU Data command request data
+ */
+struct ReadFruDataRequest
+{
+ uint8_t fruID; ///< FRU Device ID. FFh = reserved
+ uint8_t offsetLS; ///< FRU Inventory Offset to read, LS Byte
+ uint8_t offsetMS; ///< FRU Inventory Offset ro read, MS Byte
+ uint8_t count; ///< Count to read
+}__attribute__ ((packed));
+
+/**
+ * @struct Get FRU inventory area info command request data
+ */
+struct FruInvenAreaInfoRequest
+{
+ uint8_t fruID; ///< FRU Device ID. FFH = reserved.
+}__attribute__ ((packed));
+
+
+/**
+ * @struct Get FRU inventory area info command response
+ */
+struct FruInvenAreaInfoResponse
+{
+ uint8_t completionCode; ///< Completion code
+ uint8_t sizels; ///< Fru Inventory area size in bytes, LS Byte
+ uint8_t sizems; ///< Fru Inventory are size in bytes, MS Byte
+ uint8_t access; ///< 0b Devices is accessed by bytes, 1b - by words
+}__attribute__ ((packed));
+
#endif
OpenPOWER on IntegriCloud