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 19:38:28 -0500 |
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) | |||
706 | void | 706 | void |
707 | lpfc_port_link_failure(struct lpfc_vport *vport) | 707 | lpfc_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 | */ |
1698 | static void | 1700 | void |
1699 | lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | 1701 | lpfc_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) { |