|
@@ -235,10 +235,7 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
|
|
(iocb->iocb_cmpl) (phba, iocb, iocb);
|
|
(iocb->iocb_cmpl) (phba, iocb, iocb);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
- /* If we are delaying issuing an ELS command, cancel it */
|
|
|
|
- if (ndlp->nlp_flag & NLP_DELAY_TMO)
|
|
|
|
- lpfc_cancel_retry_delay_tmo(phba->pport, ndlp);
|
|
|
|
|
|
+ lpfc_cancel_retry_delay_tmo(phba->pport, ndlp);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -249,7 +246,6 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
|
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
|
struct lpfc_hba *phba = vport->phba;
|
|
struct lpfc_hba *phba = vport->phba;
|
|
struct lpfc_dmabuf *pcmd;
|
|
struct lpfc_dmabuf *pcmd;
|
|
- struct lpfc_work_evt *evtp;
|
|
|
|
uint32_t *lp;
|
|
uint32_t *lp;
|
|
IOCB_t *icmd;
|
|
IOCB_t *icmd;
|
|
struct serv_parm *sp;
|
|
struct serv_parm *sp;
|
|
@@ -425,73 +421,8 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|
ndlp, mbox);
|
|
ndlp, mbox);
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
-
|
|
|
|
- /* If the remote NPort logs into us, before we can initiate
|
|
|
|
- * discovery to them, cleanup the NPort from discovery accordingly.
|
|
|
|
- */
|
|
|
|
- if (ndlp->nlp_state == NLP_STE_NPR_NODE) {
|
|
|
|
- spin_lock_irq(shost->host_lock);
|
|
|
|
- ndlp->nlp_flag &= ~NLP_DELAY_TMO;
|
|
|
|
- spin_unlock_irq(shost->host_lock);
|
|
|
|
- del_timer_sync(&ndlp->nlp_delayfunc);
|
|
|
|
- ndlp->nlp_last_elscmd = 0;
|
|
|
|
-
|
|
|
|
- if (!list_empty(&ndlp->els_retry_evt.evt_listp)) {
|
|
|
|
- list_del_init(&ndlp->els_retry_evt.evt_listp);
|
|
|
|
- /* Decrement ndlp reference count held for the
|
|
|
|
- * delayed retry
|
|
|
|
- */
|
|
|
|
- evtp = &ndlp->els_retry_evt;
|
|
|
|
- lpfc_nlp_put((struct lpfc_nodelist *)evtp->evt_arg1);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
|
|
|
|
- spin_lock_irq(shost->host_lock);
|
|
|
|
- ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
|
|
|
|
- spin_unlock_irq(shost->host_lock);
|
|
|
|
-
|
|
|
|
- if ((ndlp->nlp_flag & NLP_ADISC_SND) &&
|
|
|
|
- (vport->num_disc_nodes)) {
|
|
|
|
- /* Check to see if there are more
|
|
|
|
- * ADISCs to be sent
|
|
|
|
- */
|
|
|
|
- lpfc_more_adisc(vport);
|
|
|
|
-
|
|
|
|
- if ((vport->num_disc_nodes == 0) &&
|
|
|
|
- (vport->fc_npr_cnt))
|
|
|
|
- lpfc_els_disc_plogi(vport);
|
|
|
|
-
|
|
|
|
- if (vport->num_disc_nodes == 0) {
|
|
|
|
- spin_lock_irq(shost->host_lock);
|
|
|
|
- vport->fc_flag &= ~FC_NDISC_ACTIVE;
|
|
|
|
- spin_unlock_irq(shost->host_lock);
|
|
|
|
- lpfc_can_disctmo(vport);
|
|
|
|
- lpfc_end_rscn(vport);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } else if ((ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) &&
|
|
|
|
- (ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
|
|
|
|
- (vport->num_disc_nodes)) {
|
|
|
|
- spin_lock_irq(shost->host_lock);
|
|
|
|
- ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
|
|
|
|
- spin_unlock_irq(shost->host_lock);
|
|
|
|
- /* Check to see if there are more
|
|
|
|
- * PLOGIs to be sent
|
|
|
|
- */
|
|
|
|
- lpfc_more_plogi(vport);
|
|
|
|
- if (vport->num_disc_nodes == 0) {
|
|
|
|
- spin_lock_irq(shost->host_lock);
|
|
|
|
- vport->fc_flag &= ~FC_NDISC_ACTIVE;
|
|
|
|
- spin_unlock_irq(shost->host_lock);
|
|
|
|
- lpfc_can_disctmo(vport);
|
|
|
|
- lpfc_end_rscn(vport);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox);
|
|
lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox);
|
|
return 1;
|
|
return 1;
|
|
-
|
|
|
|
out:
|
|
out:
|
|
stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
|
|
stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
|
|
stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE;
|
|
stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE;
|
|
@@ -574,7 +505,9 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|
else
|
|
else
|
|
lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
|
|
lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
|
|
|
|
|
|
- if (!(ndlp->nlp_type & NLP_FABRIC) ||
|
|
|
|
|
|
+ if ((!(ndlp->nlp_type & NLP_FABRIC) &&
|
|
|
|
+ ((ndlp->nlp_type & NLP_FCP_TARGET) ||
|
|
|
|
+ !(ndlp->nlp_type & NLP_FCP_INITIATOR))) ||
|
|
(ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) {
|
|
(ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) {
|
|
/* Only try to re-login if this is NOT a Fabric Node */
|
|
/* Only try to re-login if this is NOT a Fabric Node */
|
|
mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
|
|
mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
|
|
@@ -751,6 +684,7 @@ static uint32_t
|
|
lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|
lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|
void *arg, uint32_t evt)
|
|
void *arg, uint32_t evt)
|
|
{
|
|
{
|
|
|
|
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
|
struct lpfc_hba *phba = vport->phba;
|
|
struct lpfc_hba *phba = vport->phba;
|
|
struct lpfc_iocbq *cmdiocb = arg;
|
|
struct lpfc_iocbq *cmdiocb = arg;
|
|
struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
|
|
struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
|
|
@@ -776,7 +710,22 @@ lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
|
|
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
|
|
NULL);
|
|
NULL);
|
|
} else {
|
|
} else {
|
|
- lpfc_rcv_plogi(vport, ndlp, cmdiocb);
|
|
|
|
|
|
+ if (lpfc_rcv_plogi(vport, ndlp, cmdiocb) &&
|
|
|
|
+ (ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
|
|
|
|
+ (vport->num_disc_nodes)) {
|
|
|
|
+ spin_lock_irq(shost->host_lock);
|
|
|
|
+ ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
|
|
|
|
+ spin_unlock_irq(shost->host_lock);
|
|
|
|
+ /* Check if there are more PLOGIs to be sent */
|
|
|
|
+ lpfc_more_plogi(vport);
|
|
|
|
+ if (vport->num_disc_nodes == 0) {
|
|
|
|
+ spin_lock_irq(shost->host_lock);
|
|
|
|
+ vport->fc_flag &= ~FC_NDISC_ACTIVE;
|
|
|
|
+ spin_unlock_irq(shost->host_lock);
|
|
|
|
+ lpfc_can_disctmo(vport);
|
|
|
|
+ lpfc_end_rscn(vport);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
} /* If our portname was less */
|
|
} /* If our portname was less */
|
|
|
|
|
|
return ndlp->nlp_state;
|
|
return ndlp->nlp_state;
|
|
@@ -1040,6 +989,7 @@ static uint32_t
|
|
lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|
lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|
void *arg, uint32_t evt)
|
|
void *arg, uint32_t evt)
|
|
{
|
|
{
|
|
|
|
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
|
struct lpfc_hba *phba = vport->phba;
|
|
struct lpfc_hba *phba = vport->phba;
|
|
struct lpfc_iocbq *cmdiocb;
|
|
struct lpfc_iocbq *cmdiocb;
|
|
|
|
|
|
@@ -1048,9 +998,28 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|
|
|
|
|
cmdiocb = (struct lpfc_iocbq *) arg;
|
|
cmdiocb = (struct lpfc_iocbq *) arg;
|
|
|
|
|
|
- if (lpfc_rcv_plogi(vport, ndlp, cmdiocb))
|
|
|
|
- return ndlp->nlp_state;
|
|
|
|
|
|
+ if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
|
|
|
|
+ if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
|
|
|
|
+ spin_lock_irq(shost->host_lock);
|
|
|
|
+ ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
|
|
|
|
+ spin_unlock_irq(shost->host_lock);
|
|
|
|
|
|
|
|
+ if (vport->num_disc_nodes) {
|
|
|
|
+ lpfc_more_adisc(vport);
|
|
|
|
+ if ((vport->num_disc_nodes == 0) &&
|
|
|
|
+ (vport->fc_npr_cnt))
|
|
|
|
+ lpfc_els_disc_plogi(vport);
|
|
|
|
+ if (vport->num_disc_nodes == 0) {
|
|
|
|
+ spin_lock_irq(shost->host_lock);
|
|
|
|
+ vport->fc_flag &= ~FC_NDISC_ACTIVE;
|
|
|
|
+ spin_unlock_irq(shost->host_lock);
|
|
|
|
+ lpfc_can_disctmo(vport);
|
|
|
|
+ lpfc_end_rscn(vport);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return ndlp->nlp_state;
|
|
|
|
+ }
|
|
ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
|
|
ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
|
|
lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
|
|
lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
|
|
lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
|
|
lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
|
|
@@ -1742,24 +1711,21 @@ lpfc_rcv_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|
struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
|
|
struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
|
|
|
|
|
|
/* Ignore PLOGI if we have an outstanding LOGO */
|
|
/* Ignore PLOGI if we have an outstanding LOGO */
|
|
- if (ndlp->nlp_flag & (NLP_LOGO_SND | NLP_LOGO_ACC)) {
|
|
|
|
|
|
+ if (ndlp->nlp_flag & (NLP_LOGO_SND | NLP_LOGO_ACC))
|
|
return ndlp->nlp_state;
|
|
return ndlp->nlp_state;
|
|
- }
|
|
|
|
-
|
|
|
|
if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
|
|
if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
|
|
|
|
+ lpfc_cancel_retry_delay_tmo(vport, ndlp);
|
|
spin_lock_irq(shost->host_lock);
|
|
spin_lock_irq(shost->host_lock);
|
|
- ndlp->nlp_flag &= ~NLP_NPR_ADISC;
|
|
|
|
|
|
+ ndlp->nlp_flag &= ~(NLP_NPR_ADISC | NLP_NPR_2B_DISC);
|
|
spin_unlock_irq(shost->host_lock);
|
|
spin_unlock_irq(shost->host_lock);
|
|
- return ndlp->nlp_state;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* send PLOGI immediately, move to PLOGI issue state */
|
|
|
|
- if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
|
|
|
|
- ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
|
|
|
|
- lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
|
|
|
|
- lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
|
|
|
|
|
|
+ } else if (!(ndlp->nlp_flag & NLP_NPR_2B_DISC)) {
|
|
|
|
+ /* send PLOGI immediately, move to PLOGI issue state */
|
|
|
|
+ if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
|
|
|
|
+ ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
|
|
|
|
+ lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
|
|
|
|
+ lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-
|
|
|
|
return ndlp->nlp_state;
|
|
return ndlp->nlp_state;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1810,7 +1776,6 @@ lpfc_rcv_padisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|
struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
|
|
struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
|
|
|
|
|
|
lpfc_rcv_padisc(vport, ndlp, cmdiocb);
|
|
lpfc_rcv_padisc(vport, ndlp, cmdiocb);
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* Do not start discovery if discovery is about to start
|
|
* Do not start discovery if discovery is about to start
|
|
* or discovery in progress for this node. Starting discovery
|
|
* or discovery in progress for this node. Starting discovery
|
|
@@ -1973,9 +1938,7 @@ lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
|
spin_lock_irq(shost->host_lock);
|
|
spin_lock_irq(shost->host_lock);
|
|
ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
|
|
ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
|
|
spin_unlock_irq(shost->host_lock);
|
|
spin_unlock_irq(shost->host_lock);
|
|
- if (ndlp->nlp_flag & NLP_DELAY_TMO) {
|
|
|
|
- lpfc_cancel_retry_delay_tmo(vport, ndlp);
|
|
|
|
- }
|
|
|
|
|
|
+ lpfc_cancel_retry_delay_tmo(vport, ndlp);
|
|
return ndlp->nlp_state;
|
|
return ndlp->nlp_state;
|
|
}
|
|
}
|
|
|
|
|