Commit fdcebe28 authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.1.4 : Fixed RSCN handling when a PLOGI is in retry



Fixed RSCN handling when a PLOGI is in retry.

Signed-off-by: default avatarJames Smart <James.Smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 488d1469
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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 *,
+42 −9
Original line number Diff line number Diff line
@@ -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;
+4 −20
Original line number Diff line number Diff line
@@ -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;
+5 −16
Original line number Diff line number Diff line
@@ -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;
	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;
	if (ndlp->nlp_flag & NLP_DELAY_TMO) {
		lpfc_cancel_retry_delay_tmo(phba, ndlp);
	}
	spin_unlock_irq(phba->host->host_lock);
	return ndlp->nlp_state;
}