aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_sli.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_sli.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c62
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 **/
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