diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_scsi.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 49 |
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) { |