Skip to content

Commit

Permalink
Add check for long operation status and messages about that state
Browse files Browse the repository at this point in the history
Signed-off-by: Glenn L Diviney <[email protected]>
  • Loading branch information
gldiviney committed Jan 17, 2019
1 parent 5403b4f commit fb529c1
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 10 deletions.
3 changes: 3 additions & 0 deletions DcpmPkg/cli/Common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,9 @@ MatchCliReturnCode(
case NVM_ERR_REGION_GOAL_NAMESPACE_EXISTS:
case NVM_ERR_REGION_REMAINING_SIZE_NOT_IN_LAST_PROPERTY:
case NVM_ERR_ARS_IN_PROGRESS:
case NVM_ERR_FWUPDATE_IN_PROGRESS:
case NVM_ERR_OVERWRITE_DIMM_IN_PROGRESS:
case NVM_ERR_UNKNOWN_LONG_OP_IN_PROGRESS:
case NVM_ERR_APPDIRECT_IN_SYSTEM:
case NVM_ERR_OPERATION_NOT_SUPPORTED_BY_MIXED_SKU:
case NVM_ERR_SECURE_ERASE_NAMESPACE_EXISTS:
Expand Down
3 changes: 3 additions & 0 deletions DcpmPkg/common/NvmSharedDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ typedef enum _NvmStatusCode {

NVM_SUCCESS_NO_EVENT_FOUND = 302, ///< Error: No events found in the event log
NVM_ERR_FILE_NOT_FOUND = 303, ///< Error: No events found in the event log
NVM_ERR_OVERWRITE_DIMM_IN_PROGRESS = 304, ///< Error: No events found in the event log
NVM_ERR_FWUPDATE_IN_PROGRESS = 305, ///< Error: No events found in the event log
NVM_ERR_UNKNOWN_LONG_OP_IN_PROGRESS = 306, ///< Error: No events found in the event log
NVM_LAST_STATUS_VALUE
} NvmStatusCode;

Expand Down
6 changes: 6 additions & 0 deletions DcpmPkg/common/NvmStatus.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,12 @@ GetSingleNvmStatusCodeMessage(

case NVM_ERR_ARS_IN_PROGRESS:
return HiiGetString(HiiHandle, STRING_TOKEN(STR_DCPMM_STATUS_ERR_ARS_IN_PROGRESS), NULL);
case NVM_ERR_FWUPDATE_IN_PROGRESS:
return HiiGetString(HiiHandle, STRING_TOKEN(STR_DCPMM_STATUS_ERR_FWUPDATE_IN_PROGRESS), NULL);
case NVM_ERR_OVERWRITE_DIMM_IN_PROGRESS:
return HiiGetString(HiiHandle, STRING_TOKEN(STR_DCPMM_STATUS_ERR_OVERWRITE_DIMM_IN_PROGRESS), NULL);
case NVM_ERR_UNKNOWN_LONG_OP_IN_PROGRESS:
return HiiGetString(HiiHandle, STRING_TOKEN(STR_DCPMM_STATUS_ERR_UNKNOWN_LONG_OP_IN_PROGRESS), NULL);

case NVM_ERR_APPDIRECT_IN_SYSTEM:
return HiiGetString(HiiHandle, STRING_TOKEN(STR_DCPMM_STATUS_ERR_APPDIRECT_IN_SYSTEM), NULL);
Expand Down
Binary file modified DcpmPkg/common/NvmStatus.uni
Binary file not shown.
96 changes: 86 additions & 10 deletions DcpmPkg/driver/Protocol/Driver/NvmDimmConfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -5307,6 +5307,9 @@ UpdateFw(
UINT32 VerificationFailures = 0;
UINT32 ForceRequiredDimms = 0;

EFI_STATUS LongOpStatusReturnCode = 0;
NVM_STATUS LongOpNvmStatus = NVM_ERR_OPERATION_NOT_STARTED;

ZeroMem(pDimms, sizeof(pDimms));

NVDIMM_ENTRY();
Expand Down Expand Up @@ -5429,7 +5432,6 @@ UpdateFw(
}
else {
pDimmsCanBeUpdated[Index] = TRUE;
DimmsToUpdate++;
SetObjStatusForDimmWithErase(pCommandStatus, pDimms[Index], NVM_SUCCESS_IMAGE_EXAMINE_OK, TRUE);
}
#endif
Expand All @@ -5451,7 +5453,6 @@ UpdateFw(
}
else {
pDimmsCanBeUpdated[Index] = TRUE;
DimmsToUpdate++;
SetObjStatusForDimmWithErase(pCommandStatus, pDimms[Index], NVM_SUCCESS_IMAGE_EXAMINE_OK, TRUE);
}
}
Expand All @@ -5464,6 +5465,14 @@ UpdateFw(
goto Finish;
}

//count up the number of DIMMs to update
DimmsToUpdate = 0;
for (Index = 0; Index < DimmsNum; Index++) {
if (pDimmsCanBeUpdated[Index] == TRUE) {
DimmsToUpdate++;
}
}

if (DimmsToUpdate == 0) {
if (pCommandStatus->GeneralStatus == NVM_ERR_OPERATION_NOT_STARTED) {
NVDIMM_DBG("Found no DIMMs to update - either none were passed or none passed the verification checks");
Expand All @@ -5475,7 +5484,7 @@ UpdateFw(
// upload FW image to all specified DIMMs
for (Index = 0; Index < DimmsNum; Index++) {
if (pDimmsCanBeUpdated[Index] == FALSE) {
NVDIMM_DBG("Skipping dimm %d. It is marked as not being capable of this update", pDimms[Index]->DeviceHandle.AsUint32);
NVDIMM_DBG("Skipping dimm %d. It is marked as not being currently capable of this update", pDimms[Index]->DeviceHandle.AsUint32);
continue;
}

Expand All @@ -5492,14 +5501,23 @@ UpdateFw(

if (ReturnCode != EFI_SUCCESS) {
UpdateFailures++;
if (NvmStatus == NVM_SUCCESS) {
pCommandStatus->GeneralStatus = NVM_ERR_OPERATION_FAILED;
SetObjStatusForDimmWithErase(pCommandStatus, pDimms[Index], NVM_ERR_OPERATION_FAILED, TRUE);

//Perform a check to see if it was a long operation that blocked the update and get more details about it
LongOpStatusReturnCode = CheckForLongOpStatusInProgress(pDimms[Index], &LongOpNvmStatus);
if (LongOpStatusReturnCode == EFI_SUCCESS && LongOpNvmStatus != NVM_SUCCESS) {
pCommandStatus->GeneralStatus = LongOpNvmStatus;
SetObjStatusForDimmWithErase(pCommandStatus, pDimms[Index], LongOpNvmStatus, TRUE);
}
else
{
pCommandStatus->GeneralStatus = NvmStatus;
SetObjStatusForDimmWithErase(pCommandStatus, pDimms[Index], NvmStatus, TRUE);
else {
if (NvmStatus == NVM_SUCCESS) {
pCommandStatus->GeneralStatus = NVM_ERR_OPERATION_FAILED;
SetObjStatusForDimmWithErase(pCommandStatus, pDimms[Index], NVM_ERR_OPERATION_FAILED, TRUE);
}
else
{
pCommandStatus->GeneralStatus = NvmStatus;
SetObjStatusForDimmWithErase(pCommandStatus, pDimms[Index], NvmStatus, TRUE);
}
}
}
else
Expand Down Expand Up @@ -5533,6 +5551,64 @@ UpdateFw(
return ReturnCode;
}

/**
Examine a given DIMM to see if a long op is in progress and report it back
@param[in] pDimm The dimm to check the status of
@param[out] pNvmStatus The status of the dimm's long op status. NVM_SUCCESS = No long op status is under way.
@retval EFI_SUCCESS if the request for long op status was successful (whether a long op status is under way or not)
@retval EFI_... the error preventing the check for the long op status
**/
EFI_STATUS
CheckForLongOpStatusInProgress(
IN DIMM *pDimm,
OUT NVM_STATUS *pNvmStatus
)
{
EFI_STATUS ReturnCode = EFI_SUCCESS;
UINT8 LongOpStatusCode = 0;
PT_OUTPUT_PAYLOAD_FW_LONG_OP_STATUS LongOpStatus;
EFI_STATUS LongOpCheckRetCode = EFI_SUCCESS;

NVDIMM_ENTRY();

if (pNvmStatus == NULL) {
ReturnCode = EFI_INVALID_PARAMETER;
goto Finish;
}

*pNvmStatus = NVM_SUCCESS;
LongOpCheckRetCode = FwCmdGetLongOperationStatus(pDimm, &LongOpStatusCode, &LongOpStatus);
if (EFI_ERROR(LongOpCheckRetCode)) {
//fatal error
*pNvmStatus = NVM_ERR_UNKNOWN;
ReturnCode = LongOpCheckRetCode;
goto Finish;
}
else if (LongOpStatus.Status != FW_DEVICE_BUSY) {
//no long op in progress
goto Finish;
}

if (LongOpStatus.CmdOpcode == PtGetFeatures && LongOpStatus.CmdSubcode == SubopAddressRangeScrub) {
*pNvmStatus = NVM_ERR_ARS_IN_PROGRESS;
}
else if (LongOpStatus.CmdOpcode == PtUpdateFw && LongOpStatus.CmdSubcode == SubopUpdateFw) {
*pNvmStatus = NVM_ERR_FWUPDATE_IN_PROGRESS;
}
else if (LongOpStatus.CmdOpcode == PtSetSecInfo && LongOpStatus.CmdSubcode == SubopOverwriteDimm) {
*pNvmStatus = NVM_ERR_OVERWRITE_DIMM_IN_PROGRESS;
}
else {
*pNvmStatus = NVM_ERR_UNKNOWN_LONG_OP_IN_PROGRESS;
}

Finish:
NVDIMM_EXIT_I64(ReturnCode);
return ReturnCode;
}

/**
Filter a list of dimms by a given socket and return an array of dimms
that exist on a given socket
Expand Down
15 changes: 15 additions & 0 deletions DcpmPkg/driver/Protocol/Driver/NvmDimmConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -1478,6 +1478,21 @@ VerifyTargetDimms(
OUT COMMAND_STATUS *pCommandStatus
);

/**
Examine a given DIMM to see if a long op is in progress and report it back
@param[in] pDimm The dimm to check the status of
@param[out] pNvmStatus The status of the dimm's long op status. NVM_SUCCESS = No long op status is under way.
@retval EFI_SUCCESS if the request for long op status was successful (whether a long op status is under way or not)
@retval EFI_... the error preventing the check for the long op status
**/
EFI_STATUS
CheckForLongOpStatusInProgress(
IN DIMM *pDimm,
OUT NVM_STATUS *pNvmStatus
);

// Debug Only
#ifndef MDEPKG_NDEBUG

Expand Down

0 comments on commit fb529c1

Please sign in to comment.