aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c49
1 files changed, 40 insertions, 9 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 483fb74bc592..b16bb2c9978b 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -620,23 +620,40 @@ lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
620 uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri); 620 uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
621 struct lpfc_scsi_buf *psb, *next_psb; 621 struct lpfc_scsi_buf *psb, *next_psb;
622 unsigned long iflag = 0; 622 unsigned long iflag = 0;
623 struct lpfc_iocbq *iocbq;
624 int i;
623 625
624 spin_lock_irqsave(&phba->sli4_hba.abts_scsi_buf_list_lock, iflag); 626 spin_lock_irqsave(&phba->hbalock, iflag);
627 spin_lock(&phba->sli4_hba.abts_scsi_buf_list_lock);
625 list_for_each_entry_safe(psb, next_psb, 628 list_for_each_entry_safe(psb, next_psb,
626 &phba->sli4_hba.lpfc_abts_scsi_buf_list, list) { 629 &phba->sli4_hba.lpfc_abts_scsi_buf_list, list) {
627 if (psb->cur_iocbq.sli4_xritag == xri) { 630 if (psb->cur_iocbq.sli4_xritag == xri) {
628 list_del(&psb->list); 631 list_del(&psb->list);
629 psb->exch_busy = 0; 632 psb->exch_busy = 0;
630 psb->status = IOSTAT_SUCCESS; 633 psb->status = IOSTAT_SUCCESS;
631 spin_unlock_irqrestore( 634 spin_unlock(
632 &phba->sli4_hba.abts_scsi_buf_list_lock, 635 &phba->sli4_hba.abts_scsi_buf_list_lock);
633 iflag); 636 spin_unlock_irqrestore(&phba->hbalock, iflag);
634 lpfc_release_scsi_buf_s4(phba, psb); 637 lpfc_release_scsi_buf_s4(phba, psb);
635 return; 638 return;
636 } 639 }
637 } 640 }
638 spin_unlock_irqrestore(&phba->sli4_hba.abts_scsi_buf_list_lock, 641 spin_unlock(&phba->sli4_hba.abts_scsi_buf_list_lock);
639 iflag); 642 for (i = 1; i <= phba->sli.last_iotag; i++) {
643 iocbq = phba->sli.iocbq_lookup[i];
644
645 if (!(iocbq->iocb_flag & LPFC_IO_FCP) ||
646 (iocbq->iocb_flag & LPFC_IO_LIBDFC))
647 continue;
648 if (iocbq->sli4_xritag != xri)
649 continue;
650 psb = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq);
651 psb->exch_busy = 0;
652 spin_unlock_irqrestore(&phba->hbalock, iflag);
653 return;
654
655 }
656 spin_unlock_irqrestore(&phba->hbalock, iflag);
640} 657}
641 658
642/** 659/**
@@ -1006,6 +1023,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
1006 struct scatterlist *sgel = NULL; 1023 struct scatterlist *sgel = NULL;
1007 struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd; 1024 struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
1008 struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl; 1025 struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl;
1026 struct lpfc_iocbq *iocbq = &lpfc_cmd->cur_iocbq;
1009 IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb; 1027 IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
1010 struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde; 1028 struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde;
1011 dma_addr_t physaddr; 1029 dma_addr_t physaddr;
@@ -1056,6 +1074,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
1056 physaddr = sg_dma_address(sgel); 1074 physaddr = sg_dma_address(sgel);
1057 if (phba->sli_rev == 3 && 1075 if (phba->sli_rev == 3 &&
1058 !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) && 1076 !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
1077 !(iocbq->iocb_flag & DSS_SECURITY_OP) &&
1059 nseg <= LPFC_EXT_DATA_BDE_COUNT) { 1078 nseg <= LPFC_EXT_DATA_BDE_COUNT) {
1060 data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; 1079 data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
1061 data_bde->tus.f.bdeSize = sg_dma_len(sgel); 1080 data_bde->tus.f.bdeSize = sg_dma_len(sgel);
@@ -1082,7 +1101,8 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
1082 * explicitly reinitialized since all iocb memory resources are reused. 1101 * explicitly reinitialized since all iocb memory resources are reused.
1083 */ 1102 */
1084 if (phba->sli_rev == 3 && 1103 if (phba->sli_rev == 3 &&
1085 !(phba->sli3_options & LPFC_SLI3_BG_ENABLED)) { 1104 !(phba->sli3_options & LPFC_SLI3_BG_ENABLED) &&
1105 !(iocbq->iocb_flag & DSS_SECURITY_OP)) {
1086 if (num_bde > LPFC_EXT_DATA_BDE_COUNT) { 1106 if (num_bde > LPFC_EXT_DATA_BDE_COUNT) {
1087 /* 1107 /*
1088 * The extended IOCB format can only fit 3 BDE or a BPL. 1108 * The extended IOCB format can only fit 3 BDE or a BPL.
@@ -1107,6 +1127,7 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
1107 } else { 1127 } else {
1108 iocb_cmd->un.fcpi64.bdl.bdeSize = 1128 iocb_cmd->un.fcpi64.bdl.bdeSize =
1109 ((num_bde + 2) * sizeof(struct ulp_bde64)); 1129 ((num_bde + 2) * sizeof(struct ulp_bde64));
1130 iocb_cmd->unsli3.fcp_ext.ebde_count = (num_bde + 1);
1110 } 1131 }
1111 fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd)); 1132 fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd));
1112 1133
@@ -2079,8 +2100,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
2079 2100
2080 if (resp_info & RSP_LEN_VALID) { 2101 if (resp_info & RSP_LEN_VALID) {
2081 rsplen = be32_to_cpu(fcprsp->rspRspLen); 2102 rsplen = be32_to_cpu(fcprsp->rspRspLen);
2082 if ((rsplen != 0 && rsplen != 4 && rsplen != 8) || 2103 if (rsplen != 0 && rsplen != 4 && rsplen != 8) {
2083 (fcprsp->rspInfo3 != RSP_NO_FAILURE)) {
2084 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, 2104 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
2085 "2719 Invalid response length: " 2105 "2719 Invalid response length: "
2086 "tgt x%x lun x%x cmnd x%x rsplen x%x\n", 2106 "tgt x%x lun x%x cmnd x%x rsplen x%x\n",
@@ -2090,6 +2110,17 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
2090 host_status = DID_ERROR; 2110 host_status = DID_ERROR;
2091 goto out; 2111 goto out;
2092 } 2112 }
2113 if (fcprsp->rspInfo3 != RSP_NO_FAILURE) {
2114 lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
2115 "2757 Protocol failure detected during "
2116 "processing of FCP I/O op: "
2117 "tgt x%x lun x%x cmnd x%x rspInfo3 x%x\n",
2118 cmnd->device->id,
2119 cmnd->device->lun, cmnd->cmnd[0],
2120 fcprsp->rspInfo3);
2121 host_status = DID_ERROR;
2122 goto out;
2123 }
2093 } 2124 }
2094 2125
2095 if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) { 2126 if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) {