aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/request.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-05-10 05:28:47 -0400
committerDan Williams <dan.j.williams@intel.com>2011-07-03 07:04:47 -0400
commitf139303d17c47eff4c5b5407dee0a6d43e8fd146 (patch)
treeb58d13c01567500e7b0a451bbcd46dd78ceb4da7 /drivers/scsi/isci/request.c
parente2f8db509fdd354bb7a68c86515e9d2d8909ccc9 (diff)
isci: merge ssp task management substates into primary state machine
Remove usage of the request substate machine for ssp task management requests identified by: ireq->ttype == tmf_task && dev->dev_type == SAS_END_DEV; The only routine that checks the base 'started' state is scic_sds_io_request_tc_completion which calls the substate machine handler if we are not in the 'started' state or we are 'started' and no substate machine is defined. This routine requires no conversion because we have transitioned out of 'started' and the substate routine will be called naturally as a result. There are also no side effects of this conversion on exiting the 'started', state because it only stops the substate machine, which is no longer relevant for this transaction type. Reported-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/request.c')
-rw-r--r--drivers/scsi/isci/request.c185
1 files changed, 164 insertions, 21 deletions
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index 48e2dac72528..5f5168110556 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -656,7 +656,7 @@ enum sci_status scic_sds_io_request_frame_handler(
656 * @sci_req: This parameter specifies the request object for which to copy 656 * @sci_req: This parameter specifies the request object for which to copy
657 * the response data. 657 * the response data.
658 */ 658 */
659void scic_sds_io_request_copy_response(struct scic_sds_request *sci_req) 659static void scic_sds_io_request_copy_response(struct scic_sds_request *sci_req)
660{ 660{
661 void *resp_buf; 661 void *resp_buf;
662 u32 len; 662 u32 len;
@@ -978,7 +978,6 @@ scic_sds_io_request_tc_completion(struct scic_sds_request *request, u32 completi
978 sci_base_state_machine_get_state(&request->state_machine)); 978 sci_base_state_machine_get_state(&request->state_machine));
979 979
980 return SCI_FAILURE_INVALID_STATE; 980 return SCI_FAILURE_INVALID_STATE;
981
982} 981}
983 982
984/* 983/*
@@ -1151,9 +1150,119 @@ static enum sci_status scic_sds_request_aborting_state_frame_handler(
1151 return SCI_SUCCESS; 1150 return SCI_SUCCESS;
1152} 1151}
1153 1152
1153/**
1154 * This method processes the completions transport layer (TL) status to
1155 * determine if the RAW task management frame was sent successfully. If the
1156 * raw frame was sent successfully, then the state for the task request
1157 * transitions to waiting for a response frame.
1158 * @sci_req: This parameter specifies the request for which the TC
1159 * completion was received.
1160 * @completion_code: This parameter indicates the completion status information
1161 * for the TC.
1162 *
1163 * Indicate if the tc completion handler was successful. SCI_SUCCESS currently
1164 * this method always returns success.
1165 */
1166static enum sci_status scic_sds_ssp_task_request_await_tc_completion_tc_completion_handler(
1167 struct scic_sds_request *sci_req,
1168 u32 completion_code)
1169{
1170 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1171 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1172 scic_sds_request_set_status(sci_req, SCU_TASK_DONE_GOOD,
1173 SCI_SUCCESS);
1174
1175 sci_base_state_machine_change_state(&sci_req->state_machine,
1176 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE);
1177 break;
1178
1179 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_ACK_NAK_TO):
1180 /*
1181 * Currently, the decision is to simply allow the task request to
1182 * timeout if the task IU wasn't received successfully.
1183 * There is a potential for receiving multiple task responses if we
1184 * decide to send the task IU again. */
1185 dev_warn(scic_to_dev(sci_req->owning_controller),
1186 "%s: TaskRequest:0x%p CompletionCode:%x - "
1187 "ACK/NAK timeout\n",
1188 __func__,
1189 sci_req,
1190 completion_code);
1191
1192 sci_base_state_machine_change_state(&sci_req->state_machine,
1193 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE);
1194 break;
1195
1196 default:
1197 /*
1198 * All other completion status cause the IO to be complete. If a NAK
1199 * was received, then it is up to the user to retry the request. */
1200 scic_sds_request_set_status(
1201 sci_req,
1202 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1203 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1204 );
1205
1206 sci_base_state_machine_change_state(&sci_req->state_machine,
1207 SCI_BASE_REQUEST_STATE_COMPLETED);
1208 break;
1209 }
1210
1211 return SCI_SUCCESS;
1212}
1213
1214/**
1215 * This method is responsible for processing a terminate/abort request for this
1216 * TC while the request is waiting for the task management response
1217 * unsolicited frame.
1218 * @sci_req: This parameter specifies the request for which the
1219 * termination was requested.
1220 *
1221 * This method returns an indication as to whether the abort request was
1222 * successfully handled. need to update to ensure the received UF doesn't cause
1223 * damage to subsequent requests (i.e. put the extended tag in a holding
1224 * pattern for this particular device).
1225 */
1226static enum sci_status scic_sds_ssp_task_request_await_tc_response_abort_handler(
1227 struct scic_sds_request *request)
1228{
1229 sci_base_state_machine_change_state(&request->state_machine,
1230 SCI_BASE_REQUEST_STATE_ABORTING);
1231 sci_base_state_machine_change_state(&request->state_machine,
1232 SCI_BASE_REQUEST_STATE_COMPLETED);
1233 return SCI_SUCCESS;
1234}
1235
1236/**
1237 * This method processes an unsolicited frame while the task mgmt request is
1238 * waiting for a response frame. It will copy the response data, release
1239 * the unsolicited frame, and transition the request to the
1240 * SCI_BASE_REQUEST_STATE_COMPLETED state.
1241 * @sci_req: This parameter specifies the request for which the
1242 * unsolicited frame was received.
1243 * @frame_index: This parameter indicates the unsolicited frame index that
1244 * should contain the response.
1245 *
1246 * This method returns an indication of whether the TC response frame was
1247 * handled successfully or not. SCI_SUCCESS Currently this value is always
1248 * returned and indicates successful processing of the TC response. Should
1249 * probably update to check frame type and make sure it is a response frame.
1250 */
1251static enum sci_status scic_sds_ssp_task_request_await_tc_response_frame_handler(
1252 struct scic_sds_request *request,
1253 u32 frame_index)
1254{
1255 scic_sds_io_request_copy_response(request);
1256
1257 sci_base_state_machine_change_state(&request->state_machine,
1258 SCI_BASE_REQUEST_STATE_COMPLETED);
1259 scic_sds_controller_release_frame(request->owning_controller,
1260 frame_index);
1261 return SCI_SUCCESS;
1262}
1263
1154static const struct scic_sds_io_request_state_handler scic_sds_request_state_handler_table[] = { 1264static const struct scic_sds_io_request_state_handler scic_sds_request_state_handler_table[] = {
1155 [SCI_BASE_REQUEST_STATE_INITIAL] = { 1265 [SCI_BASE_REQUEST_STATE_INITIAL] = { },
1156 },
1157 [SCI_BASE_REQUEST_STATE_CONSTRUCTED] = { 1266 [SCI_BASE_REQUEST_STATE_CONSTRUCTED] = {
1158 .start_handler = scic_sds_request_constructed_state_start_handler, 1267 .start_handler = scic_sds_request_constructed_state_start_handler,
1159 .abort_handler = scic_sds_request_constructed_state_abort_handler, 1268 .abort_handler = scic_sds_request_constructed_state_abort_handler,
@@ -1163,6 +1272,14 @@ static const struct scic_sds_io_request_state_handler scic_sds_request_state_han
1163 .tc_completion_handler = scic_sds_request_started_state_tc_completion_handler, 1272 .tc_completion_handler = scic_sds_request_started_state_tc_completion_handler,
1164 .frame_handler = scic_sds_request_started_state_frame_handler, 1273 .frame_handler = scic_sds_request_started_state_frame_handler,
1165 }, 1274 },
1275 [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION] = {
1276 .abort_handler = scic_sds_request_started_state_abort_handler,
1277 .tc_completion_handler = scic_sds_ssp_task_request_await_tc_completion_tc_completion_handler,
1278 },
1279 [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE] = {
1280 .abort_handler = scic_sds_ssp_task_request_await_tc_response_abort_handler,
1281 .frame_handler = scic_sds_ssp_task_request_await_tc_response_frame_handler,
1282 },
1166 [SCI_BASE_REQUEST_STATE_COMPLETED] = { 1283 [SCI_BASE_REQUEST_STATE_COMPLETED] = {
1167 .complete_handler = scic_sds_request_completed_state_complete_handler, 1284 .complete_handler = scic_sds_request_completed_state_complete_handler,
1168 }, 1285 },
@@ -1171,8 +1288,7 @@ static const struct scic_sds_io_request_state_handler scic_sds_request_state_han
1171 .tc_completion_handler = scic_sds_request_aborting_state_tc_completion_handler, 1288 .tc_completion_handler = scic_sds_request_aborting_state_tc_completion_handler,
1172 .frame_handler = scic_sds_request_aborting_state_frame_handler, 1289 .frame_handler = scic_sds_request_aborting_state_frame_handler,
1173 }, 1290 },
1174 [SCI_BASE_REQUEST_STATE_FINAL] = { 1291 [SCI_BASE_REQUEST_STATE_FINAL] = { },
1175 },
1176}; 1292};
1177 1293
1178 1294
@@ -1919,6 +2035,9 @@ static void scic_sds_request_constructed_state_enter(void *object)
1919static void scic_sds_request_started_state_enter(void *object) 2035static void scic_sds_request_started_state_enter(void *object)
1920{ 2036{
1921 struct scic_sds_request *sci_req = object; 2037 struct scic_sds_request *sci_req = object;
2038 struct sci_base_state_machine *sm = &sci_req->state_machine;
2039 struct isci_request *ireq = sci_req_to_ireq(sci_req);
2040 struct domain_device *dev = sci_dev_to_domain(sci_req->target_device);
1922 2041
1923 SET_STATE_HANDLER( 2042 SET_STATE_HANDLER(
1924 sci_req, 2043 sci_req,
@@ -1926,9 +2045,13 @@ static void scic_sds_request_started_state_enter(void *object)
1926 SCI_BASE_REQUEST_STATE_STARTED 2045 SCI_BASE_REQUEST_STATE_STARTED
1927 ); 2046 );
1928 2047
1929 /* 2048 if (ireq->ttype == tmf_task && dev->dev_type == SAS_END_DEV)
1930 * Most of the request state machines have a started substate machine so 2049 sci_base_state_machine_change_state(sm,
1931 * start its execution on the entry to the started state. */ 2050 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION);
2051
2052 /* Most of the request state machines have a started substate machine so
2053 * start its execution on the entry to the started state.
2054 */
1932 if (sci_req->has_started_substate_machine == true) 2055 if (sci_req->has_started_substate_machine == true)
1933 sci_base_state_machine_start(&sci_req->started_substate_machine); 2056 sci_base_state_machine_start(&sci_req->started_substate_machine);
1934} 2057}
@@ -2026,6 +2149,30 @@ static void scic_sds_request_final_state_enter(void *object)
2026 ); 2149 );
2027} 2150}
2028 2151
2152static void scic_sds_io_request_started_task_mgmt_await_tc_completion_substate_enter(
2153 void *object)
2154{
2155 struct scic_sds_request *sci_req = object;
2156
2157 SET_STATE_HANDLER(
2158 sci_req,
2159 scic_sds_request_state_handler_table,
2160 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION
2161 );
2162}
2163
2164static void scic_sds_io_request_started_task_mgmt_await_task_response_substate_enter(
2165 void *object)
2166{
2167 struct scic_sds_request *sci_req = object;
2168
2169 SET_STATE_HANDLER(
2170 sci_req,
2171 scic_sds_request_state_handler_table,
2172 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE
2173 );
2174}
2175
2029static const struct sci_base_state scic_sds_request_state_table[] = { 2176static const struct sci_base_state scic_sds_request_state_table[] = {
2030 [SCI_BASE_REQUEST_STATE_INITIAL] = { 2177 [SCI_BASE_REQUEST_STATE_INITIAL] = {
2031 .enter_state = scic_sds_request_initial_state_enter, 2178 .enter_state = scic_sds_request_initial_state_enter,
@@ -2037,6 +2184,12 @@ static const struct sci_base_state scic_sds_request_state_table[] = {
2037 .enter_state = scic_sds_request_started_state_enter, 2184 .enter_state = scic_sds_request_started_state_enter,
2038 .exit_state = scic_sds_request_started_state_exit 2185 .exit_state = scic_sds_request_started_state_exit
2039 }, 2186 },
2187 [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION] = {
2188 .enter_state = scic_sds_io_request_started_task_mgmt_await_tc_completion_substate_enter,
2189 },
2190 [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE] = {
2191 .enter_state = scic_sds_io_request_started_task_mgmt_await_task_response_substate_enter,
2192 },
2040 [SCI_BASE_REQUEST_STATE_COMPLETED] = { 2193 [SCI_BASE_REQUEST_STATE_COMPLETED] = {
2041 .enter_state = scic_sds_request_completed_state_enter, 2194 .enter_state = scic_sds_request_completed_state_enter,
2042 }, 2195 },
@@ -2126,19 +2279,9 @@ enum sci_status scic_task_request_construct(struct scic_sds_controller *scic,
2126 /* Build the common part of the request */ 2279 /* Build the common part of the request */
2127 scic_sds_general_request_construct(scic, sci_dev, io_tag, sci_req); 2280 scic_sds_general_request_construct(scic, sci_dev, io_tag, sci_req);
2128 2281
2129 if (dev->dev_type == SAS_END_DEV) { 2282 if (dev->dev_type == SAS_END_DEV)
2130 scic_sds_ssp_task_request_assign_buffers(sci_req); 2283 scic_sds_ssp_task_request_assign_buffers(sci_req);
2131 2284 else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP))
2132 sci_req->has_started_substate_machine = true;
2133
2134 /* Construct the started sub-state machine. */
2135 sci_base_state_machine_construct(
2136 &sci_req->started_substate_machine,
2137 sci_req,
2138 scic_sds_io_request_started_task_mgmt_substate_table,
2139 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION
2140 );
2141 } else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP))
2142 scic_sds_stp_request_assign_buffers(sci_req); 2285 scic_sds_stp_request_assign_buffers(sci_req);
2143 else 2286 else
2144 status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; 2287 status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;