[SCSI] lpfc 8.1.4 : Fixed RSCN handling when a PLOGI is in retry
authorJames Smart <James.Smart@Emulex.Com>
Tue, 7 Mar 2006 20:04:01 +0000 (15:04 -0500)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Sun, 12 Mar 2006 14:56:13 +0000 (08:56 -0600)
Fixed RSCN handling when a PLOGI is in retry.

Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_nportdisc.c

index 7b6534a1c315957eeb638261ec9b6568fc7db337..f716c1d85f41369d19a093e65b7656187cdc1191 100644 (file)
@@ -84,6 +84,7 @@ int lpfc_els_rsp_adisc_acc(struct lpfc_hba *, struct lpfc_iocbq *,
                           struct lpfc_nodelist *);
 int lpfc_els_rsp_prli_acc(struct lpfc_hba *, struct lpfc_iocbq *,
                          struct lpfc_nodelist *);
+void lpfc_cancel_retry_delay_tmo(struct lpfc_hba *, struct lpfc_nodelist *);
 void lpfc_els_retry_delay(unsigned long);
 void lpfc_els_retry_delay_handler(struct lpfc_nodelist *);
 void lpfc_els_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
index efba875e53e455c6896870cc7d57187f1121abf1..6d12cd0c49ff0ad78df2f09d26cf427855eae6dc 100644 (file)
@@ -1434,6 +1434,46 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
        return 0;
 }
 
+void
+lpfc_cancel_retry_delay_tmo(struct lpfc_hba *phba, struct lpfc_nodelist * nlp)
+{
+       nlp->nlp_flag &= ~NLP_DELAY_TMO;
+       del_timer_sync(&nlp->nlp_delayfunc);
+       nlp->nlp_last_elscmd = 0;
+
+       if (!list_empty(&nlp->els_retry_evt.evt_listp))
+               list_del_init(&nlp->els_retry_evt.evt_listp);
+
+       if (nlp->nlp_flag & NLP_NPR_2B_DISC) {
+               nlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+               if (phba->num_disc_nodes) {
+                       /* Check to see if there are more
+                        * PLOGIs to be sent
+                        */
+                       lpfc_more_plogi(phba);
+               }
+
+               if (phba->num_disc_nodes == 0) {
+                       phba->fc_flag &= ~FC_NDISC_ACTIVE;
+                       lpfc_can_disctmo(phba);
+                       if (phba->fc_flag & FC_RSCN_MODE) {
+                               /* Check to see if more RSCNs
+                                * came in while we were
+                                * processing this one.
+                                */
+                               if((phba->fc_rscn_id_cnt==0) &&
+                                  (!(phba->fc_flag & FC_RSCN_DISCOVERY))) {
+                                       phba->fc_flag &= ~FC_RSCN_MODE;
+                               }
+                               else {
+                                       lpfc_els_handle_rscn(phba);
+                               }
+                       }
+               }
+       }
+       return;
+}
+
 void
 lpfc_els_retry_delay(unsigned long ptr)
 {
@@ -2415,15 +2455,8 @@ lpfc_rscn_recovery_check(struct lpfc_hba * phba)
                        /* Make sure NLP_DELAY_TMO is NOT running
                         * after a device recovery event.
                         */
-                       if (ndlp->nlp_flag & NLP_DELAY_TMO) {
-                               ndlp->nlp_flag &= ~NLP_DELAY_TMO;
-                               ndlp->nlp_last_elscmd = 0;
-                               del_timer_sync(&ndlp->nlp_delayfunc);
-                               if (!list_empty(&ndlp->
-                                               els_retry_evt.evt_listp))
-                                       list_del_init(&ndlp->
-                                               els_retry_evt.evt_listp);
-                       }
+                       if (ndlp->nlp_flag & NLP_DELAY_TMO)
+                               lpfc_cancel_retry_delay_tmo(phba, ndlp);
                }
        }
        return 0;
