scsi: lpfc: Revise lpfc_error_lost_link() reason code evaluation logic
authorJustin Tee <justin.tee@broadcom.com>
Wed, 1 Mar 2023 23:16:24 +0000 (15:16 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 10 Mar 2023 02:21:45 +0000 (21:21 -0500)
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 <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20230301231626.9621-9-justintee8345@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_ct.c
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_hw.h

index 976fd5ee7f7e775c6729a88bc09cfb11daf16d6b..b833b983e69d8c53e929943864051aafb42df490 100644 (file)
@@ -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;
index e290aff2e881761b4ea7e9424f5b2bdf18ba05f7..c6e10e23f3424e4a30e748fc1b364eb039030926 100644 (file)
@@ -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 "
index 9f50f611662728a6513691302bd654c745b13236..6a15f879e5173e5369eca9262ff55782cd73053e 100644 (file)
@@ -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;
index 11ba26ac495a7abec6a3b6e72eba6062de27d7bf..5ba3a9ad95016cd52961ff6a94f4e27308b5a00b 100644 (file)
@@ -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: <x%x:x%x>\n",
+                                ulp_status, ulp_word4);
+               return true;
+       }
+
+       return false;
+}
index 5c283936ff08eb19cc1ae255081f40750261ea25..e9244bedb0f4a148f88ccb8efcdd6744743038dd 100644 (file)
@@ -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 */