@@ -5307,6 +5307,9 @@ UpdateFw(
53075307 UINT32 VerificationFailures = 0 ;
53085308 UINT32 ForceRequiredDimms = 0 ;
53095309
5310+ EFI_STATUS LongOpStatusReturnCode = 0 ;
5311+ NVM_STATUS LongOpNvmStatus = NVM_ERR_OPERATION_NOT_STARTED ;
5312+
53105313 ZeroMem (pDimms , sizeof (pDimms ));
53115314
53125315 NVDIMM_ENTRY ();
@@ -5429,7 +5432,6 @@ UpdateFw(
54295432 }
54305433 else {
54315434 pDimmsCanBeUpdated [Index ] = TRUE;
5432- DimmsToUpdate ++ ;
54335435 SetObjStatusForDimmWithErase (pCommandStatus , pDimms [Index ], NVM_SUCCESS_IMAGE_EXAMINE_OK , TRUE);
54345436 }
54355437#endif
@@ -5451,7 +5453,6 @@ UpdateFw(
54515453 }
54525454 else {
54535455 pDimmsCanBeUpdated [Index ] = TRUE;
5454- DimmsToUpdate ++ ;
54555456 SetObjStatusForDimmWithErase (pCommandStatus , pDimms [Index ], NVM_SUCCESS_IMAGE_EXAMINE_OK , TRUE);
54565457 }
54575458 }
@@ -5464,6 +5465,14 @@ UpdateFw(
54645465 goto Finish ;
54655466 }
54665467
5468+ //count up the number of DIMMs to update
5469+ DimmsToUpdate = 0 ;
5470+ for (Index = 0 ; Index < DimmsNum ; Index ++ ) {
5471+ if (pDimmsCanBeUpdated [Index ] == TRUE) {
5472+ DimmsToUpdate ++ ;
5473+ }
5474+ }
5475+
54675476 if (DimmsToUpdate == 0 ) {
54685477 if (pCommandStatus -> GeneralStatus == NVM_ERR_OPERATION_NOT_STARTED ) {
54695478 NVDIMM_DBG ("Found no DIMMs to update - either none were passed or none passed the verification checks" );
@@ -5475,7 +5484,7 @@ UpdateFw(
54755484 // upload FW image to all specified DIMMs
54765485 for (Index = 0 ; Index < DimmsNum ; Index ++ ) {
54775486 if (pDimmsCanBeUpdated [Index ] == FALSE) {
5478- NVDIMM_DBG ("Skipping dimm %d. It is marked as not being capable of this update" , pDimms [Index ]-> DeviceHandle .AsUint32 );
5487+ NVDIMM_DBG ("Skipping dimm %d. It is marked as not being currently capable of this update" , pDimms [Index ]-> DeviceHandle .AsUint32 );
54795488 continue ;
54805489 }
54815490
@@ -5492,14 +5501,23 @@ UpdateFw(
54925501
54935502 if (ReturnCode != EFI_SUCCESS ) {
54945503 UpdateFailures ++ ;
5495- if (NvmStatus == NVM_SUCCESS ) {
5496- pCommandStatus -> GeneralStatus = NVM_ERR_OPERATION_FAILED ;
5497- SetObjStatusForDimmWithErase (pCommandStatus , pDimms [Index ], NVM_ERR_OPERATION_FAILED , TRUE);
5504+
5505+ //Perform a check to see if it was a long operation that blocked the update and get more details about it
5506+ LongOpStatusReturnCode = CheckForLongOpStatusInProgress (pDimms [Index ], & LongOpNvmStatus );
5507+ if (LongOpStatusReturnCode == EFI_SUCCESS && LongOpNvmStatus != NVM_SUCCESS ) {
5508+ pCommandStatus -> GeneralStatus = LongOpNvmStatus ;
5509+ SetObjStatusForDimmWithErase (pCommandStatus , pDimms [Index ], LongOpNvmStatus , TRUE);
54985510 }
5499- else
5500- {
5501- pCommandStatus -> GeneralStatus = NvmStatus ;
5502- SetObjStatusForDimmWithErase (pCommandStatus , pDimms [Index ], NvmStatus , TRUE);
5511+ else {
5512+ if (NvmStatus == NVM_SUCCESS ) {
5513+ pCommandStatus -> GeneralStatus = NVM_ERR_OPERATION_FAILED ;
5514+ SetObjStatusForDimmWithErase (pCommandStatus , pDimms [Index ], NVM_ERR_OPERATION_FAILED , TRUE);
5515+ }
5516+ else
5517+ {
5518+ pCommandStatus -> GeneralStatus = NvmStatus ;
5519+ SetObjStatusForDimmWithErase (pCommandStatus , pDimms [Index ], NvmStatus , TRUE);
5520+ }
55035521 }
55045522 }
55055523 else
@@ -5533,6 +5551,64 @@ UpdateFw(
55335551 return ReturnCode ;
55345552}
55355553
5554+ /**
5555+ Examine a given DIMM to see if a long op is in progress and report it back
5556+
5557+ @param[in] pDimm The dimm to check the status of
5558+ @param[out] pNvmStatus The status of the dimm's long op status. NVM_SUCCESS = No long op status is under way.
5559+
5560+ @retval EFI_SUCCESS if the request for long op status was successful (whether a long op status is under way or not)
5561+ @retval EFI_... the error preventing the check for the long op status
5562+ **/
5563+ EFI_STATUS
5564+ CheckForLongOpStatusInProgress (
5565+ IN DIMM * pDimm ,
5566+ OUT NVM_STATUS * pNvmStatus
5567+ )
5568+ {
5569+ EFI_STATUS ReturnCode = EFI_SUCCESS ;
5570+ UINT8 LongOpStatusCode = 0 ;
5571+ PT_OUTPUT_PAYLOAD_FW_LONG_OP_STATUS LongOpStatus ;
5572+ EFI_STATUS LongOpCheckRetCode = EFI_SUCCESS ;
5573+
5574+ NVDIMM_ENTRY ();
5575+
5576+ if (pNvmStatus == NULL ) {
5577+ ReturnCode = EFI_INVALID_PARAMETER ;
5578+ goto Finish ;
5579+ }
5580+
5581+ * pNvmStatus = NVM_SUCCESS ;
5582+ LongOpCheckRetCode = FwCmdGetLongOperationStatus (pDimm , & LongOpStatusCode , & LongOpStatus );
5583+ if (EFI_ERROR (LongOpCheckRetCode )) {
5584+ //fatal error
5585+ * pNvmStatus = NVM_ERR_UNKNOWN ;
5586+ ReturnCode = LongOpCheckRetCode ;
5587+ goto Finish ;
5588+ }
5589+ else if (LongOpStatus .Status != FW_DEVICE_BUSY ) {
5590+ //no long op in progress
5591+ goto Finish ;
5592+ }
5593+
5594+ if (LongOpStatus .CmdOpcode == PtGetFeatures && LongOpStatus .CmdSubcode == SubopAddressRangeScrub ) {
5595+ * pNvmStatus = NVM_ERR_ARS_IN_PROGRESS ;
5596+ }
5597+ else if (LongOpStatus .CmdOpcode == PtUpdateFw && LongOpStatus .CmdSubcode == SubopUpdateFw ) {
5598+ * pNvmStatus = NVM_ERR_FWUPDATE_IN_PROGRESS ;
5599+ }
5600+ else if (LongOpStatus .CmdOpcode == PtSetSecInfo && LongOpStatus .CmdSubcode == SubopOverwriteDimm ) {
5601+ * pNvmStatus = NVM_ERR_OVERWRITE_DIMM_IN_PROGRESS ;
5602+ }
5603+ else {
5604+ * pNvmStatus = NVM_ERR_UNKNOWN_LONG_OP_IN_PROGRESS ;
5605+ }
5606+
5607+ Finish :
5608+ NVDIMM_EXIT_I64 (ReturnCode );
5609+ return ReturnCode ;
5610+ }
5611+
55365612/**
55375613 Filter a list of dimms by a given socket and return an array of dimms
55385614 that exist on a given socket
0 commit comments