> On Apr 19, 2021, at 6:01 AM, Kashyap Desai <kashyap.desai@xxxxxxxxxxxx> wrote: > > This operation requests that the IOC update the TimeStamp. > > When the I/O Unit is powered on, it sets the TimeStamp field value to > 0x0000_0000_0000_0000 and increments the current value every millisecond. > A host driver sets the TimeStamp field to the current time by using an > IOCInit request. The TimeStamp field is periodically updated by host driver. > > Signed-off-by: Kashyap Desai <kashyap.desai@xxxxxxxxxxxx> > Reviewed-by: Hannes Reinecke <hare@xxxxxxx> > Reviewed-by: Tomas Henzl <thenzl@xxxxxxxxxx> > > Cc: sathya.prakash@xxxxxxxxxxxx > --- > drivers/scsi/mpi3mr/mpi3mr.h | 3 ++ > drivers/scsi/mpi3mr/mpi3mr_fw.c | 74 +++++++++++++++++++++++++++++++++ > 2 files changed, 77 insertions(+) > > diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h > index d18bfb954bc4..801612c9eb2a 100644 > --- a/drivers/scsi/mpi3mr/mpi3mr.h > +++ b/drivers/scsi/mpi3mr/mpi3mr.h > @@ -99,6 +99,7 @@ extern struct list_head mrioc_list; > #define MPI3MR_PORTENABLE_TIMEOUT 300 > #define MPI3MR_RESETTM_TIMEOUT 30 > #define MPI3MR_RESET_HOST_IOWAIT_TIMEOUT 5 > +#define MPI3MR_TSUPDATE_INTERVAL 900 > #define MPI3MR_DEFAULT_SHUTDOWN_TIME 120 > > #define MPI3MR_WATCHDOG_INTERVAL 1000 /* in milli seconds */ > @@ -631,6 +632,7 @@ struct scmd_priv { > * @dev_handle_bitmap_sz: Device handle bitmap size > * @removepend_bitmap: Remove pending bitmap > * @delayed_rmhs_list: Delayed device removal list > + * @ts_update_counter: Timestamp update counter > * @fault_dbg: Fault debug flag > * @reset_in_progress: Reset in progress flag > * @unrecoverable: Controller unrecoverable flag > @@ -753,6 +755,7 @@ struct mpi3mr_ioc { > void *removepend_bitmap; > struct list_head delayed_rmhs_list; > > + u32 ts_update_counter; > u8 fault_dbg; > u8 reset_in_progress; > u8 unrecoverable; > diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c > index a74eb4914c9d..4e28a0efb082 100644 > --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c > +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c > @@ -1482,6 +1482,74 @@ int mpi3mr_op_request_post(struct mpi3mr_ioc *mrioc, > return retval; > } > > +/** > + * mpi3mr_sync_timestamp - Issue time stamp sync request > + * @mrioc: Adapter reference > + * > + * Issue IO unit control MPI request to synchornize firmware > + * timestamp with host time. > + * > + * Return: 0 on success, non-zero on failure. > + */ > +static int mpi3mr_sync_timestamp(struct mpi3mr_ioc *mrioc) > +{ > + ktime_t current_time; > + Mpi3IoUnitControlRequest_t iou_ctrl; > + int retval = 0; > + > + memset(&iou_ctrl, 0, sizeof(iou_ctrl)); > + mutex_lock(&mrioc->init_cmds.mutex); > + if (mrioc->init_cmds.state & MPI3MR_CMD_PENDING) { > + retval = -1; > + ioc_err(mrioc, "Issue IOUCTL TimeStamp: command is in use\n"); > + mutex_unlock(&mrioc->init_cmds.mutex); > + goto out; > + } > + mrioc->init_cmds.state = MPI3MR_CMD_PENDING; > + mrioc->init_cmds.is_waiting = 1; > + mrioc->init_cmds.callback = NULL; > + iou_ctrl.HostTag = cpu_to_le16(MPI3MR_HOSTTAG_INITCMDS); > + iou_ctrl.Function = MPI3_FUNCTION_IO_UNIT_CONTROL; > + iou_ctrl.Operation = MPI3_CTRL_OP_UPDATE_TIMESTAMP; > + current_time = ktime_get_real(); > + iou_ctrl.Param64[0] = cpu_to_le64(ktime_to_ms(current_time)); > + > + init_completion(&mrioc->init_cmds.done); > + retval = mpi3mr_admin_request_post(mrioc, &iou_ctrl, > + sizeof(iou_ctrl), 0); > + if (retval) { > + ioc_err(mrioc, "Issue IOUCTL TimeStamp: Admin Post failed\n"); > + goto out_unlock; > + } > + > + wait_for_completion_timeout(&mrioc->init_cmds.done, > + (MPI3MR_INTADMCMD_TIMEOUT * HZ)); > + if (!(mrioc->init_cmds.state & MPI3MR_CMD_COMPLETE)) { > + ioc_err(mrioc, "Issue IOUCTL TimeStamp: command timed out\n"); > + mrioc->init_cmds.is_waiting = 0; > + mpi3mr_soft_reset_handler(mrioc, > + MPI3MR_RESET_FROM_TSU_TIMEOUT, 1); > + retval = -1; > + goto out_unlock; > + } > + if ((mrioc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK) > + != MPI3_IOCSTATUS_SUCCESS) { > + ioc_err(mrioc, > + "Issue IOUCTL TimeStamp: Failed IOCStatus(0x%04x) Loginfo(0x%08x)\n", > + (mrioc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK), > + mrioc->init_cmds.ioc_loginfo); > + retval = -1; > + goto out_unlock; > + } > + > +out_unlock: > + mrioc->init_cmds.state = MPI3MR_CMD_NOTUSED; > + mutex_unlock(&mrioc->init_cmds.mutex); > + > +out: > + return retval; > +} > + > /** > * mpi3mr_watchdog_work - watchdog thread to monitor faults > * @work: work struct > @@ -1500,6 +1568,11 @@ static void mpi3mr_watchdog_work(struct work_struct *work) > enum mpi3mr_iocstate ioc_state; > u32 fault, host_diagnostic; > > + if (mrioc->ts_update_counter++ >= MPI3MR_TSUPDATE_INTERVAL) { > + mrioc->ts_update_counter = 0; > + mpi3mr_sync_timestamp(mrioc); > + } > + > /*Check for fault state every one second and issue Soft reset*/ > ioc_state = mpi3mr_get_iocstate(mrioc); > if (ioc_state == MRIOC_STATE_FAULT) { > @@ -3313,6 +3386,7 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc, > mrioc->reset_in_progress = 0; > scsi_unblock_requests(mrioc->shost); > mpi3mr_rfresh_tgtdevs(mrioc); > + mrioc->ts_update_counter = 0; > spin_lock_irqsave(&mrioc->watchdog_lock, flags); > if (mrioc->watchdog_work_q) > queue_delayed_work(mrioc->watchdog_work_q, > -- > 2.18.1 > Reviewed-by: Himanshu Madhani <himanshu.madhani@xxxxxxxxxx> -- Himanshu Madhani Oracle Linux Engineering