summaryrefslogtreecommitdiffstats
path: root/src/usr/ipmi/ipmifruinv.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/ipmi/ipmifruinv.C')
-rw-r--r--src/usr/ipmi/ipmifruinv.C76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/usr/ipmi/ipmifruinv.C b/src/usr/ipmi/ipmifruinv.C
index b8f012709..267782e27 100644
--- a/src/usr/ipmi/ipmifruinv.C
+++ b/src/usr/ipmi/ipmifruinv.C
@@ -42,6 +42,7 @@
#include <assert.h>
#include <pnor/pnorif.H>
#include <ipmi/ipmi_reasoncodes.H>
+#include <console/consoleif.H>
extern trace_desc_t * g_trac_ipmi;
/**
@@ -1764,6 +1765,81 @@ void IPMIFRUINV::setData(bool i_updateData)
return;
}
+void IPMIFRUINV::readFruData(uint8_t i_deviceId, uint8_t *o_data)
+{
+ //Use IMPIFRU::readData to send data to service processor
+ // it will do any error handling and memory management
+ IPMIFRU::readData(i_deviceId, o_data);
+}
+
+char * IPMIFRUINV::getProductSN(uint8_t i_deviceId)
+{
+ //If we cannot read the product serial number, default is 0's (set below)
+ char * l_prodSN = NULL;
+
+ //First read the entire record that contains the SN
+ uint8_t *l_record = new uint8_t[IPMIFRU::MAX_RECORD_SIZE];
+ memset(l_record, 0, IPMIFRU::MAX_RECORD_SIZE);
+ readFruData(i_deviceId, l_record);
+
+ do {
+
+ //Code only supports version 1 of the FRU spec if for whatever reason
+ // we didn't get data, this would be 0
+ if (l_record[IPMIFRUINV::HEADER_FORMART_VERSION]
+ != IPMIFRUINV::SPEC_VERSION)
+ {
+ TRACFCOMP(g_trac_ipmi, "FW does not support IPMI FRU Version: %d",
+ l_record[1]);
+ break;
+ }
+
+ //Get the offset in the record pointed to the product info area
+ // (where the SN is located)
+ uint8_t l_prodInfoOffset = l_record[IPMIFRUINV::PRODUCT_INFO_AREA];
+
+ if (l_prodInfoOffset == IPMIFRUINV::RECORD_NOT_PRESENT)
+ {
+ TRACFCOMP(g_trac_ipmi, "Product Info Area Not present "
+ "- returning empty SN");
+ break;
+ }
+
+ //Start at the beginning of the Product Info Record and traverse to the
+ // serial number entry
+ uint8_t l_prodIndex = l_prodInfoOffset * RECORD_UNIT_OF_MEASUREMENT;
+ l_prodIndex += 3; //Version, Length Byte, Language Code
+
+ //MFG NAME Length + TYPELENGTH Byte
+ l_prodIndex += ((TYPELENGTH_SIZE_MASK&l_record[l_prodIndex]) + 1);
+
+ //Prod NAME Length + TYPELENGTH Byte
+ l_prodIndex += ((TYPELENGTH_SIZE_MASK&l_record[l_prodIndex]) + 1);
+
+ //Prod Part/Model Number Length + TYPELENGTH Byte
+ l_prodIndex += ((TYPELENGTH_SIZE_MASK&l_record[l_prodIndex]) + 1);
+
+ //Prod Version Length + TYPELEGNTH Byte
+ l_prodIndex += ((TYPELENGTH_SIZE_MASK&l_record[l_prodIndex]) + 1);
+
+ //Serial number located after Prod Version
+ uint8_t l_prodSNOffset = l_prodIndex;
+ uint8_t l_prodSNsize = TYPELENGTH_SIZE_MASK&l_record[l_prodSNOffset];
+
+ //Grab Serial Number as char array
+ l_prodSN = new char[l_prodSNsize+1];
+ memcpy(l_prodSN, &l_record[l_prodSNOffset+1], l_prodSNsize);
+ l_prodSN[l_prodSNsize] = '\0';
+
+ //Can skip the rest.
+
+ } while (0);
+
+
+ delete[] l_record;
+
+ return l_prodSN;
+}
void IPMIFRUINV::gatherClearData(const TARGETING::Target* i_pSys,
std::map<uint8_t,bool>& io_frusToClear)
OpenPOWER on IntegriCloud