diff options
author | James Smart <James.Smart@Emulex.Com> | 2009-11-18 15:39:44 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:01:51 -0500 |
commit | 5ffc266ee7a62741ebee89ede15049ec0f02fa75 (patch) | |
tree | 1ffd531c5b95d3e0c2bf0d905d34f497827ff0ee /drivers/scsi/lpfc/lpfc_sli.c | |
parent | c868595d5686e97183bc1ad85502835d81d7a457 (diff) |
[SCSI] lpfc 8.3.6 : FC Protocol Fixes
FC protocol fixes.
- Fix send sequence logic to handle multi SGL IOCBs.
- Fix FDISC completion always setting VPORT state to failed.
- Ported the fix on reporting of max_vpi to uppper layer.
- Fix incorrect number of Vports allowed to be created.
- Fixed Dead FCoE port after creating vports.
- Added handling of ELS request for Reinstate Recovery Qualifier (RRQ)
- Handle unsolicited CT exchange initiator receiving CT exchange ABTS
- Migrate LUN queue depth ramp up code to scsi mid-layer.
- Made ABTS WQE go to the same WQ as the WQE to be aborted.
- Fix Vport does not rediscover after FCF goes away.
- Fixed lpfc_unreg_vfi failure after devloss timeout.
- Fixed RPI bit leak.
- Fix hbq pointer corruption during target discovery.
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 | 133 |
1 files changed, 107 insertions, 26 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index ce0a1a1c4792..1d2f65c4eb0b 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -5748,7 +5748,7 @@ static int | |||
5748 | lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | 5748 | lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, |
5749 | union lpfc_wqe *wqe) | 5749 | union lpfc_wqe *wqe) |
5750 | { | 5750 | { |
5751 | uint32_t payload_len = 0; | 5751 | uint32_t xmit_len = 0, total_len = 0; |
5752 | uint8_t ct = 0; | 5752 | uint8_t ct = 0; |
5753 | uint32_t fip; | 5753 | uint32_t fip; |
5754 | uint32_t abort_tag; | 5754 | uint32_t abort_tag; |
@@ -5757,6 +5757,8 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
5757 | uint16_t xritag; | 5757 | uint16_t xritag; |
5758 | struct ulp_bde64 *bpl = NULL; | 5758 | struct ulp_bde64 *bpl = NULL; |
5759 | uint32_t els_id = ELS_ID_DEFAULT; | 5759 | uint32_t els_id = ELS_ID_DEFAULT; |
5760 | int numBdes, i; | ||
5761 | struct ulp_bde64 bde; | ||
5760 | 5762 | ||
5761 | fip = phba->hba_flag & HBA_FIP_SUPPORT; | 5763 | fip = phba->hba_flag & HBA_FIP_SUPPORT; |
5762 | /* The fcp commands will set command type */ | 5764 | /* The fcp commands will set command type */ |
@@ -5774,6 +5776,8 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
5774 | wqe->words[7] = 0; /* The ct field has moved so reset */ | 5776 | wqe->words[7] = 0; /* The ct field has moved so reset */ |
5775 | /* words0-2 bpl convert bde */ | 5777 | /* words0-2 bpl convert bde */ |
5776 | if (iocbq->iocb.un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) { | 5778 | if (iocbq->iocb.un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) { |
5779 | numBdes = iocbq->iocb.un.genreq64.bdl.bdeSize / | ||
5780 | sizeof(struct ulp_bde64); | ||
5777 | bpl = (struct ulp_bde64 *) | 5781 | bpl = (struct ulp_bde64 *) |
5778 | ((struct lpfc_dmabuf *)iocbq->context3)->virt; | 5782 | ((struct lpfc_dmabuf *)iocbq->context3)->virt; |
5779 | if (!bpl) | 5783 | if (!bpl) |
@@ -5786,9 +5790,14 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
5786 | * can assign it to the sgl. | 5790 | * can assign it to the sgl. |
5787 | */ | 5791 | */ |
5788 | wqe->generic.bde.tus.w = le32_to_cpu(bpl->tus.w); | 5792 | wqe->generic.bde.tus.w = le32_to_cpu(bpl->tus.w); |
5789 | payload_len = wqe->generic.bde.tus.f.bdeSize; | 5793 | xmit_len = wqe->generic.bde.tus.f.bdeSize; |
5794 | total_len = 0; | ||
5795 | for (i = 0; i < numBdes; i++) { | ||
5796 | bde.tus.w = le32_to_cpu(bpl[i].tus.w); | ||
5797 | total_len += bde.tus.f.bdeSize; | ||
5798 | } | ||
5790 | } else | 5799 | } else |
5791 | payload_len = iocbq->iocb.un.fcpi64.bdl.bdeSize; | 5800 | xmit_len = iocbq->iocb.un.fcpi64.bdl.bdeSize; |
5792 | 5801 | ||
5793 | iocbq->iocb.ulpIoTag = iocbq->iotag; | 5802 | iocbq->iocb.ulpIoTag = iocbq->iotag; |
5794 | cmnd = iocbq->iocb.ulpCommand; | 5803 | cmnd = iocbq->iocb.ulpCommand; |
@@ -5802,7 +5811,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
5802 | iocbq->iocb.ulpCommand); | 5811 | iocbq->iocb.ulpCommand); |
5803 | return IOCB_ERROR; | 5812 | return IOCB_ERROR; |
5804 | } | 5813 | } |
5805 | wqe->els_req.payload_len = payload_len; | 5814 | wqe->els_req.payload_len = xmit_len; |
5806 | /* Els_reguest64 has a TMO */ | 5815 | /* Els_reguest64 has a TMO */ |
5807 | bf_set(wqe_tmo, &wqe->els_req.wqe_com, | 5816 | bf_set(wqe_tmo, &wqe->els_req.wqe_com, |
5808 | iocbq->iocb.ulpTimeout); | 5817 | iocbq->iocb.ulpTimeout); |
@@ -5831,6 +5840,15 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
5831 | bf_set(lpfc_wqe_gen_els_id, &wqe->generic, els_id); | 5840 | bf_set(lpfc_wqe_gen_els_id, &wqe->generic, els_id); |
5832 | 5841 | ||
5833 | break; | 5842 | break; |
5843 | case CMD_XMIT_SEQUENCE64_CX: | ||
5844 | bf_set(lpfc_wqe_gen_context, &wqe->generic, | ||
5845 | iocbq->iocb.un.ulpWord[3]); | ||
5846 | wqe->generic.word3 = 0; | ||
5847 | bf_set(wqe_rcvoxid, &wqe->generic, iocbq->iocb.ulpContext); | ||
5848 | bf_set(wqe_xc, &wqe->generic, 1); | ||
5849 | /* The entire sequence is transmitted for this IOCB */ | ||
5850 | xmit_len = total_len; | ||
5851 | cmnd = CMD_XMIT_SEQUENCE64_CR; | ||
5834 | case CMD_XMIT_SEQUENCE64_CR: | 5852 | case CMD_XMIT_SEQUENCE64_CR: |
5835 | /* word3 iocb=io_tag32 wqe=payload_offset */ | 5853 | /* word3 iocb=io_tag32 wqe=payload_offset */ |
5836 | /* payload offset used for multilpe outstanding | 5854 | /* payload offset used for multilpe outstanding |
@@ -5840,7 +5858,8 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
5840 | /* word4 relative_offset memcpy */ | 5858 | /* word4 relative_offset memcpy */ |
5841 | /* word5 r_ctl/df_ctl memcpy */ | 5859 | /* word5 r_ctl/df_ctl memcpy */ |
5842 | bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0); | 5860 | bf_set(lpfc_wqe_gen_pu, &wqe->generic, 0); |
5843 | wqe->xmit_sequence.xmit_len = payload_len; | 5861 | wqe->xmit_sequence.xmit_len = xmit_len; |
5862 | command_type = OTHER_COMMAND; | ||
5844 | break; | 5863 | break; |
5845 | case CMD_XMIT_BCAST64_CN: | 5864 | case CMD_XMIT_BCAST64_CN: |
5846 | /* word3 iocb=iotag32 wqe=payload_len */ | 5865 | /* word3 iocb=iotag32 wqe=payload_len */ |
@@ -5869,7 +5888,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
5869 | case CMD_FCP_IREAD64_CR: | 5888 | case CMD_FCP_IREAD64_CR: |
5870 | /* FCP_CMD is always the 1st sgl entry */ | 5889 | /* FCP_CMD is always the 1st sgl entry */ |
5871 | wqe->fcp_iread.payload_len = | 5890 | wqe->fcp_iread.payload_len = |
5872 | payload_len + sizeof(struct fcp_rsp); | 5891 | xmit_len + sizeof(struct fcp_rsp); |
5873 | 5892 | ||
5874 | /* word 4 (xfer length) should have been set on the memcpy */ | 5893 | /* word 4 (xfer length) should have been set on the memcpy */ |
5875 | 5894 | ||
@@ -5906,7 +5925,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
5906 | * sgl[1] = rsp. | 5925 | * sgl[1] = rsp. |
5907 | * | 5926 | * |
5908 | */ | 5927 | */ |
5909 | wqe->gen_req.command_len = payload_len; | 5928 | wqe->gen_req.command_len = xmit_len; |
5910 | /* Word4 parameter copied in the memcpy */ | 5929 | /* Word4 parameter copied in the memcpy */ |
5911 | /* Word5 [rctl, type, df_ctl, la] copied in memcpy */ | 5930 | /* Word5 [rctl, type, df_ctl, la] copied in memcpy */ |
5912 | /* word6 context tag copied in memcpy */ | 5931 | /* word6 context tag copied in memcpy */ |
@@ -5979,10 +5998,25 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
5979 | * iocbq from scratch. | 5998 | * iocbq from scratch. |
5980 | */ | 5999 | */ |
5981 | memset(wqe, 0, sizeof(union lpfc_wqe)); | 6000 | memset(wqe, 0, sizeof(union lpfc_wqe)); |
6001 | /* OX_ID is invariable to who sent ABTS to CT exchange */ | ||
5982 | bf_set(xmit_bls_rsp64_oxid, &wqe->xmit_bls_rsp, | 6002 | bf_set(xmit_bls_rsp64_oxid, &wqe->xmit_bls_rsp, |
5983 | iocbq->iocb.un.ulpWord[3]); | 6003 | bf_get(lpfc_abts_oxid, &iocbq->iocb.un.bls_acc)); |
5984 | bf_set(xmit_bls_rsp64_rxid, &wqe->xmit_bls_rsp, | 6004 | if (bf_get(lpfc_abts_orig, &iocbq->iocb.un.bls_acc) == |
5985 | iocbq->sli4_xritag); | 6005 | LPFC_ABTS_UNSOL_INT) { |
6006 | /* ABTS sent by initiator to CT exchange, the | ||
6007 | * RX_ID field will be filled with the newly | ||
6008 | * allocated responder XRI. | ||
6009 | */ | ||
6010 | bf_set(xmit_bls_rsp64_rxid, &wqe->xmit_bls_rsp, | ||
6011 | iocbq->sli4_xritag); | ||
6012 | } else { | ||
6013 | /* ABTS sent by responder to CT exchange, the | ||
6014 | * RX_ID field will be filled with the responder | ||
6015 | * RX_ID from ABTS. | ||
6016 | */ | ||
6017 | bf_set(xmit_bls_rsp64_rxid, &wqe->xmit_bls_rsp, | ||
6018 | bf_get(lpfc_abts_rxid, &iocbq->iocb.un.bls_acc)); | ||
6019 | } | ||
5986 | bf_set(xmit_bls_rsp64_seqcnthi, &wqe->xmit_bls_rsp, 0xffff); | 6020 | bf_set(xmit_bls_rsp64_seqcnthi, &wqe->xmit_bls_rsp, 0xffff); |
5987 | bf_set(wqe_xmit_bls_pt, &wqe->xmit_bls_rsp.wqe_dest, 0x1); | 6021 | bf_set(wqe_xmit_bls_pt, &wqe->xmit_bls_rsp.wqe_dest, 0x1); |
5988 | bf_set(wqe_ctxt_tag, &wqe->xmit_bls_rsp.wqe_com, | 6022 | bf_set(wqe_ctxt_tag, &wqe->xmit_bls_rsp.wqe_com, |
@@ -6044,7 +6078,6 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
6044 | uint16_t xritag; | 6078 | uint16_t xritag; |
6045 | union lpfc_wqe wqe; | 6079 | union lpfc_wqe wqe; |
6046 | struct lpfc_sli_ring *pring = &phba->sli.ring[ring_number]; | 6080 | struct lpfc_sli_ring *pring = &phba->sli.ring[ring_number]; |
6047 | uint32_t fcp_wqidx; | ||
6048 | 6081 | ||
6049 | if (piocb->sli4_xritag == NO_XRI) { | 6082 | if (piocb->sli4_xritag == NO_XRI) { |
6050 | if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN || | 6083 | if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN || |
@@ -6079,8 +6112,17 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
6079 | return IOCB_ERROR; | 6112 | return IOCB_ERROR; |
6080 | 6113 | ||
6081 | if (piocb->iocb_flag & LPFC_IO_FCP) { | 6114 | if (piocb->iocb_flag & LPFC_IO_FCP) { |
6082 | fcp_wqidx = lpfc_sli4_scmd_to_wqidx_distr(phba); | 6115 | /* |
6083 | if (lpfc_sli4_wq_put(phba->sli4_hba.fcp_wq[fcp_wqidx], &wqe)) | 6116 | * For FCP command IOCB, get a new WQ index to distribute |
6117 | * WQE across the WQsr. On the other hand, for abort IOCB, | ||
6118 | * it carries the same WQ index to the original command | ||
6119 | * IOCB. | ||
6120 | */ | ||
6121 | if ((piocb->iocb.ulpCommand != CMD_ABORT_XRI_CN) && | ||
6122 | (piocb->iocb.ulpCommand != CMD_CLOSE_XRI_CN)) | ||
6123 | piocb->fcp_wqidx = lpfc_sli4_scmd_to_wqidx_distr(phba); | ||
6124 | if (lpfc_sli4_wq_put(phba->sli4_hba.fcp_wq[piocb->fcp_wqidx], | ||
6125 | &wqe)) | ||
6084 | return IOCB_ERROR; | 6126 | return IOCB_ERROR; |
6085 | } else { | 6127 | } else { |
6086 | if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, &wqe)) | 6128 | if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, &wqe)) |
@@ -7070,6 +7112,9 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
7070 | iabt->ulpLe = 1; | 7112 | iabt->ulpLe = 1; |
7071 | iabt->ulpClass = icmd->ulpClass; | 7113 | iabt->ulpClass = icmd->ulpClass; |
7072 | 7114 | ||
7115 | /* ABTS WQE must go to the same WQ as the WQE to be aborted */ | ||
7116 | abtsiocbp->fcp_wqidx = cmdiocb->fcp_wqidx; | ||
7117 | |||
7073 | if (phba->link_state >= LPFC_LINK_UP) | 7118 | if (phba->link_state >= LPFC_LINK_UP) |
7074 | iabt->ulpCommand = CMD_ABORT_XRI_CN; | 7119 | iabt->ulpCommand = CMD_ABORT_XRI_CN; |
7075 | else | 7120 | else |
@@ -7273,6 +7318,9 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, | |||
7273 | abtsiocb->iocb.ulpClass = cmd->ulpClass; | 7318 | abtsiocb->iocb.ulpClass = cmd->ulpClass; |
7274 | abtsiocb->vport = phba->pport; | 7319 | abtsiocb->vport = phba->pport; |
7275 | 7320 | ||
7321 | /* ABTS WQE must go to the same WQ as the WQE to be aborted */ | ||
7322 | abtsiocb->fcp_wqidx = iocbq->fcp_wqidx; | ||
7323 | |||
7276 | if (lpfc_is_link_up(phba)) | 7324 | if (lpfc_is_link_up(phba)) |
7277 | abtsiocb->iocb.ulpCommand = CMD_ABORT_XRI_CN; | 7325 | abtsiocb->iocb.ulpCommand = CMD_ABORT_XRI_CN; |
7278 | else | 7326 | else |
@@ -8671,7 +8719,6 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe) | |||
8671 | uint32_t status; | 8719 | uint32_t status; |
8672 | unsigned long iflags; | 8720 | unsigned long iflags; |
8673 | 8721 | ||
8674 | lpfc_sli4_rq_release(hrq, drq); | ||
8675 | if (bf_get(lpfc_rcqe_rq_id, rcqe) != hrq->queue_id) | 8722 | if (bf_get(lpfc_rcqe_rq_id, rcqe) != hrq->queue_id) |
8676 | goto out; | 8723 | goto out; |
8677 | 8724 | ||
@@ -8681,6 +8728,7 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe) | |||
8681 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | 8728 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
8682 | "2537 Receive Frame Truncated!!\n"); | 8729 | "2537 Receive Frame Truncated!!\n"); |
8683 | case FC_STATUS_RQ_SUCCESS: | 8730 | case FC_STATUS_RQ_SUCCESS: |
8731 | lpfc_sli4_rq_release(hrq, drq); | ||
8684 | spin_lock_irqsave(&phba->hbalock, iflags); | 8732 | spin_lock_irqsave(&phba->hbalock, iflags); |
8685 | dma_buf = lpfc_sli_hbqbuf_get(&phba->hbqs[0].hbq_buffer_list); | 8733 | dma_buf = lpfc_sli_hbqbuf_get(&phba->hbqs[0].hbq_buffer_list); |
8686 | if (!dma_buf) { | 8734 | if (!dma_buf) { |
@@ -10997,8 +11045,8 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba, | |||
10997 | { | 11045 | { |
10998 | struct lpfc_iocbq *ctiocb = NULL; | 11046 | struct lpfc_iocbq *ctiocb = NULL; |
10999 | struct lpfc_nodelist *ndlp; | 11047 | struct lpfc_nodelist *ndlp; |
11000 | uint16_t oxid; | 11048 | uint16_t oxid, rxid; |
11001 | uint32_t sid; | 11049 | uint32_t sid, fctl; |
11002 | IOCB_t *icmd; | 11050 | IOCB_t *icmd; |
11003 | 11051 | ||
11004 | if (!lpfc_is_link_up(phba)) | 11052 | if (!lpfc_is_link_up(phba)) |
@@ -11006,6 +11054,7 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba, | |||
11006 | 11054 | ||
11007 | sid = sli4_sid_from_fc_hdr(fc_hdr); | 11055 | sid = sli4_sid_from_fc_hdr(fc_hdr); |
11008 | oxid = be16_to_cpu(fc_hdr->fh_ox_id); | 11056 | oxid = be16_to_cpu(fc_hdr->fh_ox_id); |
11057 | rxid = be16_to_cpu(fc_hdr->fh_rx_id); | ||
11009 | 11058 | ||
11010 | ndlp = lpfc_findnode_did(phba->pport, sid); | 11059 | ndlp = lpfc_findnode_did(phba->pport, sid); |
11011 | if (!ndlp) { | 11060 | if (!ndlp) { |
@@ -11020,9 +11069,12 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba, | |||
11020 | if (!ctiocb) | 11069 | if (!ctiocb) |
11021 | return; | 11070 | return; |
11022 | 11071 | ||
11072 | /* Extract the F_CTL field from FC_HDR */ | ||
11073 | fctl = sli4_fctl_from_fc_hdr(fc_hdr); | ||
11074 | |||
11023 | icmd = &ctiocb->iocb; | 11075 | icmd = &ctiocb->iocb; |
11024 | icmd->un.xseq64.bdl.ulpIoTag32 = 0; | ||
11025 | icmd->un.xseq64.bdl.bdeSize = 0; | 11076 | icmd->un.xseq64.bdl.bdeSize = 0; |
11077 | icmd->un.xseq64.bdl.ulpIoTag32 = 0; | ||
11026 | icmd->un.xseq64.w5.hcsw.Dfctl = 0; | 11078 | icmd->un.xseq64.w5.hcsw.Dfctl = 0; |
11027 | icmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_BA_ACC; | 11079 | icmd->un.xseq64.w5.hcsw.Rctl = FC_RCTL_BA_ACC; |
11028 | icmd->un.xseq64.w5.hcsw.Type = FC_TYPE_BLS; | 11080 | icmd->un.xseq64.w5.hcsw.Type = FC_TYPE_BLS; |
@@ -11033,13 +11085,30 @@ lpfc_sli4_seq_abort_acc(struct lpfc_hba *phba, | |||
11033 | icmd->ulpLe = 1; | 11085 | icmd->ulpLe = 1; |
11034 | icmd->ulpClass = CLASS3; | 11086 | icmd->ulpClass = CLASS3; |
11035 | icmd->ulpContext = ndlp->nlp_rpi; | 11087 | icmd->ulpContext = ndlp->nlp_rpi; |
11036 | icmd->un.ulpWord[3] = oxid; | ||
11037 | 11088 | ||
11038 | ctiocb->sli4_xritag = NO_XRI; | ||
11039 | ctiocb->iocb_cmpl = NULL; | 11089 | ctiocb->iocb_cmpl = NULL; |
11040 | ctiocb->vport = phba->pport; | 11090 | ctiocb->vport = phba->pport; |
11041 | ctiocb->iocb_cmpl = lpfc_sli4_seq_abort_acc_cmpl; | 11091 | ctiocb->iocb_cmpl = lpfc_sli4_seq_abort_acc_cmpl; |
11042 | 11092 | ||
11093 | if (fctl & FC_FC_EX_CTX) { | ||
11094 | /* ABTS sent by responder to CT exchange, construction | ||
11095 | * of BA_ACC will use OX_ID from ABTS for the XRI_TAG | ||
11096 | * field and RX_ID from ABTS for RX_ID field. | ||
11097 | */ | ||
11098 | bf_set(lpfc_abts_orig, &icmd->un.bls_acc, LPFC_ABTS_UNSOL_RSP); | ||
11099 | bf_set(lpfc_abts_rxid, &icmd->un.bls_acc, rxid); | ||
11100 | ctiocb->sli4_xritag = oxid; | ||
11101 | } else { | ||
11102 | /* ABTS sent by initiator to CT exchange, construction | ||
11103 | * of BA_ACC will need to allocate a new XRI as for the | ||
11104 | * XRI_TAG and RX_ID fields. | ||
11105 | */ | ||
11106 | bf_set(lpfc_abts_orig, &icmd->un.bls_acc, LPFC_ABTS_UNSOL_INT); | ||
11107 | bf_set(lpfc_abts_rxid, &icmd->un.bls_acc, NO_XRI); | ||
11108 | ctiocb->sli4_xritag = NO_XRI; | ||
11109 | } | ||
11110 | bf_set(lpfc_abts_oxid, &icmd->un.bls_acc, oxid); | ||
11111 | |||
11043 | /* Xmit CT abts accept on exchange <xid> */ | 11112 | /* Xmit CT abts accept on exchange <xid> */ |
11044 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 11113 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
11045 | "1200 Xmit CT ABTS ACC on exchange x%x Data: x%x\n", | 11114 | "1200 Xmit CT ABTS ACC on exchange x%x Data: x%x\n", |
@@ -11066,19 +11135,31 @@ lpfc_sli4_handle_unsol_abort(struct lpfc_vport *vport, | |||
11066 | { | 11135 | { |
11067 | struct lpfc_hba *phba = vport->phba; | 11136 | struct lpfc_hba *phba = vport->phba; |
11068 | struct fc_frame_header fc_hdr; | 11137 | struct fc_frame_header fc_hdr; |
11138 | uint32_t fctl; | ||
11069 | bool abts_par; | 11139 | bool abts_par; |
11070 | 11140 | ||
11071 | /* Try to abort partially assembled seq */ | ||
11072 | abts_par = lpfc_sli4_abort_partial_seq(vport, dmabuf); | ||
11073 | |||
11074 | /* Make a copy of fc_hdr before the dmabuf being released */ | 11141 | /* Make a copy of fc_hdr before the dmabuf being released */ |
11075 | memcpy(&fc_hdr, dmabuf->hbuf.virt, sizeof(struct fc_frame_header)); | 11142 | memcpy(&fc_hdr, dmabuf->hbuf.virt, sizeof(struct fc_frame_header)); |
11143 | fctl = sli4_fctl_from_fc_hdr(&fc_hdr); | ||
11076 | 11144 | ||
11077 | /* Send abort to ULP if partially seq abort failed */ | 11145 | if (fctl & FC_FC_EX_CTX) { |
11078 | if (abts_par == false) | 11146 | /* |
11079 | lpfc_sli4_send_seq_to_ulp(vport, dmabuf); | 11147 | * ABTS sent by responder to exchange, just free the buffer |
11080 | else | 11148 | */ |
11081 | lpfc_in_buf_free(phba, &dmabuf->dbuf); | 11149 | lpfc_in_buf_free(phba, &dmabuf->dbuf); |
11150 | } else { | ||
11151 | /* | ||
11152 | * ABTS sent by initiator to exchange, need to do cleanup | ||
11153 | */ | ||
11154 | /* Try to abort partially assembled seq */ | ||
11155 | abts_par = lpfc_sli4_abort_partial_seq(vport, dmabuf); | ||
11156 | |||
11157 | /* Send abort to ULP if partially seq abort failed */ | ||
11158 | if (abts_par == false) | ||
11159 | lpfc_sli4_send_seq_to_ulp(vport, dmabuf); | ||
11160 | else | ||
11161 | lpfc_in_buf_free(phba, &dmabuf->dbuf); | ||
11162 | } | ||
11082 | /* Send basic accept (BA_ACC) to the abort requester */ | 11163 | /* Send basic accept (BA_ACC) to the abort requester */ |
11083 | lpfc_sli4_seq_abort_acc(phba, &fc_hdr); | 11164 | lpfc_sli4_seq_abort_acc(phba, &fc_hdr); |
11084 | } | 11165 | } |