diff options
-rw-r--r-- | src/include/usr/devicefw/driverif.H | 1 | ||||
-rwxr-xr-x | src/usr/i2c/i2c.C | 16 | ||||
-rw-r--r-- | src/usr/isteps/nvdimm/nvdimm_update.C | 4 | ||||
-rwxr-xr-x | src/usr/isteps/nvdimm/nvdimmdd.C | 100 |
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 |