aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_isr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_isr.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index ffc855f7697..51800332822 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -984,6 +984,86 @@ logio_done:
984} 984}
985 985
986static void 986static void
987qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
988 sts_entry_t *pkt, int iocb_type)
989{
990 const char func[] = "CT_IOCB";
991 const char *type;
992 struct qla_hw_data *ha = vha->hw;
993 srb_t *sp;
994 struct srb_ctx *sp_bsg;
995 struct fc_bsg_job *bsg_job;
996 uint16_t comp_status;
997
998 sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
999 if (!sp)
1000 return;
1001
1002 sp_bsg = sp->ctx;
1003 bsg_job = sp_bsg->u.bsg_job;
1004
1005 type = NULL;
1006 switch (sp_bsg->type) {
1007 case SRB_CT_CMD:
1008 type = "ct pass-through";
1009 break;
1010 default:
1011 qla_printk(KERN_WARNING, ha,
1012 "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
1013 sp_bsg->type);
1014 return;
1015 }
1016
1017 comp_status = le16_to_cpu(pkt->comp_status);
1018
1019 /* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT
1020 * fc payload to the caller
1021 */
1022 bsg_job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
1023 bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1024
1025 if (comp_status != CS_COMPLETE) {
1026 if (comp_status == CS_DATA_UNDERRUN) {
1027 bsg_job->reply->result = DID_OK << 16;
1028 bsg_job->reply->reply_payload_rcv_len =
1029 le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len);
1030
1031 DEBUG2(qla_printk(KERN_WARNING, ha,
1032 "scsi(%ld): CT pass-through-%s error "
1033 "comp_status-status=0x%x total_byte = 0x%x.\n",
1034 vha->host_no, type, comp_status,
1035 bsg_job->reply->reply_payload_rcv_len));
1036 } else {
1037 DEBUG2(qla_printk(KERN_WARNING, ha,
1038 "scsi(%ld): CT pass-through-%s error "
1039 "comp_status-status=0x%x.\n",
1040 vha->host_no, type, comp_status));
1041 bsg_job->reply->result = DID_ERROR << 16;
1042 bsg_job->reply->reply_payload_rcv_len = 0;
1043 }
1044 DEBUG2(qla2x00_dump_buffer((uint8_t *)pkt, sizeof(*pkt)));
1045 } else {
1046 bsg_job->reply->result = DID_OK << 16;;
1047 bsg_job->reply->reply_payload_rcv_len =
1048 bsg_job->reply_payload.payload_len;
1049 bsg_job->reply_len = 0;
1050 }
1051
1052 dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
1053 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1054
1055 dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
1056 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1057
1058 if (sp_bsg->type == SRB_ELS_CMD_HST || sp_bsg->type == SRB_CT_CMD)
1059 kfree(sp->fcport);
1060
1061 kfree(sp->ctx);
1062 mempool_free(sp, ha->srb_mempool);
1063 bsg_job->job_done(bsg_job);
1064}
1065
1066static void
987qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, 1067qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
988 struct sts_entry_24xx *pkt, int iocb_type) 1068 struct sts_entry_24xx *pkt, int iocb_type)
989{ 1069{
@@ -1303,6 +1383,9 @@ qla2x00_process_response_queue(struct rsp_que *rsp)
1303 qla2x00_mbx_iocb_entry(vha, rsp->req, 1383 qla2x00_mbx_iocb_entry(vha, rsp->req,
1304 (struct mbx_entry *)pkt); 1384 (struct mbx_entry *)pkt);
1305 break; 1385 break;
1386 case CT_IOCB_TYPE:
1387 qla2x00_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
1388 break;
1306 default: 1389 default:
1307 /* Type Not Supported. */ 1390 /* Type Not Supported. */
1308 DEBUG4(printk(KERN_WARNING 1391 DEBUG4(printk(KERN_WARNING