From 796876fdaefe504a2f3abe7445d57e886a2af139 Mon Sep 17 00:00:00 2001 From: Justin Tee Date: Wed, 1 Mar 2023 15:16:24 -0800 Subject: scsi: lpfc: Revise lpfc_error_lost_link() reason code evaluation logic Extended status reason code errors should mask off the IOERR_PARAM_MASK before checking strict equalities for IOERR values. Update the lpfc_error_lost_link() routine as such. Signed-off-by: Justin Tee Link: https://lore.kernel.org/r/20230301231626.9621-9-justintee8345@gmail.com Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_crtn.h | 2 ++ drivers/scsi/lpfc/lpfc_ct.c | 4 ++-- drivers/scsi/lpfc/lpfc_els.c | 14 +++++++------- drivers/scsi/lpfc/lpfc_hbadisc.c | 35 +++++++++++++++++++++++++++++++++++ drivers/scsi/lpfc/lpfc_hw.h | 12 ------------ 5 files changed, 46 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 976fd5ee7f7e..b833b983e69d 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -458,6 +458,8 @@ void lpfc_get_cfgparam(struct lpfc_hba *); void lpfc_get_vport_cfgparam(struct lpfc_vport *); int lpfc_alloc_sysfs_attr(struct lpfc_vport *); void lpfc_free_sysfs_attr(struct lpfc_vport *); +bool lpfc_error_lost_link(struct lpfc_vport *vport, u32 ulp_status, + u32 ulp_word4); extern const struct attribute_group *lpfc_hba_groups[]; extern const struct attribute_group *lpfc_vport_groups[]; extern struct scsi_host_template lpfc_template; diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index e290aff2e881..c6e10e23f342 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -958,7 +958,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_vport_set_state(vport, FC_VPORT_FAILED); goto out; } - if (lpfc_error_lost_link(ulp_status, ulp_word4)) { + if (lpfc_error_lost_link(vport, ulp_status, ulp_word4)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "0226 NS query failed due to link event: " "ulp_status x%x ulp_word4 x%x fc_flag x%x " @@ -1181,7 +1181,7 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_vport_set_state(vport, FC_VPORT_FAILED); goto out; } - if (lpfc_error_lost_link(ulp_status, ulp_word4)) { + if (lpfc_error_lost_link(vport, ulp_status, ulp_word4)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "4166 NS query failed due to link event: " "ulp_status x%x ulp_word4 x%x fc_flag x%x " diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 9f50f6116627..6a15f879e517 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1088,7 +1088,7 @@ stop_rr_fcf_flogi: } /* Do not register VFI if the driver aborted FLOGI */ - if (!lpfc_error_lost_link(ulp_status, ulp_word4)) + if (!lpfc_error_lost_link(vport, ulp_status, ulp_word4)) lpfc_issue_reg_vfi(vport); lpfc_nlp_put(ndlp); @@ -1207,7 +1207,7 @@ flogifail: phba->fcf.fcf_flag &= ~FCF_DISCOVERY; spin_unlock_irq(&phba->hbalock); - if (!lpfc_error_lost_link(ulp_status, ulp_word4)) { + if (!lpfc_error_lost_link(vport, ulp_status, ulp_word4)) { /* FLOGI failed, so just use loop map to make discovery list */ lpfc_disc_list_loopmap(vport); @@ -2087,7 +2087,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ulp_word4); /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ - if (!lpfc_error_lost_link(ulp_status, ulp_word4)) + if (!lpfc_error_lost_link(vport, ulp_status, ulp_word4)) lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_PLOGI); @@ -2383,7 +2383,7 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ndlp->fc4_prli_sent); /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ - if (!lpfc_error_lost_link(ulp_status, ulp_word4)) + if (!lpfc_error_lost_link(vport, ulp_status, ulp_word4)) lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_PRLI); @@ -3038,7 +3038,7 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ndlp->nlp_DID, ulp_status, ulp_word4); - if (lpfc_error_lost_link(ulp_status, ulp_word4)) + if (lpfc_error_lost_link(vport, ulp_status, ulp_word4)) skip_recovery = 1; } @@ -4930,7 +4930,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if ((cmd == ELS_CMD_FLOGI) && (phba->fc_topology != LPFC_TOPOLOGY_LOOP) && - !lpfc_error_lost_link(ulp_status, ulp_word4)) { + !lpfc_error_lost_link(vport, ulp_status, ulp_word4)) { /* FLOGI retry policy */ retry = 1; /* retry FLOGI forever */ @@ -4944,7 +4944,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, else if (cmdiocb->retry >= 32) delay = 1000; } else if ((cmd == ELS_CMD_FDISC) && - !lpfc_error_lost_link(ulp_status, ulp_word4)) { + !lpfc_error_lost_link(vport, ulp_status, ulp_word4)) { /* retry FDISCs every second up to devloss */ retry = 1; maxretry = vport->cfg_devloss_tmo; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 11ba26ac495a..5ba3a9ad9501 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -7269,3 +7269,38 @@ lpfc_parse_fcoe_conf(struct lpfc_hba *phba, lpfc_read_fcf_conn_tbl(phba, rec_ptr); } + +/* + * lpfc_error_lost_link - IO failure from link event or FW reset check. + * + * @vport: Pointer to lpfc_vport data structure. + * @ulp_status: IO completion status. + * @ulp_word4: Reason code for the ulp_status. + * + * This function evaluates the ulp_status and ulp_word4 values + * for specific error values that indicate an internal link fault + * or fw reset event for the completing IO. Callers require this + * common data to decide next steps on the IO. + * + * Return: + * false - No link or reset error occurred. + * true - A link or reset error occurred. + */ +bool +lpfc_error_lost_link(struct lpfc_vport *vport, u32 ulp_status, u32 ulp_word4) +{ + /* Mask off the extra port data to get just the reason code. */ + u32 rsn_code = IOERR_PARAM_MASK & ulp_word4; + + if (ulp_status == IOSTAT_LOCAL_REJECT && + (rsn_code == IOERR_SLI_ABORTED || + rsn_code == IOERR_LINK_DOWN || + rsn_code == IOERR_SLI_DOWN)) { + lpfc_printf_vlog(vport, KERN_WARNING, LOG_SLI | LOG_ELS, + "0408 Report link error true: \n", + ulp_status, ulp_word4); + return true; + } + + return false; +} diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 5c283936ff08..e9244bedb0f4 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -4435,16 +4435,4 @@ lpfc_is_LC_HBA(unsigned short device) return 0; } -/* - * Determine if failed because of a link event or firmware reset. - */ -static inline int -lpfc_error_lost_link(u32 ulp_status, u32 ulp_word4) -{ - return (ulp_status == IOSTAT_LOCAL_REJECT && - (ulp_word4 == IOERR_SLI_ABORTED || - ulp_word4 == IOERR_LINK_DOWN || - ulp_word4 == IOERR_SLI_DOWN)); -} - #define BPL_ALIGN_SZ 8 /* 8 byte alignment for bpl and mbufs */ -- cgit v1.2.3