diff options
author | James Smart <james.smart@emulex.com> | 2010-01-26 23:08:03 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-02-08 18:38:28 -0600 |
commit | 695a814e18561c52456acf5051fac0ea4b8111da (patch) | |
tree | 3cbe747f38bbd5dae092e643de42be1a735d9552 /drivers/scsi/lpfc/lpfc_hbadisc.c | |
parent | 341af10239c4c87192bf762f53c7bcb1f3a1e767 (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>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 36 |
1 files changed, 35 insertions, 1 deletions
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) void lpfc_port_link_failure(struct lpfc_vport *vport) { + lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN); + /* Cleanup any outstanding received buffers */ lpfc_cleanup_rcv_buffers(vport); @@ -1695,10 +1697,11 @@ out: * * This function handles completion of init vpi mailbox command. */ -static void +void lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) { struct lpfc_vport *vport = mboxq->vport; + struct lpfc_nodelist *ndlp; if (mboxq->u.mb.mbxStatus) { lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, @@ -1712,6 +1715,20 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; spin_unlock_irq(&phba->hbalock); + /* If this port is physical port or FDISC is done, do reg_vpi */ + if ((phba->pport == vport) || (vport->port_state == LPFC_FDISC)) { + ndlp = lpfc_findnode_did(vport, Fabric_DID); + if (!ndlp) + lpfc_printf_vlog(vport, KERN_ERR, + LOG_DISCOVERY, + "2731 Cannot find fabric " + "controller node\n"); + else + lpfc_register_new_vport(phba, vport, ndlp); + mempool_free(mboxq, phba->mbox_mem_pool); + return; + } + if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) lpfc_initial_fdisc(vport); else { @@ -1719,6 +1736,7 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "2606 No NPIV Fabric support\n"); } + mempool_free(mboxq, phba->mbox_mem_pool); return; } @@ -1814,6 +1832,9 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) } /* The VPI is implicitly registered when the VFI is registered */ vport->vpi_state |= LPFC_VPI_REGISTERED; + vport->fc_flag |= FC_VFI_REGISTERED; + + vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; if (vport->port_state == LPFC_FABRIC_CFG_LINK) { lpfc_start_fdiscs(phba); @@ -2333,6 +2354,7 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) } vport->vpi_state |= LPFC_VPI_REGISTERED; + vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; vport->num_disc_nodes = 0; /* go thru NPR list and issue ELS PLOGIs */ if (vport->fc_npr_cnt) @@ -4462,6 +4484,7 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) int rc; struct lpfc_vport **vports; int i; + struct lpfc_nodelist *ndlp; spin_lock_irq(&phba->hbalock); /* @@ -4489,6 +4512,10 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) if (vports && (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { + /* Stop FLOGI/FDISC retries */ + ndlp = lpfc_findnode_did(vports[i], Fabric_DID); + if (ndlp) + lpfc_cancel_retry_delay_tmo(vports[i], ndlp); lpfc_mbx_unreg_vpi(vports[i]); spin_lock_irq(&phba->hbalock); vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; @@ -4497,6 +4524,9 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) } lpfc_destroy_vport_work_array(phba, vports); + /* Cleanup any outstanding ELS commands */ + lpfc_els_flush_all_cmd(phba); + /* Unregister VFI */ mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mbox) { @@ -4521,6 +4551,10 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) return; } + spin_lock_irq(&phba->hbalock); + phba->pport->fc_flag &= ~FC_VFI_REGISTERED; + spin_unlock_irq(&phba->hbalock); + /* Unregister FCF */ mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mbox) { |