diff options
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 | |||