Driver is hitting null pring pointers in lpfc_do_work().

Pointer assignment occurs based on SLI-revision. If recovering after
an error, its possible the sli revision for the port was cleared,
making the lpfc_phba_elsring() not return a ring pointer, thus
the null pointer.

Add SLI revision checking to lpfc_phba_elsring() and status checking
to all callers.

Signed-off-by: Dick Kennedy <dick.kenn...@broadcom.com>
Signed-off-by: James Smart <jsmart2...@gmail.com>
---
 drivers/scsi/lpfc/lpfc.h      | 6 ++++++
 drivers/scsi/lpfc/lpfc_els.c  | 2 ++
 drivers/scsi/lpfc/lpfc_init.c | 7 ++++++-
 drivers/scsi/lpfc/lpfc_sli.c  | 2 ++
 4 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index c23c29b451c2..b37e0caf0781 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -1277,6 +1277,12 @@ lpfc_sli_read_hs(struct lpfc_hba *phba)
 static inline struct lpfc_sli_ring *
 lpfc_phba_elsring(struct lpfc_hba *phba)
 {
+       /* Return NULL if sli_rev has become invalid due to bad fw */
+       if (phba->sli_rev != LPFC_SLI_REV4  &&
+           phba->sli_rev != LPFC_SLI_REV3  &&
+           phba->sli_rev != LPFC_SLI_REV2)
+               return NULL;
+
        if (phba->sli_rev == LPFC_SLI_REV4) {
                if (phba->sli4_hba.els_wq)
                        return phba->sli4_hba.els_wq->pring;
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 902234a1fcfb..3f21338d95d1 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -1343,6 +1343,8 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba)
                        Fabric_DID);
 
        pring = lpfc_phba_elsring(phba);
+       if (unlikely(!pring))
+               return -EIO;
 
        /*
         * Check the txcmplq for an iocb that matches the nport the driver is
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index e95a768575b0..647a037d6f4d 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1797,7 +1797,12 @@ lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int 
mbx_action,
        lpfc_offline(phba);
        /* release interrupt for possible resource change */
        lpfc_sli4_disable_intr(phba);
-       lpfc_sli_brdrestart(phba);
+       rc = lpfc_sli_brdrestart(phba);
+       if (rc) {
+               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                               "6309 Failed to restart board\n");
+               return rc;
+       }
        /* request and enable interrupt */
        intr_mode = lpfc_sli4_enable_intr(phba, phba->intr_mode);
        if (intr_mode == LPFC_INTR_ERROR) {
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 353652fbc954..9821ab81c2f9 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -4687,6 +4687,8 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba)
        hba_aer_enabled = phba->hba_flag & HBA_AER_ENABLED;
 
        rc = lpfc_sli4_brdreset(phba);
+       if (rc)
+               return rc;
 
        spin_lock_irq(&phba->hbalock);
        phba->pport->stopped = 0;
-- 
2.13.7

Reply via email to