summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/usr/devicefw/driverif.H1
-rwxr-xr-xsrc/usr/i2c/i2c.C16
-rw-r--r--src/usr/isteps/nvdimm/nvdimm_update.C4
-rwxr-xr-xsrc/usr/isteps/nvdimm/nvdimmdd.C100
4 files changed, 77 insertions, 44 deletions
diff --git a/src/include/usr/devicefw/driverif.H b/src/include/usr/devicefw/driverif.H
index 048b8dc19..118e08973 100644
--- a/src/include/usr/devicefw/driverif.H
+++ b/src/include/usr/devicefw/driverif.H
@@ -103,6 +103,7 @@ namespace DeviceFW
I2C_SMBUS_WORD = 3, ///< I2c SMBUS Read/Write Word
I2C_SMBUS_BYTE = 4, ///< I2c SMBUS Read/Write Byte
I2C_SMBUS_SEND_OR_RECV = 5, ///< I2c SMBUS Send/Receive Byte
+ I2C_SMBUS_WORD_NO_PEC = 6, ///< I2c SMBUS Read/Write Word without PEC byte
};
#ifndef PARSER
diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C
index 63b579202..97334408b 100755
--- a/src/usr/i2c/i2c.C
+++ b/src/usr/i2c/i2c.C
@@ -449,12 +449,13 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
{
if( (subop==DeviceFW::I2C_SMBUS_BLOCK)
|| (subop==DeviceFW::I2C_SMBUS_BYTE)
- || (subop==DeviceFW::I2C_SMBUS_WORD))
+ || (subop==DeviceFW::I2C_SMBUS_WORD)
+ || (subop == DeviceFW::I2C_SMBUS_WORD_NO_PEC) )
{
args.smbus.commandCode =
static_cast<decltype(args.smbus.commandCode)>(
va_arg(i_args,uint64_t));
- args.smbus.usePec = true; // All implementations use PEC
+ args.smbus.usePec = true; // Most implementations use PEC
args.i2cMuxBusSelector = va_arg(i_args,uint64_t);
args.i2cMuxPath = reinterpret_cast<const TARGETING::EntityPath*>(
va_arg(i_args, uint64_t));
@@ -477,11 +478,18 @@ errlHndl_t i2cPerformOp( DeviceFW::OperationType i_opType,
if ( args.offset_length != 0 )
{
args.offset_buffer = temp;
-
}
}
- args.subop=subop;
+ if (subop == DeviceFW::I2C_SMBUS_WORD_NO_PEC)
+ {
+ args.smbus.usePec = false;
+ args.subop = DeviceFW::I2C_SMBUS_WORD;
+ }
+ else
+ {
+ args.subop=subop;
+ }
err = i2cCommonOp( i_opType,
i_target,
diff --git a/src/usr/isteps/nvdimm/nvdimm_update.C b/src/usr/isteps/nvdimm/nvdimm_update.C
index 4f235aa6c..2f50c11b0 100644
--- a/src/usr/isteps/nvdimm/nvdimm_update.C
+++ b/src/usr/isteps/nvdimm/nvdimm_update.C
@@ -41,7 +41,7 @@ TRAC_INIT(&g_trac_nvdimm_upd, NVDIMM_UPD, 2*KILOBYTE);
// Easy macro replace for unit testing
-// #define TRACUCOMP(args...) TRACFCOMP(args)
+//#define TRACUCOMP(args...) TRACFCOMP(args)
#define TRACUCOMP(args...)
namespace NVDIMM
@@ -1446,6 +1446,7 @@ errlHndl_t NvdimmInstalledImage::byteRegionBlockTransfer(const uint8_t * i_data,
// After a block has been transferred, verify that the 32-byte block
// was received by polling FIRMWARE_OPS_STATUS offset for
// FIRMWARE_BLOCK_RECEIVED.
+ TRACUCOMP(g_trac_nvdimm_upd, ">> waitFwOpsBlockReceived");
l_err = waitFwOpsBlockReceived();
if (l_err)
{
@@ -1454,6 +1455,7 @@ errlHndl_t NvdimmInstalledImage::byteRegionBlockTransfer(const uint8_t * i_data,
" 0x%.8X", blockNum, TARGETING::get_huid(iv_dimm));
break;
}
+
// block of data successfully sent to NV controller
TRACUCOMP(g_trac_nvdimm_upd,"byteRegionBlockTransfer: block 0x%02X successfully sent to NV controller", blockNum);
blockNum++;
diff --git a/src/usr/isteps/nvdimm/nvdimmdd.C b/src/usr/isteps/nvdimm/nvdimmdd.C
index 84869266a..a17197d2b 100755
--- a/src/usr/isteps/nvdimm/nvdimmdd.C
+++ b/src/usr/isteps/nvdimm/nvdimmdd.C
@@ -68,8 +68,8 @@ TRAC_INIT( & g_trac_nvdimmr, "NVDIMMR", KILOBYTE );
// Easy macro replace for unit testing
-#define TRACUCOMP(args...) TRACFCOMP(args)
-//#define TRACUCOMP(args...)
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
// ----------------------------------------------
// Defines
@@ -208,7 +208,7 @@ errlHndl_t nvdimmPerformOp( DeviceFW::OperationType i_opType,
l_currentOpLen = l_snglChipSize - i2cInfo.offset;
}
- TRACFCOMP( g_trac_nvdimm,
+ TRACUCOMP( g_trac_nvdimm,
"nvdimmPerformOp(): i_opType=%d "
"e/p/dA=%d/%d/0x%X, offset=0x%X, len=0x%X, "
"snglChipKB=0x%X, chipCount=0x%X, devSizeKB=0x%X", i_opType,
@@ -218,7 +218,7 @@ errlHndl_t nvdimmPerformOp( DeviceFW::OperationType i_opType,
// Printing mux info separately, if combined, nothing is displayed
char* l_muxPath = i2cInfo.i2cMuxPath.toString();
- TRACFCOMP(g_trac_nvdimm, "nvdimmPerformOp(): "
+ TRACUCOMP(g_trac_nvdimm, "nvdimmPerformOp(): "
"muxSelector=0x%X, muxPath=%s",
i2cInfo.i2cMuxBusSelector,
l_muxPath);
@@ -650,8 +650,6 @@ errlHndl_t nvdimmWrite ( TARGETING::Target * i_target,
size_t byteAddrSize = 0;
uint8_t * newBuffer = nullptr;
bool needFree = false;
- uint32_t data_left = 0;
- uint32_t diff_wps = 0;
TRACDCOMP( g_trac_nvdimm,
ENTER_MRK"nvdimmWrite()" );
@@ -716,6 +714,15 @@ errlHndl_t nvdimmWrite ( TARGETING::Target * i_target,
// Setup a max-size buffer of writePageSize
size_t newBufLen = i_i2cInfo.writePageSize;
+
+ // Break data into word size transfers if possible
+ if ( (io_buflen > sizeof(uint16_t)) &&
+ ((io_buflen % sizeof(uint16_t)) == 0) )
+ {
+ newBufLen = sizeof(uint16_t);
+ }
+ assert(newBufLen > 0, "Unable to allocate 0 buffer size for nvdimmWrite()");
+
newBuffer = static_cast<uint8_t*>(malloc( newBufLen ));
needFree = true;
@@ -730,16 +737,6 @@ errlHndl_t nvdimmWrite ( TARGETING::Target * i_target,
while( total_bytes_written < io_buflen )
{
- // Determine how much data can be written in this loop
- // Can't go over a writePageSize boundary
-
- // Total data left to write
- data_left = io_buflen - total_bytes_written;
-
- // Difference to next writePageSize boundary
- diff_wps = i_i2cInfo.writePageSize -
- (i_i2cInfo.offset % i_i2cInfo.writePageSize);
-
// Add the data the user wanted to write
memcpy( newBuffer,
&l_data_ptr[total_bytes_written],
@@ -759,15 +756,13 @@ errlHndl_t nvdimmWrite ( TARGETING::Target * i_target,
}
TRACUCOMP(g_trac_nvdimm,"nvdimmWrite() Loop: %d/%d/0x%X "
- "writeBuflen=%d, offset=0x%X, "
- "bAS=%d, diffs=%d/%d",
+ "writeBuflen=%d, offset=0x%X, bAS=%d",
i_i2cInfo.port, i_i2cInfo.engine, i_i2cInfo.devAddr,
- newBufLen, i_i2cInfo.offset, byteAddrSize,
- data_left, diff_wps);
+ newBufLen, i_i2cInfo.offset, byteAddrSize);
// Printing mux info separately, if combined, nothing is displayed
char* l_muxPath = i_i2cInfo.i2cMuxPath.toString();
- TRACFCOMP(g_trac_nvdimm, "nvdimmWrite(): "
+ TRACUCOMP(g_trac_nvdimm, "nvdimmWrite(): "
"muxSelector=0x%X, muxPath=%s",
i_i2cInfo.i2cMuxBusSelector,
l_muxPath);
@@ -789,6 +784,14 @@ errlHndl_t nvdimmWrite ( TARGETING::Target * i_target,
// for this loop
TRACFCOMP(g_trac_nvdimm,
"Failed writing data: original nvdimm write");
+ // total writes for the data size (divide by each write size)
+ size_t totalWritesNeeded = io_buflen/newBufLen;
+ // current write number (writes done + next one)
+ size_t currentWrite = total_bytes_written/newBufLen + 1;
+ TRACFCOMP( g_trac_nvdimm,ERR_MRK"nvdimmWrite(): "
+ "Tried to write out %d bytes out of %d total: "
+ "Failed on the %d of %d writes", newBufLen, io_buflen,
+ currentWrite, totalWritesNeeded );
break;
}
@@ -850,28 +853,47 @@ errlHndl_t nvdimmWriteData( TARGETING::Target * i_target,
errlHndl_t err_retryable = nullptr;
do
{
- /***********************************************************/
- /* Attempt write multiple times ONLY on retryable fails */
- /***********************************************************/
+ /***********************************************************/
+ /* Attempt write multiple times ONLY on retryable fails */
+ /***********************************************************/
for (uint8_t retry = 0;
retry <= NVDIMM_MAX_RETRIES;
retry++)
- {
+ {
// Do the actual data write
- err = deviceOp( DeviceFW::WRITE,
- i_target,
- i_dataToWrite,
- i_dataLen,
- DEVICE_I2C_ADDRESS_OFFSET(
- i_i2cInfo.port,
- i_i2cInfo.engine,
- i_i2cInfo.devAddr,
- i_byteAddressSize,
- reinterpret_cast<uint8_t*>(
- i_byteAddress),
- i_i2cInfo.i2cMuxBusSelector,
- &(i_i2cInfo.i2cMuxPath) ));
-
+ if ( i_dataLen == sizeof(uint16_t) )
+ {
+ err = deviceOp( DeviceFW::WRITE,
+ i_target,
+ i_dataToWrite,
+ i_dataLen,
+ DeviceFW::I2C,
+ I2C_SMBUS_RW_W_CMD_PARAMS(
+ DeviceFW::I2C_SMBUS_WORD_NO_PEC,
+ i_i2cInfo.engine,
+ i_i2cInfo.port,
+ i_i2cInfo.devAddr,
+ *(reinterpret_cast<uint8_t*>(i_byteAddress)
+ + (i_byteAddressSize-1)),
+ i_i2cInfo.i2cMuxBusSelector,
+ &(i_i2cInfo.i2cMuxPath)) );
+ }
+ else
+ {
+ err = deviceOp( DeviceFW::WRITE,
+ i_target,
+ i_dataToWrite,
+ i_dataLen,
+ DEVICE_I2C_ADDRESS_OFFSET(
+ i_i2cInfo.port,
+ i_i2cInfo.engine,
+ i_i2cInfo.devAddr,
+ i_byteAddressSize,
+ reinterpret_cast<uint8_t*>(
+ i_byteAddress),
+ i_i2cInfo.i2cMuxBusSelector,
+ &(i_i2cInfo.i2cMuxPath) ));
+ }
if ( err == nullptr )
{
// Operation completed successfully
OpenPOWER on IntegriCloud