index 2b227b363ae366cbebe0462e730b33fde7df1d59..e15120d21aaaadf872a70f1d6735a31d6c8434ce 100644 (file)
@@ -1152,13 +1152,9 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
                /* Stop delay tmo if taking node off NPR list */
                if ((nlp->nlp_flag & NLP_DELAY_TMO) &&
                   (list != NLP_NPR_LIST)) {
-                       nlp->nlp_flag &= ~NLP_DELAY_TMO;
-                       nlp->nlp_last_elscmd = 0;
                        spin_unlock_irq(phba->host->host_lock);
-                       del_timer_sync(&nlp->nlp_delayfunc);
+                       lpfc_cancel_retry_delay_tmo(phba, nlp);
                        spin_lock_irq(phba->host->host_lock);
-                       if (!list_empty(&nlp->els_retry_evt.evt_listp))
-                               list_del_init(&nlp->els_retry_evt.evt_listp);
                }
                break;
        }
@@ -1598,13 +1594,7 @@ lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
 
 
        if (ndlp->nlp_flag & NLP_DELAY_TMO) {
-               spin_lock_irq(phba->host->host_lock);
-               ndlp->nlp_flag &= ~NLP_DELAY_TMO;
-               spin_unlock_irq(phba->host->host_lock);
-               ndlp->nlp_last_elscmd = 0;
-               del_timer_sync(&ndlp->nlp_delayfunc);
-               if (!list_empty(&ndlp->els_retry_evt.evt_listp))
-                       list_del_init(&ndlp->els_retry_evt.evt_listp);
+               lpfc_cancel_retry_delay_tmo(phba, ndlp);
        }
 
        if (ndlp->nlp_disc_refcnt) {
@@ -1896,14 +1886,8 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did)
                        /* Since this node is marked for discovery,
                         * delay timeout is not needed.
                         */
-                       if (ndlp->nlp_flag & NLP_DELAY_TMO) {
-                               ndlp->nlp_flag &= ~NLP_DELAY_TMO;
-                               del_timer_sync(&ndlp->nlp_delayfunc);
-                               if (!list_empty(&ndlp->els_retry_evt.
-                                                               evt_listp))
-                                       list_del_init(&ndlp->els_retry_evt.
-                                                               evt_listp);
-                       }
+                       if (ndlp->nlp_flag & NLP_DELAY_TMO)
+                               lpfc_cancel_retry_delay_tmo(phba, ndlp);
                } else {
                        ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
                        ndlp = NULL;
index 8affc1543c6e170cfe731d7fd3090afe44a37aee..3d77bd999b70bca83daa57bad3f051a515ad444c 100644 (file)
@@ -259,13 +259,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
        } while(found);
 
        /* If we are delaying issuing an ELS command, cancel it */
-       if (ndlp->nlp_flag & NLP_DELAY_TMO) {
-               ndlp->nlp_flag &= ~NLP_DELAY_TMO;
-               ndlp->nlp_last_elscmd = 0;
-               del_timer_sync(&ndlp->nlp_delayfunc);
-               if (!list_empty(&ndlp->els_retry_evt.evt_listp))
-                       list_del_init(&ndlp->els_retry_evt.evt_listp);
-       }
+       if (ndlp->nlp_flag & NLP_DELAY_TMO)
+               lpfc_cancel_retry_delay_tmo(phba, ndlp);
        return 0;
 }
 
@@ -1496,7 +1491,7 @@ lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba,
 
        if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) {
                spin_lock_irq(phba->host->host_lock);
-               ndlp->nlp_flag &= ~(NLP_NPR_ADISC | NLP_NPR_2B_DISC);
+               ndlp->nlp_flag &= ~NLP_NPR_ADISC;
                spin_unlock_irq(phba->host->host_lock);
                return ndlp->nlp_state;
        }
@@ -1693,16 +1688,10 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba,
 {
        spin_lock_irq(phba->host->host_lock);
        ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+       spin_unlock_irq(phba->host->host_lock);
        if (ndlp->nlp_flag & NLP_DELAY_TMO) {
-               ndlp->nlp_flag &= ~NLP_DELAY_TMO;
-               if (!list_empty(&ndlp->els_retry_evt.evt_listp))
-                       list_del_init(&ndlp->els_retry_evt.evt_listp);
-               spin_unlock_irq(phba->host->host_lock);
-               ndlp->nlp_last_elscmd = 0;
-               del_timer_sync(&ndlp->nlp_delayfunc);
-               return ndlp->nlp_state;
+               lpfc_cancel_retry_delay_tmo(phba, ndlp);
        }
-       spin_unlock_irq(phba->host->host_lock);
        return ndlp->nlp_state;
 }