diff options
author | Giridhar Malavali <giridhar.malavali@qlogic.com> | 2012-02-09 14:15:36 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 09:14:08 -0500 |
commit | 9ba56b95a588906a65664a9299a9f8ac1a0f6a91 (patch) | |
tree | 93786c52320c2a7276c99cc4d9b3672ca6e0a50d /drivers/scsi/qla2xxx/qla_isr.c | |
parent | 69e5f1ea61a3e84c03103c6a18ee9cacef4cbb9e (diff) |
[SCSI] qla2xxx: Consolidation of SRB processing.
Rework the structures related to SRB processing to minimize the memory
allocations per I/O and manage resources associated with and completions
from common routines.
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_isr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 299 |
1 files changed, 104 insertions, 195 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 18e7d961aa0..87f2611c380 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -853,8 +853,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha, | |||
853 | req->outstanding_cmds[index] = NULL; | 853 | req->outstanding_cmds[index] = NULL; |
854 | 854 | ||
855 | /* Save ISP completion status */ | 855 | /* Save ISP completion status */ |
856 | sp->cmd->result = DID_OK << 16; | 856 | sp->done(ha, sp, DID_OK << 16); |
857 | qla2x00_sp_compl(ha, sp); | ||
858 | } else { | 857 | } else { |
859 | ql_log(ql_log_warn, vha, 0x3016, "Invalid SCSI SRB.\n"); | 858 | ql_log(ql_log_warn, vha, 0x3016, "Invalid SCSI SRB.\n"); |
860 | 859 | ||
@@ -911,7 +910,6 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
911 | fc_port_t *fcport; | 910 | fc_port_t *fcport; |
912 | srb_t *sp; | 911 | srb_t *sp; |
913 | struct srb_iocb *lio; | 912 | struct srb_iocb *lio; |
914 | struct srb_ctx *ctx; | ||
915 | uint16_t *data; | 913 | uint16_t *data; |
916 | uint16_t status; | 914 | uint16_t status; |
917 | 915 | ||
@@ -919,9 +917,8 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
919 | if (!sp) | 917 | if (!sp) |
920 | return; | 918 | return; |
921 | 919 | ||
922 | ctx = sp->ctx; | 920 | lio = &sp->u.iocb_cmd; |
923 | lio = ctx->u.iocb_cmd; | 921 | type = sp->name; |
924 | type = ctx->name; | ||
925 | fcport = sp->fcport; | 922 | fcport = sp->fcport; |
926 | data = lio->u.logio.data; | 923 | data = lio->u.logio.data; |
927 | 924 | ||
@@ -945,7 +942,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
945 | } | 942 | } |
946 | 943 | ||
947 | status = le16_to_cpu(mbx->status); | 944 | status = le16_to_cpu(mbx->status); |
948 | if (status == 0x30 && ctx->type == SRB_LOGIN_CMD && | 945 | if (status == 0x30 && sp->type == SRB_LOGIN_CMD && |
949 | le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) | 946 | le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) |
950 | status = 0; | 947 | status = 0; |
951 | if (!status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) { | 948 | if (!status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) { |
@@ -956,7 +953,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
956 | le16_to_cpu(mbx->mb1)); | 953 | le16_to_cpu(mbx->mb1)); |
957 | 954 | ||
958 | data[0] = MBS_COMMAND_COMPLETE; | 955 | data[0] = MBS_COMMAND_COMPLETE; |
959 | if (ctx->type == SRB_LOGIN_CMD) { | 956 | if (sp->type == SRB_LOGIN_CMD) { |
960 | fcport->port_type = FCT_TARGET; | 957 | fcport->port_type = FCT_TARGET; |
961 | if (le16_to_cpu(mbx->mb1) & BIT_0) | 958 | if (le16_to_cpu(mbx->mb1) & BIT_0) |
962 | fcport->port_type = FCT_INITIATOR; | 959 | fcport->port_type = FCT_INITIATOR; |
@@ -987,7 +984,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
987 | le16_to_cpu(mbx->mb7)); | 984 | le16_to_cpu(mbx->mb7)); |
988 | 985 | ||
989 | logio_done: | 986 | logio_done: |
990 | lio->done(sp); | 987 | sp->done(vha, sp, 0); |
991 | } | 988 | } |
992 | 989 | ||
993 | static void | 990 | static void |
@@ -996,29 +993,18 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
996 | { | 993 | { |
997 | const char func[] = "CT_IOCB"; | 994 | const char func[] = "CT_IOCB"; |
998 | const char *type; | 995 | const char *type; |
999 | struct qla_hw_data *ha = vha->hw; | ||
1000 | srb_t *sp; | 996 | srb_t *sp; |
1001 | struct srb_ctx *sp_bsg; | ||
1002 | struct fc_bsg_job *bsg_job; | 997 | struct fc_bsg_job *bsg_job; |
1003 | uint16_t comp_status; | 998 | uint16_t comp_status; |
999 | int res; | ||
1004 | 1000 | ||
1005 | sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); | 1001 | sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); |
1006 | if (!sp) | 1002 | if (!sp) |
1007 | return; | 1003 | return; |
1008 | 1004 | ||
1009 | sp_bsg = sp->ctx; | 1005 | bsg_job = sp->u.bsg_job; |
1010 | bsg_job = sp_bsg->u.bsg_job; | ||
1011 | 1006 | ||
1012 | type = NULL; | 1007 | type = "ct pass-through"; |
1013 | switch (sp_bsg->type) { | ||
1014 | case SRB_CT_CMD: | ||
1015 | type = "ct pass-through"; | ||
1016 | break; | ||
1017 | default: | ||
1018 | ql_log(ql_log_warn, vha, 0x5047, | ||
1019 | "Unrecognized SRB: (%p) type=%d.\n", sp, sp_bsg->type); | ||
1020 | return; | ||
1021 | } | ||
1022 | 1008 | ||
1023 | comp_status = le16_to_cpu(pkt->comp_status); | 1009 | comp_status = le16_to_cpu(pkt->comp_status); |
1024 | 1010 | ||
@@ -1030,7 +1016,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1030 | 1016 | ||
1031 | if (comp_status != CS_COMPLETE) { | 1017 | if (comp_status != CS_COMPLETE) { |
1032 | if (comp_status == CS_DATA_UNDERRUN) { | 1018 | if (comp_status == CS_DATA_UNDERRUN) { |
1033 | bsg_job->reply->result = DID_OK << 16; | 1019 | res = DID_OK << 16; |
1034 | bsg_job->reply->reply_payload_rcv_len = | 1020 | bsg_job->reply->reply_payload_rcv_len = |
1035 | le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len); | 1021 | le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len); |
1036 | 1022 | ||
@@ -1043,30 +1029,19 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1043 | ql_log(ql_log_warn, vha, 0x5049, | 1029 | ql_log(ql_log_warn, vha, 0x5049, |
1044 | "CT pass-through-%s error " | 1030 | "CT pass-through-%s error " |
1045 | "comp_status-status=0x%x.\n", type, comp_status); | 1031 | "comp_status-status=0x%x.\n", type, comp_status); |
1046 | bsg_job->reply->result = DID_ERROR << 16; | 1032 | res = DID_ERROR << 16; |
1047 | bsg_job->reply->reply_payload_rcv_len = 0; | 1033 | bsg_job->reply->reply_payload_rcv_len = 0; |
1048 | } | 1034 | } |
1049 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035, | 1035 | ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035, |
1050 | (uint8_t *)pkt, sizeof(*pkt)); | 1036 | (uint8_t *)pkt, sizeof(*pkt)); |
1051 | } else { | 1037 | } else { |
1052 | bsg_job->reply->result = DID_OK << 16; | 1038 | res = DID_OK << 16; |
1053 | bsg_job->reply->reply_payload_rcv_len = | 1039 | bsg_job->reply->reply_payload_rcv_len = |
1054 | bsg_job->reply_payload.payload_len; | 1040 | bsg_job->reply_payload.payload_len; |
1055 | bsg_job->reply_len = 0; | 1041 | bsg_job->reply_len = 0; |
1056 | } | 1042 | } |
1057 | 1043 | ||
1058 | dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, | 1044 | sp->done(vha, sp, res); |
1059 | bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); | ||
1060 | |||
1061 | dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list, | ||
1062 | bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE); | ||
1063 | |||
1064 | if (sp_bsg->type == SRB_ELS_CMD_HST || sp_bsg->type == SRB_CT_CMD) | ||
1065 | kfree(sp->fcport); | ||
1066 | |||
1067 | kfree(sp->ctx); | ||
1068 | mempool_free(sp, ha->srb_mempool); | ||
1069 | bsg_job->job_done(bsg_job); | ||
1070 | } | 1045 | } |
1071 | 1046 | ||
1072 | static void | 1047 | static void |
@@ -1075,22 +1050,20 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1075 | { | 1050 | { |
1076 | const char func[] = "ELS_CT_IOCB"; | 1051 | const char func[] = "ELS_CT_IOCB"; |
1077 | const char *type; | 1052 | const char *type; |
1078 | struct qla_hw_data *ha = vha->hw; | ||
1079 | srb_t *sp; | 1053 | srb_t *sp; |
1080 | struct srb_ctx *sp_bsg; | ||
1081 | struct fc_bsg_job *bsg_job; | 1054 | struct fc_bsg_job *bsg_job; |
1082 | uint16_t comp_status; | 1055 | uint16_t comp_status; |
1083 | uint32_t fw_status[3]; | 1056 | uint32_t fw_status[3]; |
1084 | uint8_t* fw_sts_ptr; | 1057 | uint8_t* fw_sts_ptr; |
1058 | int res; | ||
1085 | 1059 | ||
1086 | sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); | 1060 | sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); |
1087 | if (!sp) | 1061 | if (!sp) |
1088 | return; | 1062 | return; |
1089 | sp_bsg = sp->ctx; | 1063 | bsg_job = sp->u.bsg_job; |
1090 | bsg_job = sp_bsg->u.bsg_job; | ||
1091 | 1064 | ||
1092 | type = NULL; | 1065 | type = NULL; |
1093 | switch (sp_bsg->type) { | 1066 | switch (sp->type) { |
1094 | case SRB_ELS_CMD_RPT: | 1067 | case SRB_ELS_CMD_RPT: |
1095 | case SRB_ELS_CMD_HST: | 1068 | case SRB_ELS_CMD_HST: |
1096 | type = "els"; | 1069 | type = "els"; |
@@ -1100,7 +1073,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1100 | break; | 1073 | break; |
1101 | default: | 1074 | default: |
1102 | ql_log(ql_log_warn, vha, 0x503e, | 1075 | ql_log(ql_log_warn, vha, 0x503e, |
1103 | "Unrecognized SRB: (%p) type=%d.\n", sp, sp_bsg->type); | 1076 | "Unrecognized SRB: (%p) type=%d.\n", sp, sp->type); |
1104 | return; | 1077 | return; |
1105 | } | 1078 | } |
1106 | 1079 | ||
@@ -1116,9 +1089,9 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1116 | 1089 | ||
1117 | if (comp_status != CS_COMPLETE) { | 1090 | if (comp_status != CS_COMPLETE) { |
1118 | if (comp_status == CS_DATA_UNDERRUN) { | 1091 | if (comp_status == CS_DATA_UNDERRUN) { |
1119 | bsg_job->reply->result = DID_OK << 16; | 1092 | res = DID_OK << 16; |
1120 | bsg_job->reply->reply_payload_rcv_len = | 1093 | bsg_job->reply->reply_payload_rcv_len = |
1121 | le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count); | 1094 | le16_to_cpu(((struct els_sts_entry_24xx *)pkt)->total_byte_count); |
1122 | 1095 | ||
1123 | ql_log(ql_log_info, vha, 0x503f, | 1096 | ql_log(ql_log_info, vha, 0x503f, |
1124 | "ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x " | 1097 | "ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x " |
@@ -1138,7 +1111,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1138 | pkt)->error_subcode_1), | 1111 | pkt)->error_subcode_1), |
1139 | le16_to_cpu(((struct els_sts_entry_24xx *) | 1112 | le16_to_cpu(((struct els_sts_entry_24xx *) |
1140 | pkt)->error_subcode_2)); | 1113 | pkt)->error_subcode_2)); |
1141 | bsg_job->reply->result = DID_ERROR << 16; | 1114 | res = DID_ERROR << 16; |
1142 | bsg_job->reply->reply_payload_rcv_len = 0; | 1115 | bsg_job->reply->reply_payload_rcv_len = 0; |
1143 | fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply); | 1116 | fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply); |
1144 | memcpy( fw_sts_ptr, fw_status, sizeof(fw_status)); | 1117 | memcpy( fw_sts_ptr, fw_status, sizeof(fw_status)); |
@@ -1147,23 +1120,12 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1147 | (uint8_t *)pkt, sizeof(*pkt)); | 1120 | (uint8_t *)pkt, sizeof(*pkt)); |
1148 | } | 1121 | } |
1149 | else { | 1122 | else { |
1150 | bsg_job->reply->result = DID_OK << 16; | 1123 | res = DID_OK << 16; |
1151 | bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len; | 1124 | bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len; |
1152 | bsg_job->reply_len = 0; | 1125 | bsg_job->reply_len = 0; |
1153 | } | 1126 | } |
1154 | 1127 | ||
1155 | dma_unmap_sg(&ha->pdev->dev, | 1128 | sp->done(vha, sp, res); |
1156 | bsg_job->request_payload.sg_list, | ||
1157 | bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); | ||
1158 | dma_unmap_sg(&ha->pdev->dev, | ||
1159 | bsg_job->reply_payload.sg_list, | ||
1160 | bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE); | ||
1161 | if ((sp_bsg->type == SRB_ELS_CMD_HST) || | ||
1162 | (sp_bsg->type == SRB_CT_CMD)) | ||
1163 | kfree(sp->fcport); | ||
1164 | kfree(sp->ctx); | ||
1165 | mempool_free(sp, ha->srb_mempool); | ||
1166 | bsg_job->job_done(bsg_job); | ||
1167 | } | 1129 | } |
1168 | 1130 | ||
1169 | static void | 1131 | static void |
@@ -1175,7 +1137,6 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1175 | fc_port_t *fcport; | 1137 | fc_port_t *fcport; |
1176 | srb_t *sp; | 1138 | srb_t *sp; |
1177 | struct srb_iocb *lio; | 1139 | struct srb_iocb *lio; |
1178 | struct srb_ctx *ctx; | ||
1179 | uint16_t *data; | 1140 | uint16_t *data; |
1180 | uint32_t iop[2]; | 1141 | uint32_t iop[2]; |
1181 | 1142 | ||
@@ -1183,9 +1144,8 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1183 | if (!sp) | 1144 | if (!sp) |
1184 | return; | 1145 | return; |
1185 | 1146 | ||
1186 | ctx = sp->ctx; | 1147 | lio = &sp->u.iocb_cmd; |
1187 | lio = ctx->u.iocb_cmd; | 1148 | type = sp->name; |
1188 | type = ctx->name; | ||
1189 | fcport = sp->fcport; | 1149 | fcport = sp->fcport; |
1190 | data = lio->u.logio.data; | 1150 | data = lio->u.logio.data; |
1191 | 1151 | ||
@@ -1213,7 +1173,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1213 | le32_to_cpu(logio->io_parameter[0])); | 1173 | le32_to_cpu(logio->io_parameter[0])); |
1214 | 1174 | ||
1215 | data[0] = MBS_COMMAND_COMPLETE; | 1175 | data[0] = MBS_COMMAND_COMPLETE; |
1216 | if (ctx->type != SRB_LOGIN_CMD) | 1176 | if (sp->type != SRB_LOGIN_CMD) |
1217 | goto logio_done; | 1177 | goto logio_done; |
1218 | 1178 | ||
1219 | iop[0] = le32_to_cpu(logio->io_parameter[0]); | 1179 | iop[0] = le32_to_cpu(logio->io_parameter[0]); |
@@ -1256,7 +1216,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1256 | le32_to_cpu(logio->io_parameter[1])); | 1216 | le32_to_cpu(logio->io_parameter[1])); |
1257 | 1217 | ||
1258 | logio_done: | 1218 | logio_done: |
1259 | lio->done(sp); | 1219 | sp->done(vha, sp, 0); |
1260 | } | 1220 | } |
1261 | 1221 | ||
1262 | static void | 1222 | static void |
@@ -1268,7 +1228,6 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1268 | fc_port_t *fcport; | 1228 | fc_port_t *fcport; |
1269 | srb_t *sp; | 1229 | srb_t *sp; |
1270 | struct srb_iocb *iocb; | 1230 | struct srb_iocb *iocb; |
1271 | struct srb_ctx *ctx; | ||
1272 | struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk; | 1231 | struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk; |
1273 | int error = 1; | 1232 | int error = 1; |
1274 | 1233 | ||
@@ -1276,9 +1235,8 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1276 | if (!sp) | 1235 | if (!sp) |
1277 | return; | 1236 | return; |
1278 | 1237 | ||
1279 | ctx = sp->ctx; | 1238 | iocb = &sp->u.iocb_cmd; |
1280 | iocb = ctx->u.iocb_cmd; | 1239 | type = sp->name; |
1281 | type = ctx->name; | ||
1282 | fcport = sp->fcport; | 1240 | fcport = sp->fcport; |
1283 | 1241 | ||
1284 | if (sts->entry_status) { | 1242 | if (sts->entry_status) { |
@@ -1312,7 +1270,7 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
1312 | (uint8_t *)sts, sizeof(*sts)); | 1270 | (uint8_t *)sts, sizeof(*sts)); |
1313 | } | 1271 | } |
1314 | 1272 | ||
1315 | iocb->done(sp); | 1273 | sp->done(vha, sp, 0); |
1316 | } | 1274 | } |
1317 | 1275 | ||
1318 | /** | 1276 | /** |
@@ -1398,25 +1356,32 @@ qla2x00_process_response_queue(struct rsp_que *rsp) | |||
1398 | 1356 | ||
1399 | static inline void | 1357 | static inline void |
1400 | qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len, | 1358 | qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len, |
1401 | uint32_t sense_len, struct rsp_que *rsp) | 1359 | uint32_t sense_len, struct rsp_que *rsp, int res) |
1402 | { | 1360 | { |
1403 | struct scsi_qla_host *vha = sp->fcport->vha; | 1361 | struct scsi_qla_host *vha = sp->fcport->vha; |
1404 | struct scsi_cmnd *cp = sp->cmd; | 1362 | struct scsi_cmnd *cp = GET_CMD_SP(sp); |
1363 | uint32_t track_sense_len; | ||
1405 | 1364 | ||
1406 | if (sense_len >= SCSI_SENSE_BUFFERSIZE) | 1365 | if (sense_len >= SCSI_SENSE_BUFFERSIZE) |
1407 | sense_len = SCSI_SENSE_BUFFERSIZE; | 1366 | sense_len = SCSI_SENSE_BUFFERSIZE; |
1408 | 1367 | ||
1409 | sp->request_sense_length = sense_len; | 1368 | SET_CMD_SENSE_LEN(sp, sense_len); |
1410 | sp->request_sense_ptr = cp->sense_buffer; | 1369 | SET_CMD_SENSE_PTR(sp, cp->sense_buffer); |
1411 | if (sp->request_sense_length > par_sense_len) | 1370 | track_sense_len = sense_len; |
1371 | |||
1372 | if (sense_len > par_sense_len) | ||
1412 | sense_len = par_sense_len; | 1373 | sense_len = par_sense_len; |
1413 | 1374 | ||
1414 | memcpy(cp->sense_buffer, sense_data, sense_len); | 1375 | memcpy(cp->sense_buffer, sense_data, sense_len); |
1415 | 1376 | ||
1416 | sp->request_sense_ptr += sense_len; | 1377 | SET_CMD_SENSE_PTR(sp, cp->sense_buffer + sense_len); |
1417 | sp->request_sense_length -= sense_len; | 1378 | track_sense_len -= sense_len; |
1418 | if (sp->request_sense_length != 0) | 1379 | SET_CMD_SENSE_LEN(sp, track_sense_len); |
1380 | |||
1381 | if (track_sense_len != 0) { | ||
1419 | rsp->status_srb = sp; | 1382 | rsp->status_srb = sp; |
1383 | cp->result = res; | ||
1384 | } | ||
1420 | 1385 | ||
1421 | if (sense_len) { | 1386 | if (sense_len) { |
1422 | ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x301c, | 1387 | ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x301c, |
@@ -1444,7 +1409,7 @@ static inline int | |||
1444 | qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) | 1409 | qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) |
1445 | { | 1410 | { |
1446 | struct scsi_qla_host *vha = sp->fcport->vha; | 1411 | struct scsi_qla_host *vha = sp->fcport->vha; |
1447 | struct scsi_cmnd *cmd = sp->cmd; | 1412 | struct scsi_cmnd *cmd = GET_CMD_SP(sp); |
1448 | uint8_t *ap = &sts24->data[12]; | 1413 | uint8_t *ap = &sts24->data[12]; |
1449 | uint8_t *ep = &sts24->data[20]; | 1414 | uint8_t *ep = &sts24->data[20]; |
1450 | uint32_t e_ref_tag, a_ref_tag; | 1415 | uint32_t e_ref_tag, a_ref_tag; |
@@ -1588,6 +1553,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1588 | uint16_t que; | 1553 | uint16_t que; |
1589 | struct req_que *req; | 1554 | struct req_que *req; |
1590 | int logit = 1; | 1555 | int logit = 1; |
1556 | int res = 0; | ||
1591 | 1557 | ||
1592 | sts = (sts_entry_t *) pkt; | 1558 | sts = (sts_entry_t *) pkt; |
1593 | sts24 = (struct sts_entry_24xx *) pkt; | 1559 | sts24 = (struct sts_entry_24xx *) pkt; |
@@ -1627,7 +1593,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1627 | qla2xxx_wake_dpc(vha); | 1593 | qla2xxx_wake_dpc(vha); |
1628 | return; | 1594 | return; |
1629 | } | 1595 | } |
1630 | cp = sp->cmd; | 1596 | cp = GET_CMD_SP(sp); |
1631 | if (cp == NULL) { | 1597 | if (cp == NULL) { |
1632 | ql_dbg(ql_dbg_io, vha, 0x3018, | 1598 | ql_dbg(ql_dbg_io, vha, 0x3018, |
1633 | "Command already returned (0x%x/%p).\n", | 1599 | "Command already returned (0x%x/%p).\n", |
@@ -1680,7 +1646,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1680 | "FCP I/O protocol failure (0x%x/0x%x).\n", | 1646 | "FCP I/O protocol failure (0x%x/0x%x).\n", |
1681 | rsp_info_len, rsp_info[3]); | 1647 | rsp_info_len, rsp_info[3]); |
1682 | 1648 | ||
1683 | cp->result = DID_BUS_BUSY << 16; | 1649 | res = DID_BUS_BUSY << 16; |
1684 | goto out; | 1650 | goto out; |
1685 | } | 1651 | } |
1686 | } | 1652 | } |
@@ -1697,7 +1663,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1697 | case CS_COMPLETE: | 1663 | case CS_COMPLETE: |
1698 | case CS_QUEUE_FULL: | 1664 | case CS_QUEUE_FULL: |
1699 | if (scsi_status == 0) { | 1665 | if (scsi_status == 0) { |
1700 | cp->result = DID_OK << 16; | 1666 | res = DID_OK << 16; |
1701 | break; | 1667 | break; |
1702 | } | 1668 | } |
1703 | if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) { | 1669 | if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) { |
@@ -1712,11 +1678,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1712 | "detected (0x%x of 0x%x bytes).\n", | 1678 | "detected (0x%x of 0x%x bytes).\n", |
1713 | resid, scsi_bufflen(cp)); | 1679 | resid, scsi_bufflen(cp)); |
1714 | 1680 | ||
1715 | cp->result = DID_ERROR << 16; | 1681 | res = DID_ERROR << 16; |
1716 | break; | 1682 | break; |
1717 | } | 1683 | } |
1718 | } | 1684 | } |
1719 | cp->result = DID_OK << 16 | lscsi_status; | 1685 | res = DID_OK << 16 | lscsi_status; |
1720 | 1686 | ||
1721 | if (lscsi_status == SAM_STAT_TASK_SET_FULL) { | 1687 | if (lscsi_status == SAM_STAT_TASK_SET_FULL) { |
1722 | ql_dbg(ql_dbg_io, vha, 0x301b, | 1688 | ql_dbg(ql_dbg_io, vha, 0x301b, |
@@ -1732,7 +1698,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1732 | break; | 1698 | break; |
1733 | 1699 | ||
1734 | qla2x00_handle_sense(sp, sense_data, par_sense_len, sense_len, | 1700 | qla2x00_handle_sense(sp, sense_data, par_sense_len, sense_len, |
1735 | rsp); | 1701 | rsp, res); |
1736 | break; | 1702 | break; |
1737 | 1703 | ||
1738 | case CS_DATA_UNDERRUN: | 1704 | case CS_DATA_UNDERRUN: |
@@ -1746,7 +1712,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1746 | "(0x%x of 0x%x bytes).\n", | 1712 | "(0x%x of 0x%x bytes).\n", |
1747 | resid, scsi_bufflen(cp)); | 1713 | resid, scsi_bufflen(cp)); |
1748 | 1714 | ||
1749 | cp->result = DID_ERROR << 16 | lscsi_status; | 1715 | res = DID_ERROR << 16 | lscsi_status; |
1750 | goto check_scsi_status; | 1716 | goto check_scsi_status; |
1751 | } | 1717 | } |
1752 | 1718 | ||
@@ -1758,7 +1724,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1758 | "detected (0x%x of 0x%x bytes).\n", | 1724 | "detected (0x%x of 0x%x bytes).\n", |
1759 | resid, scsi_bufflen(cp)); | 1725 | resid, scsi_bufflen(cp)); |
1760 | 1726 | ||
1761 | cp->result = DID_ERROR << 16; | 1727 | res = DID_ERROR << 16; |
1762 | break; | 1728 | break; |
1763 | } | 1729 | } |
1764 | } else { | 1730 | } else { |
@@ -1766,11 +1732,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1766 | "Dropped frame(s) detected (0x%x " | 1732 | "Dropped frame(s) detected (0x%x " |
1767 | "of 0x%x bytes).\n", resid, scsi_bufflen(cp)); | 1733 | "of 0x%x bytes).\n", resid, scsi_bufflen(cp)); |
1768 | 1734 | ||
1769 | cp->result = DID_ERROR << 16 | lscsi_status; | 1735 | res = DID_ERROR << 16 | lscsi_status; |
1770 | goto check_scsi_status; | 1736 | goto check_scsi_status; |
1771 | } | 1737 | } |
1772 | 1738 | ||
1773 | cp->result = DID_OK << 16 | lscsi_status; | 1739 | res = DID_OK << 16 | lscsi_status; |
1774 | logit = 0; | 1740 | logit = 0; |
1775 | 1741 | ||
1776 | check_scsi_status: | 1742 | check_scsi_status: |
@@ -1793,7 +1759,7 @@ check_scsi_status: | |||
1793 | break; | 1759 | break; |
1794 | 1760 | ||
1795 | qla2x00_handle_sense(sp, sense_data, par_sense_len, | 1761 | qla2x00_handle_sense(sp, sense_data, par_sense_len, |
1796 | sense_len, rsp); | 1762 | sense_len, rsp, res); |
1797 | } | 1763 | } |
1798 | break; | 1764 | break; |
1799 | 1765 | ||
@@ -1810,7 +1776,7 @@ check_scsi_status: | |||
1810 | * while we try to recover so instruct the mid layer | 1776 | * while we try to recover so instruct the mid layer |
1811 | * to requeue until the class decides how to handle this. | 1777 | * to requeue until the class decides how to handle this. |
1812 | */ | 1778 | */ |
1813 | cp->result = DID_TRANSPORT_DISRUPTED << 16; | 1779 | res = DID_TRANSPORT_DISRUPTED << 16; |
1814 | 1780 | ||
1815 | if (comp_status == CS_TIMEOUT) { | 1781 | if (comp_status == CS_TIMEOUT) { |
1816 | if (IS_FWI2_CAPABLE(ha)) | 1782 | if (IS_FWI2_CAPABLE(ha)) |
@@ -1829,14 +1795,14 @@ check_scsi_status: | |||
1829 | break; | 1795 | break; |
1830 | 1796 | ||
1831 | case CS_ABORTED: | 1797 | case CS_ABORTED: |
1832 | cp->result = DID_RESET << 16; | 1798 | res = DID_RESET << 16; |
1833 | break; | 1799 | break; |
1834 | 1800 | ||
1835 | case CS_DIF_ERROR: | 1801 | case CS_DIF_ERROR: |
1836 | logit = qla2x00_handle_dif_error(sp, sts24); | 1802 | logit = qla2x00_handle_dif_error(sp, sts24); |
1837 | break; | 1803 | break; |
1838 | default: | 1804 | default: |
1839 | cp->result = DID_ERROR << 16; | 1805 | res = DID_ERROR << 16; |
1840 | break; | 1806 | break; |
1841 | } | 1807 | } |
1842 | 1808 | ||
@@ -1847,7 +1813,7 @@ out: | |||
1847 | "nexus=%ld:%d:%d portid=%02x%02x%02x oxid=0x%x " | 1813 | "nexus=%ld:%d:%d portid=%02x%02x%02x oxid=0x%x " |
1848 | "cdb=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x len=0x%x " | 1814 | "cdb=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x len=0x%x " |
1849 | "rsp_info=0x%x resid=0x%x fw_resid=0x%x.\n", | 1815 | "rsp_info=0x%x resid=0x%x fw_resid=0x%x.\n", |
1850 | comp_status, scsi_status, cp->result, vha->host_no, | 1816 | comp_status, scsi_status, res, vha->host_no, |
1851 | cp->device->id, cp->device->lun, fcport->d_id.b.domain, | 1817 | cp->device->id, cp->device->lun, fcport->d_id.b.domain, |
1852 | fcport->d_id.b.area, fcport->d_id.b.al_pa, ox_id, | 1818 | fcport->d_id.b.area, fcport->d_id.b.al_pa, ox_id, |
1853 | cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3], | 1819 | cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3], |
@@ -1856,7 +1822,7 @@ out: | |||
1856 | resid_len, fw_resid_len); | 1822 | resid_len, fw_resid_len); |
1857 | 1823 | ||
1858 | if (rsp->status_srb == NULL) | 1824 | if (rsp->status_srb == NULL) |
1859 | qla2x00_sp_compl(ha, sp); | 1825 | sp->done(ha, sp, res); |
1860 | } | 1826 | } |
1861 | 1827 | ||
1862 | /** | 1828 | /** |
@@ -1869,84 +1835,52 @@ out: | |||
1869 | static void | 1835 | static void |
1870 | qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt) | 1836 | qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt) |
1871 | { | 1837 | { |
1872 | uint8_t sense_sz = 0; | 1838 | uint8_t sense_sz = 0; |
1873 | struct qla_hw_data *ha = rsp->hw; | 1839 | struct qla_hw_data *ha = rsp->hw; |
1874 | struct scsi_qla_host *vha = pci_get_drvdata(ha->pdev); | 1840 | struct scsi_qla_host *vha = pci_get_drvdata(ha->pdev); |
1875 | srb_t *sp = rsp->status_srb; | 1841 | srb_t *sp = rsp->status_srb; |
1876 | struct scsi_cmnd *cp; | 1842 | struct scsi_cmnd *cp; |
1843 | uint32_t sense_len; | ||
1844 | uint8_t *sense_ptr; | ||
1877 | 1845 | ||
1878 | if (sp != NULL && sp->request_sense_length != 0) { | 1846 | if (!sp || !GET_CMD_SENSE_LEN(sp)) |
1879 | cp = sp->cmd; | 1847 | return; |
1880 | if (cp == NULL) { | ||
1881 | ql_log(ql_log_warn, vha, 0x3025, | ||
1882 | "cmd is NULL: already returned to OS (sp=%p).\n", | ||
1883 | sp); | ||
1884 | 1848 | ||
1885 | rsp->status_srb = NULL; | 1849 | sense_len = GET_CMD_SENSE_LEN(sp); |
1886 | return; | 1850 | sense_ptr = GET_CMD_SENSE_PTR(sp); |
1887 | } | ||
1888 | 1851 | ||
1889 | if (sp->request_sense_length > sizeof(pkt->data)) { | 1852 | cp = GET_CMD_SP(sp); |
1890 | sense_sz = sizeof(pkt->data); | 1853 | if (cp == NULL) { |
1891 | } else { | 1854 | ql_log(ql_log_warn, vha, 0x3025, |
1892 | sense_sz = sp->request_sense_length; | 1855 | "cmd is NULL: already returned to OS (sp=%p).\n", sp); |
1893 | } | ||
1894 | 1856 | ||
1895 | /* Move sense data. */ | 1857 | rsp->status_srb = NULL; |
1896 | if (IS_FWI2_CAPABLE(ha)) | 1858 | return; |
1897 | host_to_fcp_swap(pkt->data, sizeof(pkt->data)); | ||
1898 | memcpy(sp->request_sense_ptr, pkt->data, sense_sz); | ||
1899 | ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302c, | ||
1900 | sp->request_sense_ptr, sense_sz); | ||
1901 | |||
1902 | sp->request_sense_ptr += sense_sz; | ||
1903 | sp->request_sense_length -= sense_sz; | ||
1904 | |||
1905 | /* Place command on done queue. */ | ||
1906 | if (sp->request_sense_length == 0) { | ||
1907 | rsp->status_srb = NULL; | ||
1908 | qla2x00_sp_compl(ha, sp); | ||
1909 | } | ||
1910 | } | 1859 | } |
1911 | } | ||
1912 | 1860 | ||
1913 | static int | 1861 | if (sense_len > sizeof(pkt->data)) |
1914 | qla2x00_free_sp_ctx(scsi_qla_host_t *vha, srb_t *sp) | 1862 | sense_sz = sizeof(pkt->data); |
1915 | { | 1863 | else |
1916 | struct qla_hw_data *ha = vha->hw; | 1864 | sense_sz = sense_len; |
1917 | struct srb_ctx *ctx; | ||
1918 | 1865 | ||
1919 | if (!sp->ctx) | 1866 | /* Move sense data. */ |
1920 | return 1; | 1867 | if (IS_FWI2_CAPABLE(ha)) |
1868 | host_to_fcp_swap(pkt->data, sizeof(pkt->data)); | ||
1869 | memcpy(sense_ptr, pkt->data, sense_sz); | ||
1870 | ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302c, | ||
1871 | sense_ptr, sense_sz); | ||
1921 | 1872 | ||
1922 | ctx = sp->ctx; | 1873 | sense_len -= sense_sz; |
1874 | sense_ptr += sense_sz; | ||
1923 | 1875 | ||
1924 | if (ctx->type == SRB_LOGIN_CMD || | 1876 | SET_CMD_SENSE_PTR(sp, sense_ptr); |
1925 | ctx->type == SRB_LOGOUT_CMD || | 1877 | SET_CMD_SENSE_LEN(sp, sense_len); |
1926 | ctx->type == SRB_TM_CMD) { | 1878 | |
1927 | ctx->u.iocb_cmd->done(sp); | 1879 | /* Place command on done queue. */ |
1928 | return 0; | 1880 | if (sense_len == 0) { |
1929 | } else if (ctx->type == SRB_ADISC_CMD) { | 1881 | rsp->status_srb = NULL; |
1930 | ctx->u.iocb_cmd->free(sp); | 1882 | sp->done(ha, sp, cp->result); |
1931 | return 0; | ||
1932 | } else { | ||
1933 | struct fc_bsg_job *bsg_job; | ||
1934 | |||
1935 | bsg_job = ctx->u.bsg_job; | ||
1936 | if (ctx->type == SRB_ELS_CMD_HST || | ||
1937 | ctx->type == SRB_CT_CMD) | ||
1938 | kfree(sp->fcport); | ||
1939 | |||
1940 | bsg_job->reply->reply_data.ctels_reply.status = | ||
1941 | FC_CTELS_STATUS_OK; | ||
1942 | bsg_job->reply->result = DID_ERROR << 16; | ||
1943 | bsg_job->reply->reply_payload_rcv_len = 0; | ||
1944 | kfree(sp->ctx); | ||
1945 | mempool_free(sp, ha->srb_mempool); | ||
1946 | bsg_job->job_done(bsg_job); | ||
1947 | return 0; | ||
1948 | } | 1883 | } |
1949 | return 1; | ||
1950 | } | 1884 | } |
1951 | 1885 | ||
1952 | /** | 1886 | /** |
@@ -1962,43 +1896,18 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt) | |||
1962 | const char func[] = "ERROR-IOCB"; | 1896 | const char func[] = "ERROR-IOCB"; |
1963 | uint16_t que = MSW(pkt->handle); | 1897 | uint16_t que = MSW(pkt->handle); |
1964 | struct req_que *req = ha->req_q_map[que]; | 1898 | struct req_que *req = ha->req_q_map[que]; |
1899 | int res = DID_ERROR << 16; | ||
1965 | 1900 | ||
1966 | if (pkt->entry_status & RF_INV_E_ORDER) | 1901 | ql_dbg(ql_dbg_async, vha, 0x502a, |
1967 | ql_dbg(ql_dbg_async, vha, 0x502a, | 1902 | "type of error status in response: 0x%x\n", pkt->entry_status); |
1968 | "Invalid Entry Order.\n"); | 1903 | |
1969 | else if (pkt->entry_status & RF_INV_E_COUNT) | 1904 | if (pkt->entry_status & RF_BUSY) |
1970 | ql_dbg(ql_dbg_async, vha, 0x502b, | 1905 | res = DID_BUS_BUSY << 16; |
1971 | "Invalid Entry Count.\n"); | ||
1972 | else if (pkt->entry_status & RF_INV_E_PARAM) | ||
1973 | ql_dbg(ql_dbg_async, vha, 0x502c, | ||
1974 | "Invalid Entry Parameter.\n"); | ||
1975 | else if (pkt->entry_status & RF_INV_E_TYPE) | ||
1976 | ql_dbg(ql_dbg_async, vha, 0x502d, | ||
1977 | "Invalid Entry Type.\n"); | ||
1978 | else if (pkt->entry_status & RF_BUSY) | ||
1979 | ql_dbg(ql_dbg_async, vha, 0x502e, | ||
1980 | "Busy.\n"); | ||
1981 | else | ||
1982 | ql_dbg(ql_dbg_async, vha, 0x502f, | ||
1983 | "UNKNOWN flag error.\n"); | ||
1984 | 1906 | ||
1985 | sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); | 1907 | sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); |
1986 | if (sp) { | 1908 | if (sp) |
1987 | if (qla2x00_free_sp_ctx(vha, sp)) { | 1909 | sp->done(ha, sp, res); |
1988 | if (pkt->entry_status & | 1910 | else { |
1989 | (RF_INV_E_ORDER | RF_INV_E_COUNT | | ||
1990 | RF_INV_E_PARAM | RF_INV_E_TYPE)) { | ||
1991 | sp->cmd->result = DID_ERROR << 16; | ||
1992 | } else if (pkt->entry_status & RF_BUSY) { | ||
1993 | sp->cmd->result = DID_BUS_BUSY << 16; | ||
1994 | } else { | ||
1995 | sp->cmd->result = DID_ERROR << 16; | ||
1996 | } | ||
1997 | qla2x00_sp_compl(ha, sp); | ||
1998 | } | ||
1999 | } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type == | ||
2000 | COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7 | ||
2001 | || pkt->entry_type == COMMAND_TYPE_6) { | ||
2002 | ql_log(ql_log_warn, vha, 0x5030, | 1911 | ql_log(ql_log_warn, vha, 0x5030, |
2003 | "Error entry - invalid handle.\n"); | 1912 | "Error entry - invalid handle.\n"); |
2004 | 1913 | ||