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.c110
1 files changed, 107 insertions, 3 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 6fc63b98818c..ab90329ff2e4 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/delay.h> 9#include <linux/delay.h>
10#include <scsi/scsi_tcq.h> 10#include <scsi/scsi_tcq.h>
11#include <scsi/scsi_bsg_fc.h>
11 12
12static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); 13static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
13static void qla2x00_process_completed_request(struct scsi_qla_host *, 14static void qla2x00_process_completed_request(struct scsi_qla_host *,
@@ -881,7 +882,9 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func,
881 index); 882 index);
882 return NULL; 883 return NULL;
883 } 884 }
885
884 req->outstanding_cmds[index] = NULL; 886 req->outstanding_cmds[index] = NULL;
887
885done: 888done:
886 return sp; 889 return sp;
887} 890}
@@ -982,6 +985,100 @@ done_post_logio_done_work:
982} 985}
983 986
984static void 987static void
988qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
989 struct sts_entry_24xx *pkt, int iocb_type)
990{
991 const char func[] = "ELS_CT_IOCB";
992 const char *type;
993 struct qla_hw_data *ha = vha->hw;
994 srb_t *sp;
995 struct srb_bsg *sp_bsg;
996 struct fc_bsg_job *bsg_job;
997 uint16_t comp_status;
998 uint32_t fw_status[3];
999 uint8_t* fw_sts_ptr;
1000
1001 sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
1002 if (!sp)
1003 return;
1004 sp_bsg = (struct srb_bsg*)sp->ctx;
1005 bsg_job = sp_bsg->bsg_job;
1006
1007 type = NULL;
1008 switch (sp_bsg->ctx.type) {
1009 case SRB_ELS_CMD_RPT:
1010 case SRB_ELS_CMD_HST:
1011 type = "els";
1012 break;
1013 case SRB_CT_CMD:
1014 type = "ct pass-through";
1015 break;
1016 default:
1017 qla_printk(KERN_WARNING, ha,
1018 "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
1019 sp_bsg->ctx.type);
1020 return;
1021 }
1022
1023 comp_status = fw_status[0] = le16_to_cpu(pkt->comp_status);
1024 fw_status[1] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_1);
1025 fw_status[2] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_2);
1026
1027 /* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT
1028 * fc payload to the caller
1029 */
1030 bsg_job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
1031 bsg_job->reply_len = sizeof(struct fc_bsg_reply) + sizeof(fw_status);
1032
1033 if (comp_status != CS_COMPLETE) {
1034 if (comp_status == CS_DATA_UNDERRUN) {
1035 bsg_job->reply->result = DID_OK << 16;
1036 bsg_job->reply->reply_payload_rcv_len =
1037 le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count);
1038
1039 DEBUG2(qla_printk(KERN_WARNING, ha,
1040 "scsi(%ld:0x%x): ELS-CT pass-through-%s error comp_status-status=0x%x "
1041 "error subcode 1=0x%x error subcode 2=0x%x total_byte = 0x%x.\n",
1042 vha->host_no, sp->handle, type, comp_status, fw_status[1], fw_status[2],
1043 le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count)));
1044 fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
1045 memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
1046 }
1047 else {
1048 DEBUG2(qla_printk(KERN_WARNING, ha,
1049 "scsi(%ld:0x%x): ELS-CT pass-through-%s error comp_status-status=0x%x "
1050 "error subcode 1=0x%x error subcode 2=0x%x.\n",
1051 vha->host_no, sp->handle, type, comp_status,
1052 le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_1),
1053 le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_2)));
1054 bsg_job->reply->result = DID_ERROR << 16;
1055 bsg_job->reply->reply_payload_rcv_len = 0;
1056 fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
1057 memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
1058 }
1059 DEBUG2(qla2x00_dump_buffer((uint8_t *)pkt, sizeof(*pkt)));
1060 }
1061 else {
1062 bsg_job->reply->result = DID_OK << 16;;
1063 bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
1064 bsg_job->reply_len = 0;
1065 }
1066
1067 dma_unmap_sg(&ha->pdev->dev,
1068 bsg_job->request_payload.sg_list,
1069 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1070 dma_unmap_sg(&ha->pdev->dev,
1071 bsg_job->reply_payload.sg_list,
1072 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1073 if ((sp_bsg->ctx.type == SRB_ELS_CMD_HST) ||
1074 (sp_bsg->ctx.type == SRB_CT_CMD))
1075 kfree(sp->fcport);
1076 kfree(sp->ctx);
1077 mempool_free(sp, ha->srb_mempool);
1078 bsg_job->job_done(bsg_job);
1079}
1080
1081static void
985qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, 1082qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
986 struct logio_entry_24xx *logio) 1083 struct logio_entry_24xx *logio)
987{ 1084{
@@ -1749,6 +1846,13 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
1749 qla24xx_logio_entry(vha, rsp->req, 1846 qla24xx_logio_entry(vha, rsp->req,
1750 (struct logio_entry_24xx *)pkt); 1847 (struct logio_entry_24xx *)pkt);
1751 break; 1848 break;
1849 case CT_IOCB_TYPE:
1850 qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
1851 clear_bit(MBX_INTERRUPT, &vha->hw->mbx_cmd_flags);
1852 break;
1853 case ELS_IOCB_TYPE:
1854 qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE);
1855 break;
1752 default: 1856 default:
1753 /* Type Not Supported. */ 1857 /* Type Not Supported. */
1754 DEBUG4(printk(KERN_WARNING 1858 DEBUG4(printk(KERN_WARNING
@@ -2049,7 +2153,6 @@ qla24xx_msix_default(int irq, void *dev_id)
2049 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 2153 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
2050 complete(&ha->mbx_intr_comp); 2154 complete(&ha->mbx_intr_comp);
2051 } 2155 }
2052
2053 return IRQ_HANDLED; 2156 return IRQ_HANDLED;
2054} 2157}
2055 2158
@@ -2255,10 +2358,11 @@ qla2x00_free_irqs(scsi_qla_host_t *vha)
2255 2358
2256 if (ha->flags.msix_enabled) 2359 if (ha->flags.msix_enabled)
2257 qla24xx_disable_msix(ha); 2360 qla24xx_disable_msix(ha);
2258 else if (ha->flags.inta_enabled) { 2361 else if (ha->flags.msi_enabled) {
2259 free_irq(ha->pdev->irq, rsp); 2362 free_irq(ha->pdev->irq, rsp);
2260 pci_disable_msi(ha->pdev); 2363 pci_disable_msi(ha->pdev);
2261 } 2364 } else
2365 free_irq(ha->pdev->irq, rsp);
2262} 2366}
2263 2367
2264 2368