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>
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 *,
}
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)
{
struct lpfc_nodelist *ndlp;
/* 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;
/* 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;
}
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) {
/* 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;
} 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;
}
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;
}
{
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;
}