Commit c9f8735b authored by Jamie Wellnitz's avatar Jamie Wellnitz Committed by James Bottomley

[SCSI] lpfc 8.1.2: Misc FC Discovery changes :

Misc FC Discovery changes :
   - Added FC_BYPASSED_MODE statistic
   - Corrected some log message data
   - Fix up Discovery infrastructure to support FAN:
       Allow Fabric entities to flow thru DSM
       Fix up linkup/linkdown unregister login processing for Fabric entities
       Clean up Discovery code
       Utilize nodev_tmo for Fabric entities
   - Use of 3 * ratov for CT handling timeouts
   - Fix up DSM to make more appropriate decisions and clean up code.
Signed-off-by: default avatarJamie Wellnitz <Jamie.Wellnitz@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent b28485ac
...@@ -247,6 +247,7 @@ struct lpfc_hba { ...@@ -247,6 +247,7 @@ struct lpfc_hba {
#define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */
#define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */
#define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */ #define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */
#define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */
uint32_t fc_topology; /* link topology, from LINK INIT */ uint32_t fc_topology; /* link topology, from LINK INIT */
......
...@@ -260,8 +260,10 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp, ...@@ -260,8 +260,10 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp,
icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL; icmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL;
icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP; icmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP;
if (!tmo) if (!tmo) {
tmo = (2 * phba->fc_ratov) + 1; /* FC spec states we need 3 * ratov for CT requests */
tmo = (3 * phba->fc_ratov);
}
icmd->ulpTimeout = tmo; icmd->ulpTimeout = tmo;
icmd->ulpBdeCount = 1; icmd->ulpBdeCount = 1;
icmd->ulpLe = 1; icmd->ulpLe = 1;
...@@ -449,6 +451,11 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -449,6 +451,11 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
CTrsp = (struct lpfc_sli_ct_request *) outp->virt; CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
if (CTrsp->CommandResponse.bits.CmdRsp == if (CTrsp->CommandResponse.bits.CmdRsp ==
be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) { be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) {
lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
"%d:0239 NameServer Rsp "
"Data: x%x\n",
phba->brd_no,
phba->fc_flag);
lpfc_ns_rsp(phba, outp, lpfc_ns_rsp(phba, outp,
(uint32_t) (irsp->un.genreq64.bdl.bdeSize)); (uint32_t) (irsp->un.genreq64.bdl.bdeSize));
} else if (CTrsp->CommandResponse.bits.CmdRsp == } else if (CTrsp->CommandResponse.bits.CmdRsp ==
......
...@@ -92,7 +92,7 @@ lpfc_els_chk_latt(struct lpfc_hba * phba) ...@@ -92,7 +92,7 @@ lpfc_els_chk_latt(struct lpfc_hba * phba)
} }
} }
return (1); return 1;
} }
...@@ -235,7 +235,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, ...@@ -235,7 +235,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
ndlp->nlp_DID, icmd->ulpIoTag, cmdSize); ndlp->nlp_DID, icmd->ulpIoTag, cmdSize);
} }
return (elsiocb); return elsiocb;
} }
...@@ -446,9 +446,10 @@ lpfc_cmpl_els_flogi(struct lpfc_hba * phba, ...@@ -446,9 +446,10 @@ lpfc_cmpl_els_flogi(struct lpfc_hba * phba,
lpfc_printf_log(phba, lpfc_printf_log(phba,
KERN_INFO, KERN_INFO,
LOG_ELS, LOG_ELS,
"%d:0100 FLOGI failure Data: x%x x%x\n", "%d:0100 FLOGI failure Data: x%x x%x x%x\n",
phba->brd_no, phba->brd_no,
irsp->ulpStatus, irsp->un.ulpWord[4]); irsp->ulpStatus, irsp->un.ulpWord[4],
irsp->ulpTimeout);
goto flogifail; goto flogifail;
} }
...@@ -517,7 +518,7 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -517,7 +518,7 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm));
if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry,
ndlp, ELS_CMD_FLOGI)) == 0) { ndlp, ELS_CMD_FLOGI)) == 0) {
return (1); return 1;
} }
icmd = &elsiocb->iocb; icmd = &elsiocb->iocb;
...@@ -552,9 +553,9 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -552,9 +553,9 @@ lpfc_issue_els_flogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
if (rc == IOCB_ERROR) { if (rc == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return (1); return 1;
} }
return (0); return 0;
} }
int int
...@@ -611,29 +612,21 @@ lpfc_initial_flogi(struct lpfc_hba * phba) ...@@ -611,29 +612,21 @@ lpfc_initial_flogi(struct lpfc_hba * phba)
{ {
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
/* First look for Fabric ndlp on the unmapped list */ /* First look for the Fabric ndlp */
ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, Fabric_DID);
if ((ndlp = if (!ndlp) {
lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED,
Fabric_DID)) == 0) {
/* Cannot find existing Fabric ndlp, so allocate a new one */ /* Cannot find existing Fabric ndlp, so allocate a new one */
if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
== 0) { if (!ndlp)
return (0); return 0;
}
lpfc_nlp_init(phba, ndlp, Fabric_DID); lpfc_nlp_init(phba, ndlp, Fabric_DID);
} } else {
else { lpfc_nlp_list(phba, ndlp, NLP_JUST_DQ);
phba->fc_unmap_cnt--;
list_del(&ndlp->nlp_listp);
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~NLP_LIST_MASK;
spin_unlock_irq(phba->host->host_lock);
} }
if (lpfc_issue_els_flogi(phba, ndlp, 0)) { if (lpfc_issue_els_flogi(phba, ndlp, 0)) {
mempool_free( ndlp, phba->nlp_mem_pool); mempool_free( ndlp, phba->nlp_mem_pool);
} }
return (1); return 1;
} }
static void static void
...@@ -675,22 +668,23 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -675,22 +668,23 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
irsp = &rspiocb->iocb; irsp = &rspiocb->iocb;
ndlp = (struct lpfc_nodelist *) cmdiocb->context1; ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~NLP_PLOGI_SND;
spin_unlock_irq(phba->host->host_lock);
/* Since ndlp can be freed in the disc state machine, note if this node /* Since ndlp can be freed in the disc state machine, note if this node
* is being used during discovery. * is being used during discovery.
*/ */
disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~(NLP_PLOGI_SND | NLP_NPR_2B_DISC);
spin_unlock_irq(phba->host->host_lock);
rc = 0; rc = 0;
/* PLOGI completes to NPort <nlp_DID> */ /* PLOGI completes to NPort <nlp_DID> */
lpfc_printf_log(phba, KERN_INFO, LOG_ELS, lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
"%d:0102 PLOGI completes to NPort x%x " "%d:0102 PLOGI completes to NPort x%x "
"Data: x%x x%x x%x x%x\n", "Data: x%x x%x x%x x%x x%x\n",
phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus,
irsp->un.ulpWord[4], disc, phba->num_disc_nodes); irsp->un.ulpWord[4], irsp->ulpTimeout, disc,
phba->num_disc_nodes);
/* Check to see if link went down during discovery */ /* Check to see if link went down during discovery */
if (lpfc_els_chk_latt(phba)) { if (lpfc_els_chk_latt(phba)) {
...@@ -722,7 +716,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -722,7 +716,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
(irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
(irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); rc = NLP_STE_FREED_NODE;
} }
else { else {
rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb,
...@@ -747,18 +741,11 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -747,18 +741,11 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
lpfc_more_plogi(phba); lpfc_more_plogi(phba);
} }
if (rc != NLP_STE_FREED_NODE) { if (phba->num_disc_nodes == 0) {
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; phba->fc_flag &= ~FC_NDISC_ACTIVE;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
}
if (phba->num_disc_nodes == 0) {
if(disc) {
spin_lock_irq(phba->host->host_lock);
phba->fc_flag &= ~FC_NDISC_ACTIVE;
spin_unlock_irq(phba->host->host_lock);
}
lpfc_can_disctmo(phba); lpfc_can_disctmo(phba);
if (phba->fc_flag & FC_RSCN_MODE) { if (phba->fc_flag & FC_RSCN_MODE) {
/* Check to see if more RSCNs came in while we were /* Check to see if more RSCNs came in while we were
...@@ -796,10 +783,10 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -796,10 +783,10 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm));
if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp,
ndlp, ELS_CMD_PLOGI)) == 0) { ELS_CMD_PLOGI);
return (1); if (!elsiocb)
} return 1;
icmd = &elsiocb->iocb; icmd = &elsiocb->iocb;
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
...@@ -824,10 +811,10 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -824,10 +811,10 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
ndlp->nlp_flag &= ~NLP_PLOGI_SND; ndlp->nlp_flag &= ~NLP_PLOGI_SND;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return (1); return 1;
} }
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return (0); return 0;
} }
static void static void
...@@ -851,9 +838,10 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -851,9 +838,10 @@ lpfc_cmpl_els_prli(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
/* PRLI completes to NPort <nlp_DID> */ /* PRLI completes to NPort <nlp_DID> */
lpfc_printf_log(phba, KERN_INFO, LOG_ELS, lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
"%d:0103 PRLI completes to NPort x%x " "%d:0103 PRLI completes to NPort x%x "
"Data: x%x x%x x%x\n", "Data: x%x x%x x%x x%x\n",
phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus,
irsp->un.ulpWord[4], phba->num_disc_nodes); irsp->un.ulpWord[4], irsp->ulpTimeout,
phba->num_disc_nodes);
phba->fc_prli_sent--; phba->fc_prli_sent--;
/* Check to see if link went down during discovery */ /* Check to see if link went down during discovery */
...@@ -906,7 +894,7 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -906,7 +894,7 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
cmdsize = (sizeof (uint32_t) + sizeof (PRLI)); cmdsize = (sizeof (uint32_t) + sizeof (PRLI));
if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry,
ndlp, ELS_CMD_PRLI)) == 0) { ndlp, ELS_CMD_PRLI)) == 0) {
return (1); return 1;
} }
icmd = &elsiocb->iocb; icmd = &elsiocb->iocb;
...@@ -943,11 +931,11 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -943,11 +931,11 @@ lpfc_issue_els_prli(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
ndlp->nlp_flag &= ~NLP_PRLI_SND; ndlp->nlp_flag &= ~NLP_PRLI_SND;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return (1); return 1;
} }
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
phba->fc_prli_sent++; phba->fc_prli_sent++;
return (0); return 0;
} }
static void static void
...@@ -1016,21 +1004,22 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1016,21 +1004,22 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
irsp = &(rspiocb->iocb); irsp = &(rspiocb->iocb);
ndlp = (struct lpfc_nodelist *) cmdiocb->context1; ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~NLP_ADISC_SND;
spin_unlock_irq(phba->host->host_lock);
/* Since ndlp can be freed in the disc state machine, note if this node /* Since ndlp can be freed in the disc state machine, note if this node
* is being used during discovery. * is being used during discovery.
*/ */
disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC); disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~(NLP_ADISC_SND | NLP_NPR_2B_DISC);
spin_unlock_irq(phba->host->host_lock);
/* ADISC completes to NPort <nlp_DID> */ /* ADISC completes to NPort <nlp_DID> */
lpfc_printf_log(phba, KERN_INFO, LOG_ELS, lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
"%d:0104 ADISC completes to NPort x%x " "%d:0104 ADISC completes to NPort x%x "
"Data: x%x x%x x%x x%x\n", "Data: x%x x%x x%x x%x x%x\n",
phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus,
irsp->un.ulpWord[4], disc, phba->num_disc_nodes); irsp->un.ulpWord[4], irsp->ulpTimeout, disc,
phba->num_disc_nodes);
/* Check to see if link went down during discovery */ /* Check to see if link went down during discovery */
if (lpfc_els_chk_latt(phba)) { if (lpfc_els_chk_latt(phba)) {
...@@ -1054,13 +1043,10 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1054,13 +1043,10 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
} }
/* ADISC failed */ /* ADISC failed */
/* Do not call DSM for lpfc_els_abort'ed ELS cmds */ /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && if ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) ||
((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || ((irsp->un.ulpWord[4] != IOERR_SLI_ABORTED) &&
(irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || (irsp->un.ulpWord[4] != IOERR_LINK_DOWN) &&
(irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { (irsp->un.ulpWord[4] != IOERR_SLI_DOWN))) {
disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
}
else {
lpfc_disc_state_machine(phba, ndlp, cmdiocb, lpfc_disc_state_machine(phba, ndlp, cmdiocb,
NLP_EVT_CMPL_ADISC); NLP_EVT_CMPL_ADISC);
} }
...@@ -1112,9 +1098,6 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1112,9 +1098,6 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
} }
} }
} }
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
spin_unlock_irq(phba->host->host_lock);
out: out:
lpfc_els_free_iocb(phba, cmdiocb); lpfc_els_free_iocb(phba, cmdiocb);
return; return;
...@@ -1138,7 +1121,7 @@ lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -1138,7 +1121,7 @@ lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
cmdsize = (sizeof (uint32_t) + sizeof (ADISC)); cmdsize = (sizeof (uint32_t) + sizeof (ADISC));
if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry,
ndlp, ELS_CMD_ADISC)) == 0) { ndlp, ELS_CMD_ADISC)) == 0) {
return (1); return 1;
} }
icmd = &elsiocb->iocb; icmd = &elsiocb->iocb;
...@@ -1163,10 +1146,10 @@ lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -1163,10 +1146,10 @@ lpfc_issue_els_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
ndlp->nlp_flag &= ~NLP_ADISC_SND; ndlp->nlp_flag &= ~NLP_ADISC_SND;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return (1); return 1;
} }
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return (0); return 0;
} }
static void static void
...@@ -1190,9 +1173,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1190,9 +1173,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
/* LOGO completes to NPort <nlp_DID> */ /* LOGO completes to NPort <nlp_DID> */
lpfc_printf_log(phba, KERN_INFO, LOG_ELS, lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
"%d:0105 LOGO completes to NPort x%x " "%d:0105 LOGO completes to NPort x%x "
"Data: x%x x%x x%x\n", "Data: x%x x%x x%x x%x\n",
phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus, phba->brd_no, ndlp->nlp_DID, irsp->ulpStatus,
irsp->un.ulpWord[4], phba->num_disc_nodes); irsp->un.ulpWord[4], irsp->ulpTimeout,
phba->num_disc_nodes);
/* Check to see if link went down during discovery */ /* Check to see if link went down during discovery */
if (lpfc_els_chk_latt(phba)) if (lpfc_els_chk_latt(phba))
...@@ -1247,7 +1231,7 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -1247,7 +1231,7 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
cmdsize = 2 * (sizeof (uint32_t) + sizeof (struct lpfc_name)); cmdsize = 2 * (sizeof (uint32_t) + sizeof (struct lpfc_name));
if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry,
ndlp, ELS_CMD_LOGO)) == 0) { ndlp, ELS_CMD_LOGO)) == 0) {
return (1); return 1;
} }
icmd = &elsiocb->iocb; icmd = &elsiocb->iocb;
...@@ -1268,10 +1252,10 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -1268,10 +1252,10 @@ lpfc_issue_els_logo(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
ndlp->nlp_flag &= ~NLP_LOGO_SND; ndlp->nlp_flag &= ~NLP_LOGO_SND;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return (1); return 1;
} }
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return (0); return 0;
} }
static void static void
...@@ -1286,9 +1270,10 @@ lpfc_cmpl_els_cmd(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1286,9 +1270,10 @@ lpfc_cmpl_els_cmd(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
lpfc_printf_log(phba, lpfc_printf_log(phba,
KERN_INFO, KERN_INFO,
LOG_ELS, LOG_ELS,
"%d:0106 ELS cmd tag x%x completes Data: x%x x%x\n", "%d:0106 ELS cmd tag x%x completes Data: x%x x%x x%x\n",
phba->brd_no, phba->brd_no,
irsp->ulpIoTag, irsp->ulpStatus, irsp->un.ulpWord[4]); irsp->ulpIoTag, irsp->ulpStatus,
irsp->un.ulpWord[4], irsp->ulpTimeout);
/* Check to see if link went down during discovery */ /* Check to see if link went down during discovery */
lpfc_els_chk_latt(phba); lpfc_els_chk_latt(phba);
...@@ -1310,16 +1295,16 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) ...@@ -1310,16 +1295,16 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
psli = &phba->sli; psli = &phba->sli;
pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
cmdsize = (sizeof (uint32_t) + sizeof (SCR)); cmdsize = (sizeof (uint32_t) + sizeof (SCR));
if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) == 0) { ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
return (1); if (!ndlp)
} return 1;
lpfc_nlp_init(phba, ndlp, nportid); lpfc_nlp_init(phba, ndlp, nportid);
if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry,
ndlp, ELS_CMD_SCR)) == 0) { ndlp, ELS_CMD_SCR)) == 0) {
mempool_free( ndlp, phba->nlp_mem_pool); mempool_free( ndlp, phba->nlp_mem_pool);
return (1); return 1;
} }
icmd = &elsiocb->iocb; icmd = &elsiocb->iocb;
...@@ -1339,11 +1324,11 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) ...@@ -1339,11 +1324,11 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
mempool_free( ndlp, phba->nlp_mem_pool); mempool_free( ndlp, phba->nlp_mem_pool);
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return (1); return 1;
} }
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
mempool_free( ndlp, phba->nlp_mem_pool); mempool_free( ndlp, phba->nlp_mem_pool);
return (0); return 0;
} }
static int static int
...@@ -1363,15 +1348,15 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) ...@@ -1363,15 +1348,15 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
psli = &phba->sli; psli = &phba->sli;
pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
cmdsize = (sizeof (uint32_t) + sizeof (FARP)); cmdsize = (sizeof (uint32_t) + sizeof (FARP));
if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) == 0) { ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
return (1); if (!ndlp)
} return 1;
lpfc_nlp_init(phba, ndlp, nportid); lpfc_nlp_init(phba, ndlp, nportid);
if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, if ((elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry,
ndlp, ELS_CMD_RNID)) == 0) { ndlp, ELS_CMD_RNID)) == 0) {
mempool_free( ndlp, phba->nlp_mem_pool); mempool_free( ndlp, phba->nlp_mem_pool);
return (1); return 1;
} }
icmd = &elsiocb->iocb; icmd = &elsiocb->iocb;
...@@ -1405,11 +1390,11 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) ...@@ -1405,11 +1390,11 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry)
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
mempool_free( ndlp, phba->nlp_mem_pool); mempool_free( ndlp, phba->nlp_mem_pool);
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return (1); return 1;
} }
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
mempool_free( ndlp, phba->nlp_mem_pool); mempool_free( ndlp, phba->nlp_mem_pool);
return (0); return 0;
} }
void void
...@@ -1541,11 +1526,6 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1541,11 +1526,6 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
case IOERR_SEQUENCE_TIMEOUT: case IOERR_SEQUENCE_TIMEOUT:
retry = 1; retry = 1;
if ((cmd == ELS_CMD_FLOGI)
&& (phba->fc_topology != TOPOLOGY_LOOP)) {
delay = 1;
maxretry = 48;
}
break; break;
case IOERR_NO_RESOURCES: case IOERR_NO_RESOURCES:
...@@ -1654,32 +1634,32 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1654,32 +1634,32 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
ndlp->nlp_last_elscmd = cmd; ndlp->nlp_last_elscmd = cmd;
return (1); return 1;
} }
switch (cmd) { switch (cmd) {
case ELS_CMD_FLOGI: case ELS_CMD_FLOGI:
lpfc_issue_els_flogi(phba, ndlp, cmdiocb->retry); lpfc_issue_els_flogi(phba, ndlp, cmdiocb->retry);
return (1); return 1;
case ELS_CMD_PLOGI: case ELS_CMD_PLOGI:
ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
lpfc_issue_els_plogi(phba, ndlp, cmdiocb->retry); lpfc_issue_els_plogi(phba, ndlp, cmdiocb->retry);
return (1); return 1;
case ELS_CMD_ADISC: case ELS_CMD_ADISC:
ndlp->nlp_state = NLP_STE_ADISC_ISSUE; ndlp->nlp_state = NLP_STE_ADISC_ISSUE;
lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST);
lpfc_issue_els_adisc(phba, ndlp, cmdiocb->retry); lpfc_issue_els_adisc(phba, ndlp, cmdiocb->retry);
return (1); return 1;
case ELS_CMD_PRLI: case ELS_CMD_PRLI:
ndlp->nlp_state = NLP_STE_PRLI_ISSUE; ndlp->nlp_state = NLP_STE_PRLI_ISSUE;
lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST);
lpfc_issue_els_prli(phba, ndlp, cmdiocb->retry); lpfc_issue_els_prli(phba, ndlp, cmdiocb->retry);
return (1); return 1;
case ELS_CMD_LOGO: case ELS_CMD_LOGO:
ndlp->nlp_state = NLP_STE_NPR_NODE; ndlp->nlp_state = NLP_STE_NPR_NODE;
lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
lpfc_issue_els_logo(phba, ndlp, cmdiocb->retry); lpfc_issue_els_logo(phba, ndlp, cmdiocb->retry);
return (1); return 1;
} }
} }
...@@ -1690,7 +1670,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1690,7 +1670,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
phba->brd_no, phba->brd_no,
cmd, ndlp->nlp_DID, cmdiocb->retry, ndlp->nlp_flag); cmd, ndlp->nlp_DID, cmdiocb->retry, ndlp->nlp_flag);
return (0); return 0;
} }
int int
...@@ -1780,11 +1760,12 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1780,11 +1760,12 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
/* ELS response tag <ulpIoTag> completes */ /* ELS response tag <ulpIoTag> completes */
lpfc_printf_log(phba, KERN_INFO, LOG_ELS, lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
"%d:0110 ELS response tag x%x completes " "%d:0110 ELS response tag x%x completes "
"Data: x%x x%x x%x x%x x%x x%x\n", "Data: x%x x%x x%x x%x x%x x%x x%x\n",
phba->brd_no, phba->brd_no,
cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus, cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus,
rspiocb->iocb.un.ulpWord[4], ndlp->nlp_DID, rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout,
ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
ndlp->nlp_rpi);
if (mbox) { if (mbox) {
if ((rspiocb->iocb.ulpStatus == 0) if ((rspiocb->iocb.ulpStatus == 0)
...@@ -1846,7 +1827,7 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, ...@@ -1846,7 +1827,7 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
if ((elsiocb = if ((elsiocb =
lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
ndlp, ELS_CMD_ACC)) == 0) { ndlp, ELS_CMD_ACC)) == 0) {
return (1); return 1;
} }
icmd = &elsiocb->iocb; icmd = &elsiocb->iocb;
icmd->ulpContext = oldcmd->ulpContext; /* Xri */ icmd->ulpContext = oldcmd->ulpContext; /* Xri */
...@@ -1859,7 +1840,7 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, ...@@ -1859,7 +1840,7 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
if ((elsiocb = if ((elsiocb =
lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
ndlp, ELS_CMD_ACC)) == 0) { ndlp, ELS_CMD_ACC)) == 0) {
return (1); return 1;
} }
icmd = &elsiocb->iocb; icmd = &elsiocb->iocb;
icmd->ulpContext = oldcmd->ulpContext; /* Xri */ icmd->ulpContext = oldcmd->ulpContext; /* Xri */
...@@ -1873,7 +1854,7 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, ...@@ -1873,7 +1854,7 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm)); memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm));
break; break;
default: default:
return (1); return 1;
} }
if (newnode) if (newnode)
...@@ -1889,6 +1870,9 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, ...@@ -1889,6 +1870,9 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
if (ndlp->nlp_flag & NLP_LOGO_ACC) { if (ndlp->nlp_flag & NLP_LOGO_ACC) {
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~NLP_LOGO_ACC;
spin_unlock_irq(phba->host->host_lock);
elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc; elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc;
} else { } else {
elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; elsiocb->iocb_cmpl = lpfc_cmpl_els_acc;
...@@ -1900,9 +1884,9 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, ...@@ -1900,9 +1884,9 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
if (rc == IOCB_ERROR) { if (rc == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return (1); return 1;
} }
return (0); return 0;
} }
int int
...@@ -1924,7 +1908,7 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError, ...@@ -1924,7 +1908,7 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError,
cmdsize = 2 * sizeof (uint32_t); cmdsize = 2 * sizeof (uint32_t);
if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
ndlp, ELS_CMD_LS_RJT)) == 0) { ndlp, ELS_CMD_LS_RJT)) == 0) {
return (1); return 1;
} }
icmd = &elsiocb->iocb; icmd = &elsiocb->iocb;
...@@ -1952,9 +1936,9 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError, ...@@ -1952,9 +1936,9 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError,
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
if (rc == IOCB_ERROR) { if (rc == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return (1); return 1;
} }
return (0); return 0;
} }
int int
...@@ -1977,7 +1961,7 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba, ...@@ -1977,7 +1961,7 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba,
cmdsize = sizeof (uint32_t) + sizeof (ADISC); cmdsize = sizeof (uint32_t) + sizeof (ADISC);
if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
ndlp, ELS_CMD_ACC)) == 0) { ndlp, ELS_CMD_ACC)) == 0) {
return (1); return 1;
} }
/* Xmit ADISC ACC response tag <ulpIoTag> */ /* Xmit ADISC ACC response tag <ulpIoTag> */
...@@ -2010,9 +1994,9 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba, ...@@ -2010,9 +1994,9 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba,
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
if (rc == IOCB_ERROR) { if (rc == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return (1); return 1;
} }
return (0); return 0;
} }
int int
...@@ -2034,13 +2018,10 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba * phba, ...@@ -2034,13 +2018,10 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba * phba,
pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
cmdsize = sizeof (uint32_t) + sizeof (PRLI); cmdsize = sizeof (uint32_t) + sizeof (PRLI);
if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, ndlp,
ndlp, (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)));
(ELS_CMD_ACC | if (!elsiocb)
(ELS_CMD_PRLI & ~ELS_RSP_MASK)))) == return 1;
0) {
return (1);
}
/* Xmit PRLI ACC response tag <ulpIoTag> */ /* Xmit PRLI ACC response tag <ulpIoTag> */
lpfc_printf_log(phba, KERN_INFO, LOG_ELS, lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
...@@ -2090,9 +2071,9 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba * phba, ...@@ -2090,9 +2071,9 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba * phba,
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
if (rc == IOCB_ERROR) { if (rc == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return (1); return 1;
} }
return (0); return 0;
} }
static int static int
...@@ -2120,7 +2101,7 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba, ...@@ -2120,7 +2101,7 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba,
if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
ndlp, ELS_CMD_ACC)) == 0) { ndlp, ELS_CMD_ACC)) == 0) {
return (1); return 1;
} }
/* Xmit RNID ACC response tag <ulpIoTag> */ /* Xmit RNID ACC response tag <ulpIoTag> */
...@@ -2173,9 +2154,9 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba, ...@@ -2173,9 +2154,9 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba,
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
if (rc == IOCB_ERROR) { if (rc == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb); lpfc_els_free_iocb(phba, elsiocb);
return (1); return 1;
} }
return (0); return 0;
} }
int int
...@@ -2268,7 +2249,7 @@ lpfc_els_flush_rscn(struct lpfc_hba * phba) ...@@ -2268,7 +2249,7 @@ lpfc_els_flush_rscn(struct lpfc_hba * phba)
phba->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY); phba->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY);
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
lpfc_can_disctmo(phba); lpfc_can_disctmo(phba);
return (0); return 0;
} }
int int
...@@ -2289,7 +2270,7 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did) ...@@ -2289,7 +2270,7 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did)
/* If we are doing a FULL RSCN rediscovery, match everything */ /* If we are doing a FULL RSCN rediscovery, match everything */
if (phba->fc_flag & FC_RSCN_DISCOVERY) { if (phba->fc_flag & FC_RSCN_DISCOVERY) {
return (did); return did;
} }
for (i = 0; i < phba->fc_rscn_id_cnt; i++) { for (i = 0; i < phba->fc_rscn_id_cnt; i++) {
...@@ -2337,7 +2318,7 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did) ...@@ -2337,7 +2318,7 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did)
} }
} }
} }
return (match); return match;
} }
static int static int
...@@ -2379,7 +2360,7 @@ lpfc_rscn_recovery_check(struct lpfc_hba * phba) ...@@ -2379,7 +2360,7 @@ lpfc_rscn_recovery_check(struct lpfc_hba * phba)
} }
} }
} }
return (0); return 0;
} }
static int static int
...@@ -2415,7 +2396,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba, ...@@ -2415,7 +2396,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba,
if (phba->hba_state < LPFC_NS_QRY) { if (phba->hba_state < LPFC_NS_QRY) {
lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL,
newnode); newnode);
return (0); return 0;
} }
/* If we are already processing an RSCN, save the received /* If we are already processing an RSCN, save the received
...@@ -2457,7 +2438,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba, ...@@ -2457,7 +2438,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba,
/* send RECOVERY event for ALL nodes that match RSCN payload */ /* send RECOVERY event for ALL nodes that match RSCN payload */
lpfc_rscn_recovery_check(phba); lpfc_rscn_recovery_check(phba);
return (0); return 0;
} }
phba->fc_flag |= FC_RSCN_MODE; phba->fc_flag |= FC_RSCN_MODE;
...@@ -2476,7 +2457,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba, ...@@ -2476,7 +2457,7 @@ lpfc_els_rcv_rscn(struct lpfc_hba * phba,
/* send RECOVERY event for ALL nodes that match RSCN payload */ /* send RECOVERY event for ALL nodes that match RSCN payload */
lpfc_rscn_recovery_check(phba); lpfc_rscn_recovery_check(phba);
return (lpfc_els_handle_rscn(phba)); return lpfc_els_handle_rscn(phba);
} }
int int
...@@ -2498,27 +2479,27 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) ...@@ -2498,27 +2479,27 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba)
/* To process RSCN, first compare RSCN data with NameServer */ /* To process RSCN, first compare RSCN data with NameServer */
phba->fc_ns_retry = 0; phba->fc_ns_retry = 0;
if ((ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, NameServer_DID);
NameServer_DID))) { if (ndlp) {
/* Good ndlp, issue CT Request to NameServer */ /* Good ndlp, issue CT Request to NameServer */
if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) { if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) {
/* Wait for NameServer query cmpl before we can /* Wait for NameServer query cmpl before we can
continue */ continue */
return (1); return 1;
} }
} else { } else {
/* If login to NameServer does not exist, issue one */ /* If login to NameServer does not exist, issue one */
/* Good status, issue PLOGI to NameServer */ /* Good status, issue PLOGI to NameServer */
if ((ndlp = ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID);
lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID))) { if (ndlp) {
/* Wait for NameServer login cmpl before we can /* Wait for NameServer login cmpl before we can
continue */ continue */
return (1); return 1;
} }
if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
== 0) { if (!ndlp) {
lpfc_els_flush_rscn(phba); lpfc_els_flush_rscn(phba);
return (0); return 0;
} else { } else {
lpfc_nlp_init(phba, ndlp, NameServer_DID); lpfc_nlp_init(phba, ndlp, NameServer_DID);
ndlp->nlp_type |= NLP_FABRIC; ndlp->nlp_type |= NLP_FABRIC;
...@@ -2526,12 +2507,12 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) ...@@ -2526,12 +2507,12 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba)
lpfc_issue_els_plogi(phba, ndlp, 0); lpfc_issue_els_plogi(phba, ndlp, 0);
/* Wait for NameServer login cmpl before we can /* Wait for NameServer login cmpl before we can
continue */ continue */
return (1); return 1;
} }
} }
lpfc_els_flush_rscn(phba); lpfc_els_flush_rscn(phba);
return (0); return 0;
} }
static int static int
...@@ -2565,7 +2546,7 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, ...@@ -2565,7 +2546,7 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba,
"%d:0113 An FLOGI ELS command x%x was received " "%d:0113 An FLOGI ELS command x%x was received "
"from DID x%x in Loop Mode\n", "from DID x%x in Loop Mode\n",
phba->brd_no, cmd, did); phba->brd_no, cmd, did);
return (1); return 1;
} }
did = Fabric_DID; did = Fabric_DID;
...@@ -2581,7 +2562,7 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, ...@@ -2581,7 +2562,7 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba,
if (!rc) { if (!rc) {
if ((mbox = mempool_alloc(phba->mbox_mem_pool, if ((mbox = mempool_alloc(phba->mbox_mem_pool,
GFP_KERNEL)) == 0) { GFP_KERNEL)) == 0) {
return (1); return 1;
} }
lpfc_linkdown(phba); lpfc_linkdown(phba);
lpfc_init_link(phba, mbox, lpfc_init_link(phba, mbox,
...@@ -2594,7 +2575,7 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, ...@@ -2594,7 +2575,7 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba,
if (rc == MBX_NOT_FINISHED) { if (rc == MBX_NOT_FINISHED) {
mempool_free( mbox, phba->mbox_mem_pool); mempool_free( mbox, phba->mbox_mem_pool);
} }
return (1); return 1;
} }
else if (rc > 0) { /* greater than */ else if (rc > 0) { /* greater than */
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
...@@ -2610,13 +2591,13 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, ...@@ -2610,13 +2591,13 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba,
stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
stat.un.b.vendorUnique = 0; stat.un.b.vendorUnique = 0;
lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
return (1); return 1;
} }
/* Send back ACC */ /* Send back ACC */
lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode); lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode);
return (0); return 0;
} }
static int static int
...@@ -2654,7 +2635,7 @@ lpfc_els_rcv_rnid(struct lpfc_hba * phba, ...@@ -2654,7 +2635,7 @@ lpfc_els_rcv_rnid(struct lpfc_hba * phba,
stat.un.b.vendorUnique = 0; stat.un.b.vendorUnique = 0;
lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
} }
return (0); return 0;
} }
static int static int
...@@ -2702,10 +2683,10 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -2702,10 +2683,10 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t); cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t);
mempool_free( pmb, phba->mbox_mem_pool); mempool_free( pmb, phba->mbox_mem_pool);
if ((elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, 3, elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, lpfc_max_els_tries,
ndlp, ELS_CMD_ACC)) == 0) { ndlp, ELS_CMD_ACC);
if (!elsiocb)
return; return;
}
icmd = &elsiocb->iocb; icmd = &elsiocb->iocb;
icmd->ulpContext = xri; icmd->ulpContext = xri;
...@@ -2926,7 +2907,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, ...@@ -2926,7 +2907,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba,
/* We will only support match on WWPN or WWNN */ /* We will only support match on WWPN or WWNN */
if (fp->Mflags & ~(FARP_MATCH_NODE | FARP_MATCH_PORT)) { if (fp->Mflags & ~(FARP_MATCH_NODE | FARP_MATCH_PORT)) {
return (0); return 0;
} }
cnt = 0; cnt = 0;
...@@ -2960,7 +2941,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, ...@@ -2960,7 +2941,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba,
} }
} }
} }
return (0); return 0;
} }
static int static int
...@@ -3026,14 +3007,14 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -3026,14 +3007,14 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
/* This node has switched fabrics. An FLOGI is required /* This node has switched fabrics. An FLOGI is required
* after the timeout * after the timeout
*/ */
return (0); return 0;
} }
/* Start discovery */ /* Start discovery */
lpfc_disc_start(phba); lpfc_disc_start(phba);
} }
return (0); return 0;
} }
void void
...@@ -3156,7 +3137,6 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) ...@@ -3156,7 +3137,6 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
struct lpfc_dmabuf *pcmd; struct lpfc_dmabuf *pcmd;
uint32_t *elscmd; uint32_t *elscmd;
uint32_t els_command; uint32_t els_command;
uint32_t remote_ID;
pring = &phba->sli.ring[LPFC_ELS_RING]; pring = &phba->sli.ring[LPFC_ELS_RING];
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
...@@ -3179,18 +3159,6 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) ...@@ -3179,18 +3159,6 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
elscmd = (uint32_t *) (pcmd->virt); elscmd = (uint32_t *) (pcmd->virt);
els_command = *elscmd; els_command = *elscmd;
if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) {
struct lpfc_nodelist *ndlp;
ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext);
remote_ID = ndlp->nlp_DID;
if (phba->hba_state == LPFC_HBA_READY) {
continue;
}
} else {
remote_ID = cmd->un.elsreq64.remoteID;
}
list_del(&piocb->list); list_del(&piocb->list);
pring->txcmplq_cnt--; pring->txcmplq_cnt--;
...@@ -3216,18 +3184,6 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) ...@@ -3216,18 +3184,6 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba)
elscmd = (uint32_t *) (pcmd->virt); elscmd = (uint32_t *) (pcmd->virt);
els_command = *elscmd; els_command = *elscmd;
if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) {
struct lpfc_nodelist *ndlp;
ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext);
remote_ID = ndlp->nlp_DID;
if (phba->hba_state == LPFC_HBA_READY) {
continue;
}
} else {
remote_ID = cmd->un.elsreq64.remoteID;
}
list_del(&piocb->list); list_del(&piocb->list);
pring->txcmplq_cnt--; pring->txcmplq_cnt--;
...@@ -3311,10 +3267,11 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, ...@@ -3311,10 +3267,11 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
} }
did = icmd->un.rcvels.remoteID; did = icmd->un.rcvels.remoteID;
if ((ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did)) == 0) { ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did);
if (!ndlp) {
/* Cannot find existing Fabric ndlp, so allocate a new one */ /* Cannot find existing Fabric ndlp, so allocate a new one */
if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
== 0) { if (!ndlp) {
lpfc_mbuf_free(phba, mp->virt, mp->phys); lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp); kfree(mp);
drop_cmd = 1; drop_cmd = 1;
...@@ -3475,8 +3432,9 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, ...@@ -3475,8 +3432,9 @@ lpfc_els_unsol_event(struct lpfc_hba * phba,
if (drop_cmd == 1) { if (drop_cmd == 1) {
lpfc_printf_log(phba, KERN_ERR, LOG_ELS, lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
"%d:0111 Dropping received ELS cmd " "%d:0111 Dropping received ELS cmd "
"Data: x%x x%x\n", phba->brd_no, "Data: x%x x%x x%x\n", phba->brd_no,
icmd->ulpStatus, icmd->un.ulpWord[4]); icmd->ulpStatus, icmd->un.ulpWord[4],
icmd->ulpTimeout);
phba->fc_stat.elsRcvDrop++; phba->fc_stat.elsRcvDrop++;
} }
return; return;
......
...@@ -283,16 +283,18 @@ lpfc_linkdown(struct lpfc_hba * phba) ...@@ -283,16 +283,18 @@ lpfc_linkdown(struct lpfc_hba * phba)
{ {
struct lpfc_sli *psli; struct lpfc_sli *psli;
struct lpfc_nodelist *ndlp, *next_ndlp; struct lpfc_nodelist *ndlp, *next_ndlp;
struct list_head *listp; struct list_head *listp, *node_list[7];
struct list_head *node_list[7];
LPFC_MBOXQ_t *mb; LPFC_MBOXQ_t *mb;
int rc, i; int rc, i;
psli = &phba->sli; psli = &phba->sli;
spin_lock_irq(phba->host->host_lock); /* sysfs or selective reset may call this routine to clean up */
phba->hba_state = LPFC_LINK_DOWN; if (phba->hba_state > LPFC_LINK_DOWN) {
spin_unlock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
phba->hba_state = LPFC_LINK_DOWN;
spin_unlock_irq(phba->host->host_lock);
}
/* Clean up any firmware default rpi's */ /* Clean up any firmware default rpi's */
if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) { if ((mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))) {
...@@ -324,32 +326,20 @@ lpfc_linkdown(struct lpfc_hba * phba) ...@@ -324,32 +326,20 @@ lpfc_linkdown(struct lpfc_hba * phba)
continue; continue;
list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) { list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) {
/* Fabric nodes are not handled thru state machine for
link down */ rc = lpfc_disc_state_machine(phba, ndlp, NULL,
if (ndlp->nlp_type & NLP_FABRIC) { NLP_EVT_DEVICE_RECOVERY);
/* Remove ALL Fabric nodes except Fabric_DID */
if (ndlp->nlp_DID != Fabric_DID) { /* Check config parameter use-adisc or FCP-2 */
/* Take it off current list and free */ if ((rc != NLP_STE_FREED_NODE) &&
lpfc_nlp_list(phba, ndlp, (phba->cfg_use_adisc == 0) &&
NLP_NO_LIST); !(ndlp->nlp_fcp_info &
} NLP_FCP_2_DEVICE)) {
} /* We know we will have to relogin, so
else { * unreglogin the rpi right now to fail
* any outstanding I/Os quickly.
rc = lpfc_disc_state_machine(phba, ndlp, NULL, */
NLP_EVT_DEVICE_RECOVERY); lpfc_unreg_rpi(phba, ndlp);
/* Check config parameter use-adisc or FCP-2 */
if ((rc != NLP_STE_FREED_NODE) &&
(phba->cfg_use_adisc == 0) &&
!(ndlp->nlp_fcp_info &
NLP_FCP_2_DEVICE)) {
/* We know we will have to relogin, so
* unreglogin the rpi right now to fail
* any outstanding I/Os quickly.
*/
lpfc_unreg_rpi(phba, ndlp);
}
} }
} }
} }
...@@ -391,6 +381,8 @@ static int ...@@ -391,6 +381,8 @@ static int
lpfc_linkup(struct lpfc_hba * phba) lpfc_linkup(struct lpfc_hba * phba)
{ {
struct lpfc_nodelist *ndlp, *next_ndlp; struct lpfc_nodelist *ndlp, *next_ndlp;
struct list_head *listp, *node_list[7];
int i;
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
phba->hba_state = LPFC_LINK_UP; phba->hba_state = LPFC_LINK_UP;
...@@ -401,14 +393,33 @@ lpfc_linkup(struct lpfc_hba * phba) ...@@ -401,14 +393,33 @@ lpfc_linkup(struct lpfc_hba * phba)
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
/* node_list[0] = &phba->fc_plogi_list;
* Clean up old Fabric NLP_FABRIC logins. node_list[1] = &phba->fc_adisc_list;
*/ node_list[2] = &phba->fc_reglogin_list;
list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpunmap_list, node_list[3] = &phba->fc_prli_list;
nlp_listp) { node_list[4] = &phba->fc_nlpunmap_list;
if (ndlp->nlp_DID == Fabric_DID) { node_list[5] = &phba->fc_nlpmap_list;
/* Take it off current list and free */ node_list[6] = &phba->fc_npr_list;
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); for (i = 0; i < 7; i++) {
listp = node_list[i];
if (list_empty(listp))
continue;
list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) {
if (phba->fc_flag & FC_LBIT) {
if (ndlp->nlp_type & NLP_FABRIC) {
/* On Linkup its safe to clean up the
* ndlp from Fabric connections.
*/
lpfc_nlp_list(phba, ndlp,
NLP_UNUSED_LIST);
} else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
/* Fail outstanding IO now since device
* is marked for PLOGI.
*/
lpfc_unreg_rpi(phba, ndlp);
}
}
} }
} }
...@@ -784,6 +795,13 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -784,6 +795,13 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
memcpy(&phba->alpa_map[0], mp->virt, 128); memcpy(&phba->alpa_map[0], mp->virt, 128);
spin_lock_irq(phba->host->host_lock);
if (la->pb)
phba->fc_flag |= FC_BYPASSED_MODE;
else
phba->fc_flag &= ~FC_BYPASSED_MODE;
spin_unlock_irq(phba->host->host_lock);
if (((phba->fc_eventTag + 1) < la->eventTag) || if (((phba->fc_eventTag + 1) < la->eventTag) ||
(phba->fc_eventTag == la->eventTag)) { (phba->fc_eventTag == la->eventTag)) {
phba->fc_stat.LinkMultiEvent++; phba->fc_stat.LinkMultiEvent++;
...@@ -904,32 +922,36 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -904,32 +922,36 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
*/ */
lpfc_issue_els_scr(phba, SCR_DID, 0); lpfc_issue_els_scr(phba, SCR_DID, 0);
/* Allocate a new node instance. If the pool is empty, just ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID);
* start the discovery process and skip the Nameserver login if (!ndlp) {
* process. This is attempted again later on. Otherwise, issue /* Allocate a new node instance. If the pool is empty,
* a Port Login (PLOGI) to the NameServer * start the discovery process and skip the Nameserver
*/ * login process. This is attempted again later on.
if ((ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL)) * Otherwise, issue a Port Login (PLOGI) to NameServer.
== 0) { */
lpfc_disc_start(phba); ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
} else { if (!ndlp) {
lpfc_nlp_init(phba, ndlp, NameServer_DID); lpfc_disc_start(phba);
ndlp->nlp_type |= NLP_FABRIC; lpfc_mbuf_free(phba, mp->virt, mp->phys);
ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; kfree(mp);
lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); mempool_free( pmb, phba->mbox_mem_pool);
lpfc_issue_els_plogi(phba, ndlp, 0); return;
if (phba->cfg_fdmi_on) { } else {
if ((ndlp_fdmi = mempool_alloc( lpfc_nlp_init(phba, ndlp, NameServer_DID);
phba->nlp_mem_pool, ndlp->nlp_type |= NLP_FABRIC;
GFP_KERNEL))) { }
lpfc_nlp_init(phba, ndlp_fdmi, }
FDMI_DID); ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
ndlp_fdmi->nlp_type |= NLP_FABRIC; lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
ndlp_fdmi->nlp_state = lpfc_issue_els_plogi(phba, ndlp, 0);
NLP_STE_PLOGI_ISSUE; if (phba->cfg_fdmi_on) {
lpfc_issue_els_plogi(phba, ndlp_fdmi, ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
0); GFP_KERNEL);
} if (ndlp_fdmi) {
lpfc_nlp_init(phba, ndlp_fdmi, FDMI_DID);
ndlp_fdmi->nlp_type |= NLP_FABRIC;
ndlp_fdmi->nlp_state = NLP_STE_PLOGI_ISSUE;
lpfc_issue_els_plogi(phba, ndlp_fdmi, 0);
} }
} }
} }
...@@ -937,7 +959,6 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -937,7 +959,6 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
lpfc_mbuf_free(phba, mp->virt, mp->phys); lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp); kfree(mp);
mempool_free( pmb, phba->mbox_mem_pool); mempool_free( pmb, phba->mbox_mem_pool);
return; return;
} }
...@@ -1241,16 +1262,9 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) ...@@ -1241,16 +1262,9 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
list_add_tail(&nlp->nlp_listp, &phba->fc_npr_list); list_add_tail(&nlp->nlp_listp, &phba->fc_npr_list);
phba->fc_npr_cnt++; phba->fc_npr_cnt++;
/* if (!(nlp->nlp_flag & NLP_NODEV_TMO)) {
* Sanity check for Fabric entity.
* Set nodev_tmo for NPR state, for Fabric use 1 sec.
*/
if (nlp->nlp_type & NLP_FABRIC) {
mod_timer(&nlp->nlp_tmofunc, jiffies + HZ);
}
else {
mod_timer(&nlp->nlp_tmofunc, mod_timer(&nlp->nlp_tmofunc,
jiffies + HZ * phba->cfg_nodev_tmo); jiffies + HZ * phba->cfg_nodev_tmo);
} }
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
nlp->nlp_flag |= NLP_NODEV_TMO; nlp->nlp_flag |= NLP_NODEV_TMO;
...@@ -1314,7 +1328,15 @@ lpfc_set_disctmo(struct lpfc_hba * phba) ...@@ -1314,7 +1328,15 @@ lpfc_set_disctmo(struct lpfc_hba * phba)
{ {
uint32_t tmo; uint32_t tmo;
tmo = ((phba->fc_ratov * 2) + 1); if (phba->hba_state == LPFC_LOCAL_CFG_LINK) {
/* For FAN, timeout should be greater then edtov */
tmo = (((phba->fc_edtov + 999) / 1000) + 1);
} else {
/* Normal discovery timeout should be > then ELS/CT timeout
* FC spec states we need 3 * ratov for CT requests
*/
tmo = ((phba->fc_ratov * 3) + 3);
}
mod_timer(&phba->fc_disctmo, jiffies + HZ * tmo); mod_timer(&phba->fc_disctmo, jiffies + HZ * tmo);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
...@@ -1846,8 +1868,9 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) ...@@ -1846,8 +1868,9 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did)
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
uint32_t flg; uint32_t flg;
if ((ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did)) == 0) { ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did);
if ((phba->hba_state == LPFC_HBA_READY) && if (!ndlp) {
if ((phba->fc_flag & FC_RSCN_MODE) &&
((lpfc_rscn_payload_check(phba, did) == 0))) ((lpfc_rscn_payload_check(phba, did) == 0)))
return NULL; return NULL;
ndlp = (struct lpfc_nodelist *) ndlp = (struct lpfc_nodelist *)
...@@ -1860,10 +1883,23 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) ...@@ -1860,10 +1883,23 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did)
ndlp->nlp_flag |= NLP_NPR_2B_DISC; ndlp->nlp_flag |= NLP_NPR_2B_DISC;
return ndlp; return ndlp;
} }
if ((phba->hba_state == LPFC_HBA_READY) && if (phba->fc_flag & FC_RSCN_MODE) {
(phba->fc_flag & FC_RSCN_MODE)) {
if (lpfc_rscn_payload_check(phba, did)) { if (lpfc_rscn_payload_check(phba, did)) {
ndlp->nlp_flag |= NLP_NPR_2B_DISC; ndlp->nlp_flag |= NLP_NPR_2B_DISC;
/* 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;
spin_unlock_irq(phba->host->host_lock);
del_timer_sync(&ndlp->nlp_delayfunc);
spin_lock_irq(phba->host->host_lock);
if (!list_empty(&ndlp->els_retry_evt.
evt_listp))
list_del_init(&ndlp->els_retry_evt.
evt_listp);
}
} }
else { else {
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
...@@ -1872,10 +1908,8 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) ...@@ -1872,10 +1908,8 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did)
} }
else { else {
flg = ndlp->nlp_flag & NLP_LIST_MASK; flg = ndlp->nlp_flag & NLP_LIST_MASK;
if ((flg == NLP_ADISC_LIST) || if ((flg == NLP_ADISC_LIST) || (flg == NLP_PLOGI_LIST))
(flg == NLP_PLOGI_LIST)) {
return NULL; return NULL;
}
ndlp->nlp_state = NLP_STE_NPR_NODE; ndlp->nlp_state = NLP_STE_NPR_NODE;
lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
ndlp->nlp_flag |= NLP_NPR_2B_DISC; ndlp->nlp_flag |= NLP_NPR_2B_DISC;
...@@ -2174,7 +2208,7 @@ static void ...@@ -2174,7 +2208,7 @@ static void
lpfc_disc_timeout_handler(struct lpfc_hba *phba) lpfc_disc_timeout_handler(struct lpfc_hba *phba)
{ {
struct lpfc_sli *psli; struct lpfc_sli *psli;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp, *next_ndlp;
LPFC_MBOXQ_t *clearlambox, *initlinkmbox; LPFC_MBOXQ_t *clearlambox, *initlinkmbox;
int rc, clrlaerr = 0; int rc, clrlaerr = 0;
...@@ -2201,10 +2235,20 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) ...@@ -2201,10 +2235,20 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
"%d:0221 FAN timeout\n", "%d:0221 FAN timeout\n",
phba->brd_no); phba->brd_no);
/* Forget about FAN, Start discovery by sending a FLOGI /* Start discovery by sending FLOGI, clean up old rpis */
* hba_state is identically LPFC_FLOGI while waiting for FLOGI list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list,
* cmpl nlp_listp) {
*/ if (ndlp->nlp_type & NLP_FABRIC) {
/* Clean up the ndlp on Fabric connections */
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
}
else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
/* Fail outstanding IO now since device
* is marked for PLOGI.
*/
lpfc_unreg_rpi(phba, ndlp);
}
}
phba->hba_state = LPFC_FLOGI; phba->hba_state = LPFC_FLOGI;
lpfc_set_disctmo(phba); lpfc_set_disctmo(phba);
lpfc_initial_flogi(phba); lpfc_initial_flogi(phba);
......
...@@ -46,13 +46,13 @@ lpfc_check_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -46,13 +46,13 @@ lpfc_check_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
* table entry for that node. * table entry for that node.
*/ */
if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)) != 0) if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)) != 0)
return (0); return 0;
if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)) != 0) if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)) != 0)
return (0); return 0;
/* we match, return success */ /* we match, return success */
return (1); return 1;
} }
int int
...@@ -159,7 +159,7 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba, ...@@ -159,7 +159,7 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba,
} }
ptr = NULL; ptr = NULL;
} }
return (ptr); return ptr;
} }
...@@ -266,7 +266,7 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -266,7 +266,7 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
if (!list_empty(&ndlp->els_retry_evt.evt_listp)) if (!list_empty(&ndlp->els_retry_evt.evt_listp))
list_del_init(&ndlp->els_retry_evt.evt_listp); list_del_init(&ndlp->els_retry_evt.evt_listp);
} }
return (0); return 0;
} }
static int static int
...@@ -321,7 +321,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, ...@@ -321,7 +321,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba,
stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
return (0); return 0;
} }
icmd = &cmdiocb->iocb; icmd = &cmdiocb->iocb;
...@@ -362,7 +362,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, ...@@ -362,7 +362,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba,
case NLP_STE_UNMAPPED_NODE: case NLP_STE_UNMAPPED_NODE:
case NLP_STE_MAPPED_NODE: case NLP_STE_MAPPED_NODE:
lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0); lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0);
return (1); return 1;
} }
if ((phba->fc_flag & FC_PT2PT) if ((phba->fc_flag & FC_PT2PT)
...@@ -409,13 +409,13 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, ...@@ -409,13 +409,13 @@ lpfc_rcv_plogi(struct lpfc_hba * phba,
} }
ndlp->nlp_flag |= NLP_RCV_PLOGI; ndlp->nlp_flag |= NLP_RCV_PLOGI;
lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0);
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;
lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp);
return (0); return 0;
} }
static int static int
...@@ -456,7 +456,7 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, ...@@ -456,7 +456,7 @@ lpfc_rcv_padisc(struct lpfc_hba * phba,
lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp,
NULL, 0); NULL, 0);
} }
return (1); return 1;
} }
/* Reject this request because invalid parameters */ /* Reject this request because invalid parameters */
stat.un.b.lsRjtRsvd0 = 0; stat.un.b.lsRjtRsvd0 = 0;
...@@ -474,7 +474,7 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, ...@@ -474,7 +474,7 @@ lpfc_rcv_padisc(struct lpfc_hba * phba,
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
ndlp->nlp_state = NLP_STE_NPR_NODE; ndlp->nlp_state = NLP_STE_NPR_NODE;
lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
return (0); return 0;
} }
static int static int
...@@ -489,25 +489,31 @@ lpfc_rcv_logo(struct lpfc_hba * phba, ...@@ -489,25 +489,31 @@ lpfc_rcv_logo(struct lpfc_hba * phba,
ndlp->nlp_flag |= NLP_LOGO_ACC; ndlp->nlp_flag |= NLP_LOGO_ACC;
lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
if (!(ndlp->nlp_type & NLP_FABRIC)) { if (!(ndlp->nlp_type & NLP_FABRIC) ||
(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 */
ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI;
mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag |= NLP_DELAY_TMO; ndlp->nlp_flag |= NLP_DELAY_TMO;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
}
ndlp->nlp_state = NLP_STE_NPR_NODE; ndlp->nlp_state = NLP_STE_NPR_NODE;
lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
} else {
ndlp->nlp_state = NLP_STE_UNUSED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
}
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~NLP_NPR_ADISC; ndlp->nlp_flag &= ~NLP_NPR_ADISC;
spin_unlock_irq(phba->host->host_lock);
/* The driver has to wait until the ACC completes before it continues /* The driver has to wait until the ACC completes before it continues
* processing the LOGO. The action will resume in * processing the LOGO. The action will resume in
* lpfc_cmpl_els_logo_acc routine. Since part of processing includes an * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an
* unreg_login, the driver waits so the ACC does not get aborted. * unreg_login, the driver waits so the ACC does not get aborted.
*/ */
return (0); return 0;
} }
static void static void
...@@ -555,20 +561,12 @@ lpfc_disc_set_adisc(struct lpfc_hba * phba, ...@@ -555,20 +561,12 @@ lpfc_disc_set_adisc(struct lpfc_hba * phba,
if ((phba->cfg_use_adisc == 0) && if ((phba->cfg_use_adisc == 0) &&
!(phba->fc_flag & FC_RSCN_MODE)) { !(phba->fc_flag & FC_RSCN_MODE)) {
if (!(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE)) if (!(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE))
return (0); return 0;
} }
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag |= NLP_NPR_ADISC; ndlp->nlp_flag |= NLP_NPR_ADISC;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return (1); return 1;
}
static uint32_t
lpfc_disc_noop(struct lpfc_hba * phba,
struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
{
/* This routine does nothing, just return the current state */
return (ndlp->nlp_state);
} }
static uint32_t static uint32_t
...@@ -583,7 +581,7 @@ lpfc_disc_illegal(struct lpfc_hba * phba, ...@@ -583,7 +581,7 @@ lpfc_disc_illegal(struct lpfc_hba * phba,
phba->brd_no, phba->brd_no,
ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,
ndlp->nlp_flag); ndlp->nlp_flag);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
/* Start of Discovery State Machine routines */ /* Start of Discovery State Machine routines */
...@@ -599,10 +597,10 @@ lpfc_rcv_plogi_unused_node(struct lpfc_hba * phba, ...@@ -599,10 +597,10 @@ lpfc_rcv_plogi_unused_node(struct lpfc_hba * phba,
if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) {
ndlp->nlp_state = NLP_STE_UNUSED_NODE; ndlp->nlp_state = NLP_STE_UNUSED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
return (NLP_STE_FREED_NODE); return NLP_STE_FREED_NODE;
} }
static uint32_t static uint32_t
...@@ -611,7 +609,7 @@ lpfc_rcv_els_unused_node(struct lpfc_hba * phba, ...@@ -611,7 +609,7 @@ lpfc_rcv_els_unused_node(struct lpfc_hba * phba,
{ {
lpfc_issue_els_logo(phba, ndlp, 0); lpfc_issue_els_logo(phba, ndlp, 0);
lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -628,7 +626,7 @@ lpfc_rcv_logo_unused_node(struct lpfc_hba * phba, ...@@ -628,7 +626,7 @@ lpfc_rcv_logo_unused_node(struct lpfc_hba * phba,
lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -636,7 +634,7 @@ lpfc_cmpl_logo_unused_node(struct lpfc_hba * phba, ...@@ -636,7 +634,7 @@ lpfc_cmpl_logo_unused_node(struct lpfc_hba * phba,
struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
{ {
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
return (NLP_STE_FREED_NODE); return NLP_STE_FREED_NODE;
} }
static uint32_t static uint32_t
...@@ -644,7 +642,7 @@ lpfc_device_rm_unused_node(struct lpfc_hba * phba, ...@@ -644,7 +642,7 @@ lpfc_device_rm_unused_node(struct lpfc_hba * phba,
struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
{ {
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
return (NLP_STE_FREED_NODE); return NLP_STE_FREED_NODE;
} }
static uint32_t static uint32_t
...@@ -682,7 +680,22 @@ lpfc_rcv_plogi_plogi_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -682,7 +680,22 @@ lpfc_rcv_plogi_plogi_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
lpfc_rcv_plogi(phba, ndlp, cmdiocb); lpfc_rcv_plogi(phba, ndlp, cmdiocb);
} /* if our portname was less */ } /* if our portname was less */
return (ndlp->nlp_state); return ndlp->nlp_state;
}
static uint32_t
lpfc_rcv_logo_plogi_issue(struct lpfc_hba * phba,
struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
{
struct lpfc_iocbq *cmdiocb;
cmdiocb = (struct lpfc_iocbq *) arg;
/* software abort outstanding PLOGI */
lpfc_els_abort(phba, ndlp, 1);
lpfc_rcv_logo(phba, ndlp, cmdiocb);
return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -712,7 +725,7 @@ lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba, ...@@ -712,7 +725,7 @@ lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba,
ndlp->nlp_state = NLP_STE_NPR_NODE; ndlp->nlp_state = NLP_STE_NPR_NODE;
lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -731,7 +744,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, ...@@ -731,7 +744,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba,
rspiocb = cmdiocb->context_un.rsp_iocb; rspiocb = cmdiocb->context_un.rsp_iocb;
if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
irsp = &rspiocb->iocb; irsp = &rspiocb->iocb;
...@@ -812,7 +825,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, ...@@ -812,7 +825,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba,
NLP_STE_REG_LOGIN_ISSUE; NLP_STE_REG_LOGIN_ISSUE;
lpfc_nlp_list(phba, ndlp, lpfc_nlp_list(phba, ndlp,
NLP_REGLOGIN_LIST); NLP_REGLOGIN_LIST);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
mempool_free(mbox, phba->mbox_mem_pool); mempool_free(mbox, phba->mbox_mem_pool);
} else { } else {
...@@ -824,7 +837,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, ...@@ -824,7 +837,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba,
/* Free this node since the driver cannot login or has the wrong /* Free this node since the driver cannot login or has the wrong
sparm */ sparm */
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
return (NLP_STE_FREED_NODE); return NLP_STE_FREED_NODE;
} }
static uint32_t static uint32_t
...@@ -835,7 +848,7 @@ lpfc_device_rm_plogi_issue(struct lpfc_hba * phba, ...@@ -835,7 +848,7 @@ lpfc_device_rm_plogi_issue(struct lpfc_hba * phba,
lpfc_els_abort(phba, ndlp, 1); lpfc_els_abort(phba, ndlp, 1);
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
return (NLP_STE_FREED_NODE); return NLP_STE_FREED_NODE;
} }
static uint32_t static uint32_t
...@@ -852,7 +865,7 @@ lpfc_device_recov_plogi_issue(struct lpfc_hba * phba, ...@@ -852,7 +865,7 @@ lpfc_device_recov_plogi_issue(struct lpfc_hba * phba,
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -868,13 +881,13 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba, ...@@ -868,13 +881,13 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) {
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
lpfc_issue_els_plogi(phba, ndlp, 0); lpfc_issue_els_plogi(phba, ndlp, 0);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -887,7 +900,7 @@ lpfc_rcv_prli_adisc_issue(struct lpfc_hba * phba, ...@@ -887,7 +900,7 @@ lpfc_rcv_prli_adisc_issue(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -903,7 +916,7 @@ lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba, ...@@ -903,7 +916,7 @@ lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba,
lpfc_els_abort(phba, ndlp, 0); lpfc_els_abort(phba, ndlp, 0);
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -916,7 +929,7 @@ lpfc_rcv_padisc_adisc_issue(struct lpfc_hba * phba, ...@@ -916,7 +929,7 @@ lpfc_rcv_padisc_adisc_issue(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_padisc(phba, ndlp, cmdiocb); lpfc_rcv_padisc(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -930,7 +943,7 @@ lpfc_rcv_prlo_adisc_issue(struct lpfc_hba * phba, ...@@ -930,7 +943,7 @@ lpfc_rcv_prlo_adisc_issue(struct lpfc_hba * phba,
/* Treat like rcv logo */ /* Treat like rcv logo */
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -963,7 +976,7 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba, ...@@ -963,7 +976,7 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba,
ndlp->nlp_state = NLP_STE_NPR_NODE; ndlp->nlp_state = NLP_STE_NPR_NODE;
lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
lpfc_unreg_rpi(phba, ndlp); lpfc_unreg_rpi(phba, ndlp);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
if (ndlp->nlp_type & NLP_FCP_TARGET) { if (ndlp->nlp_type & NLP_FCP_TARGET) {
ndlp->nlp_state = NLP_STE_MAPPED_NODE; ndlp->nlp_state = NLP_STE_MAPPED_NODE;
...@@ -972,7 +985,7 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba, ...@@ -972,7 +985,7 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba,
ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
} }
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -984,7 +997,7 @@ lpfc_device_rm_adisc_issue(struct lpfc_hba * phba, ...@@ -984,7 +997,7 @@ lpfc_device_rm_adisc_issue(struct lpfc_hba * phba,
lpfc_els_abort(phba, ndlp, 1); lpfc_els_abort(phba, ndlp, 1);
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
return (NLP_STE_FREED_NODE); return NLP_STE_FREED_NODE;
} }
static uint32_t static uint32_t
...@@ -999,10 +1012,10 @@ lpfc_device_recov_adisc_issue(struct lpfc_hba * phba, ...@@ -999,10 +1012,10 @@ lpfc_device_recov_adisc_issue(struct lpfc_hba * phba,
lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
ndlp->nlp_flag |= NLP_NPR_ADISC;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
lpfc_disc_set_adisc(phba, ndlp); return ndlp->nlp_state;
return (ndlp->nlp_state);
} }
static uint32_t static uint32_t
...@@ -1015,7 +1028,7 @@ lpfc_rcv_plogi_reglogin_issue(struct lpfc_hba * phba, ...@@ -1015,7 +1028,7 @@ lpfc_rcv_plogi_reglogin_issue(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_plogi(phba, ndlp, cmdiocb); lpfc_rcv_plogi(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1028,7 +1041,7 @@ lpfc_rcv_prli_reglogin_issue(struct lpfc_hba * phba, ...@@ -1028,7 +1041,7 @@ lpfc_rcv_prli_reglogin_issue(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1041,7 +1054,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba, ...@@ -1041,7 +1054,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1054,7 +1067,7 @@ lpfc_rcv_padisc_reglogin_issue(struct lpfc_hba * phba, ...@@ -1054,7 +1067,7 @@ lpfc_rcv_padisc_reglogin_issue(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_padisc(phba, ndlp, cmdiocb); lpfc_rcv_padisc(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1066,7 +1079,7 @@ lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba, ...@@ -1066,7 +1079,7 @@ lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1100,7 +1113,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, ...@@ -1100,7 +1113,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,
ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI;
ndlp->nlp_state = NLP_STE_NPR_NODE; ndlp->nlp_state = NLP_STE_NPR_NODE;
lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
ndlp->nlp_rpi = mb->un.varWords[0]; ndlp->nlp_rpi = mb->un.varWords[0];
...@@ -1114,7 +1127,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, ...@@ -1114,7 +1127,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,
ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
} }
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1123,7 +1136,7 @@ lpfc_device_rm_reglogin_issue(struct lpfc_hba * phba, ...@@ -1123,7 +1136,7 @@ lpfc_device_rm_reglogin_issue(struct lpfc_hba * phba,
uint32_t evt) uint32_t evt)
{ {
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
return (NLP_STE_FREED_NODE); return NLP_STE_FREED_NODE;
} }
static uint32_t static uint32_t
...@@ -1136,7 +1149,7 @@ lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba, ...@@ -1136,7 +1149,7 @@ lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba,
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1148,7 +1161,7 @@ lpfc_rcv_plogi_prli_issue(struct lpfc_hba * phba, ...@@ -1148,7 +1161,7 @@ lpfc_rcv_plogi_prli_issue(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_plogi(phba, ndlp, cmdiocb); lpfc_rcv_plogi(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1160,7 +1173,7 @@ lpfc_rcv_prli_prli_issue(struct lpfc_hba * phba, ...@@ -1160,7 +1173,7 @@ lpfc_rcv_prli_prli_issue(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1175,7 +1188,7 @@ lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba, ...@@ -1175,7 +1188,7 @@ lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba,
lpfc_els_abort(phba, ndlp, 1); lpfc_els_abort(phba, ndlp, 1);
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1187,7 +1200,7 @@ lpfc_rcv_padisc_prli_issue(struct lpfc_hba * phba, ...@@ -1187,7 +1200,7 @@ lpfc_rcv_padisc_prli_issue(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_padisc(phba, ndlp, cmdiocb); lpfc_rcv_padisc(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
/* This routine is envoked when we rcv a PRLO request from a nport /* This routine is envoked when we rcv a PRLO request from a nport
...@@ -1203,7 +1216,7 @@ lpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba, ...@@ -1203,7 +1216,7 @@ lpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1222,7 +1235,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, ...@@ -1222,7 +1235,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba,
if (irsp->ulpStatus) { if (irsp->ulpStatus) {
ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
/* Check out PRLI rsp */ /* Check out PRLI rsp */
...@@ -1240,7 +1253,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, ...@@ -1240,7 +1253,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba,
ndlp->nlp_state = NLP_STE_MAPPED_NODE; ndlp->nlp_state = NLP_STE_MAPPED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
/*! lpfc_device_rm_prli_issue /*! lpfc_device_rm_prli_issue
...@@ -1268,7 +1281,7 @@ lpfc_device_rm_prli_issue(struct lpfc_hba * phba, ...@@ -1268,7 +1281,7 @@ lpfc_device_rm_prli_issue(struct lpfc_hba * phba,
lpfc_els_abort(phba, ndlp, 1); lpfc_els_abort(phba, ndlp, 1);
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
return (NLP_STE_FREED_NODE); return NLP_STE_FREED_NODE;
} }
...@@ -1300,7 +1313,7 @@ lpfc_device_recov_prli_issue(struct lpfc_hba * phba, ...@@ -1300,7 +1313,7 @@ lpfc_device_recov_prli_issue(struct lpfc_hba * phba,
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1312,7 +1325,7 @@ lpfc_rcv_plogi_unmap_node(struct lpfc_hba * phba, ...@@ -1312,7 +1325,7 @@ lpfc_rcv_plogi_unmap_node(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_plogi(phba, ndlp, cmdiocb); lpfc_rcv_plogi(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1325,7 +1338,7 @@ lpfc_rcv_prli_unmap_node(struct lpfc_hba * phba, ...@@ -1325,7 +1338,7 @@ lpfc_rcv_prli_unmap_node(struct lpfc_hba * phba,
lpfc_rcv_prli(phba, ndlp, cmdiocb); lpfc_rcv_prli(phba, ndlp, cmdiocb);
lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1337,7 +1350,7 @@ lpfc_rcv_logo_unmap_node(struct lpfc_hba * phba, ...@@ -1337,7 +1350,7 @@ lpfc_rcv_logo_unmap_node(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1349,7 +1362,7 @@ lpfc_rcv_padisc_unmap_node(struct lpfc_hba * phba, ...@@ -1349,7 +1362,7 @@ lpfc_rcv_padisc_unmap_node(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_padisc(phba, ndlp, cmdiocb); lpfc_rcv_padisc(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1360,9 +1373,8 @@ lpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba, ...@@ -1360,9 +1373,8 @@ lpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
/* Treat like rcv logo */ lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
lpfc_rcv_logo(phba, ndlp, cmdiocb); return ndlp->nlp_state;
return (ndlp->nlp_state);
} }
static uint32_t static uint32_t
...@@ -1374,7 +1386,7 @@ lpfc_device_recov_unmap_node(struct lpfc_hba * phba, ...@@ -1374,7 +1386,7 @@ lpfc_device_recov_unmap_node(struct lpfc_hba * phba,
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
lpfc_disc_set_adisc(phba, ndlp); lpfc_disc_set_adisc(phba, ndlp);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1386,7 +1398,7 @@ lpfc_rcv_plogi_mapped_node(struct lpfc_hba * phba, ...@@ -1386,7 +1398,7 @@ lpfc_rcv_plogi_mapped_node(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_plogi(phba, ndlp, cmdiocb); lpfc_rcv_plogi(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1398,7 +1410,7 @@ lpfc_rcv_prli_mapped_node(struct lpfc_hba * phba, ...@@ -1398,7 +1410,7 @@ lpfc_rcv_prli_mapped_node(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1410,7 +1422,7 @@ lpfc_rcv_logo_mapped_node(struct lpfc_hba * phba, ...@@ -1410,7 +1422,7 @@ lpfc_rcv_logo_mapped_node(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1423,7 +1435,7 @@ lpfc_rcv_padisc_mapped_node(struct lpfc_hba * phba, ...@@ -1423,7 +1435,7 @@ lpfc_rcv_padisc_mapped_node(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_padisc(phba, ndlp, cmdiocb); lpfc_rcv_padisc(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1442,7 +1454,7 @@ lpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba, ...@@ -1442,7 +1454,7 @@ lpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba,
/* Treat like rcv logo */ /* Treat like rcv logo */
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1456,7 +1468,7 @@ lpfc_device_recov_mapped_node(struct lpfc_hba * phba, ...@@ -1456,7 +1468,7 @@ lpfc_device_recov_mapped_node(struct lpfc_hba * phba,
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
lpfc_disc_set_adisc(phba, ndlp); lpfc_disc_set_adisc(phba, ndlp);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1470,14 +1482,14 @@ lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba, ...@@ -1470,14 +1482,14 @@ lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba,
/* Ignore PLOGI if we have an outstanding LOGO */ /* Ignore PLOGI if we have an outstanding LOGO */
if (ndlp->nlp_flag & NLP_LOGO_SND) { if (ndlp->nlp_flag & NLP_LOGO_SND) {
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) {
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~(NLP_NPR_ADISC | NLP_NPR_2B_DISC); ndlp->nlp_flag &= ~(NLP_NPR_ADISC | NLP_NPR_2B_DISC);
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
/* send PLOGI immediately, move to PLOGI issue state */ /* send PLOGI immediately, move to PLOGI issue state */
...@@ -1486,7 +1498,7 @@ lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba, ...@@ -1486,7 +1498,7 @@ lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba,
lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST);
lpfc_issue_els_plogi(phba, ndlp, 0); lpfc_issue_els_plogi(phba, ndlp, 0);
} }
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1506,6 +1518,9 @@ lpfc_rcv_prli_npr_node(struct lpfc_hba * phba, ...@@ -1506,6 +1518,9 @@ lpfc_rcv_prli_npr_node(struct lpfc_hba * phba,
if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
if (ndlp->nlp_flag & NLP_NPR_ADISC) { if (ndlp->nlp_flag & NLP_NPR_ADISC) {
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~NLP_NPR_ADISC;
spin_unlock_irq(phba->host->host_lock);
ndlp->nlp_state = NLP_STE_ADISC_ISSUE; ndlp->nlp_state = NLP_STE_ADISC_ISSUE;
lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST);
lpfc_issue_els_adisc(phba, ndlp, 0); lpfc_issue_els_adisc(phba, ndlp, 0);
...@@ -1515,7 +1530,7 @@ lpfc_rcv_prli_npr_node(struct lpfc_hba * phba, ...@@ -1515,7 +1530,7 @@ lpfc_rcv_prli_npr_node(struct lpfc_hba * phba,
lpfc_issue_els_plogi(phba, ndlp, 0); lpfc_issue_els_plogi(phba, ndlp, 0);
} }
} }
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1528,7 +1543,7 @@ lpfc_rcv_logo_npr_node(struct lpfc_hba * phba, ...@@ -1528,7 +1543,7 @@ lpfc_rcv_logo_npr_node(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1553,7 +1568,7 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, ...@@ -1553,7 +1568,7 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba,
lpfc_issue_els_plogi(phba, ndlp, 0); lpfc_issue_els_plogi(phba, ndlp, 0);
} }
} }
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1565,25 +1580,46 @@ lpfc_rcv_prlo_npr_node(struct lpfc_hba * phba, ...@@ -1565,25 +1580,46 @@ lpfc_rcv_prlo_npr_node(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag |= NLP_LOGO_ACC;
spin_unlock_irq(phba->host->host_lock);
lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
if (ndlp->nlp_flag & NLP_DELAY_TMO) { if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
if (ndlp->nlp_last_elscmd == (unsigned long)ELS_CMD_PLOGI) { mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
return (ndlp->nlp_state); spin_lock_irq(phba->host->host_lock);
} else { ndlp->nlp_flag |= NLP_DELAY_TMO;
spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag &= ~NLP_NPR_ADISC;
ndlp->nlp_flag &= ~NLP_DELAY_TMO; spin_unlock_irq(phba->host->host_lock);
spin_unlock_irq(phba->host->host_lock); } else {
del_timer_sync(&ndlp->nlp_delayfunc); spin_lock_irq(phba->host->host_lock);
if (!list_empty(&ndlp->els_retry_evt.evt_listp)) ndlp->nlp_flag &= ~NLP_NPR_ADISC;
list_del_init(&ndlp->els_retry_evt.evt_listp); spin_unlock_irq(phba->host->host_lock);
}
} }
return ndlp->nlp_state;
}
ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; static uint32_t
lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); lpfc_cmpl_plogi_npr_node(struct lpfc_hba * phba,
lpfc_issue_els_plogi(phba, ndlp, 0); struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
return (ndlp->nlp_state); {
struct lpfc_iocbq *cmdiocb, *rspiocb;
cmdiocb = (struct lpfc_iocbq *) arg;
rspiocb = cmdiocb->context_un.rsp_iocb;
return ndlp->nlp_state;
}
static uint32_t
lpfc_cmpl_prli_npr_node(struct lpfc_hba * phba,
struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
{
struct lpfc_iocbq *cmdiocb, *rspiocb;
cmdiocb = (struct lpfc_iocbq *) arg;
rspiocb = cmdiocb->context_un.rsp_iocb;
return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1592,7 +1628,19 @@ lpfc_cmpl_logo_npr_node(struct lpfc_hba * phba, ...@@ -1592,7 +1628,19 @@ lpfc_cmpl_logo_npr_node(struct lpfc_hba * phba,
{ {
lpfc_unreg_rpi(phba, ndlp); lpfc_unreg_rpi(phba, ndlp);
/* This routine does nothing, just return the current state */ /* This routine does nothing, just return the current state */
return (ndlp->nlp_state); return ndlp->nlp_state;
}
static uint32_t
lpfc_cmpl_adisc_npr_node(struct lpfc_hba * phba,
struct lpfc_nodelist * ndlp, void *arg,
uint32_t evt)
{
struct lpfc_iocbq *cmdiocb, *rspiocb;
cmdiocb = (struct lpfc_iocbq *) arg;
rspiocb = cmdiocb->context_un.rsp_iocb;
return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1606,9 +1654,10 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba, ...@@ -1606,9 +1654,10 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba,
pmb = (LPFC_MBOXQ_t *) arg; pmb = (LPFC_MBOXQ_t *) arg;
mb = &pmb->mb; mb = &pmb->mb;
ndlp->nlp_rpi = mb->un.varWords[0]; if (!mb->mbxStatus)
ndlp->nlp_rpi = mb->un.varWords[0];
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
static uint32_t static uint32_t
...@@ -1617,7 +1666,7 @@ lpfc_device_rm_npr_node(struct lpfc_hba * phba, ...@@ -1617,7 +1666,7 @@ lpfc_device_rm_npr_node(struct lpfc_hba * phba,
uint32_t evt) uint32_t evt)
{ {
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
return (NLP_STE_FREED_NODE); return NLP_STE_FREED_NODE;
} }
static uint32_t static uint32_t
...@@ -1633,10 +1682,10 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba, ...@@ -1633,10 +1682,10 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba,
list_del_init(&ndlp->els_retry_evt.evt_listp); list_del_init(&ndlp->els_retry_evt.evt_listp);
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
del_timer_sync(&ndlp->nlp_delayfunc); del_timer_sync(&ndlp->nlp_delayfunc);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
return (ndlp->nlp_state); return ndlp->nlp_state;
} }
...@@ -1715,7 +1764,7 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) ...@@ -1715,7 +1764,7 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
lpfc_rcv_plogi_plogi_issue, /* RCV_PLOGI PLOGI_ISSUE */ lpfc_rcv_plogi_plogi_issue, /* RCV_PLOGI PLOGI_ISSUE */
lpfc_rcv_els_plogi_issue, /* RCV_PRLI */ lpfc_rcv_els_plogi_issue, /* RCV_PRLI */
lpfc_rcv_els_plogi_issue, /* RCV_LOGO */ lpfc_rcv_logo_plogi_issue, /* RCV_LOGO */
lpfc_rcv_els_plogi_issue, /* RCV_ADISC */ lpfc_rcv_els_plogi_issue, /* RCV_ADISC */
lpfc_rcv_els_plogi_issue, /* RCV_PDISC */ lpfc_rcv_els_plogi_issue, /* RCV_PDISC */
lpfc_rcv_els_plogi_issue, /* RCV_PRLO */ lpfc_rcv_els_plogi_issue, /* RCV_PRLO */
...@@ -1803,10 +1852,10 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) ...@@ -1803,10 +1852,10 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
lpfc_rcv_padisc_npr_node, /* RCV_ADISC */ lpfc_rcv_padisc_npr_node, /* RCV_ADISC */
lpfc_rcv_padisc_npr_node, /* RCV_PDISC */ lpfc_rcv_padisc_npr_node, /* RCV_PDISC */
lpfc_rcv_prlo_npr_node, /* RCV_PRLO */ lpfc_rcv_prlo_npr_node, /* RCV_PRLO */
lpfc_disc_noop, /* CMPL_PLOGI */ lpfc_cmpl_plogi_npr_node, /* CMPL_PLOGI */
lpfc_disc_noop, /* CMPL_PRLI */ lpfc_cmpl_prli_npr_node, /* CMPL_PRLI */
lpfc_cmpl_logo_npr_node, /* CMPL_LOGO */ lpfc_cmpl_logo_npr_node, /* CMPL_LOGO */
lpfc_disc_noop, /* CMPL_ADISC */ lpfc_cmpl_adisc_npr_node, /* CMPL_ADISC */
lpfc_cmpl_reglogin_npr_node, /* CMPL_REG_LOGIN */ lpfc_cmpl_reglogin_npr_node, /* CMPL_REG_LOGIN */
lpfc_device_rm_npr_node, /* DEVICE_RM */ lpfc_device_rm_npr_node, /* DEVICE_RM */
lpfc_device_recov_npr_node, /* DEVICE_RECOVERY */ lpfc_device_recov_npr_node, /* DEVICE_RECOVERY */
...@@ -1852,10 +1901,10 @@ lpfc_disc_state_machine(struct lpfc_hba * phba, ...@@ -1852,10 +1901,10 @@ lpfc_disc_state_machine(struct lpfc_hba * phba,
ndlp->nlp_flag &= ~NLP_DELAY_REMOVE; ndlp->nlp_flag &= ~NLP_DELAY_REMOVE;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
lpfc_nlp_remove(phba, ndlp); lpfc_nlp_remove(phba, ndlp);
return (NLP_STE_FREED_NODE); return NLP_STE_FREED_NODE;
} }
if (rc == NLP_STE_FREED_NODE) if (rc == NLP_STE_FREED_NODE)
return (NLP_STE_FREED_NODE); return NLP_STE_FREED_NODE;
ndlp->nlp_state = rc; ndlp->nlp_state = rc;
return (rc); return rc;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment