Skip to content
This repository was archived by the owner on Mar 9, 2026. It is now read-only.

Commit fb529c1

Browse files
committed
Add check for long operation status and messages about that state
Signed-off-by: Glenn L Diviney <glenn.l.diviney@intel.com>
1 parent 5403b4f commit fb529c1

File tree

6 files changed

+113
-10
lines changed

6 files changed

+113
-10
lines changed

DcpmPkg/cli/Common.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,9 @@ MatchCliReturnCode(
12201220
case NVM_ERR_REGION_GOAL_NAMESPACE_EXISTS:
12211221
case NVM_ERR_REGION_REMAINING_SIZE_NOT_IN_LAST_PROPERTY:
12221222
case NVM_ERR_ARS_IN_PROGRESS:
1223+
case NVM_ERR_FWUPDATE_IN_PROGRESS:
1224+
case NVM_ERR_OVERWRITE_DIMM_IN_PROGRESS:
1225+
case NVM_ERR_UNKNOWN_LONG_OP_IN_PROGRESS:
12231226
case NVM_ERR_APPDIRECT_IN_SYSTEM:
12241227
case NVM_ERR_OPERATION_NOT_SUPPORTED_BY_MIXED_SKU:
12251228
case NVM_ERR_SECURE_ERASE_NAMESPACE_EXISTS:

DcpmPkg/common/NvmSharedDefs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ typedef enum _NvmStatusCode {
179179

180180
NVM_SUCCESS_NO_EVENT_FOUND = 302, ///< Error: No events found in the event log
181181
NVM_ERR_FILE_NOT_FOUND = 303, ///< Error: No events found in the event log
182+
NVM_ERR_OVERWRITE_DIMM_IN_PROGRESS = 304, ///< Error: No events found in the event log
183+
NVM_ERR_FWUPDATE_IN_PROGRESS = 305, ///< Error: No events found in the event log
184+
NVM_ERR_UNKNOWN_LONG_OP_IN_PROGRESS = 306, ///< Error: No events found in the event log
182185
NVM_LAST_STATUS_VALUE
183186
} NvmStatusCode;
184187

DcpmPkg/common/NvmStatus.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,12 @@ GetSingleNvmStatusCodeMessage(
535535

536536
case NVM_ERR_ARS_IN_PROGRESS:
537537
return HiiGetString(HiiHandle, STRING_TOKEN(STR_DCPMM_STATUS_ERR_ARS_IN_PROGRESS), NULL);
538+
case NVM_ERR_FWUPDATE_IN_PROGRESS:
539+
return HiiGetString(HiiHandle, STRING_TOKEN(STR_DCPMM_STATUS_ERR_FWUPDATE_IN_PROGRESS), NULL);
540+
case NVM_ERR_OVERWRITE_DIMM_IN_PROGRESS:
541+
return HiiGetString(HiiHandle, STRING_TOKEN(STR_DCPMM_STATUS_ERR_OVERWRITE_DIMM_IN_PROGRESS), NULL);
542+
case NVM_ERR_UNKNOWN_LONG_OP_IN_PROGRESS:
543+
return HiiGetString(HiiHandle, STRING_TOKEN(STR_DCPMM_STATUS_ERR_UNKNOWN_LONG_OP_IN_PROGRESS), NULL);
538544

539545
case NVM_ERR_APPDIRECT_IN_SYSTEM:
540546
return HiiGetString(HiiHandle, STRING_TOKEN(STR_DCPMM_STATUS_ERR_APPDIRECT_IN_SYSTEM), NULL);

DcpmPkg/common/NvmStatus.uni

736 Bytes
Binary file not shown.

DcpmPkg/driver/Protocol/Driver/NvmDimmConfig.c

Lines changed: 86 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

DcpmPkg/driver/Protocol/Driver/NvmDimmConfig.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,6 +1478,21 @@ VerifyTargetDimms(
14781478
OUT COMMAND_STATUS *pCommandStatus
14791479
);
14801480

1481+
/**
1482+
Examine a given DIMM to see if a long op is in progress and report it back
1483+
1484+
@param[in] pDimm The dimm to check the status of
1485+
@param[out] pNvmStatus The status of the dimm's long op status. NVM_SUCCESS = No long op status is under way.
1486+
1487+
@retval EFI_SUCCESS if the request for long op status was successful (whether a long op status is under way or not)
1488+
@retval EFI_... the error preventing the check for the long op status
1489+
**/
1490+
EFI_STATUS
1491+
CheckForLongOpStatusInProgress(
1492+
IN DIMM *pDimm,
1493+
OUT NVM_STATUS *pNvmStatus
1494+
);
1495+
14811496
// Debug Only
14821497
#ifndef MDEPKG_NDEBUG
14831498

0 commit comments

Comments
 (0)