Commit 5024ab17 authored by Jamie Wellnitz's avatar Jamie Wellnitz Committed by James Bottomley

[SCSI] lpfc 8.1.2: Added support for FAN

Added support for FAN
Signed-off-by: default avatarJamie Wellnitz <Jamie.Wellnitz@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 41415862
...@@ -62,6 +62,7 @@ struct lpfc_nodelist { ...@@ -62,6 +62,7 @@ struct lpfc_nodelist {
uint16_t nlp_rpi; uint16_t nlp_rpi;
uint16_t nlp_state; /* state transition indicator */ uint16_t nlp_state; /* state transition indicator */
uint16_t nlp_prev_state; /* state transition indicator */
uint16_t nlp_xri; /* output exchange id for RPI */ uint16_t nlp_xri; /* output exchange id for RPI */
uint16_t nlp_sid; /* scsi id */ uint16_t nlp_sid; /* scsi id */
#define NLP_NO_SID 0xffff #define NLP_NO_SID 0xffff
......
...@@ -1201,12 +1201,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1201,12 +1201,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
NLP_EVT_CMPL_LOGO); NLP_EVT_CMPL_LOGO);
} }
} else { } else {
/* Good status, call state machine */ /* Good status, call state machine.
* This will unregister the rpi if needed.
*/
lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO); lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO);
if (ndlp->nlp_flag & NLP_DELAY_TMO) {
lpfc_unreg_rpi(phba, ndlp);
}
} }
out: out:
...@@ -1435,8 +1433,9 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) ...@@ -1435,8 +1433,9 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
phba = ndlp->nlp_phba; phba = ndlp->nlp_phba;
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
did = (uint32_t) (ndlp->nlp_DID); did = ndlp->nlp_DID;
cmd = (uint32_t) (ndlp->nlp_last_elscmd); cmd = ndlp->nlp_last_elscmd;
ndlp->nlp_last_elscmd = 0;
if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
...@@ -1453,24 +1452,28 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) ...@@ -1453,24 +1452,28 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
break; break;
case ELS_CMD_PLOGI: case ELS_CMD_PLOGI:
if (!lpfc_issue_els_plogi(phba, ndlp, retry)) { if (!lpfc_issue_els_plogi(phba, ndlp, retry)) {
ndlp->nlp_prev_state = 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);
} }
break; break;
case ELS_CMD_ADISC: case ELS_CMD_ADISC:
if (!lpfc_issue_els_adisc(phba, ndlp, retry)) { if (!lpfc_issue_els_adisc(phba, ndlp, retry)) {
ndlp->nlp_prev_state = ndlp->nlp_state;
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);
} }
break; break;
case ELS_CMD_PRLI: case ELS_CMD_PRLI:
if (!lpfc_issue_els_prli(phba, ndlp, retry)) { if (!lpfc_issue_els_prli(phba, ndlp, retry)) {
ndlp->nlp_prev_state = ndlp->nlp_state;
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);
} }
break; break;
case ELS_CMD_LOGO: case ELS_CMD_LOGO:
if (!lpfc_issue_els_logo(phba, ndlp, retry)) { if (!lpfc_issue_els_logo(phba, ndlp, retry)) {
ndlp->nlp_prev_state = ndlp->nlp_state;
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);
} }
...@@ -1630,6 +1633,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1630,6 +1633,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
ndlp->nlp_flag |= NLP_DELAY_TMO; ndlp->nlp_flag |= NLP_DELAY_TMO;
ndlp->nlp_prev_state = ndlp->nlp_state;
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_last_elscmd = cmd; ndlp->nlp_last_elscmd = cmd;
...@@ -1641,21 +1645,25 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1641,21 +1645,25 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
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_prev_state = 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, cmdiocb->retry); lpfc_issue_els_plogi(phba, ndlp, cmdiocb->retry);
return 1; return 1;
case ELS_CMD_ADISC: case ELS_CMD_ADISC:
ndlp->nlp_prev_state = ndlp->nlp_state;
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_prev_state = ndlp->nlp_state;
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_prev_state = ndlp->nlp_state;
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);
...@@ -1719,10 +1727,6 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1719,10 +1727,6 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag,
ndlp->nlp_state, ndlp->nlp_rpi); ndlp->nlp_state, ndlp->nlp_rpi);
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~NLP_LOGO_ACC;
spin_unlock_irq(phba->host->host_lock);
switch (ndlp->nlp_state) { switch (ndlp->nlp_state) {
case NLP_STE_UNUSED_NODE: /* node is just allocated */ case NLP_STE_UNUSED_NODE: /* node is just allocated */
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
...@@ -1776,6 +1780,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1776,6 +1780,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
lpfc_unreg_rpi(phba, ndlp); lpfc_unreg_rpi(phba, ndlp);
mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
mbox->context2 = ndlp; mbox->context2 = ndlp;
ndlp->nlp_prev_state = ndlp->nlp_state;
ndlp->nlp_state = NLP_STE_REG_LOGIN_ISSUE; ndlp->nlp_state = NLP_STE_REG_LOGIN_ISSUE;
lpfc_nlp_list(phba, ndlp, NLP_REGLOGIN_LIST); lpfc_nlp_list(phba, ndlp, NLP_REGLOGIN_LIST);
if (lpfc_sli_issue_mbox(phba, mbox, if (lpfc_sli_issue_mbox(phba, mbox,
...@@ -1790,6 +1795,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ...@@ -1790,6 +1795,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
mempool_free( mbox, phba->mbox_mem_pool); mempool_free( mbox, phba->mbox_mem_pool);
if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
ndlp = NULL;
} }
} }
} }
...@@ -1827,6 +1833,7 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, ...@@ -1827,6 +1833,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) {
ndlp->nlp_flag &= ~NLP_LOGO_ACC;
return 1; return 1;
} }
icmd = &elsiocb->iocb; icmd = &elsiocb->iocb;
...@@ -2172,6 +2179,7 @@ lpfc_els_disc_adisc(struct lpfc_hba * phba) ...@@ -2172,6 +2179,7 @@ lpfc_els_disc_adisc(struct lpfc_hba * phba)
if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
if (ndlp->nlp_flag & NLP_NPR_ADISC) { if (ndlp->nlp_flag & NLP_NPR_ADISC) {
ndlp->nlp_flag &= ~NLP_NPR_ADISC; ndlp->nlp_flag &= ~NLP_NPR_ADISC;
ndlp->nlp_prev_state = ndlp->nlp_state;
ndlp->nlp_state = NLP_STE_ADISC_ISSUE; ndlp->nlp_state = NLP_STE_ADISC_ISSUE;
lpfc_nlp_list(phba, ndlp, lpfc_nlp_list(phba, ndlp,
NLP_ADISC_LIST); NLP_ADISC_LIST);
...@@ -2209,6 +2217,7 @@ lpfc_els_disc_plogi(struct lpfc_hba * phba) ...@@ -2209,6 +2217,7 @@ lpfc_els_disc_plogi(struct lpfc_hba * phba)
if ((ndlp->nlp_flag & NLP_NPR_2B_DISC) && if ((ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
(!(ndlp->nlp_flag & NLP_DELAY_TMO))) { (!(ndlp->nlp_flag & NLP_DELAY_TMO))) {
if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
ndlp->nlp_prev_state = 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);
...@@ -2350,8 +2359,13 @@ lpfc_rscn_recovery_check(struct lpfc_hba * phba) ...@@ -2350,8 +2359,13 @@ lpfc_rscn_recovery_check(struct lpfc_hba * phba)
lpfc_disc_state_machine(phba, ndlp, NULL, lpfc_disc_state_machine(phba, ndlp, NULL,
NLP_EVT_DEVICE_RECOVERY); NLP_EVT_DEVICE_RECOVERY);
/* Make sure NLP_DELAY_TMO is NOT running
* after a device recovery event.
*/
if (ndlp->nlp_flag & NLP_DELAY_TMO) { if (ndlp->nlp_flag & NLP_DELAY_TMO) {
ndlp->nlp_flag &= ~NLP_DELAY_TMO; ndlp->nlp_flag &= ~NLP_DELAY_TMO;
ndlp->nlp_last_elscmd = 0;
del_timer_sync(&ndlp->nlp_delayfunc); del_timer_sync(&ndlp->nlp_delayfunc);
if (!list_empty(&ndlp-> if (!list_empty(&ndlp->
els_retry_evt.evt_listp)) els_retry_evt.evt_listp))
...@@ -2503,6 +2517,7 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) ...@@ -2503,6 +2517,7 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba)
} 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;
ndlp->nlp_prev_state = ndlp->nlp_state;
ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; ndlp->nlp_state = NLP_STE_PLOGI_ISSUE;
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
...@@ -2930,6 +2945,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, ...@@ -2930,6 +2945,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba,
(ndlp->nlp_state == NLP_STE_MAPPED_NODE)) { (ndlp->nlp_state == NLP_STE_MAPPED_NODE)) {
/* Log back into the node before sending the FARP. */ /* Log back into the node before sending the FARP. */
if (fp->Rflags & FARP_REQUEST_PLOGI) { if (fp->Rflags & FARP_REQUEST_PLOGI) {
ndlp->nlp_prev_state = 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);
...@@ -2974,46 +2990,89 @@ lpfc_els_rcv_farpr(struct lpfc_hba * phba, ...@@ -2974,46 +2990,89 @@ lpfc_els_rcv_farpr(struct lpfc_hba * phba,
static int static int
lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
struct lpfc_nodelist * ndlp) struct lpfc_nodelist * fan_ndlp)
{ {
struct lpfc_dmabuf *pcmd; struct lpfc_dmabuf *pcmd;
uint32_t *lp; uint32_t *lp;
IOCB_t *icmd; IOCB_t *icmd;
FAN *fp;
uint32_t cmd, did; uint32_t cmd, did;
FAN *fp;
struct lpfc_nodelist *ndlp, *next_ndlp;
/* FAN received */
lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:265 FAN received\n",
phba->brd_no);
icmd = &cmdiocb->iocb; icmd = &cmdiocb->iocb;
did = icmd->un.elsreq64.remoteID; did = icmd->un.elsreq64.remoteID;
pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; pcmd = (struct lpfc_dmabuf *)cmdiocb->context2;
lp = (uint32_t *) pcmd->virt; lp = (uint32_t *)pcmd->virt;
cmd = *lp++; cmd = *lp++;
fp = (FAN *) lp; fp = (FAN *)lp;
/* FAN received */ /* FAN received; Fan does not have a reply sequence */
/* ACCEPT the FAN request */
lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { if (phba->hba_state == LPFC_LOCAL_CFG_LINK) {
/* The discovery state machine needs to take a different if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName,
* action if this node has switched fabrics sizeof(struct lpfc_name)) != 0) ||
*/ (memcmp(&phba->fc_fabparam.portName, &fp->FportName,
if ((memcmp(&fp->FportName, &phba->fc_fabparam.portName, sizeof(struct lpfc_name)) != 0)) {
sizeof (struct lpfc_name)) != 0) /*
|| * This node has switched fabrics. FLOGI is required
(memcmp(&fp->FnodeName, &phba->fc_fabparam.nodeName, * Clean up the old rpi's
sizeof (struct lpfc_name)) != 0)) {
/* This node has switched fabrics. An FLOGI is required
* after the timeout
*/ */
list_for_each_entry_safe(ndlp, next_ndlp,
&phba->fc_npr_list, nlp_listp) {
if (ndlp->nlp_type & NLP_FABRIC) {
/*
* Clean up old Fabric, Nameserver and
* other NLP_FABRIC logins
*/
lpfc_nlp_list(phba, ndlp, NLP_NO_LIST);
}
else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
/* Fail outstanding I/O now since this
* device is marked for PLOGI
*/
lpfc_unreg_rpi(phba, ndlp);
}
}
phba->hba_state = LPFC_FLOGI;
lpfc_set_disctmo(phba);
lpfc_initial_flogi(phba);
return 0; return 0;
} }
/* Discovery not needed,
* move the nodes to their original state.
*/
list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list,
nlp_listp) {
/* Start discovery */ switch (ndlp->nlp_prev_state) {
case NLP_STE_UNMAPPED_NODE:
ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
break;
case NLP_STE_MAPPED_NODE:
ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
ndlp->nlp_state = NLP_STE_MAPPED_NODE;
lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST);
break;
default:
break;
}
}
/* Start discovery - this should just do CLEAR_LA */
lpfc_disc_start(phba); lpfc_disc_start(phba);
} }
return 0; return 0;
} }
......
...@@ -309,14 +309,12 @@ lpfc_linkdown(struct lpfc_hba * phba) ...@@ -309,14 +309,12 @@ lpfc_linkdown(struct lpfc_hba * phba)
LPFC_MBOXQ_t *mb; LPFC_MBOXQ_t *mb;
int rc, i; int rc, i;
if (phba->hba_state == LPFC_LINK_DOWN) {
return 0;
}
psli = &phba->sli; psli = &phba->sli;
/* sysfs or selective reset may call this routine to clean up */ /* sysfs or selective reset may call this routine to clean up */
if (phba->hba_state > LPFC_LINK_DOWN) { if (phba->hba_state >= LPFC_LINK_DOWN) {
if (phba->hba_state == LPFC_LINK_DOWN)
return 0;
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
phba->hba_state = LPFC_LINK_DOWN; phba->hba_state = LPFC_LINK_DOWN;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
...@@ -1172,6 +1170,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) ...@@ -1172,6 +1170,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list)
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
nlp->nlp_flag &= ~NLP_DELAY_TMO; nlp->nlp_flag &= ~NLP_DELAY_TMO;
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
nlp->nlp_last_elscmd = 0;
del_timer_sync(&nlp->nlp_delayfunc); del_timer_sync(&nlp->nlp_delayfunc);
if (!list_empty(&nlp->els_retry_evt.evt_listp)) if (!list_empty(&nlp->els_retry_evt.evt_listp))
list_del_init(&nlp->els_retry_evt.evt_listp); list_del_init(&nlp->els_retry_evt.evt_listp);
...@@ -1595,6 +1594,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) ...@@ -1595,6 +1594,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
del_timer_sync(&ndlp->nlp_tmofunc); del_timer_sync(&ndlp->nlp_tmofunc);
ndlp->nlp_last_elscmd = 0;
del_timer_sync(&ndlp->nlp_delayfunc); del_timer_sync(&ndlp->nlp_delayfunc);
if (!list_empty(&ndlp->nodev_timeout_evt.evt_listp)) if (!list_empty(&ndlp->nodev_timeout_evt.evt_listp))
...@@ -1630,6 +1630,7 @@ lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) ...@@ -1630,6 +1630,7 @@ lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
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_last_elscmd = 0;
del_timer_sync(&ndlp->nlp_delayfunc); del_timer_sync(&ndlp->nlp_delayfunc);
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);
......
...@@ -262,6 +262,7 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -262,6 +262,7 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
/* If we are delaying issuing an ELS command, cancel it */ /* If we are delaying issuing an ELS command, cancel it */
if (ndlp->nlp_flag & NLP_DELAY_TMO) { if (ndlp->nlp_flag & NLP_DELAY_TMO) {
ndlp->nlp_flag &= ~NLP_DELAY_TMO; ndlp->nlp_flag &= ~NLP_DELAY_TMO;
ndlp->nlp_last_elscmd = 0;
del_timer_sync(&ndlp->nlp_delayfunc); del_timer_sync(&ndlp->nlp_delayfunc);
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);
...@@ -398,16 +399,8 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, ...@@ -398,16 +399,8 @@ lpfc_rcv_plogi(struct lpfc_hba * phba,
*/ */
mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
mbox->context2 = ndlp; mbox->context2 = ndlp;
ndlp->nlp_flag |= NLP_ACC_REGLOGIN; ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI);
/* If there is an outstanding PLOGI issued, abort it before
* sending ACC rsp to PLOGI recieved.
*/
if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) {
/* software abort outstanding PLOGI */
lpfc_els_abort(phba, ndlp, 1);
}
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;
...@@ -465,13 +458,14 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, ...@@ -465,13 +458,14 @@ lpfc_rcv_padisc(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);
ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI;
/* 1 sec timeout */ /* 1 sec timeout */
mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
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_last_elscmd = ELS_CMD_PLOGI;
ndlp->nlp_prev_state = ndlp->nlp_state;
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;
...@@ -492,15 +486,17 @@ lpfc_rcv_logo(struct lpfc_hba * phba, ...@@ -492,15 +486,17 @@ lpfc_rcv_logo(struct lpfc_hba * phba,
if (!(ndlp->nlp_type & NLP_FABRIC) || if (!(ndlp->nlp_type & NLP_FABRIC) ||
(ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) {
/* Only try to re-login if this is NOT a Fabric Node */ /* Only try to re-login if this is NOT a Fabric Node */
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_last_elscmd = ELS_CMD_PLOGI;
ndlp->nlp_prev_state = ndlp->nlp_state;
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 { } else {
ndlp->nlp_prev_state = ndlp->nlp_state;
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);
} }
...@@ -595,6 +591,7 @@ lpfc_rcv_plogi_unused_node(struct lpfc_hba * phba, ...@@ -595,6 +591,7 @@ lpfc_rcv_plogi_unused_node(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)) {
ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
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;
...@@ -708,10 +705,6 @@ lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba, ...@@ -708,10 +705,6 @@ lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba,
/* software abort outstanding PLOGI */ /* software abort outstanding PLOGI */
lpfc_els_abort(phba, ndlp, 1); lpfc_els_abort(phba, ndlp, 1);
mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag |= NLP_DELAY_TMO;
spin_unlock_irq(phba->host->host_lock);
if (evt == NLP_EVT_RCV_LOGO) { if (evt == NLP_EVT_RCV_LOGO) {
lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
...@@ -721,7 +714,12 @@ lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba, ...@@ -721,7 +714,12 @@ lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba,
} }
/* Put ndlp in npr list set plogi timer for 1 sec */ /* Put ndlp in npr list set plogi timer for 1 sec */
ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag |= NLP_DELAY_TMO;
spin_unlock_irq(phba->host->host_lock);
ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE;
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);
...@@ -744,6 +742,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, ...@@ -744,6 +742,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) {
/* Recovery from PLOGI collision logic */
return ndlp->nlp_state; return ndlp->nlp_state;
} }
...@@ -859,6 +858,7 @@ lpfc_device_recov_plogi_issue(struct lpfc_hba * phba, ...@@ -859,6 +858,7 @@ lpfc_device_recov_plogi_issue(struct lpfc_hba * phba,
/* software abort outstanding PLOGI */ /* software abort outstanding PLOGI */
lpfc_els_abort(phba, ndlp, 1); lpfc_els_abort(phba, ndlp, 1);
ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE;
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);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
...@@ -883,6 +883,7 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba, ...@@ -883,6 +883,7 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba,
if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) {
return ndlp->nlp_state; return ndlp->nlp_state;
} }
ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
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);
...@@ -963,25 +964,29 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba, ...@@ -963,25 +964,29 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba,
if ((irsp->ulpStatus) || if ((irsp->ulpStatus) ||
(!lpfc_check_adisc(phba, ndlp, &ap->nodeName, &ap->portName))) { (!lpfc_check_adisc(phba, ndlp, &ap->nodeName, &ap->portName))) {
ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI;
/* 1 sec timeout */ /* 1 sec timeout */
mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
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_last_elscmd = ELS_CMD_PLOGI;
memset(&ndlp->nlp_nodename, 0, sizeof (struct lpfc_name)); memset(&ndlp->nlp_nodename, 0, sizeof (struct lpfc_name));
memset(&ndlp->nlp_portname, 0, sizeof (struct lpfc_name)); memset(&ndlp->nlp_portname, 0, sizeof (struct lpfc_name));
ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
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_prev_state = NLP_STE_ADISC_ISSUE;
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);
} else { } else {
ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
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);
} }
...@@ -1008,6 +1013,7 @@ lpfc_device_recov_adisc_issue(struct lpfc_hba * phba, ...@@ -1008,6 +1013,7 @@ lpfc_device_recov_adisc_issue(struct lpfc_hba * phba,
/* software abort outstanding ADISC */ /* software abort outstanding ADISC */
lpfc_els_abort(phba, ndlp, 1); lpfc_els_abort(phba, ndlp, 1);
ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
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);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
...@@ -1103,14 +1109,15 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, ...@@ -1103,14 +1109,15 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,
phba->brd_no, phba->brd_no,
did, mb->mbxStatus, phba->hba_state); did, mb->mbxStatus, phba->hba_state);
/* Put ndlp in npr list set plogi timer for 1 sec */
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_last_elscmd = ELS_CMD_PLOGI;
lpfc_issue_els_logo(phba, ndlp, 0); lpfc_issue_els_logo(phba, ndlp, 0);
/* Put ndlp in npr list set plogi timer for 1 sec */ ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
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;
...@@ -1120,10 +1127,12 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, ...@@ -1120,10 +1127,12 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba,
/* Only if we are not a fabric nport do we issue PRLI */ /* Only if we are not a fabric nport do we issue PRLI */
if (!(ndlp->nlp_type & NLP_FABRIC)) { if (!(ndlp->nlp_type & NLP_FABRIC)) {
ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
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, 0); lpfc_issue_els_prli(phba, ndlp, 0);
} else { } else {
ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
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);
} }
...@@ -1144,6 +1153,7 @@ lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba, ...@@ -1144,6 +1153,7 @@ lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba,
struct lpfc_nodelist * ndlp, void *arg, struct lpfc_nodelist * ndlp, void *arg,
uint32_t evt) uint32_t evt)
{ {
ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
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);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
...@@ -1233,6 +1243,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, ...@@ -1233,6 +1243,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba,
irsp = &rspiocb->iocb; irsp = &rspiocb->iocb;
if (irsp->ulpStatus) { if (irsp->ulpStatus) {
ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
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;
...@@ -1251,6 +1262,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, ...@@ -1251,6 +1262,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba,
ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
} }
ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
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;
...@@ -1308,6 +1320,7 @@ lpfc_device_recov_prli_issue(struct lpfc_hba * phba, ...@@ -1308,6 +1320,7 @@ lpfc_device_recov_prli_issue(struct lpfc_hba * phba,
/* software abort outstanding PRLI */ /* software abort outstanding PRLI */
lpfc_els_abort(phba, ndlp, 1); lpfc_els_abort(phba, ndlp, 1);
ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
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);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
...@@ -1381,6 +1394,7 @@ static uint32_t ...@@ -1381,6 +1394,7 @@ static uint32_t
lpfc_device_recov_unmap_node(struct lpfc_hba * phba, lpfc_device_recov_unmap_node(struct lpfc_hba * phba,
struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) struct lpfc_nodelist * ndlp, void *arg, uint32_t evt)
{ {
ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE;
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;
...@@ -1462,6 +1476,7 @@ lpfc_device_recov_mapped_node(struct lpfc_hba * phba, ...@@ -1462,6 +1476,7 @@ lpfc_device_recov_mapped_node(struct lpfc_hba * phba,
struct lpfc_nodelist * ndlp, void *arg, struct lpfc_nodelist * ndlp, void *arg,
uint32_t evt) uint32_t evt)
{ {
ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE;
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);
spin_lock_irq(phba->host->host_lock); spin_lock_irq(phba->host->host_lock);
...@@ -1494,6 +1509,7 @@ lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba, ...@@ -1494,6 +1509,7 @@ lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba,
/* send PLOGI immediately, move to PLOGI issue state */ /* send PLOGI immediately, move to PLOGI issue state */
if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
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);
...@@ -1521,10 +1537,12 @@ lpfc_rcv_prli_npr_node(struct lpfc_hba * phba, ...@@ -1521,10 +1537,12 @@ lpfc_rcv_prli_npr_node(struct lpfc_hba * phba,
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);
ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
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);
} else { } else {
ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
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);
...@@ -1559,10 +1577,12 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, ...@@ -1559,10 +1577,12 @@ lpfc_rcv_padisc_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) {
ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
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);
} else { } else {
ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
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);
...@@ -1592,6 +1612,7 @@ lpfc_rcv_prlo_npr_node(struct lpfc_hba * phba, ...@@ -1592,6 +1612,7 @@ lpfc_rcv_prlo_npr_node(struct lpfc_hba * phba,
ndlp->nlp_flag |= NLP_DELAY_TMO; ndlp->nlp_flag |= NLP_DELAY_TMO;
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);
ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
} else { } else {
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;
...@@ -1681,6 +1702,7 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba, ...@@ -1681,6 +1702,7 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba,
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);
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
ndlp->nlp_last_elscmd = 0;
del_timer_sync(&ndlp->nlp_delayfunc); del_timer_sync(&ndlp->nlp_delayfunc);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
...@@ -1905,6 +1927,5 @@ lpfc_disc_state_machine(struct lpfc_hba * phba, ...@@ -1905,6 +1927,5 @@ lpfc_disc_state_machine(struct lpfc_hba * phba,
} }
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;
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