Skip to content

Commit

Permalink
NVDIMM: poll for updated SET_EVENT_NOTIFICATION_STATUS in nvdimmArm
Browse files Browse the repository at this point in the history
Add some wait time/poll between the SET_EVENT_NOTIFICATION command
and read of the status to allow time for the command to complete.
Command sent directly by hostboot didn't allow for enough
time for completion by the nvdimm controller.  Now allow up to 1ms
for command to complete.

Change-Id: If63556856b93449fa9bc7eb8cffd3344b6620e98
CQ:SW485933
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/92148
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Corey V Swenson <cswenson@us.ibm.com>
Reviewed-by: TSUNG K YEUNG <tyeung@us.ibm.com>
Reviewed-by: Daniel M Crowell <dcrowell@us.ibm.com>
  • Loading branch information
mderkse1 authored and dcrowell77 committed Feb 25, 2020
1 parent 921a602 commit d45a939
Showing 1 changed file with 27 additions and 8 deletions.
35 changes: 27 additions & 8 deletions src/usr/isteps/nvdimm/nvdimm.C
Expand Up @@ -5415,17 +5415,36 @@ bool nvdimmArm(TargetHandleList &i_nvdimmTargetList)
break;
}

// Check notification status and errors
l_err = nvdimmReadReg(l_nvdimm, SET_EVENT_NOTIFICATION_STATUS, l_data);
// Poll for a status update since it might not be updated immediately
// Status update should be valid by 1ms (usual range: 300 - 400 us)
// A non-zero means the status has been updated
l_data = 0x00;
int status_wait_time = NS_PER_MSEC; // wait 1 msec
while (l_data == 0x00 && status_wait_time > 0)
{
// Check notification status and errors
l_err = nvdimmReadReg(l_nvdimm, SET_EVENT_NOTIFICATION_STATUS, l_data);
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"NVDIMM[%X] read of SET_EVENT_NOTIFICATION_STATUS failed (%d ns remained)",
get_huid(l_nvdimm), status_wait_time);
break;
}
nanosleep(0, NS_PER_MSEC/10); // sleep 100us (.1 ms) between reads
status_wait_time -= (NS_PER_MSEC/10);
}
// if error found from nvdimmReadReg
if (l_err)
{
// i2c read failure, exit main nvdimmArm() loop
break;
}
else if (((l_data & SET_EVENT_NOTIFICATION_ERROR) == SET_EVENT_NOTIFICATION_ERROR)
|| ((l_data & NOTIFICATIONS_ENABLED) != NOTIFICATIONS_ENABLED))

if (((l_data & SET_EVENT_NOTIFICATION_ERROR) == SET_EVENT_NOTIFICATION_ERROR)
|| ((l_data & NOTIFICATIONS_ENABLED) != NOTIFICATIONS_ENABLED))
{
TRACFCOMP(g_trac_nvdimm, "nvdimmArm() nvdimm[%X] failed to set event notification",
get_huid(l_nvdimm));
TRACFCOMP(g_trac_nvdimm, "nvdimmArm() nvdimm[%X] failed to set event notification (last status: 0x%02X)",
get_huid(l_nvdimm), l_data);

// Set NVDIMM Status flag to partial working, as error detected but data might persist
notifyNvdimmProtectionChange(l_nvdimm, NVDIMM_RISKY_HW_ERROR);
Expand All @@ -5436,7 +5455,7 @@ bool nvdimmArm(TargetHandleList &i_nvdimmTargetList)
*@severity ERRORLOG_SEV_PREDICTIVE
*@moduleid NVDIMM_SET_EVENT_NOTIFICATION
*@userdata1[0:31] Target Huid
*@userdata2 <UNUSED>
*@userdata2 SET_EVENT_NOTIFICATION_STATUS
*@devdesc NVDIMM threw an error or failed to set event
* notifications during arming
*@custdesc NVDIMM failed to enable event notificaitons
Expand All @@ -5445,7 +5464,7 @@ bool nvdimmArm(TargetHandleList &i_nvdimmTargetList)
NVDIMM_SET_EVENT_NOTIFICATION,
NVDIMM_SET_EVENT_NOTIFICATION_ERROR,
TARGETING::get_huid(l_nvdimm),
0x0,
l_data,
ERRORLOG::ErrlEntry::NO_SW_CALLOUT );

l_err->collectTrace( NVDIMM_COMP_NAME );
Expand Down

0 comments on commit d45a939

Please sign in to comment.