diff options
-rw-r--r-- | drivers/scsi/isci/core/intel_sas.h | 46 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_request.c | 222 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_stp_request.c | 2 | ||||
-rw-r--r-- | drivers/scsi/isci/sas.h | 3 | ||||
-rw-r--r-- | drivers/scsi/isci/task.c | 100 | ||||
-rw-r--r-- | drivers/scsi/isci/task.h | 20 |
6 files changed, 141 insertions, 252 deletions
diff --git a/drivers/scsi/isci/core/intel_sas.h b/drivers/scsi/isci/core/intel_sas.h index f7301aa14f02..3d4ca12df5ff 100644 --- a/drivers/scsi/isci/core/intel_sas.h +++ b/drivers/scsi/isci/core/intel_sas.h | |||
@@ -160,52 +160,6 @@ enum sci_sas_frame_type { | |||
160 | SCI_SAS_TASK_FRAME = 0x16 | 160 | SCI_SAS_TASK_FRAME = 0x16 |
161 | }; | 161 | }; |
162 | 162 | ||
163 | #define SSP_RESPONSE_IU_MAX_DATA 64 | ||
164 | |||
165 | #define SCI_SSP_RESPONSE_IU_DATA_PRESENT_MASK (0x03) | ||
166 | |||
167 | |||
168 | #define sci_ssp_get_sense_data_length(sense_data_length_buffer) \ | ||
169 | SCIC_BUILD_DWORD(sense_data_length_buffer) | ||
170 | |||
171 | #define sci_ssp_get_response_data_length(response_data_length_buffer) \ | ||
172 | SCIC_BUILD_DWORD(response_data_length_buffer) | ||
173 | |||
174 | /** | ||
175 | * struct sci_ssp_response_iu - This structure depicts the contents of the SSP | ||
176 | * RESPONSE INFORMATION UNIT. For specific information on each of these | ||
177 | * individual fields please reference the SAS specification SSP transport | ||
178 | * layer section. | ||
179 | * | ||
180 | * | ||
181 | */ | ||
182 | struct sci_ssp_response_iu { | ||
183 | u8 reserved0[8]; | ||
184 | |||
185 | u8 retry_delay_timer[2]; | ||
186 | u8 data_present; | ||
187 | u8 status; | ||
188 | |||
189 | u8 reserved1[4]; | ||
190 | u8 sense_data_length[4]; | ||
191 | u8 response_data_length[4]; | ||
192 | |||
193 | u32 data[SSP_RESPONSE_IU_MAX_DATA]; | ||
194 | |||
195 | }; | ||
196 | |||
197 | /** | ||
198 | * enum _SCI_SAS_DATA_PRESENT_TYPE - This enumeration depicts the SAS | ||
199 | * specification defined SSP data present types in struct sci_ssp_response_iu. | ||
200 | * | ||
201 | * | ||
202 | */ | ||
203 | enum sci_ssp_response_iu_data_present_type { | ||
204 | SCI_SSP_RESPONSE_IU_NO_DATA = 0x00, | ||
205 | SCI_SSP_RESPONSE_IU_RESPONSE_DATA = 0x01, | ||
206 | SCI_SSP_RESPONSE_IU_SENSE_DATA = 0x02 | ||
207 | }; | ||
208 | |||
209 | /** | 163 | /** |
210 | * struct sci_ssp_frame_header - This structure depicts the contents of an SSP | 164 | * struct sci_ssp_frame_header - This structure depicts the contents of an SSP |
211 | * frame header. For specific information on the individual fields please | 165 | * frame header. For specific information on the individual fields please |
diff --git a/drivers/scsi/isci/core/scic_sds_request.c b/drivers/scsi/isci/core/scic_sds_request.c index b6d1333e01fd..ef59e019398e 100644 --- a/drivers/scsi/isci/core/scic_sds_request.c +++ b/drivers/scsi/isci/core/scic_sds_request.c | |||
@@ -100,7 +100,7 @@ | |||
100 | #define scic_ssp_io_request_get_object_size() \ | 100 | #define scic_ssp_io_request_get_object_size() \ |
101 | (\ | 101 | (\ |
102 | sizeof(struct ssp_cmd_iu) \ | 102 | sizeof(struct ssp_cmd_iu) \ |
103 | + sizeof(struct sci_ssp_response_iu) \ | 103 | + SSP_RESP_IU_MAX_SIZE \ |
104 | ) | 104 | ) |
105 | 105 | ||
106 | /** | 106 | /** |
@@ -121,7 +121,7 @@ | |||
121 | * memory | 121 | * memory |
122 | */ | 122 | */ |
123 | #define scic_sds_ssp_request_get_response_buffer(memory) \ | 123 | #define scic_sds_ssp_request_get_response_buffer(memory) \ |
124 | ((struct sci_ssp_response_iu *)(\ | 124 | ((struct ssp_response_iu *)(\ |
125 | ((char *)(scic_sds_ssp_request_get_command_buffer(memory))) \ | 125 | ((char *)(scic_sds_ssp_request_get_command_buffer(memory))) \ |
126 | + sizeof(struct ssp_cmd_iu) \ | 126 | + sizeof(struct ssp_cmd_iu) \ |
127 | )) | 127 | )) |
@@ -135,7 +135,7 @@ | |||
135 | #define scic_sds_ssp_request_get_task_context_buffer(memory) \ | 135 | #define scic_sds_ssp_request_get_task_context_buffer(memory) \ |
136 | ((struct scu_task_context *)(\ | 136 | ((struct scu_task_context *)(\ |
137 | ((char *)(scic_sds_ssp_request_get_response_buffer(memory))) \ | 137 | ((char *)(scic_sds_ssp_request_get_response_buffer(memory))) \ |
138 | + sizeof(struct sci_ssp_response_iu) \ | 138 | + SSP_RESP_IU_MAX_SIZE \ |
139 | )) | 139 | )) |
140 | 140 | ||
141 | /** | 141 | /** |
@@ -160,7 +160,7 @@ | |||
160 | #define scic_ssp_task_request_get_object_size() \ | 160 | #define scic_ssp_task_request_get_object_size() \ |
161 | (\ | 161 | (\ |
162 | sizeof(struct ssp_task_iu) \ | 162 | sizeof(struct ssp_task_iu) \ |
163 | + sizeof(struct sci_ssp_response_iu) \ | 163 | + SSP_RESP_IU_MAX_SIZE \ |
164 | ) | 164 | ) |
165 | 165 | ||
166 | /** | 166 | /** |
@@ -181,7 +181,7 @@ | |||
181 | * request memory. | 181 | * request memory. |
182 | */ | 182 | */ |
183 | #define scic_sds_ssp_task_request_get_response_buffer(memory) \ | 183 | #define scic_sds_ssp_task_request_get_response_buffer(memory) \ |
184 | ((struct sci_ssp_response_iu *)(\ | 184 | ((struct ssp_response_iu *)(\ |
185 | ((char *)(scic_sds_ssp_task_request_get_command_buffer(memory))) \ | 185 | ((char *)(scic_sds_ssp_task_request_get_command_buffer(memory))) \ |
186 | + sizeof(struct ssp_task_iu) \ | 186 | + sizeof(struct ssp_task_iu) \ |
187 | )) | 187 | )) |
@@ -194,7 +194,7 @@ | |||
194 | #define scic_sds_ssp_task_request_get_task_context_buffer(memory) \ | 194 | #define scic_sds_ssp_task_request_get_task_context_buffer(memory) \ |
195 | ((struct scu_task_context *)(\ | 195 | ((struct scu_task_context *)(\ |
196 | ((char *)(scic_sds_ssp_task_request_get_response_buffer(memory))) \ | 196 | ((char *)(scic_sds_ssp_task_request_get_response_buffer(memory))) \ |
197 | + sizeof(struct sci_ssp_response_iu) \ | 197 | + SSP_RESP_IU_MAX_SIZE \ |
198 | )) | 198 | )) |
199 | 199 | ||
200 | 200 | ||
@@ -937,52 +937,29 @@ enum sci_status scic_sds_io_request_frame_handler( | |||
937 | return SCI_FAILURE_INVALID_STATE; | 937 | return SCI_FAILURE_INVALID_STATE; |
938 | } | 938 | } |
939 | 939 | ||
940 | /** | ||
941 | * | ||
942 | * @sci_req: The SCIC_SDS_IO_REQUEST_T object for which the task start | ||
943 | * operation is to be executed. | ||
944 | * | ||
945 | * This method invokes the core state task complete handler for the | ||
946 | * SCIC_SDS_IO_REQUEST_T object. enum sci_status | ||
947 | */ | ||
948 | |||
949 | /* | 940 | /* |
950 | * **************************************************************************** | 941 | * This function copies response data for requests returning response data |
951 | * * SCIC SDS PROTECTED METHODS | ||
952 | * **************************************************************************** */ | ||
953 | |||
954 | /** | ||
955 | * This method copies response data for requests returning response data | ||
956 | * instead of sense data. | 942 | * instead of sense data. |
957 | * @sci_req: This parameter specifies the request object for which to copy | 943 | * @sci_req: This parameter specifies the request object for which to copy |
958 | * the response data. | 944 | * the response data. |
959 | * | ||
960 | */ | 945 | */ |
961 | void scic_sds_io_request_copy_response(struct scic_sds_request *sds_request) | 946 | void scic_sds_io_request_copy_response(struct scic_sds_request *sci_req) |
962 | { | 947 | { |
963 | void *response_buffer; | 948 | void *resp_buf; |
964 | u32 user_response_length; | 949 | u32 len; |
965 | u32 core_response_length; | 950 | struct ssp_response_iu *ssp_response; |
966 | struct sci_ssp_response_iu *ssp_response; | 951 | struct isci_request *ireq = sci_req->ireq; |
967 | struct isci_request *isci_request = sds_request->ireq; | 952 | struct isci_tmf *isci_tmf = isci_request_access_tmf(ireq); |
968 | |||
969 | ssp_response = | ||
970 | (struct sci_ssp_response_iu *)sds_request->response_buffer; | ||
971 | |||
972 | response_buffer = | ||
973 | isci_task_ssp_request_get_response_data_address( | ||
974 | isci_request); | ||
975 | 953 | ||
976 | user_response_length = | 954 | ssp_response = sci_req->response_buffer; |
977 | isci_task_ssp_request_get_response_data_length( | ||
978 | isci_request); | ||
979 | 955 | ||
980 | core_response_length = sci_ssp_get_response_data_length( | 956 | resp_buf = &isci_tmf->resp.resp_iu; |
981 | ssp_response->response_data_length); | ||
982 | 957 | ||
983 | user_response_length = min(user_response_length, core_response_length); | 958 | len = min_t(u32, |
959 | SSP_RESP_IU_MAX_SIZE, | ||
960 | be32_to_cpu(ssp_response->response_data_len)); | ||
984 | 961 | ||
985 | memcpy(response_buffer, ssp_response->data, user_response_length); | 962 | memcpy(resp_buf, ssp_response->resp_data, len); |
986 | } | 963 | } |
987 | 964 | ||
988 | /* | 965 | /* |
@@ -1102,7 +1079,7 @@ enum sci_status scic_sds_request_started_state_abort_handler( | |||
1102 | return SCI_SUCCESS; | 1079 | return SCI_SUCCESS; |
1103 | } | 1080 | } |
1104 | 1081 | ||
1105 | /** | 1082 | /* |
1106 | * scic_sds_request_started_state_tc_completion_handler() - This method process | 1083 | * scic_sds_request_started_state_tc_completion_handler() - This method process |
1107 | * TC (task context) completions for normal IO request (i.e. Task/Abort | 1084 | * TC (task context) completions for normal IO request (i.e. Task/Abort |
1108 | * Completions of type 0). This method will update the | 1085 | * Completions of type 0). This method will update the |
@@ -1113,50 +1090,51 @@ enum sci_status scic_sds_request_started_state_abort_handler( | |||
1113 | * the SCU. | 1090 | * the SCU. |
1114 | * | 1091 | * |
1115 | */ | 1092 | */ |
1116 | enum sci_status scic_sds_request_started_state_tc_completion_handler( | 1093 | enum sci_status |
1117 | struct scic_sds_request *sci_req, | 1094 | scic_sds_request_started_state_tc_completion_handler( |
1118 | u32 completion_code) | 1095 | struct scic_sds_request *sci_req, |
1096 | u32 completion_code) | ||
1119 | { | 1097 | { |
1120 | u8 data_present; | 1098 | u8 datapres; |
1121 | struct sci_ssp_response_iu *response_buffer; | 1099 | struct ssp_response_iu *resp_iu; |
1122 | 1100 | ||
1123 | /** | 1101 | /* |
1124 | * @todo Any SDMA return code of other than 0 is bad | 1102 | * TODO: Any SDMA return code of other than 0 is bad |
1125 | * decode 0x003C0000 to determine SDMA status | 1103 | * decode 0x003C0000 to determine SDMA status |
1126 | */ | 1104 | */ |
1127 | switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) { | 1105 | switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) { |
1128 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): | 1106 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): |
1129 | scic_sds_request_set_status( | 1107 | scic_sds_request_set_status(sci_req, |
1130 | sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS | 1108 | SCU_TASK_DONE_GOOD, |
1131 | ); | 1109 | SCI_SUCCESS); |
1132 | break; | 1110 | break; |
1133 | 1111 | ||
1134 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EARLY_RESP): | 1112 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EARLY_RESP): |
1135 | { | 1113 | { |
1136 | /* | 1114 | /* |
1137 | * There are times when the SCU hardware will return an early response | 1115 | * There are times when the SCU hardware will return an early |
1138 | * because the io request specified more data than is returned by the | 1116 | * response because the io request specified more data than is |
1139 | * target device (mode pages, inquiry data, etc.). We must check the | 1117 | * returned by the target device (mode pages, inquiry data, |
1140 | * response stats to see if this is truly a failed request or a good | 1118 | * etc.). We must check the response stats to see if this is |
1141 | * request that just got completed early. */ | 1119 | * truly a failed request or a good request that just got |
1142 | struct sci_ssp_response_iu *response = (struct sci_ssp_response_iu *) | 1120 | * completed early. |
1143 | sci_req->response_buffer; | 1121 | */ |
1122 | struct ssp_response_iu *resp = sci_req->response_buffer; | ||
1144 | scic_word_copy_with_swap( | 1123 | scic_word_copy_with_swap( |
1145 | sci_req->response_buffer, | 1124 | sci_req->response_buffer, |
1146 | sci_req->response_buffer, | 1125 | sci_req->response_buffer, |
1147 | sizeof(struct sci_ssp_response_iu) / sizeof(u32) | 1126 | SSP_RESP_IU_MAX_SIZE / sizeof(u32)); |
1148 | ); | ||
1149 | 1127 | ||
1150 | if (response->status == 0) { | 1128 | if (resp->status == 0) { |
1151 | scic_sds_request_set_status( | 1129 | scic_sds_request_set_status( |
1152 | sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS_IO_DONE_EARLY | 1130 | sci_req, |
1153 | ); | 1131 | SCU_TASK_DONE_GOOD, |
1132 | SCI_SUCCESS_IO_DONE_EARLY); | ||
1154 | } else { | 1133 | } else { |
1155 | scic_sds_request_set_status( | 1134 | scic_sds_request_set_status( |
1156 | sci_req, | 1135 | sci_req, |
1157 | SCU_TASK_DONE_CHECK_RESPONSE, | 1136 | SCU_TASK_DONE_CHECK_RESPONSE, |
1158 | SCI_FAILURE_IO_RESPONSE_VALID | 1137 | SCI_FAILURE_IO_RESPONSE_VALID); |
1159 | ); | ||
1160 | } | 1138 | } |
1161 | } | 1139 | } |
1162 | break; | 1140 | break; |
@@ -1165,36 +1143,31 @@ enum sci_status scic_sds_request_started_state_tc_completion_handler( | |||
1165 | scic_word_copy_with_swap( | 1143 | scic_word_copy_with_swap( |
1166 | sci_req->response_buffer, | 1144 | sci_req->response_buffer, |
1167 | sci_req->response_buffer, | 1145 | sci_req->response_buffer, |
1168 | sizeof(struct sci_ssp_response_iu) / sizeof(u32) | 1146 | SSP_RESP_IU_MAX_SIZE / sizeof(u32)); |
1169 | ); | ||
1170 | 1147 | ||
1171 | scic_sds_request_set_status( | 1148 | scic_sds_request_set_status( |
1172 | sci_req, | 1149 | sci_req, |
1173 | SCU_TASK_DONE_CHECK_RESPONSE, | 1150 | SCU_TASK_DONE_CHECK_RESPONSE, |
1174 | SCI_FAILURE_IO_RESPONSE_VALID | 1151 | SCI_FAILURE_IO_RESPONSE_VALID); |
1175 | ); | ||
1176 | break; | 1152 | break; |
1177 | 1153 | ||
1178 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RESP_LEN_ERR): | 1154 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RESP_LEN_ERR): |
1179 | /* | 1155 | /* |
1180 | * / @todo With TASK_DONE_RESP_LEN_ERR is the response frame guaranteed | 1156 | * / @todo With TASK_DONE_RESP_LEN_ERR is the response frame |
1181 | * / to be received before this completion status is posted? */ | 1157 | * guaranteed to be received before this completion status is |
1182 | response_buffer = | 1158 | * posted? |
1183 | (struct sci_ssp_response_iu *)sci_req->response_buffer; | 1159 | */ |
1184 | data_present = | 1160 | resp_iu = sci_req->response_buffer; |
1185 | response_buffer->data_present & SCI_SSP_RESPONSE_IU_DATA_PRESENT_MASK; | 1161 | datapres = resp_iu->datapres; |
1186 | 1162 | ||
1187 | if ((data_present == 0x01) || (data_present == 0x02)) { | 1163 | if ((datapres == 0x01) || (datapres == 0x02)) { |
1188 | scic_sds_request_set_status( | 1164 | scic_sds_request_set_status( |
1189 | sci_req, | 1165 | sci_req, |
1190 | SCU_TASK_DONE_CHECK_RESPONSE, | 1166 | SCU_TASK_DONE_CHECK_RESPONSE, |
1191 | SCI_FAILURE_IO_RESPONSE_VALID | 1167 | SCI_FAILURE_IO_RESPONSE_VALID); |
1192 | ); | 1168 | } else |
1193 | } else { | ||
1194 | scic_sds_request_set_status( | 1169 | scic_sds_request_set_status( |
1195 | sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS | 1170 | sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS); |
1196 | ); | ||
1197 | } | ||
1198 | break; | 1171 | break; |
1199 | 1172 | ||
1200 | /* only stp device gets suspended. */ | 1173 | /* only stp device gets suspended. */ |
@@ -1212,15 +1185,15 @@ enum sci_status scic_sds_request_started_state_tc_completion_handler( | |||
1212 | if (sci_req->protocol == SCIC_STP_PROTOCOL) { | 1185 | if (sci_req->protocol == SCIC_STP_PROTOCOL) { |
1213 | scic_sds_request_set_status( | 1186 | scic_sds_request_set_status( |
1214 | sci_req, | 1187 | sci_req, |
1215 | SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT, | 1188 | SCU_GET_COMPLETION_TL_STATUS(completion_code) >> |
1216 | SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED | 1189 | SCU_COMPLETION_TL_STATUS_SHIFT, |
1217 | ); | 1190 | SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED); |
1218 | } else { | 1191 | } else { |
1219 | scic_sds_request_set_status( | 1192 | scic_sds_request_set_status( |
1220 | sci_req, | 1193 | sci_req, |
1221 | SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT, | 1194 | SCU_GET_COMPLETION_TL_STATUS(completion_code) >> |
1222 | SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR | 1195 | SCU_COMPLETION_TL_STATUS_SHIFT, |
1223 | ); | 1196 | SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR); |
1224 | } | 1197 | } |
1225 | break; | 1198 | break; |
1226 | 1199 | ||
@@ -1237,9 +1210,9 @@ enum sci_status scic_sds_request_started_state_tc_completion_handler( | |||
1237 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED): | 1210 | case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED): |
1238 | scic_sds_request_set_status( | 1211 | scic_sds_request_set_status( |
1239 | sci_req, | 1212 | sci_req, |
1240 | SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT, | 1213 | SCU_GET_COMPLETION_TL_STATUS(completion_code) >> |
1241 | SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED | 1214 | SCU_COMPLETION_TL_STATUS_SHIFT, |
1242 | ); | 1215 | SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED); |
1243 | break; | 1216 | break; |
1244 | 1217 | ||
1245 | /* neither ssp nor stp gets suspended. */ | 1218 | /* neither ssp nor stp gets suspended. */ |
@@ -1261,19 +1234,20 @@ enum sci_status scic_sds_request_started_state_tc_completion_handler( | |||
1261 | default: | 1234 | default: |
1262 | scic_sds_request_set_status( | 1235 | scic_sds_request_set_status( |
1263 | sci_req, | 1236 | sci_req, |
1264 | SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT, | 1237 | SCU_GET_COMPLETION_TL_STATUS(completion_code) >> |
1265 | SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR | 1238 | SCU_COMPLETION_TL_STATUS_SHIFT, |
1266 | ); | 1239 | SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR); |
1267 | break; | 1240 | break; |
1268 | } | 1241 | } |
1269 | 1242 | ||
1270 | /** | 1243 | /* |
1271 | * @todo This is probably wrong for ACK/NAK timeout conditions | 1244 | * TODO: This is probably wrong for ACK/NAK timeout conditions |
1272 | */ | 1245 | */ |
1273 | 1246 | ||
1274 | /* In all cases we will treat this as the completion of the IO request. */ | 1247 | /* In all cases we will treat this as the completion of the IO req. */ |
1275 | sci_base_state_machine_change_state(&sci_req->state_machine, | 1248 | sci_base_state_machine_change_state( |
1276 | SCI_BASE_REQUEST_STATE_COMPLETED); | 1249 | &sci_req->state_machine, |
1250 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
1277 | return SCI_SUCCESS; | 1251 | return SCI_SUCCESS; |
1278 | } | 1252 | } |
1279 | 1253 | ||
@@ -1285,49 +1259,42 @@ enum sci_status scic_sds_request_started_state_tc_completion_handler( | |||
1285 | * at completion time. If the frame type is not a response buffer an error is | 1259 | * at completion time. If the frame type is not a response buffer an error is |
1286 | * logged. enum sci_status SCI_SUCCESS SCI_FAILURE_INVALID_PARAMETER_VALUE | 1260 | * logged. enum sci_status SCI_SUCCESS SCI_FAILURE_INVALID_PARAMETER_VALUE |
1287 | */ | 1261 | */ |
1288 | static enum sci_status scic_sds_request_started_state_frame_handler( | 1262 | static enum sci_status |
1289 | struct scic_sds_request *sci_req, | 1263 | scic_sds_request_started_state_frame_handler(struct scic_sds_request *sci_req, |
1290 | u32 frame_index) | 1264 | u32 frame_index) |
1291 | { | 1265 | { |
1292 | enum sci_status status; | 1266 | enum sci_status status; |
1293 | struct sci_ssp_frame_header *frame_header; | 1267 | struct sci_ssp_frame_header *frame_header; |
1294 | 1268 | ||
1295 | /* / @todo If this is a response frame we must record that we received it */ | ||
1296 | status = scic_sds_unsolicited_frame_control_get_header( | 1269 | status = scic_sds_unsolicited_frame_control_get_header( |
1297 | &(scic_sds_request_get_controller(sci_req)->uf_control), | 1270 | &(scic_sds_request_get_controller(sci_req)->uf_control), |
1298 | frame_index, | 1271 | frame_index, |
1299 | (void **)&frame_header | 1272 | (void **)&frame_header); |
1300 | ); | ||
1301 | 1273 | ||
1302 | if (frame_header->frame_type == SCI_SAS_RESPONSE_FRAME) { | 1274 | if (frame_header->frame_type == SCI_SAS_RESPONSE_FRAME) { |
1303 | struct sci_ssp_response_iu *response_buffer; | 1275 | struct ssp_response_iu *resp_iu; |
1304 | 1276 | ||
1305 | status = scic_sds_unsolicited_frame_control_get_buffer( | 1277 | status = scic_sds_unsolicited_frame_control_get_buffer( |
1306 | &(scic_sds_request_get_controller(sci_req)->uf_control), | 1278 | &(scic_sds_request_get_controller(sci_req)->uf_control), |
1307 | frame_index, | 1279 | frame_index, |
1308 | (void **)&response_buffer | 1280 | (void **)&resp_iu); |
1309 | ); | ||
1310 | 1281 | ||
1311 | scic_word_copy_with_swap( | 1282 | scic_word_copy_with_swap(sci_req->response_buffer, |
1312 | sci_req->response_buffer, | 1283 | (u32 *)resp_iu, |
1313 | (u32 *)response_buffer, | 1284 | SSP_RESP_IU_MAX_SIZE); |
1314 | sizeof(struct sci_ssp_response_iu) | ||
1315 | ); | ||
1316 | 1285 | ||
1317 | response_buffer = (struct sci_ssp_response_iu *)sci_req->response_buffer; | 1286 | resp_iu = sci_req->response_buffer; |
1318 | 1287 | ||
1319 | if ((response_buffer->data_present == 0x01) || | 1288 | if ((resp_iu->datapres == 0x01) || |
1320 | (response_buffer->data_present == 0x02)) { | 1289 | (resp_iu->datapres == 0x02)) { |
1321 | scic_sds_request_set_status( | 1290 | scic_sds_request_set_status( |
1322 | sci_req, | 1291 | sci_req, |
1323 | SCU_TASK_DONE_CHECK_RESPONSE, | 1292 | SCU_TASK_DONE_CHECK_RESPONSE, |
1324 | SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR | 1293 | SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR); |
1325 | ); | ||
1326 | } else | 1294 | } else |
1327 | scic_sds_request_set_status( | 1295 | scic_sds_request_set_status( |
1328 | sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS | 1296 | sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS); |
1329 | ); | 1297 | } else { |
1330 | } else | ||
1331 | /* This was not a response frame why did it get forwarded? */ | 1298 | /* This was not a response frame why did it get forwarded? */ |
1332 | dev_err(scic_to_dev(sci_req->owning_controller), | 1299 | dev_err(scic_to_dev(sci_req->owning_controller), |
1333 | "%s: SCIC IO Request 0x%p received unexpected " | 1300 | "%s: SCIC IO Request 0x%p received unexpected " |
@@ -1336,13 +1303,14 @@ static enum sci_status scic_sds_request_started_state_frame_handler( | |||
1336 | sci_req, | 1303 | sci_req, |
1337 | frame_index, | 1304 | frame_index, |
1338 | frame_header->frame_type); | 1305 | frame_header->frame_type); |
1306 | } | ||
1339 | 1307 | ||
1340 | /* | 1308 | /* |
1341 | * In any case we are done with this frame buffer return it to the | 1309 | * In any case we are done with this frame buffer return it to the |
1342 | * controller */ | 1310 | * controller |
1311 | */ | ||
1343 | scic_sds_controller_release_frame( | 1312 | scic_sds_controller_release_frame( |
1344 | sci_req->owning_controller, frame_index | 1313 | sci_req->owning_controller, frame_index); |
1345 | ); | ||
1346 | 1314 | ||
1347 | return SCI_SUCCESS; | 1315 | return SCI_SUCCESS; |
1348 | } | 1316 | } |
diff --git a/drivers/scsi/isci/core/scic_sds_stp_request.c b/drivers/scsi/isci/core/scic_sds_stp_request.c index b3ad33bc4221..8569dba6c68b 100644 --- a/drivers/scsi/isci/core/scic_sds_stp_request.c +++ b/drivers/scsi/isci/core/scic_sds_stp_request.c | |||
@@ -102,7 +102,7 @@ | |||
102 | #define scic_sds_stp_request_get_task_context_buffer(memory) \ | 102 | #define scic_sds_stp_request_get_task_context_buffer(memory) \ |
103 | ((struct scu_task_context *)(\ | 103 | ((struct scu_task_context *)(\ |
104 | ((char *)(scic_sds_stp_request_get_response_buffer(memory))) \ | 104 | ((char *)(scic_sds_stp_request_get_response_buffer(memory))) \ |
105 | + sizeof(struct sci_ssp_response_iu) \ | 105 | + SSP_RESP_IU_MAX_SIZE \ |
106 | )) | 106 | )) |
107 | 107 | ||
108 | /** | 108 | /** |
diff --git a/drivers/scsi/isci/sas.h b/drivers/scsi/isci/sas.h index 21ddd63924eb..1a1e9bc125c3 100644 --- a/drivers/scsi/isci/sas.h +++ b/drivers/scsi/isci/sas.h | |||
@@ -69,6 +69,9 @@ | |||
69 | #define FIS_PIO_SETUP 0x5F | 69 | #define FIS_PIO_SETUP 0x5F |
70 | #define FIS_DATA 0x46 | 70 | #define FIS_DATA 0x46 |
71 | 71 | ||
72 | /**************************************************************************/ | ||
73 | #define SSP_RESP_IU_MAX_SIZE 280 | ||
74 | |||
72 | /* | 75 | /* |
73 | * contents of the SSP COMMAND INFORMATION UNIT. | 76 | * contents of the SSP COMMAND INFORMATION UNIT. |
74 | * For specific information on each of these individual fields please | 77 | * For specific information on each of these individual fields please |
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index c4db95933d41..8449d8abd66a 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c | |||
@@ -55,6 +55,7 @@ | |||
55 | 55 | ||
56 | #include <linux/completion.h> | 56 | #include <linux/completion.h> |
57 | #include <linux/irqflags.h> | 57 | #include <linux/irqflags.h> |
58 | #include "sas.h" | ||
58 | #include "scic_task_request.h" | 59 | #include "scic_task_request.h" |
59 | #include "scic_io_request.h" | 60 | #include "scic_io_request.h" |
60 | #include "remote_device.h" | 61 | #include "remote_device.h" |
@@ -63,7 +64,8 @@ | |||
63 | #include "request.h" | 64 | #include "request.h" |
64 | #include "sata.h" | 65 | #include "sata.h" |
65 | #include "task.h" | 66 | #include "task.h" |
66 | #include "core/scic_sds_request.h" | 67 | #include "scic_sds_stp_request.h" |
68 | |||
67 | /** | 69 | /** |
68 | * isci_task_refuse() - complete the request to the upper layer driver in | 70 | * isci_task_refuse() - complete the request to the upper layer driver in |
69 | * the case where an I/O needs to be completed back in the submit path. | 71 | * the case where an I/O needs to be completed back in the submit path. |
@@ -1411,109 +1413,75 @@ int isci_task_query_task( | |||
1411 | return TMF_RESP_FUNC_SUCC; | 1413 | return TMF_RESP_FUNC_SUCC; |
1412 | } | 1414 | } |
1413 | 1415 | ||
1414 | /** | 1416 | /* |
1415 | * isci_task_request_complete() - This function is called by the sci core when | 1417 | * isci_task_request_complete() - This function is called by the sci core when |
1416 | * an task request completes. | 1418 | * an task request completes. |
1417 | * @isci_host: This parameter specifies the ISCI host object | 1419 | * @ihost: This parameter specifies the ISCI host object |
1418 | * @request: This parameter is the completed isci_request object. | 1420 | * @ireq: This parameter is the completed isci_request object. |
1419 | * @completion_status: This parameter specifies the completion status from the | 1421 | * @completion_status: This parameter specifies the completion status from the |
1420 | * sci core. | 1422 | * sci core. |
1421 | * | 1423 | * |
1422 | * none. | 1424 | * none. |
1423 | */ | 1425 | */ |
1424 | void isci_task_request_complete( | 1426 | void |
1425 | struct isci_host *isci_host, | 1427 | isci_task_request_complete(struct isci_host *ihost, |
1426 | struct isci_request *request, | 1428 | struct isci_request *ireq, |
1427 | enum sci_task_status completion_status) | 1429 | enum sci_task_status completion_status) |
1428 | { | 1430 | { |
1429 | struct isci_remote_device *isci_device = request->isci_device; | 1431 | struct isci_remote_device *idev = ireq->isci_device; |
1430 | enum isci_request_status old_state; | 1432 | enum isci_request_status old_state; |
1431 | struct isci_tmf *tmf = isci_request_access_tmf(request); | 1433 | struct isci_tmf *tmf = isci_request_access_tmf(ireq); |
1432 | struct completion *tmf_complete; | 1434 | struct completion *tmf_complete; |
1435 | struct scic_sds_request *sci_req = ireq->sci_request_handle; | ||
1436 | struct scic_sds_stp_request *stp_req = | ||
1437 | container_of(sci_req, typeof(*stp_req), parent); | ||
1433 | 1438 | ||
1434 | dev_dbg(&isci_host->pdev->dev, | 1439 | dev_dbg(&ihost->pdev->dev, |
1435 | "%s: request = %p, status=%d\n", | 1440 | "%s: request = %p, status=%d\n", |
1436 | __func__, request, completion_status); | 1441 | __func__, ireq, completion_status); |
1437 | 1442 | ||
1438 | old_state = isci_request_change_state(request, completed); | 1443 | old_state = isci_request_change_state(ireq, completed); |
1439 | 1444 | ||
1440 | tmf->status = completion_status; | 1445 | tmf->status = completion_status; |
1441 | request->complete_in_target = true; | 1446 | ireq->complete_in_target = true; |
1442 | |||
1443 | if (SAS_PROTOCOL_SSP == tmf->proto) { | ||
1444 | 1447 | ||
1448 | if (tmf->proto == SAS_PROTOCOL_SSP) { | ||
1445 | memcpy(&tmf->resp.resp_iu, | 1449 | memcpy(&tmf->resp.resp_iu, |
1446 | scic_io_request_get_response_iu_address( | 1450 | sci_req->response_buffer, |
1447 | request->sci_request_handle | 1451 | SSP_RESP_IU_MAX_SIZE); |
1448 | ), | 1452 | } else if (tmf->proto == SAS_PROTOCOL_SATA) { |
1449 | sizeof(struct sci_ssp_response_iu)); | ||
1450 | |||
1451 | } else if (SAS_PROTOCOL_SATA == tmf->proto) { | ||
1452 | |||
1453 | memcpy(&tmf->resp.d2h_fis, | 1453 | memcpy(&tmf->resp.d2h_fis, |
1454 | scic_stp_io_request_get_d2h_reg_address( | 1454 | &stp_req->d2h_reg_fis, |
1455 | request->sci_request_handle), | ||
1456 | sizeof(struct dev_to_host_fis)); | 1455 | sizeof(struct dev_to_host_fis)); |
1457 | } | 1456 | } |
1458 | 1457 | ||
1459 | /* Manage the timer if it is still running. */ | 1458 | /* Manage the timer if it is still running. */ |
1460 | if (tmf->timeout_timer) { | 1459 | if (tmf->timeout_timer) { |
1461 | isci_del_timer(isci_host, tmf->timeout_timer); | 1460 | isci_del_timer(ihost, tmf->timeout_timer); |
1462 | tmf->timeout_timer = NULL; | 1461 | tmf->timeout_timer = NULL; |
1463 | } | 1462 | } |
1464 | 1463 | ||
1465 | /* PRINT_TMF( ((struct isci_tmf *)request->task)); */ | 1464 | /* PRINT_TMF( ((struct isci_tmf *)request->task)); */ |
1466 | tmf_complete = tmf->complete; | 1465 | tmf_complete = tmf->complete; |
1467 | 1466 | ||
1468 | scic_controller_complete_io( | 1467 | scic_controller_complete_io(ihost->core_controller, |
1469 | isci_host->core_controller, | 1468 | &idev->sci, |
1470 | &isci_device->sci, | 1469 | ireq->sci_request_handle); |
1471 | request->sci_request_handle); | 1470 | |
1472 | /* NULL the request handle to make sure it cannot be terminated | 1471 | /* |
1472 | * NULL the request handle to make sure it cannot be terminated | ||
1473 | * or completed again. | 1473 | * or completed again. |
1474 | */ | 1474 | */ |
1475 | request->sci_request_handle = NULL; | 1475 | ireq->sci_request_handle = NULL; |
1476 | 1476 | ||
1477 | isci_request_change_state(request, unallocated); | 1477 | isci_request_change_state(ireq, unallocated); |
1478 | list_del_init(&request->dev_node); | 1478 | list_del_init(&ireq->dev_node); |
1479 | 1479 | ||
1480 | /* The task management part completes last. */ | 1480 | /* The task management part completes last. */ |
1481 | complete(tmf_complete); | 1481 | complete(tmf_complete); |
1482 | } | 1482 | } |
1483 | 1483 | ||
1484 | /** | 1484 | /** |
1485 | * isci_task_ssp_request_get_response_data_address() - This function is called | ||
1486 | * by the sci core to retrieve the response data address for a given task | ||
1487 | * request. | ||
1488 | * @request: This parameter is the isci_request object. | ||
1489 | * | ||
1490 | * response data address for specified task request. | ||
1491 | */ | ||
1492 | void *isci_task_ssp_request_get_response_data_address( | ||
1493 | struct isci_request *request) | ||
1494 | { | ||
1495 | struct isci_tmf *isci_tmf = isci_request_access_tmf(request); | ||
1496 | |||
1497 | return &isci_tmf->resp.resp_iu; | ||
1498 | } | ||
1499 | |||
1500 | /** | ||
1501 | * isci_task_ssp_request_get_response_data_length() - This function is called | ||
1502 | * by the sci core to retrieve the response data length for a given task | ||
1503 | * request. | ||
1504 | * @request: This parameter is the isci_request object. | ||
1505 | * | ||
1506 | * response data length for specified task request. | ||
1507 | */ | ||
1508 | u32 isci_task_ssp_request_get_response_data_length( | ||
1509 | struct isci_request *request) | ||
1510 | { | ||
1511 | struct isci_tmf *isci_tmf = isci_request_access_tmf(request); | ||
1512 | |||
1513 | return sizeof(isci_tmf->resp.resp_iu); | ||
1514 | } | ||
1515 | |||
1516 | /** | ||
1517 | * isci_bus_reset_handler() - This function performs a target reset of the | 1485 | * isci_bus_reset_handler() - This function performs a target reset of the |
1518 | * device referenced by "cmd'. This function is exported through the | 1486 | * device referenced by "cmd'. This function is exported through the |
1519 | * "struct scsi_host_template" structure such that it is called when an I/O | 1487 | * "struct scsi_host_template" structure such that it is called when an I/O |
diff --git a/drivers/scsi/isci/task.h b/drivers/scsi/isci/task.h index c5afd1cfbde7..77cc54dbe81f 100644 --- a/drivers/scsi/isci/task.h +++ b/drivers/scsi/isci/task.h | |||
@@ -99,7 +99,7 @@ struct isci_tmf { | |||
99 | struct completion *complete; | 99 | struct completion *complete; |
100 | enum sas_protocol proto; | 100 | enum sas_protocol proto; |
101 | union { | 101 | union { |
102 | struct sci_ssp_response_iu resp_iu; | 102 | struct ssp_response_iu resp_iu; |
103 | struct dev_to_host_fis d2h_fis; | 103 | struct dev_to_host_fis d2h_fis; |
104 | } resp; | 104 | } resp; |
105 | unsigned char lun[8]; | 105 | unsigned char lun[8]; |
@@ -120,8 +120,7 @@ struct isci_tmf { | |||
120 | 120 | ||
121 | }; | 121 | }; |
122 | 122 | ||
123 | static inline void isci_print_tmf( | 123 | static inline void isci_print_tmf(struct isci_tmf *tmf) |
124 | struct isci_tmf *tmf) | ||
125 | { | 124 | { |
126 | if (SAS_PROTOCOL_SATA == tmf->proto) | 125 | if (SAS_PROTOCOL_SATA == tmf->proto) |
127 | dev_dbg(&tmf->device->isci_port->isci_host->pdev->dev, | 126 | dev_dbg(&tmf->device->isci_port->isci_host->pdev->dev, |
@@ -144,16 +143,13 @@ static inline void isci_print_tmf( | |||
144 | "tmf->resp.resp_iu.data[3] = %x\n", | 143 | "tmf->resp.resp_iu.data[3] = %x\n", |
145 | __func__, | 144 | __func__, |
146 | tmf->status, | 145 | tmf->status, |
147 | tmf->resp.resp_iu.data_present, | 146 | tmf->resp.resp_iu.datapres, |
148 | tmf->resp.resp_iu.status, | 147 | tmf->resp.resp_iu.status, |
149 | (tmf->resp.resp_iu.response_data_length[0] << 24) + | 148 | be32_to_cpu(tmf->resp.resp_iu.response_data_len), |
150 | (tmf->resp.resp_iu.response_data_length[1] << 16) + | 149 | tmf->resp.resp_iu.resp_data[0], |
151 | (tmf->resp.resp_iu.response_data_length[2] << 8) + | 150 | tmf->resp.resp_iu.resp_data[1], |
152 | tmf->resp.resp_iu.response_data_length[3], | 151 | tmf->resp.resp_iu.resp_data[2], |
153 | tmf->resp.resp_iu.data[0], | 152 | tmf->resp.resp_iu.resp_data[3]); |
154 | tmf->resp.resp_iu.data[1], | ||
155 | tmf->resp.resp_iu.data[2], | ||
156 | tmf->resp.resp_iu.data[3]); | ||
157 | } | 153 | } |
158 | 154 | ||
159 | 155 | ||