aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-01-26 23:08:03 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-02-08 19:38:28 -0500
commit695a814e18561c52456acf5051fac0ea4b8111da (patch)
tree3cbe747f38bbd5dae092e643de42be1a735d9552
parent341af10239c4c87192bf762f53c7bcb1f3a1e767 (diff)
[SCSI] lpfc 8.3.8: BugFixes: Discovery relates changes
Discovery relates changes: - Separated VPI_REGISTERED state of physical port into VFI_REGISTERED and VPI_REGISTERED state so that driver can unregister physical port VPI independent of VFI. - Add code to unregister, re-init and re-register physical port VPI when physical port NportID change. - Add code to unregister and re-register VPI of a vport when its Nport ID change. - Add code in FDISC completion path to re-start FLOGI discovery when a FDISC complete with LOGIN_REQUIRED reason code. - Fix a memory leak in lpfc_init_vpi_cmpl - Add code to start a timer for vport to retry FDISC when CVL is received by a vport or physical port. If all Nports receive CVLs, then all timers are cancelled and a logical link level discovery will be started after one second. - Flush ELS commands after killing all delayed ELS commands. Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/lpfc/lpfc.h3
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h5
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c129
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c36
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c44
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c62
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c2
8 files changed, 265 insertions, 18 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 1cc23a69db5e..197dc3e3bdc9 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -315,6 +315,9 @@ struct lpfc_vport {
315#define FC_VPORT_NEEDS_REG_VPI 0x80000 /* Needs to have its vpi registered */ 315#define FC_VPORT_NEEDS_REG_VPI 0x80000 /* Needs to have its vpi registered */
316#define FC_RSCN_DEFERRED 0x100000 /* A deferred RSCN being processed */ 316#define FC_RSCN_DEFERRED 0x100000 /* A deferred RSCN being processed */
317#define FC_VPORT_NEEDS_INIT_VPI 0x200000 /* Need to INIT_VPI before FDISC */ 317#define FC_VPORT_NEEDS_INIT_VPI 0x200000 /* Need to INIT_VPI before FDISC */
318#define FC_VPORT_CVL_RCVD 0x400000 /* VLink failed due to CVL */
319#define FC_VFI_REGISTERED 0x800000 /* VFI is registered */
320#define FC_FDISC_COMPLETED 0x1000000/* FDISC completed */
318 321
319 uint32_t ct_flags; 322 uint32_t ct_flags;
320#define FC_CT_RFF_ID 0x1 /* RFF_ID accepted by switch */ 323#define FC_CT_RFF_ID 0x1 /* RFF_ID accepted by switch */
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 14ee7d4f71ba..b9e8cd5b818a 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -44,6 +44,8 @@ int lpfc_reg_rpi(struct lpfc_hba *, uint16_t, uint32_t, uint8_t *,
44void lpfc_unreg_login(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *); 44void lpfc_unreg_login(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
45void lpfc_unreg_did(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *); 45void lpfc_unreg_did(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *);
46void lpfc_reg_vpi(struct lpfc_vport *, LPFC_MBOXQ_t *); 46void lpfc_reg_vpi(struct lpfc_vport *, LPFC_MBOXQ_t *);
47void lpfc_register_new_vport(struct lpfc_hba *, struct lpfc_vport *,
48 struct lpfc_nodelist *);
47void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *); 49void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *);
48void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); 50void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
49void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *); 51void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *);
@@ -52,10 +54,13 @@ struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t);
52void lpfc_cleanup_rcv_buffers(struct lpfc_vport *); 54void lpfc_cleanup_rcv_buffers(struct lpfc_vport *);
53void lpfc_rcv_seq_check_edtov(struct lpfc_vport *); 55void lpfc_rcv_seq_check_edtov(struct lpfc_vport *);
54void lpfc_cleanup_rpis(struct lpfc_vport *, int); 56void lpfc_cleanup_rpis(struct lpfc_vport *, int);
57void lpfc_cleanup_pending_mbox(struct lpfc_vport *);
55int lpfc_linkdown(struct lpfc_hba *); 58int lpfc_linkdown(struct lpfc_hba *);
56void lpfc_linkdown_port(struct lpfc_vport *); 59void lpfc_linkdown_port(struct lpfc_vport *);
57void lpfc_port_link_failure(struct lpfc_vport *); 60void lpfc_port_link_failure(struct lpfc_vport *);
58void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); 61void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
62void lpfc_init_vpi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
63void lpfc_retry_pport_discovery(struct lpfc_hba *);
59 64
60void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); 65void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
61void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *); 66void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *);
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 32e3c8df22c5..2c62349a1041 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -50,9 +50,6 @@ static int lpfc_issue_els_fdisc(struct lpfc_vport *vport,
50 struct lpfc_nodelist *ndlp, uint8_t retry); 50 struct lpfc_nodelist *ndlp, uint8_t retry);
51static int lpfc_issue_fabric_iocb(struct lpfc_hba *phba, 51static int lpfc_issue_fabric_iocb(struct lpfc_hba *phba,
52 struct lpfc_iocbq *iocb); 52 struct lpfc_iocbq *iocb);
53static void lpfc_register_new_vport(struct lpfc_hba *phba,
54 struct lpfc_vport *vport,
55 struct lpfc_nodelist *ndlp);
56 53
57static int lpfc_max_els_tries = 3; 54static int lpfc_max_els_tries = 3;
58 55
@@ -604,10 +601,13 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
604 } else { 601 } else {
605 ndlp->nlp_type |= NLP_FABRIC; 602 ndlp->nlp_type |= NLP_FABRIC;
606 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); 603 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
607 if (vport->vpi_state & LPFC_VPI_REGISTERED) { 604 if ((!(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) &&
605 (vport->vpi_state & LPFC_VPI_REGISTERED)) {
608 lpfc_start_fdiscs(phba); 606 lpfc_start_fdiscs(phba);
609 lpfc_do_scr_ns_plogi(phba, vport); 607 lpfc_do_scr_ns_plogi(phba, vport);
610 } else 608 } else if (vport->fc_flag & FC_VFI_REGISTERED)
609 lpfc_register_new_vport(phba, vport, ndlp);
610 else
611 lpfc_issue_reg_vfi(vport); 611 lpfc_issue_reg_vfi(vport);
612 } 612 }
613 return 0; 613 return 0;
@@ -804,6 +804,9 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
804 irsp->ulpTimeout); 804 irsp->ulpTimeout);
805 goto flogifail; 805 goto flogifail;
806 } 806 }
807 spin_lock_irq(shost->host_lock);
808 vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
809 spin_unlock_irq(shost->host_lock);
807 810
808 /* 811 /*
809 * The FLogI succeeded. Sync the data for the CPU before 812 * The FLogI succeeded. Sync the data for the CPU before
@@ -2720,7 +2723,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2720 if (did == FDMI_DID) 2723 if (did == FDMI_DID)
2721 retry = 1; 2724 retry = 1;
2722 2725
2723 if ((cmd == ELS_CMD_FLOGI) && 2726 if (((cmd == ELS_CMD_FLOGI) || (cmd == ELS_CMD_FDISC)) &&
2724 (phba->fc_topology != TOPOLOGY_LOOP) && 2727 (phba->fc_topology != TOPOLOGY_LOOP) &&
2725 !lpfc_error_lost_link(irsp)) { 2728 !lpfc_error_lost_link(irsp)) {
2726 /* FLOGI retry policy */ 2729 /* FLOGI retry policy */
@@ -5915,6 +5918,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5915 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 5918 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5916 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; 5919 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
5917 MAILBOX_t *mb = &pmb->u.mb; 5920 MAILBOX_t *mb = &pmb->u.mb;
5921 int rc;
5918 5922
5919 spin_lock_irq(shost->host_lock); 5923 spin_lock_irq(shost->host_lock);
5920 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; 5924 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
@@ -5936,6 +5940,26 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5936 spin_unlock_irq(shost->host_lock); 5940 spin_unlock_irq(shost->host_lock);
5937 lpfc_can_disctmo(vport); 5941 lpfc_can_disctmo(vport);
5938 break; 5942 break;
5943 /* If reg_vpi fail with invalid VPI status, re-init VPI */
5944 case 0x20:
5945 spin_lock_irq(shost->host_lock);
5946 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
5947 spin_unlock_irq(shost->host_lock);
5948 lpfc_init_vpi(phba, pmb, vport->vpi);
5949 pmb->vport = vport;
5950 pmb->mbox_cmpl = lpfc_init_vpi_cmpl;
5951 rc = lpfc_sli_issue_mbox(phba, pmb,
5952 MBX_NOWAIT);
5953 if (rc == MBX_NOT_FINISHED) {
5954 lpfc_printf_vlog(vport,
5955 KERN_ERR, LOG_MBOX,
5956 "2732 Failed to issue INIT_VPI"
5957 " mailbox command\n");
5958 } else {
5959 lpfc_nlp_put(ndlp);
5960 return;
5961 }
5962
5939 default: 5963 default:
5940 /* Try to recover from this error */ 5964 /* Try to recover from this error */
5941 lpfc_mbx_unreg_vpi(vport); 5965 lpfc_mbx_unreg_vpi(vport);
@@ -5949,13 +5973,17 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5949 break; 5973 break;
5950 } 5974 }
5951 } else { 5975 } else {
5976 spin_lock_irq(shost->host_lock);
5952 vport->vpi_state |= LPFC_VPI_REGISTERED; 5977 vport->vpi_state |= LPFC_VPI_REGISTERED;
5953 if (vport == phba->pport) 5978 spin_unlock_irq(shost->host_lock);
5979 if (vport == phba->pport) {
5954 if (phba->sli_rev < LPFC_SLI_REV4) 5980 if (phba->sli_rev < LPFC_SLI_REV4)
5955 lpfc_issue_fabric_reglogin(vport); 5981 lpfc_issue_fabric_reglogin(vport);
5956 else 5982 else {
5957 lpfc_issue_reg_vfi(vport); 5983 lpfc_start_fdiscs(phba);
5958 else 5984 lpfc_do_scr_ns_plogi(phba, vport);
5985 }
5986 } else
5959 lpfc_do_scr_ns_plogi(phba, vport); 5987 lpfc_do_scr_ns_plogi(phba, vport);
5960 } 5988 }
5961 5989
@@ -5977,7 +6005,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5977 * This routine registers the @vport as a new virtual port with a HBA. 6005 * This routine registers the @vport as a new virtual port with a HBA.
5978 * It is done through a registering vpi mailbox command. 6006 * It is done through a registering vpi mailbox command.
5979 **/ 6007 **/
5980static void 6008void
5981lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, 6009lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
5982 struct lpfc_nodelist *ndlp) 6010 struct lpfc_nodelist *ndlp)
5983{ 6011{
@@ -6018,6 +6046,78 @@ mbox_err_exit:
6018} 6046}
6019 6047
6020/** 6048/**
6049 * lpfc_retry_pport_discovery - Start timer to retry FLOGI.
6050 * @phba: pointer to lpfc hba data structure.
6051 *
6052 * This routine abort all pending discovery commands and
6053 * start a timer to retry FLOGI for the physical port
6054 * discovery.
6055 **/
6056void
6057lpfc_retry_pport_discovery(struct lpfc_hba *phba)
6058{
6059 struct lpfc_vport **vports;
6060 struct lpfc_nodelist *ndlp;
6061 struct Scsi_Host *shost;
6062 int i;
6063 uint32_t link_state;
6064
6065 /* Treat this failure as linkdown for all vports */
6066 link_state = phba->link_state;
6067 lpfc_linkdown(phba);
6068 phba->link_state = link_state;
6069
6070 vports = lpfc_create_vport_work_array(phba);
6071
6072 if (vports) {
6073 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
6074 ndlp = lpfc_findnode_did(vports[i], Fabric_DID);
6075 if (ndlp)
6076 lpfc_cancel_retry_delay_tmo(vports[i], ndlp);
6077 lpfc_els_flush_cmd(vports[i]);
6078 }
6079 lpfc_destroy_vport_work_array(phba, vports);
6080 }
6081
6082 /* If fabric require FLOGI, then re-instantiate physical login */
6083 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
6084 if (!ndlp)
6085 return;
6086
6087
6088 shost = lpfc_shost_from_vport(phba->pport);
6089 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
6090 spin_lock_irq(shost->host_lock);
6091 ndlp->nlp_flag |= NLP_DELAY_TMO;
6092 spin_unlock_irq(shost->host_lock);
6093 ndlp->nlp_last_elscmd = ELS_CMD_FLOGI;
6094 phba->pport->port_state = LPFC_FLOGI;
6095 return;
6096}
6097
6098/**
6099 * lpfc_fabric_login_reqd - Check if FLOGI required.
6100 * @phba: pointer to lpfc hba data structure.
6101 * @cmdiocb: pointer to FDISC command iocb.
6102 * @rspiocb: pointer to FDISC response iocb.
6103 *
6104 * This routine checks if a FLOGI is reguired for FDISC
6105 * to succeed.
6106 **/
6107static int
6108lpfc_fabric_login_reqd(struct lpfc_hba *phba,
6109 struct lpfc_iocbq *cmdiocb,
6110 struct lpfc_iocbq *rspiocb)
6111{
6112
6113 if ((rspiocb->iocb.ulpStatus != IOSTAT_FABRIC_RJT) ||
6114 (rspiocb->iocb.un.ulpWord[4] != RJT_LOGIN_REQUIRED))
6115 return 0;
6116 else
6117 return 1;
6118}
6119
6120/**
6021 * lpfc_cmpl_els_fdisc - Completion function for fdisc iocb command 6121 * lpfc_cmpl_els_fdisc - Completion function for fdisc iocb command
6022 * @phba: pointer to lpfc hba data structure. 6122 * @phba: pointer to lpfc hba data structure.
6023 * @cmdiocb: pointer to lpfc command iocb data structure. 6123 * @cmdiocb: pointer to lpfc command iocb data structure.
@@ -6066,6 +6166,12 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6066 irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID); 6166 irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID);
6067 6167
6068 if (irsp->ulpStatus) { 6168 if (irsp->ulpStatus) {
6169
6170 if (lpfc_fabric_login_reqd(phba, cmdiocb, rspiocb)) {
6171 lpfc_retry_pport_discovery(phba);
6172 goto out;
6173 }
6174
6069 /* Check for retry */ 6175 /* Check for retry */
6070 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) 6176 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
6071 goto out; 6177 goto out;
@@ -6076,6 +6182,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6076 goto fdisc_failed; 6182 goto fdisc_failed;
6077 } 6183 }
6078 spin_lock_irq(shost->host_lock); 6184 spin_lock_irq(shost->host_lock);
6185 vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
6079 vport->fc_flag |= FC_FABRIC; 6186 vport->fc_flag |= FC_FABRIC;
6080 if (vport->phba->fc_topology == TOPOLOGY_LOOP) 6187 if (vport->phba->fc_topology == TOPOLOGY_LOOP)
6081 vport->fc_flag |= FC_PUBLIC_LOOP; 6188 vport->fc_flag |= FC_PUBLIC_LOOP;
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 2445e399fd60..7143d71c501f 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -706,6 +706,8 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove)
706void 706void
707lpfc_port_link_failure(struct lpfc_vport *vport) 707lpfc_port_link_failure(struct lpfc_vport *vport)
708{ 708{
709 lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN);
710
709 /* Cleanup any outstanding received buffers */ 711 /* Cleanup any outstanding received buffers */
710 lpfc_cleanup_rcv_buffers(vport); 712 lpfc_cleanup_rcv_buffers(vport);
711 713
@@ -1695,10 +1697,11 @@ out:
1695 * 1697 *
1696 * This function handles completion of init vpi mailbox command. 1698 * This function handles completion of init vpi mailbox command.
1697 */ 1699 */
1698static void 1700void
1699lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) 1701lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1700{ 1702{
1701 struct lpfc_vport *vport = mboxq->vport; 1703 struct lpfc_vport *vport = mboxq->vport;
1704 struct lpfc_nodelist *ndlp;
1702 if (mboxq->u.mb.mbxStatus) { 1705 if (mboxq->u.mb.mbxStatus) {
1703 lpfc_printf_vlog(vport, KERN_ERR, 1706 lpfc_printf_vlog(vport, KERN_ERR,
1704 LOG_MBOX, 1707 LOG_MBOX,
@@ -1712,6 +1715,20 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1712 vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; 1715 vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI;
1713 spin_unlock_irq(&phba->hbalock); 1716 spin_unlock_irq(&phba->hbalock);
1714 1717
1718 /* If this port is physical port or FDISC is done, do reg_vpi */
1719 if ((phba->pport == vport) || (vport->port_state == LPFC_FDISC)) {
1720 ndlp = lpfc_findnode_did(vport, Fabric_DID);
1721 if (!ndlp)
1722 lpfc_printf_vlog(vport, KERN_ERR,
1723 LOG_DISCOVERY,
1724 "2731 Cannot find fabric "
1725 "controller node\n");
1726 else
1727 lpfc_register_new_vport(phba, vport, ndlp);
1728 mempool_free(mboxq, phba->mbox_mem_pool);
1729 return;
1730 }
1731
1715 if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) 1732 if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
1716 lpfc_initial_fdisc(vport); 1733 lpfc_initial_fdisc(vport);
1717 else { 1734 else {
@@ -1719,6 +1736,7 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1719 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, 1736 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1720 "2606 No NPIV Fabric support\n"); 1737 "2606 No NPIV Fabric support\n");
1721 } 1738 }
1739 mempool_free(mboxq, phba->mbox_mem_pool);
1722 return; 1740 return;
1723} 1741}
1724 1742
@@ -1814,6 +1832,9 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1814 } 1832 }
1815 /* The VPI is implicitly registered when the VFI is registered */ 1833 /* The VPI is implicitly registered when the VFI is registered */
1816 vport->vpi_state |= LPFC_VPI_REGISTERED; 1834 vport->vpi_state |= LPFC_VPI_REGISTERED;
1835 vport->fc_flag |= FC_VFI_REGISTERED;
1836
1837 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
1817 1838
1818 if (vport->port_state == LPFC_FABRIC_CFG_LINK) { 1839 if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
1819 lpfc_start_fdiscs(phba); 1840 lpfc_start_fdiscs(phba);
@@ -2333,6 +2354,7 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
2333 } 2354 }
2334 2355
2335 vport->vpi_state |= LPFC_VPI_REGISTERED; 2356 vport->vpi_state |= LPFC_VPI_REGISTERED;
2357 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
2336 vport->num_disc_nodes = 0; 2358 vport->num_disc_nodes = 0;
2337 /* go thru NPR list and issue ELS PLOGIs */ 2359 /* go thru NPR list and issue ELS PLOGIs */
2338 if (vport->fc_npr_cnt) 2360 if (vport->fc_npr_cnt)
@@ -4462,6 +4484,7 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba)
4462 int rc; 4484 int rc;
4463 struct lpfc_vport **vports; 4485 struct lpfc_vport **vports;
4464 int i; 4486 int i;
4487 struct lpfc_nodelist *ndlp;
4465 4488
4466 spin_lock_irq(&phba->hbalock); 4489 spin_lock_irq(&phba->hbalock);
4467 /* 4490 /*
@@ -4489,6 +4512,10 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba)
4489 if (vports && 4512 if (vports &&
4490 (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) 4513 (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED))
4491 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { 4514 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
4515 /* Stop FLOGI/FDISC retries */
4516 ndlp = lpfc_findnode_did(vports[i], Fabric_DID);
4517 if (ndlp)
4518 lpfc_cancel_retry_delay_tmo(vports[i], ndlp);
4492 lpfc_mbx_unreg_vpi(vports[i]); 4519 lpfc_mbx_unreg_vpi(vports[i]);
4493 spin_lock_irq(&phba->hbalock); 4520 spin_lock_irq(&phba->hbalock);
4494 vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; 4521 vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
@@ -4497,6 +4524,9 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba)
4497 } 4524 }
4498 lpfc_destroy_vport_work_array(phba, vports); 4525 lpfc_destroy_vport_work_array(phba, vports);
4499 4526
4527 /* Cleanup any outstanding ELS commands */
4528 lpfc_els_flush_all_cmd(phba);
4529
4500 /* Unregister VFI */ 4530 /* Unregister VFI */
4501 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 4531 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
4502 if (!mbox) { 4532 if (!mbox) {
@@ -4521,6 +4551,10 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba)
4521 return; 4551 return;
4522 } 4552 }
4523 4553
4554 spin_lock_irq(&phba->hbalock);
4555 phba->pport->fc_flag &= ~FC_VFI_REGISTERED;
4556 spin_unlock_irq(&phba->hbalock);
4557
4524 /* Unregister FCF */ 4558 /* Unregister FCF */
4525 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 4559 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
4526 if (!mbox) { 4560 if (!mbox) {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index b8eb1b6e5e77..4d20c4148fae 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2246,6 +2246,9 @@ lpfc_offline_prep(struct lpfc_hba * phba)
2246 if (vports[i]->load_flag & FC_UNLOADING) 2246 if (vports[i]->load_flag & FC_UNLOADING)
2247 continue; 2247 continue;
2248 vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; 2248 vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED;
2249 vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
2250 vports[i]->fc_flag &= ~FC_VFI_REGISTERED;
2251
2249 shost = lpfc_shost_from_vport(vports[i]); 2252 shost = lpfc_shost_from_vport(vports[i]);
2250 list_for_each_entry_safe(ndlp, next_ndlp, 2253 list_for_each_entry_safe(ndlp, next_ndlp,
2251 &vports[i]->fc_nodes, 2254 &vports[i]->fc_nodes,
@@ -3007,6 +3010,9 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
3007 struct lpfc_nodelist *ndlp; 3010 struct lpfc_nodelist *ndlp;
3008 struct Scsi_Host *shost; 3011 struct Scsi_Host *shost;
3009 uint32_t link_state; 3012 uint32_t link_state;
3013 int active_vlink_present;
3014 struct lpfc_vport **vports;
3015 int i;
3010 3016
3011 phba->fc_eventTag = acqe_fcoe->event_tag; 3017 phba->fc_eventTag = acqe_fcoe->event_tag;
3012 phba->fcoe_eventtag = acqe_fcoe->event_tag; 3018 phba->fcoe_eventtag = acqe_fcoe->event_tag;
@@ -3074,14 +3080,46 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
3074 if (!ndlp) 3080 if (!ndlp)
3075 break; 3081 break;
3076 shost = lpfc_shost_from_vport(vport); 3082 shost = lpfc_shost_from_vport(vport);
3083 if (phba->pport->port_state <= LPFC_FLOGI)
3084 break;
3085 /* If virtual link is not yet instantiated ignore CVL */
3086 if (vport->port_state <= LPFC_FDISC)
3087 break;
3088
3077 lpfc_linkdown_port(vport); 3089 lpfc_linkdown_port(vport);
3078 if (vport->port_type != LPFC_NPIV_PORT) { 3090 lpfc_cleanup_pending_mbox(vport);
3091 spin_lock_irq(shost->host_lock);
3092 vport->fc_flag |= FC_VPORT_CVL_RCVD;
3093 spin_unlock_irq(shost->host_lock);
3094 active_vlink_present = 0;
3095
3096 vports = lpfc_create_vport_work_array(phba);
3097 if (vports) {
3098 for (i = 0; i <= phba->max_vports && vports[i] != NULL;
3099 i++) {
3100 if ((!(vports[i]->fc_flag &
3101 FC_VPORT_CVL_RCVD)) &&
3102 (vports[i]->port_state > LPFC_FDISC)) {
3103 active_vlink_present = 1;
3104 break;
3105 }
3106 }
3107 lpfc_destroy_vport_work_array(phba, vports);
3108 }
3109
3110 if (active_vlink_present) {
3111 /*
3112 * If there are other active VLinks present,
3113 * re-instantiate the Vlink using FDISC.
3114 */
3079 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); 3115 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
3080 spin_lock_irq(shost->host_lock); 3116 spin_lock_irq(shost->host_lock);
3081 ndlp->nlp_flag |= NLP_DELAY_TMO; 3117 ndlp->nlp_flag |= NLP_DELAY_TMO;
3082 spin_unlock_irq(shost->host_lock); 3118 spin_unlock_irq(shost->host_lock);
3083 ndlp->nlp_last_elscmd = ELS_CMD_FLOGI; 3119 ndlp->nlp_last_elscmd = ELS_CMD_FDISC;
3084 vport->port_state = LPFC_FLOGI; 3120 vport->port_state = LPFC_FDISC;
3121 } else {
3122 lpfc_retry_pport_discovery(phba);
3085 } 3123 }
3086 break; 3124 break;
3087 default: 3125 default:
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 293234a5a944..d20ae6b3b3cf 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -254,7 +254,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
254 int rc; 254 int rc;
255 255
256 memset(&stat, 0, sizeof (struct ls_rjt)); 256 memset(&stat, 0, sizeof (struct ls_rjt));
257 if (vport->port_state <= LPFC_FLOGI) { 257 if (vport->port_state <= LPFC_FDISC) {
258 /* Before responding to PLOGI, check for pt2pt mode. 258 /* Before responding to PLOGI, check for pt2pt mode.
259 * If we are pt2pt, with an outstanding FLOGI, abort 259 * If we are pt2pt, with an outstanding FLOGI, abort
260 * the FLOGI and resend it first. 260 * the FLOGI and resend it first.
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index dc7c5c1231df..8d666d9fabb4 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1710,6 +1710,7 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1710 struct lpfc_dmabuf *mp; 1710 struct lpfc_dmabuf *mp;
1711 uint16_t rpi, vpi; 1711 uint16_t rpi, vpi;
1712 int rc; 1712 int rc;
1713 struct lpfc_vport *vport = pmb->vport;
1713 1714
1714 mp = (struct lpfc_dmabuf *) (pmb->context1); 1715 mp = (struct lpfc_dmabuf *) (pmb->context1);
1715 1716
@@ -1738,6 +1739,18 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1738 return; 1739 return;
1739 } 1740 }
1740 1741
1742 /* Unreg VPI, if the REG_VPI succeed after VLink failure */
1743 if ((pmb->u.mb.mbxCommand == MBX_REG_VPI) &&
1744 !(phba->pport->load_flag & FC_UNLOADING) &&
1745 !pmb->u.mb.mbxStatus) {
1746 lpfc_unreg_vpi(phba, pmb->u.mb.un.varRegVpi.vpi, pmb);
1747 pmb->vport = vport;
1748 pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1749 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
1750 if (rc != MBX_NOT_FINISHED)
1751 return;
1752 }
1753
1741 if (bf_get(lpfc_mqe_command, &pmb->u.mqe) == MBX_SLI4_CONFIG) 1754 if (bf_get(lpfc_mqe_command, &pmb->u.mqe) == MBX_SLI4_CONFIG)
1742 lpfc_sli4_mbox_cmd_free(phba, pmb); 1755 lpfc_sli4_mbox_cmd_free(phba, pmb);
1743 else 1756 else
@@ -8440,8 +8453,10 @@ lpfc_sli4_iocb_param_transfer(struct lpfc_hba *phba,
8440 wcqe->total_data_placed; 8453 wcqe->total_data_placed;
8441 else 8454 else
8442 pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter; 8455 pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter;
8443 else 8456 else {
8444 pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter; 8457 pIocbIn->iocb.un.ulpWord[4] = wcqe->parameter;
8458 pIocbIn->iocb.un.genreq64.bdl.bdeSize = wcqe->total_data_placed;
8459 }
8445 8460
8446 /* Pick up HBA exchange busy condition */ 8461 /* Pick up HBA exchange busy condition */
8447 if (bf_get(lpfc_wcqe_c_xb, wcqe)) { 8462 if (bf_get(lpfc_wcqe_c_xb, wcqe)) {
@@ -12139,3 +12154,48 @@ out:
12139 kfree(rgn23_data); 12154 kfree(rgn23_data);
12140 return; 12155 return;
12141} 12156}
12157
12158/**
12159 * lpfc_cleanup_pending_mbox - Free up vport discovery mailbox commands.
12160 * @vport: pointer to vport data structure.
12161 *
12162 * This function iterate through the mailboxq and clean up all REG_LOGIN
12163 * and REG_VPI mailbox commands associated with the vport. This function
12164 * is called when driver want to restart discovery of the vport due to
12165 * a Clear Virtual Link event.
12166 **/
12167void
12168lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
12169{
12170 struct lpfc_hba *phba = vport->phba;
12171 LPFC_MBOXQ_t *mb, *nextmb;
12172 struct lpfc_dmabuf *mp;
12173
12174 spin_lock_irq(&phba->hbalock);
12175 list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
12176 if (mb->vport != vport)
12177 continue;
12178
12179 if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) &&
12180 (mb->u.mb.mbxCommand != MBX_REG_VPI))
12181 continue;
12182
12183 if (mb->u.mb.mbxCommand == MBX_REG_LOGIN64) {
12184 mp = (struct lpfc_dmabuf *) (mb->context1);
12185 if (mp) {
12186 __lpfc_mbuf_free(phba, mp->virt, mp->phys);
12187 kfree(mp);
12188 }
12189 }
12190 list_del(&mb->list);
12191 mempool_free(mb, phba->mbox_mem_pool);
12192 }
12193 mb = phba->sli.mbox_active;
12194 if (mb && (mb->vport == vport)) {
12195 if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) ||
12196 (mb->u.mb.mbxCommand == MBX_REG_VPI))
12197 mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
12198 }
12199 spin_unlock_irq(&phba->hbalock);
12200}
12201
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index e3c7fa642306..281ff033a7b2 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -389,7 +389,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
389 * by the port. 389 * by the port.
390 */ 390 */
391 if ((phba->sli_rev == LPFC_SLI_REV4) && 391 if ((phba->sli_rev == LPFC_SLI_REV4) &&
392 (pport->vpi_state & LPFC_VPI_REGISTERED)) { 392 (pport->fc_flag & FC_VFI_REGISTERED)) {
393 rc = lpfc_sli4_init_vpi(phba, vpi); 393 rc = lpfc_sli4_init_vpi(phba, vpi);
394 if (rc) { 394 if (rc) {
395 lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, 395 lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,