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_sli.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_sli.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 62 |
1 files changed, 61 insertions, 1 deletions
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 | **/ | ||
12167 | void | ||
12168 | lpfc_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 | |||