diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-05-11 11:27:47 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:04:48 -0400 |
commit | d1c637c35b33ddd2b405956e04b50939bb10ed2a (patch) | |
tree | e9283b5d36032d736bfab714283d60c616c546d4 /drivers | |
parent | f4636a7b2ab8288466b83a8459d47c43143a70dc (diff) |
isci: unify request frame handlers
Unify the implementation in scic_sds_io_request_frame_handler and kill
the state handler.
Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/isci/remote_device.c | 3 | ||||
-rw-r--r-- | drivers/scsi/isci/request.c | 1020 | ||||
-rw-r--r-- | drivers/scsi/isci/request.h | 6 |
3 files changed, 422 insertions, 607 deletions
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index 606ee2be154e..b900e2c1b63e 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c | |||
@@ -310,8 +310,7 @@ enum sci_status scic_sds_remote_device_frame_handler(struct scic_sds_remote_devi | |||
310 | sci_req = scic_request_by_tag(scic, be16_to_cpu(hdr.tag)); | 310 | sci_req = scic_request_by_tag(scic, be16_to_cpu(hdr.tag)); |
311 | if (sci_req && sci_req->target_device == sci_dev) { | 311 | if (sci_req && sci_req->target_device == sci_dev) { |
312 | /* The IO request is now in charge of releasing the frame */ | 312 | /* The IO request is now in charge of releasing the frame */ |
313 | status = sci_req->state_handlers->frame_handler(sci_req, | 313 | status = scic_sds_io_request_frame_handler(sci_req, frame_index); |
314 | frame_index); | ||
315 | } else { | 314 | } else { |
316 | /* We could not map this tag to a valid IO | 315 | /* We could not map this tag to a valid IO |
317 | * request Just toss the frame and continue | 316 | * request Just toss the frame and continue |
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 41a418d8b337..b9f97e8cc5e0 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
@@ -907,34 +907,6 @@ enum sci_status scic_sds_io_request_event_handler( | |||
907 | return SCI_FAILURE_INVALID_STATE; | 907 | return SCI_FAILURE_INVALID_STATE; |
908 | } | 908 | } |
909 | 909 | ||
910 | /** | ||
911 | * | ||
912 | * @sci_req: The SCIC_SDS_IO_REQUEST_T object for which the start | ||
913 | * operation is to be executed. | ||
914 | * @frame_index: The frame index returned by the hardware for the reqeust | ||
915 | * object. | ||
916 | * | ||
917 | * This method invokes the core state frame handler for the | ||
918 | * SCIC_SDS_IO_REQUEST_T object. enum sci_status | ||
919 | */ | ||
920 | enum sci_status scic_sds_io_request_frame_handler( | ||
921 | struct scic_sds_request *request, | ||
922 | u32 frame_index) | ||
923 | { | ||
924 | if (request->state_handlers->frame_handler) | ||
925 | return request->state_handlers->frame_handler(request, frame_index); | ||
926 | |||
927 | dev_warn(scic_to_dev(request->owning_controller), | ||
928 | "%s: SCIC IO Request given unexpected frame %x while in " | ||
929 | "state %d\n", | ||
930 | __func__, | ||
931 | frame_index, | ||
932 | sci_base_state_machine_get_state(&request->state_machine)); | ||
933 | |||
934 | scic_sds_controller_release_frame(request->owning_controller, frame_index); | ||
935 | return SCI_FAILURE_INVALID_STATE; | ||
936 | } | ||
937 | |||
938 | /* | 910 | /* |
939 | * This function copies response data for requests returning response data | 911 | * This function copies response data for requests returning response data |
940 | * instead of sense data. | 912 | * instead of sense data. |
@@ -1151,81 +1123,6 @@ scic_sds_io_request_tc_completion(struct scic_sds_request *request, u32 completi | |||
1151 | 1123 | ||
1152 | /* | 1124 | /* |
1153 | * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T | 1125 | * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T |
1154 | * object receives a scic_sds_request_frame_handler() request. This method | ||
1155 | * first determines the frame type received. If this is a response frame then | ||
1156 | * the response data is copied to the io request response buffer for processing | ||
1157 | * at completion time. If the frame type is not a response buffer an error is | ||
1158 | * logged. enum sci_status SCI_SUCCESS SCI_FAILURE_INVALID_PARAMETER_VALUE | ||
1159 | */ | ||
1160 | static enum sci_status | ||
1161 | scic_sds_request_started_state_frame_handler(struct scic_sds_request *sci_req, | ||
1162 | u32 frame_index) | ||
1163 | { | ||
1164 | enum sci_status status; | ||
1165 | u32 *frame_header; | ||
1166 | struct ssp_frame_hdr ssp_hdr; | ||
1167 | ssize_t word_cnt; | ||
1168 | |||
1169 | status = scic_sds_unsolicited_frame_control_get_header( | ||
1170 | &(scic_sds_request_get_controller(sci_req)->uf_control), | ||
1171 | frame_index, | ||
1172 | (void **)&frame_header); | ||
1173 | |||
1174 | word_cnt = sizeof(struct ssp_frame_hdr) / sizeof(u32); | ||
1175 | sci_swab32_cpy(&ssp_hdr, frame_header, word_cnt); | ||
1176 | |||
1177 | if (ssp_hdr.frame_type == SSP_RESPONSE) { | ||
1178 | struct ssp_response_iu *resp_iu; | ||
1179 | ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32); | ||
1180 | |||
1181 | status = scic_sds_unsolicited_frame_control_get_buffer( | ||
1182 | &(scic_sds_request_get_controller(sci_req)->uf_control), | ||
1183 | frame_index, | ||
1184 | (void **)&resp_iu); | ||
1185 | |||
1186 | sci_swab32_cpy(&sci_req->ssp.rsp, | ||
1187 | resp_iu, word_cnt); | ||
1188 | |||
1189 | resp_iu = &sci_req->ssp.rsp; | ||
1190 | |||
1191 | if ((resp_iu->datapres == 0x01) || | ||
1192 | (resp_iu->datapres == 0x02)) { | ||
1193 | scic_sds_request_set_status( | ||
1194 | sci_req, | ||
1195 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
1196 | SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR); | ||
1197 | } else | ||
1198 | scic_sds_request_set_status( | ||
1199 | sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS); | ||
1200 | } else { | ||
1201 | /* This was not a response frame why did it get forwarded? */ | ||
1202 | dev_err(scic_to_dev(sci_req->owning_controller), | ||
1203 | "%s: SCIC IO Request 0x%p received unexpected " | ||
1204 | "frame %d type 0x%02x\n", | ||
1205 | __func__, | ||
1206 | sci_req, | ||
1207 | frame_index, | ||
1208 | ssp_hdr.frame_type); | ||
1209 | } | ||
1210 | |||
1211 | /* | ||
1212 | * In any case we are done with this frame buffer return it to the | ||
1213 | * controller | ||
1214 | */ | ||
1215 | scic_sds_controller_release_frame( | ||
1216 | sci_req->owning_controller, frame_index); | ||
1217 | |||
1218 | return SCI_SUCCESS; | ||
1219 | } | ||
1220 | |||
1221 | /* | ||
1222 | * ***************************************************************************** | ||
1223 | * * COMPLETED STATE HANDLERS | ||
1224 | * ***************************************************************************** */ | ||
1225 | |||
1226 | |||
1227 | /* | ||
1228 | * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T | ||
1229 | * object receives a scic_sds_request_complete() request. This method frees up | 1126 | * object receives a scic_sds_request_complete() request. This method frees up |
1230 | * any io request resources that have been allocated and transitions the | 1127 | * any io request resources that have been allocated and transitions the |
1231 | * request to its final state. Consider stopping the state machine instead of | 1128 | * request to its final state. Consider stopping the state machine instead of |
@@ -1281,24 +1178,6 @@ static enum sci_status scic_sds_request_aborting_state_tc_completion_handler( | |||
1281 | return SCI_SUCCESS; | 1178 | return SCI_SUCCESS; |
1282 | } | 1179 | } |
1283 | 1180 | ||
1284 | /* | ||
1285 | * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T | ||
1286 | * object receives a scic_sds_request_frame_handler() request. This method | ||
1287 | * discards the unsolicited frame since we are waiting for the abort task | ||
1288 | * completion. enum sci_status SCI_SUCCESS | ||
1289 | */ | ||
1290 | static enum sci_status scic_sds_request_aborting_state_frame_handler( | ||
1291 | struct scic_sds_request *sci_req, | ||
1292 | u32 frame_index) | ||
1293 | { | ||
1294 | /* TODO: Is it even possible to get an unsolicited frame in the aborting state? */ | ||
1295 | |||
1296 | scic_sds_controller_release_frame( | ||
1297 | sci_req->owning_controller, frame_index); | ||
1298 | |||
1299 | return SCI_SUCCESS; | ||
1300 | } | ||
1301 | |||
1302 | /** | 1181 | /** |
1303 | * This method processes the completions transport layer (TL) status to | 1182 | * This method processes the completions transport layer (TL) status to |
1304 | * determine if the RAW task management frame was sent successfully. If the | 1183 | * determine if the RAW task management frame was sent successfully. If the |
@@ -1361,34 +1240,6 @@ static enum sci_status scic_sds_ssp_task_request_await_tc_completion_tc_completi | |||
1361 | } | 1240 | } |
1362 | 1241 | ||
1363 | /** | 1242 | /** |
1364 | * This method processes an unsolicited frame while the task mgmt request is | ||
1365 | * waiting for a response frame. It will copy the response data, release | ||
1366 | * the unsolicited frame, and transition the request to the | ||
1367 | * SCI_BASE_REQUEST_STATE_COMPLETED state. | ||
1368 | * @sci_req: This parameter specifies the request for which the | ||
1369 | * unsolicited frame was received. | ||
1370 | * @frame_index: This parameter indicates the unsolicited frame index that | ||
1371 | * should contain the response. | ||
1372 | * | ||
1373 | * This method returns an indication of whether the TC response frame was | ||
1374 | * handled successfully or not. SCI_SUCCESS Currently this value is always | ||
1375 | * returned and indicates successful processing of the TC response. Should | ||
1376 | * probably update to check frame type and make sure it is a response frame. | ||
1377 | */ | ||
1378 | static enum sci_status scic_sds_ssp_task_request_await_tc_response_frame_handler( | ||
1379 | struct scic_sds_request *request, | ||
1380 | u32 frame_index) | ||
1381 | { | ||
1382 | scic_sds_io_request_copy_response(request); | ||
1383 | |||
1384 | sci_base_state_machine_change_state(&request->state_machine, | ||
1385 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
1386 | scic_sds_controller_release_frame(request->owning_controller, | ||
1387 | frame_index); | ||
1388 | return SCI_SUCCESS; | ||
1389 | } | ||
1390 | |||
1391 | /** | ||
1392 | * This method processes an abnormal TC completion while the SMP request is | 1243 | * This method processes an abnormal TC completion while the SMP request is |
1393 | * waiting for a response frame. It decides what happened to the IO based | 1244 | * waiting for a response frame. It decides what happened to the IO based |
1394 | * on TC completion status. | 1245 | * on TC completion status. |
@@ -1450,81 +1301,6 @@ static enum sci_status scic_sds_smp_request_await_response_tc_completion_handler | |||
1450 | return SCI_SUCCESS; | 1301 | return SCI_SUCCESS; |
1451 | } | 1302 | } |
1452 | 1303 | ||
1453 | /* | ||
1454 | * This function processes an unsolicited frame while the SMP request is waiting | ||
1455 | * for a response frame. It will copy the response data, release the | ||
1456 | * unsolicited frame, and transition the request to the | ||
1457 | * SCI_BASE_REQUEST_STATE_COMPLETED state. | ||
1458 | * @sci_req: This parameter specifies the request for which the | ||
1459 | * unsolicited frame was received. | ||
1460 | * @frame_index: This parameter indicates the unsolicited frame index that | ||
1461 | * should contain the response. | ||
1462 | * | ||
1463 | * This function returns an indication of whether the response frame was handled | ||
1464 | * successfully or not. SCI_SUCCESS Currently this value is always returned and | ||
1465 | * indicates successful processing of the TC response. | ||
1466 | */ | ||
1467 | static enum sci_status | ||
1468 | scic_sds_smp_request_await_response_frame_handler(struct scic_sds_request *sci_req, | ||
1469 | u32 frame_index) | ||
1470 | { | ||
1471 | enum sci_status status; | ||
1472 | void *frame_header; | ||
1473 | struct smp_resp *rsp_hdr = &sci_req->smp.rsp; | ||
1474 | ssize_t word_cnt = SMP_RESP_HDR_SZ / sizeof(u32); | ||
1475 | |||
1476 | status = scic_sds_unsolicited_frame_control_get_header( | ||
1477 | &(scic_sds_request_get_controller(sci_req)->uf_control), | ||
1478 | frame_index, | ||
1479 | &frame_header); | ||
1480 | |||
1481 | /* byte swap the header. */ | ||
1482 | sci_swab32_cpy(rsp_hdr, frame_header, word_cnt); | ||
1483 | |||
1484 | if (rsp_hdr->frame_type == SMP_RESPONSE) { | ||
1485 | void *smp_resp; | ||
1486 | |||
1487 | status = scic_sds_unsolicited_frame_control_get_buffer( | ||
1488 | &(scic_sds_request_get_controller(sci_req)->uf_control), | ||
1489 | frame_index, | ||
1490 | &smp_resp); | ||
1491 | |||
1492 | word_cnt = (sizeof(struct smp_req) - SMP_RESP_HDR_SZ) / | ||
1493 | sizeof(u32); | ||
1494 | |||
1495 | sci_swab32_cpy(((u8 *) rsp_hdr) + SMP_RESP_HDR_SZ, | ||
1496 | smp_resp, word_cnt); | ||
1497 | |||
1498 | scic_sds_request_set_status( | ||
1499 | sci_req, SCU_TASK_DONE_GOOD, SCI_SUCCESS); | ||
1500 | |||
1501 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
1502 | SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION); | ||
1503 | } else { | ||
1504 | /* This was not a response frame why did it get forwarded? */ | ||
1505 | dev_err(scic_to_dev(sci_req->owning_controller), | ||
1506 | "%s: SCIC SMP Request 0x%p received unexpected frame " | ||
1507 | "%d type 0x%02x\n", | ||
1508 | __func__, | ||
1509 | sci_req, | ||
1510 | frame_index, | ||
1511 | rsp_hdr->frame_type); | ||
1512 | |||
1513 | scic_sds_request_set_status( | ||
1514 | sci_req, | ||
1515 | SCU_TASK_DONE_SMP_FRM_TYPE_ERR, | ||
1516 | SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR); | ||
1517 | |||
1518 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
1519 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
1520 | } | ||
1521 | |||
1522 | scic_sds_controller_release_frame(sci_req->owning_controller, | ||
1523 | frame_index); | ||
1524 | |||
1525 | return SCI_SUCCESS; | ||
1526 | } | ||
1527 | |||
1528 | /** | 1304 | /** |
1529 | * This method processes the completions transport layer (TL) status to | 1305 | * This method processes the completions transport layer (TL) status to |
1530 | * determine if the SMP request was sent successfully. If the SMP request | 1306 | * determine if the SMP request was sent successfully. If the SMP request |
@@ -1668,76 +1444,6 @@ static enum sci_status scic_sds_stp_request_non_data_await_h2d_tc_completion_han | |||
1668 | return SCI_SUCCESS; | 1444 | return SCI_SUCCESS; |
1669 | } | 1445 | } |
1670 | 1446 | ||
1671 | /** | ||
1672 | * | ||
1673 | * @request: This parameter specifies the request for which a frame has been | ||
1674 | * received. | ||
1675 | * @frame_index: This parameter specifies the index of the frame that has been | ||
1676 | * received. | ||
1677 | * | ||
1678 | * This method processes frames received from the target while waiting for a | ||
1679 | * device to host register FIS. If a non-register FIS is received during this | ||
1680 | * time, it is treated as a protocol violation from an IO perspective. Indicate | ||
1681 | * if the received frame was processed successfully. | ||
1682 | */ | ||
1683 | static enum sci_status scic_sds_stp_request_non_data_await_d2h_frame_handler( | ||
1684 | struct scic_sds_request *sci_req, | ||
1685 | u32 frame_index) | ||
1686 | { | ||
1687 | enum sci_status status; | ||
1688 | struct dev_to_host_fis *frame_header; | ||
1689 | u32 *frame_buffer; | ||
1690 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; | ||
1691 | struct scic_sds_controller *scic = sci_req->owning_controller; | ||
1692 | |||
1693 | status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, | ||
1694 | frame_index, | ||
1695 | (void **)&frame_header); | ||
1696 | |||
1697 | if (status != SCI_SUCCESS) { | ||
1698 | dev_err(scic_to_dev(sci_req->owning_controller), | ||
1699 | "%s: SCIC IO Request 0x%p could not get frame header " | ||
1700 | "for frame index %d, status %x\n", | ||
1701 | __func__, stp_req, frame_index, status); | ||
1702 | |||
1703 | return status; | ||
1704 | } | ||
1705 | |||
1706 | switch (frame_header->fis_type) { | ||
1707 | case FIS_REGD2H: | ||
1708 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
1709 | frame_index, | ||
1710 | (void **)&frame_buffer); | ||
1711 | |||
1712 | scic_sds_controller_copy_sata_response(&sci_req->stp.rsp, | ||
1713 | frame_header, | ||
1714 | frame_buffer); | ||
1715 | |||
1716 | /* The command has completed with error */ | ||
1717 | scic_sds_request_set_status(sci_req, SCU_TASK_DONE_CHECK_RESPONSE, | ||
1718 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
1719 | break; | ||
1720 | |||
1721 | default: | ||
1722 | dev_warn(scic_to_dev(scic), | ||
1723 | "%s: IO Request:0x%p Frame Id:%d protocol " | ||
1724 | "violation occurred\n", __func__, stp_req, | ||
1725 | frame_index); | ||
1726 | |||
1727 | scic_sds_request_set_status(sci_req, SCU_TASK_DONE_UNEXP_FIS, | ||
1728 | SCI_FAILURE_PROTOCOL_VIOLATION); | ||
1729 | break; | ||
1730 | } | ||
1731 | |||
1732 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
1733 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
1734 | |||
1735 | /* Frame has been decoded return it to the controller */ | ||
1736 | scic_sds_controller_release_frame(scic, frame_index); | ||
1737 | |||
1738 | return status; | ||
1739 | } | ||
1740 | |||
1741 | #define SCU_MAX_FRAME_BUFFER_SIZE 0x400 /* 1K is the maximum SCU frame data payload */ | 1447 | #define SCU_MAX_FRAME_BUFFER_SIZE 0x400 /* 1K is the maximum SCU frame data payload */ |
1742 | 1448 | ||
1743 | /* transmit DATA_FIS from (current sgl + offset) for input | 1449 | /* transmit DATA_FIS from (current sgl + offset) for input |
@@ -1952,196 +1658,6 @@ static enum sci_status scic_sds_stp_request_pio_await_h2d_completion_tc_completi | |||
1952 | return status; | 1658 | return status; |
1953 | } | 1659 | } |
1954 | 1660 | ||
1955 | static enum sci_status scic_sds_stp_request_pio_await_frame_frame_handler(struct scic_sds_request *sci_req, | ||
1956 | u32 frame_index) | ||
1957 | { | ||
1958 | struct scic_sds_controller *scic = sci_req->owning_controller; | ||
1959 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; | ||
1960 | struct isci_request *ireq = sci_req_to_ireq(sci_req); | ||
1961 | struct sas_task *task = isci_request_access_task(ireq); | ||
1962 | struct dev_to_host_fis *frame_header; | ||
1963 | enum sci_status status; | ||
1964 | u32 *frame_buffer; | ||
1965 | |||
1966 | status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, | ||
1967 | frame_index, | ||
1968 | (void **)&frame_header); | ||
1969 | |||
1970 | if (status != SCI_SUCCESS) { | ||
1971 | dev_err(scic_to_dev(scic), | ||
1972 | "%s: SCIC IO Request 0x%p could not get frame header " | ||
1973 | "for frame index %d, status %x\n", | ||
1974 | __func__, stp_req, frame_index, status); | ||
1975 | return status; | ||
1976 | } | ||
1977 | |||
1978 | switch (frame_header->fis_type) { | ||
1979 | case FIS_PIO_SETUP: | ||
1980 | /* Get from the frame buffer the PIO Setup Data */ | ||
1981 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
1982 | frame_index, | ||
1983 | (void **)&frame_buffer); | ||
1984 | |||
1985 | /* Get the data from the PIO Setup The SCU Hardware returns | ||
1986 | * first word in the frame_header and the rest of the data is in | ||
1987 | * the frame buffer so we need to back up one dword | ||
1988 | */ | ||
1989 | |||
1990 | /* transfer_count: first 16bits in the 4th dword */ | ||
1991 | stp_req->type.pio.pio_transfer_bytes = frame_buffer[3] & 0xffff; | ||
1992 | |||
1993 | /* ending_status: 4th byte in the 3rd dword */ | ||
1994 | stp_req->type.pio.ending_status = (frame_buffer[2] >> 24) & 0xff; | ||
1995 | |||
1996 | scic_sds_controller_copy_sata_response(&sci_req->stp.rsp, | ||
1997 | frame_header, | ||
1998 | frame_buffer); | ||
1999 | |||
2000 | sci_req->stp.rsp.status = stp_req->type.pio.ending_status; | ||
2001 | |||
2002 | /* The next state is dependent on whether the | ||
2003 | * request was PIO Data-in or Data out | ||
2004 | */ | ||
2005 | if (task->data_dir == DMA_FROM_DEVICE) { | ||
2006 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2007 | SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE); | ||
2008 | } else if (task->data_dir == DMA_TO_DEVICE) { | ||
2009 | /* Transmit data */ | ||
2010 | status = scic_sds_stp_request_pio_data_out_transmit_data(sci_req); | ||
2011 | if (status != SCI_SUCCESS) | ||
2012 | break; | ||
2013 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2014 | SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE); | ||
2015 | } | ||
2016 | break; | ||
2017 | case FIS_SETDEVBITS: | ||
2018 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2019 | SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE); | ||
2020 | break; | ||
2021 | case FIS_REGD2H: | ||
2022 | if (frame_header->status & ATA_BUSY) { | ||
2023 | /* Now why is the drive sending a D2H Register FIS when | ||
2024 | * it is still busy? Do nothing since we are still in | ||
2025 | * the right state. | ||
2026 | */ | ||
2027 | dev_dbg(scic_to_dev(scic), | ||
2028 | "%s: SCIC PIO Request 0x%p received " | ||
2029 | "D2H Register FIS with BSY status " | ||
2030 | "0x%x\n", __func__, stp_req, | ||
2031 | frame_header->status); | ||
2032 | break; | ||
2033 | } | ||
2034 | |||
2035 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
2036 | frame_index, | ||
2037 | (void **)&frame_buffer); | ||
2038 | |||
2039 | scic_sds_controller_copy_sata_response(&sci_req->stp.req, | ||
2040 | frame_header, | ||
2041 | frame_buffer); | ||
2042 | |||
2043 | scic_sds_request_set_status(sci_req, | ||
2044 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
2045 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
2046 | |||
2047 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2048 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
2049 | break; | ||
2050 | default: | ||
2051 | /* FIXME: what do we do here? */ | ||
2052 | break; | ||
2053 | } | ||
2054 | |||
2055 | /* Frame is decoded return it to the controller */ | ||
2056 | scic_sds_controller_release_frame(scic, frame_index); | ||
2057 | |||
2058 | return status; | ||
2059 | } | ||
2060 | |||
2061 | static enum sci_status scic_sds_stp_request_pio_data_in_await_data_frame_handler(struct scic_sds_request *sci_req, | ||
2062 | u32 frame_index) | ||
2063 | { | ||
2064 | enum sci_status status; | ||
2065 | struct dev_to_host_fis *frame_header; | ||
2066 | struct sata_fis_data *frame_buffer; | ||
2067 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; | ||
2068 | struct scic_sds_controller *scic = sci_req->owning_controller; | ||
2069 | |||
2070 | status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, | ||
2071 | frame_index, | ||
2072 | (void **)&frame_header); | ||
2073 | |||
2074 | if (status != SCI_SUCCESS) { | ||
2075 | dev_err(scic_to_dev(scic), | ||
2076 | "%s: SCIC IO Request 0x%p could not get frame header " | ||
2077 | "for frame index %d, status %x\n", | ||
2078 | __func__, stp_req, frame_index, status); | ||
2079 | return status; | ||
2080 | } | ||
2081 | |||
2082 | if (frame_header->fis_type == FIS_DATA) { | ||
2083 | if (stp_req->type.pio.request_current.sgl_pair == NULL) { | ||
2084 | sci_req->saved_rx_frame_index = frame_index; | ||
2085 | stp_req->type.pio.pio_transfer_bytes = 0; | ||
2086 | } else { | ||
2087 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
2088 | frame_index, | ||
2089 | (void **)&frame_buffer); | ||
2090 | |||
2091 | status = scic_sds_stp_request_pio_data_in_copy_data(stp_req, | ||
2092 | (u8 *)frame_buffer); | ||
2093 | |||
2094 | /* Frame is decoded return it to the controller */ | ||
2095 | scic_sds_controller_release_frame(scic, frame_index); | ||
2096 | } | ||
2097 | |||
2098 | /* Check for the end of the transfer, are there more | ||
2099 | * bytes remaining for this data transfer | ||
2100 | */ | ||
2101 | if (status != SCI_SUCCESS || | ||
2102 | stp_req->type.pio.pio_transfer_bytes != 0) | ||
2103 | return status; | ||
2104 | |||
2105 | if ((stp_req->type.pio.ending_status & ATA_BUSY) == 0) { | ||
2106 | scic_sds_request_set_status(sci_req, | ||
2107 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
2108 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
2109 | |||
2110 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2111 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
2112 | } else { | ||
2113 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2114 | SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE); | ||
2115 | } | ||
2116 | } else { | ||
2117 | dev_err(scic_to_dev(scic), | ||
2118 | "%s: SCIC PIO Request 0x%p received frame %d " | ||
2119 | "with fis type 0x%02x when expecting a data " | ||
2120 | "fis.\n", __func__, stp_req, frame_index, | ||
2121 | frame_header->fis_type); | ||
2122 | |||
2123 | scic_sds_request_set_status(sci_req, | ||
2124 | SCU_TASK_DONE_GOOD, | ||
2125 | SCI_FAILURE_IO_REQUIRES_SCSI_ABORT); | ||
2126 | |||
2127 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2128 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
2129 | |||
2130 | /* Frame is decoded return it to the controller */ | ||
2131 | scic_sds_controller_release_frame(scic, frame_index); | ||
2132 | } | ||
2133 | |||
2134 | return status; | ||
2135 | } | ||
2136 | |||
2137 | |||
2138 | /** | ||
2139 | * | ||
2140 | * @sci_req: | ||
2141 | * @completion_code: | ||
2142 | * | ||
2143 | * enum sci_status | ||
2144 | */ | ||
2145 | static enum sci_status scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler( | 1661 | static enum sci_status scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler( |
2146 | 1662 | ||
2147 | struct scic_sds_request *sci_req, | 1663 | struct scic_sds_request *sci_req, |
@@ -2280,6 +1796,422 @@ static enum sci_status scic_sds_stp_request_udma_general_frame_handler(struct sc | |||
2280 | return status; | 1796 | return status; |
2281 | } | 1797 | } |
2282 | 1798 | ||
1799 | enum sci_status scic_sds_io_request_frame_handler(struct scic_sds_request *sci_req, | ||
1800 | u32 frame_index) | ||
1801 | { | ||
1802 | struct scic_sds_controller *scic = sci_req->owning_controller; | ||
1803 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; | ||
1804 | enum sci_base_request_states state; | ||
1805 | enum sci_status status; | ||
1806 | ssize_t word_cnt; | ||
1807 | |||
1808 | state = sci_req->state_machine.current_state_id; | ||
1809 | switch (state) { | ||
1810 | case SCI_BASE_REQUEST_STATE_STARTED: { | ||
1811 | struct ssp_frame_hdr ssp_hdr; | ||
1812 | void *frame_header; | ||
1813 | |||
1814 | scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, | ||
1815 | frame_index, | ||
1816 | &frame_header); | ||
1817 | |||
1818 | word_cnt = sizeof(struct ssp_frame_hdr) / sizeof(u32); | ||
1819 | sci_swab32_cpy(&ssp_hdr, frame_header, word_cnt); | ||
1820 | |||
1821 | if (ssp_hdr.frame_type == SSP_RESPONSE) { | ||
1822 | struct ssp_response_iu *resp_iu; | ||
1823 | ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32); | ||
1824 | |||
1825 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
1826 | frame_index, | ||
1827 | (void **)&resp_iu); | ||
1828 | |||
1829 | sci_swab32_cpy(&sci_req->ssp.rsp, resp_iu, word_cnt); | ||
1830 | |||
1831 | resp_iu = &sci_req->ssp.rsp; | ||
1832 | |||
1833 | if (resp_iu->datapres == 0x01 || | ||
1834 | resp_iu->datapres == 0x02) { | ||
1835 | scic_sds_request_set_status(sci_req, | ||
1836 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
1837 | SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR); | ||
1838 | } else | ||
1839 | scic_sds_request_set_status(sci_req, | ||
1840 | SCU_TASK_DONE_GOOD, | ||
1841 | SCI_SUCCESS); | ||
1842 | } else { | ||
1843 | /* not a response frame, why did it get forwarded? */ | ||
1844 | dev_err(scic_to_dev(scic), | ||
1845 | "%s: SCIC IO Request 0x%p received unexpected " | ||
1846 | "frame %d type 0x%02x\n", __func__, sci_req, | ||
1847 | frame_index, ssp_hdr.frame_type); | ||
1848 | } | ||
1849 | |||
1850 | /* | ||
1851 | * In any case we are done with this frame buffer return it to the | ||
1852 | * controller | ||
1853 | */ | ||
1854 | scic_sds_controller_release_frame(scic, frame_index); | ||
1855 | |||
1856 | return SCI_SUCCESS; | ||
1857 | } | ||
1858 | case SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE: | ||
1859 | scic_sds_io_request_copy_response(sci_req); | ||
1860 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
1861 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
1862 | scic_sds_controller_release_frame(scic,frame_index); | ||
1863 | return SCI_SUCCESS; | ||
1864 | case SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE: { | ||
1865 | struct smp_resp *rsp_hdr = &sci_req->smp.rsp; | ||
1866 | void *frame_header; | ||
1867 | |||
1868 | scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, | ||
1869 | frame_index, | ||
1870 | &frame_header); | ||
1871 | |||
1872 | /* byte swap the header. */ | ||
1873 | word_cnt = SMP_RESP_HDR_SZ / sizeof(u32); | ||
1874 | sci_swab32_cpy(rsp_hdr, frame_header, word_cnt); | ||
1875 | |||
1876 | if (rsp_hdr->frame_type == SMP_RESPONSE) { | ||
1877 | void *smp_resp; | ||
1878 | |||
1879 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
1880 | frame_index, | ||
1881 | &smp_resp); | ||
1882 | |||
1883 | word_cnt = (sizeof(struct smp_req) - SMP_RESP_HDR_SZ) / | ||
1884 | sizeof(u32); | ||
1885 | |||
1886 | sci_swab32_cpy(((u8 *) rsp_hdr) + SMP_RESP_HDR_SZ, | ||
1887 | smp_resp, word_cnt); | ||
1888 | |||
1889 | scic_sds_request_set_status(sci_req, SCU_TASK_DONE_GOOD, | ||
1890 | SCI_SUCCESS); | ||
1891 | |||
1892 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
1893 | SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION); | ||
1894 | } else { | ||
1895 | /* This was not a response frame why did it get forwarded? */ | ||
1896 | dev_err(scic_to_dev(scic), | ||
1897 | "%s: SCIC SMP Request 0x%p received unexpected frame " | ||
1898 | "%d type 0x%02x\n", __func__, sci_req, | ||
1899 | frame_index, rsp_hdr->frame_type); | ||
1900 | |||
1901 | scic_sds_request_set_status(sci_req, | ||
1902 | SCU_TASK_DONE_SMP_FRM_TYPE_ERR, | ||
1903 | SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR); | ||
1904 | |||
1905 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
1906 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
1907 | } | ||
1908 | |||
1909 | scic_sds_controller_release_frame(scic, frame_index); | ||
1910 | |||
1911 | return SCI_SUCCESS; | ||
1912 | } | ||
1913 | case SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE: | ||
1914 | return scic_sds_stp_request_udma_general_frame_handler(sci_req, frame_index); | ||
1915 | case SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE: | ||
1916 | /* Use the general frame handler to copy the resposne data */ | ||
1917 | status = scic_sds_stp_request_udma_general_frame_handler(sci_req, frame_index); | ||
1918 | |||
1919 | if (status != SCI_SUCCESS) | ||
1920 | return status; | ||
1921 | |||
1922 | scic_sds_stp_request_udma_complete_request(sci_req, | ||
1923 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
1924 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
1925 | return SCI_SUCCESS; | ||
1926 | case SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE: { | ||
1927 | struct dev_to_host_fis *frame_header; | ||
1928 | u32 *frame_buffer; | ||
1929 | |||
1930 | status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, | ||
1931 | frame_index, | ||
1932 | (void **)&frame_header); | ||
1933 | |||
1934 | if (status != SCI_SUCCESS) { | ||
1935 | dev_err(scic_to_dev(scic), | ||
1936 | "%s: SCIC IO Request 0x%p could not get frame header " | ||
1937 | "for frame index %d, status %x\n", | ||
1938 | __func__, stp_req, frame_index, status); | ||
1939 | |||
1940 | return status; | ||
1941 | } | ||
1942 | |||
1943 | switch (frame_header->fis_type) { | ||
1944 | case FIS_REGD2H: | ||
1945 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
1946 | frame_index, | ||
1947 | (void **)&frame_buffer); | ||
1948 | |||
1949 | scic_sds_controller_copy_sata_response(&sci_req->stp.rsp, | ||
1950 | frame_header, | ||
1951 | frame_buffer); | ||
1952 | |||
1953 | /* The command has completed with error */ | ||
1954 | scic_sds_request_set_status(sci_req, SCU_TASK_DONE_CHECK_RESPONSE, | ||
1955 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
1956 | break; | ||
1957 | |||
1958 | default: | ||
1959 | dev_warn(scic_to_dev(scic), | ||
1960 | "%s: IO Request:0x%p Frame Id:%d protocol " | ||
1961 | "violation occurred\n", __func__, stp_req, | ||
1962 | frame_index); | ||
1963 | |||
1964 | scic_sds_request_set_status(sci_req, SCU_TASK_DONE_UNEXP_FIS, | ||
1965 | SCI_FAILURE_PROTOCOL_VIOLATION); | ||
1966 | break; | ||
1967 | } | ||
1968 | |||
1969 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
1970 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
1971 | |||
1972 | /* Frame has been decoded return it to the controller */ | ||
1973 | scic_sds_controller_release_frame(scic, frame_index); | ||
1974 | |||
1975 | return status; | ||
1976 | } | ||
1977 | case SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE: { | ||
1978 | struct isci_request *ireq = sci_req_to_ireq(sci_req); | ||
1979 | struct sas_task *task = isci_request_access_task(ireq); | ||
1980 | struct dev_to_host_fis *frame_header; | ||
1981 | u32 *frame_buffer; | ||
1982 | |||
1983 | status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, | ||
1984 | frame_index, | ||
1985 | (void **)&frame_header); | ||
1986 | |||
1987 | if (status != SCI_SUCCESS) { | ||
1988 | dev_err(scic_to_dev(scic), | ||
1989 | "%s: SCIC IO Request 0x%p could not get frame header " | ||
1990 | "for frame index %d, status %x\n", | ||
1991 | __func__, stp_req, frame_index, status); | ||
1992 | return status; | ||
1993 | } | ||
1994 | |||
1995 | switch (frame_header->fis_type) { | ||
1996 | case FIS_PIO_SETUP: | ||
1997 | /* Get from the frame buffer the PIO Setup Data */ | ||
1998 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
1999 | frame_index, | ||
2000 | (void **)&frame_buffer); | ||
2001 | |||
2002 | /* Get the data from the PIO Setup The SCU Hardware returns | ||
2003 | * first word in the frame_header and the rest of the data is in | ||
2004 | * the frame buffer so we need to back up one dword | ||
2005 | */ | ||
2006 | |||
2007 | /* transfer_count: first 16bits in the 4th dword */ | ||
2008 | stp_req->type.pio.pio_transfer_bytes = frame_buffer[3] & 0xffff; | ||
2009 | |||
2010 | /* ending_status: 4th byte in the 3rd dword */ | ||
2011 | stp_req->type.pio.ending_status = (frame_buffer[2] >> 24) & 0xff; | ||
2012 | |||
2013 | scic_sds_controller_copy_sata_response(&sci_req->stp.rsp, | ||
2014 | frame_header, | ||
2015 | frame_buffer); | ||
2016 | |||
2017 | sci_req->stp.rsp.status = stp_req->type.pio.ending_status; | ||
2018 | |||
2019 | /* The next state is dependent on whether the | ||
2020 | * request was PIO Data-in or Data out | ||
2021 | */ | ||
2022 | if (task->data_dir == DMA_FROM_DEVICE) { | ||
2023 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2024 | SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE); | ||
2025 | } else if (task->data_dir == DMA_TO_DEVICE) { | ||
2026 | /* Transmit data */ | ||
2027 | status = scic_sds_stp_request_pio_data_out_transmit_data(sci_req); | ||
2028 | if (status != SCI_SUCCESS) | ||
2029 | break; | ||
2030 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2031 | SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE); | ||
2032 | } | ||
2033 | break; | ||
2034 | case FIS_SETDEVBITS: | ||
2035 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2036 | SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE); | ||
2037 | break; | ||
2038 | case FIS_REGD2H: | ||
2039 | if (frame_header->status & ATA_BUSY) { | ||
2040 | /* Now why is the drive sending a D2H Register FIS when | ||
2041 | * it is still busy? Do nothing since we are still in | ||
2042 | * the right state. | ||
2043 | */ | ||
2044 | dev_dbg(scic_to_dev(scic), | ||
2045 | "%s: SCIC PIO Request 0x%p received " | ||
2046 | "D2H Register FIS with BSY status " | ||
2047 | "0x%x\n", __func__, stp_req, | ||
2048 | frame_header->status); | ||
2049 | break; | ||
2050 | } | ||
2051 | |||
2052 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
2053 | frame_index, | ||
2054 | (void **)&frame_buffer); | ||
2055 | |||
2056 | scic_sds_controller_copy_sata_response(&sci_req->stp.req, | ||
2057 | frame_header, | ||
2058 | frame_buffer); | ||
2059 | |||
2060 | scic_sds_request_set_status(sci_req, | ||
2061 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
2062 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
2063 | |||
2064 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2065 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
2066 | break; | ||
2067 | default: | ||
2068 | /* FIXME: what do we do here? */ | ||
2069 | break; | ||
2070 | } | ||
2071 | |||
2072 | /* Frame is decoded return it to the controller */ | ||
2073 | scic_sds_controller_release_frame(scic, frame_index); | ||
2074 | |||
2075 | return status; | ||
2076 | } | ||
2077 | case SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE: { | ||
2078 | struct dev_to_host_fis *frame_header; | ||
2079 | struct sata_fis_data *frame_buffer; | ||
2080 | |||
2081 | status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, | ||
2082 | frame_index, | ||
2083 | (void **)&frame_header); | ||
2084 | |||
2085 | if (status != SCI_SUCCESS) { | ||
2086 | dev_err(scic_to_dev(scic), | ||
2087 | "%s: SCIC IO Request 0x%p could not get frame header " | ||
2088 | "for frame index %d, status %x\n", | ||
2089 | __func__, stp_req, frame_index, status); | ||
2090 | return status; | ||
2091 | } | ||
2092 | |||
2093 | if (frame_header->fis_type != FIS_DATA) { | ||
2094 | dev_err(scic_to_dev(scic), | ||
2095 | "%s: SCIC PIO Request 0x%p received frame %d " | ||
2096 | "with fis type 0x%02x when expecting a data " | ||
2097 | "fis.\n", __func__, stp_req, frame_index, | ||
2098 | frame_header->fis_type); | ||
2099 | |||
2100 | scic_sds_request_set_status(sci_req, | ||
2101 | SCU_TASK_DONE_GOOD, | ||
2102 | SCI_FAILURE_IO_REQUIRES_SCSI_ABORT); | ||
2103 | |||
2104 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2105 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
2106 | |||
2107 | /* Frame is decoded return it to the controller */ | ||
2108 | scic_sds_controller_release_frame(scic, frame_index); | ||
2109 | return status; | ||
2110 | } | ||
2111 | |||
2112 | if (stp_req->type.pio.request_current.sgl_pair == NULL) { | ||
2113 | sci_req->saved_rx_frame_index = frame_index; | ||
2114 | stp_req->type.pio.pio_transfer_bytes = 0; | ||
2115 | } else { | ||
2116 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
2117 | frame_index, | ||
2118 | (void **)&frame_buffer); | ||
2119 | |||
2120 | status = scic_sds_stp_request_pio_data_in_copy_data(stp_req, | ||
2121 | (u8 *)frame_buffer); | ||
2122 | |||
2123 | /* Frame is decoded return it to the controller */ | ||
2124 | scic_sds_controller_release_frame(scic, frame_index); | ||
2125 | } | ||
2126 | |||
2127 | /* Check for the end of the transfer, are there more | ||
2128 | * bytes remaining for this data transfer | ||
2129 | */ | ||
2130 | if (status != SCI_SUCCESS || | ||
2131 | stp_req->type.pio.pio_transfer_bytes != 0) | ||
2132 | return status; | ||
2133 | |||
2134 | if ((stp_req->type.pio.ending_status & ATA_BUSY) == 0) { | ||
2135 | scic_sds_request_set_status(sci_req, | ||
2136 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
2137 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
2138 | |||
2139 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2140 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
2141 | } else { | ||
2142 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2143 | SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE); | ||
2144 | } | ||
2145 | return status; | ||
2146 | } | ||
2147 | case SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE: { | ||
2148 | struct dev_to_host_fis *frame_header; | ||
2149 | u32 *frame_buffer; | ||
2150 | |||
2151 | status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, | ||
2152 | frame_index, | ||
2153 | (void **)&frame_header); | ||
2154 | if (status != SCI_SUCCESS) { | ||
2155 | dev_err(scic_to_dev(scic), | ||
2156 | "%s: SCIC IO Request 0x%p could not get frame header " | ||
2157 | "for frame index %d, status %x\n", | ||
2158 | __func__, stp_req, frame_index, status); | ||
2159 | return status; | ||
2160 | } | ||
2161 | |||
2162 | switch (frame_header->fis_type) { | ||
2163 | case FIS_REGD2H: | ||
2164 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
2165 | frame_index, | ||
2166 | (void **)&frame_buffer); | ||
2167 | |||
2168 | scic_sds_controller_copy_sata_response(&sci_req->stp.rsp, | ||
2169 | frame_header, | ||
2170 | frame_buffer); | ||
2171 | |||
2172 | /* The command has completed with error */ | ||
2173 | scic_sds_request_set_status(sci_req, | ||
2174 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
2175 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
2176 | break; | ||
2177 | default: | ||
2178 | dev_warn(scic_to_dev(scic), | ||
2179 | "%s: IO Request:0x%p Frame Id:%d protocol " | ||
2180 | "violation occurred\n", __func__, stp_req, | ||
2181 | frame_index); | ||
2182 | |||
2183 | scic_sds_request_set_status(sci_req, SCU_TASK_DONE_UNEXP_FIS, | ||
2184 | SCI_FAILURE_PROTOCOL_VIOLATION); | ||
2185 | break; | ||
2186 | } | ||
2187 | |||
2188 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2189 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
2190 | |||
2191 | /* Frame has been decoded return it to the controller */ | ||
2192 | scic_sds_controller_release_frame(scic, frame_index); | ||
2193 | |||
2194 | return status; | ||
2195 | } | ||
2196 | case SCI_BASE_REQUEST_STATE_ABORTING: | ||
2197 | /* TODO: Is it even possible to get an unsolicited frame in the | ||
2198 | * aborting state? | ||
2199 | */ | ||
2200 | scic_sds_controller_release_frame(scic, frame_index); | ||
2201 | return SCI_SUCCESS; | ||
2202 | default: | ||
2203 | dev_warn(scic_to_dev(scic), | ||
2204 | "%s: SCIC IO Request given unexpected frame %x while in " | ||
2205 | "state %d\n", __func__, frame_index, state); | ||
2206 | |||
2207 | scic_sds_controller_release_frame(scic, frame_index); | ||
2208 | return SCI_FAILURE_INVALID_STATE; | ||
2209 | } | ||
2210 | } | ||
2211 | |||
2212 | |||
2213 | |||
2214 | |||
2283 | static enum sci_status scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler( | 2215 | static enum sci_status scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler( |
2284 | struct scic_sds_request *sci_req, | 2216 | struct scic_sds_request *sci_req, |
2285 | u32 completion_code) | 2217 | u32 completion_code) |
@@ -2336,32 +2268,6 @@ static enum sci_status scic_sds_stp_request_udma_await_tc_completion_tc_completi | |||
2336 | return status; | 2268 | return status; |
2337 | } | 2269 | } |
2338 | 2270 | ||
2339 | static enum sci_status scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler( | ||
2340 | struct scic_sds_request *sci_req, | ||
2341 | u32 frame_index) | ||
2342 | { | ||
2343 | enum sci_status status; | ||
2344 | |||
2345 | /* Use the general frame handler to copy the resposne data */ | ||
2346 | status = scic_sds_stp_request_udma_general_frame_handler(sci_req, frame_index); | ||
2347 | |||
2348 | if (status != SCI_SUCCESS) | ||
2349 | return status; | ||
2350 | |||
2351 | scic_sds_stp_request_udma_complete_request(sci_req, | ||
2352 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
2353 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
2354 | |||
2355 | return status; | ||
2356 | } | ||
2357 | |||
2358 | enum sci_status scic_sds_stp_udma_request_construct(struct scic_sds_request *sci_req, | ||
2359 | u32 len, | ||
2360 | enum dma_data_direction dir) | ||
2361 | { | ||
2362 | return SCI_SUCCESS; | ||
2363 | } | ||
2364 | |||
2365 | /** | 2271 | /** |
2366 | * | 2272 | * |
2367 | * @sci_req: | 2273 | * @sci_req: |
@@ -2447,117 +2353,36 @@ static enum sci_status scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_c | |||
2447 | return SCI_SUCCESS; | 2353 | return SCI_SUCCESS; |
2448 | } | 2354 | } |
2449 | 2355 | ||
2450 | /** | ||
2451 | * | ||
2452 | * @request: This parameter specifies the request for which a frame has been | ||
2453 | * received. | ||
2454 | * @frame_index: This parameter specifies the index of the frame that has been | ||
2455 | * received. | ||
2456 | * | ||
2457 | * This method processes frames received from the target while waiting for a | ||
2458 | * device to host register FIS. If a non-register FIS is received during this | ||
2459 | * time, it is treated as a protocol violation from an IO perspective. Indicate | ||
2460 | * if the received frame was processed successfully. | ||
2461 | */ | ||
2462 | static enum sci_status scic_sds_stp_request_soft_reset_await_d2h_frame_handler( | ||
2463 | struct scic_sds_request *sci_req, | ||
2464 | u32 frame_index) | ||
2465 | { | ||
2466 | enum sci_status status; | ||
2467 | struct dev_to_host_fis *frame_header; | ||
2468 | u32 *frame_buffer; | ||
2469 | struct scic_sds_stp_request *stp_req = &sci_req->stp.req; | ||
2470 | struct scic_sds_controller *scic = sci_req->owning_controller; | ||
2471 | |||
2472 | status = scic_sds_unsolicited_frame_control_get_header(&scic->uf_control, | ||
2473 | frame_index, | ||
2474 | (void **)&frame_header); | ||
2475 | if (status != SCI_SUCCESS) { | ||
2476 | dev_err(scic_to_dev(scic), | ||
2477 | "%s: SCIC IO Request 0x%p could not get frame header " | ||
2478 | "for frame index %d, status %x\n", | ||
2479 | __func__, stp_req, frame_index, status); | ||
2480 | return status; | ||
2481 | } | ||
2482 | |||
2483 | switch (frame_header->fis_type) { | ||
2484 | case FIS_REGD2H: | ||
2485 | scic_sds_unsolicited_frame_control_get_buffer(&scic->uf_control, | ||
2486 | frame_index, | ||
2487 | (void **)&frame_buffer); | ||
2488 | |||
2489 | scic_sds_controller_copy_sata_response(&sci_req->stp.rsp, | ||
2490 | frame_header, | ||
2491 | frame_buffer); | ||
2492 | |||
2493 | /* The command has completed with error */ | ||
2494 | scic_sds_request_set_status(sci_req, | ||
2495 | SCU_TASK_DONE_CHECK_RESPONSE, | ||
2496 | SCI_FAILURE_IO_RESPONSE_VALID); | ||
2497 | break; | ||
2498 | |||
2499 | default: | ||
2500 | dev_warn(scic_to_dev(scic), | ||
2501 | "%s: IO Request:0x%p Frame Id:%d protocol " | ||
2502 | "violation occurred\n", __func__, stp_req, | ||
2503 | frame_index); | ||
2504 | |||
2505 | scic_sds_request_set_status(sci_req, SCU_TASK_DONE_UNEXP_FIS, | ||
2506 | SCI_FAILURE_PROTOCOL_VIOLATION); | ||
2507 | break; | ||
2508 | } | ||
2509 | |||
2510 | sci_base_state_machine_change_state(&sci_req->state_machine, | ||
2511 | SCI_BASE_REQUEST_STATE_COMPLETED); | ||
2512 | |||
2513 | /* Frame has been decoded return it to the controller */ | ||
2514 | scic_sds_controller_release_frame(scic, frame_index); | ||
2515 | |||
2516 | return status; | ||
2517 | } | ||
2518 | |||
2519 | static const struct scic_sds_io_request_state_handler scic_sds_request_state_handler_table[] = { | 2356 | static const struct scic_sds_io_request_state_handler scic_sds_request_state_handler_table[] = { |
2520 | [SCI_BASE_REQUEST_STATE_INITIAL] = {}, | 2357 | [SCI_BASE_REQUEST_STATE_INITIAL] = {}, |
2521 | [SCI_BASE_REQUEST_STATE_CONSTRUCTED] = {}, | 2358 | [SCI_BASE_REQUEST_STATE_CONSTRUCTED] = {}, |
2522 | [SCI_BASE_REQUEST_STATE_STARTED] = { | 2359 | [SCI_BASE_REQUEST_STATE_STARTED] = { |
2523 | .tc_completion_handler = scic_sds_request_started_state_tc_completion_handler, | 2360 | .tc_completion_handler = scic_sds_request_started_state_tc_completion_handler, |
2524 | .frame_handler = scic_sds_request_started_state_frame_handler, | ||
2525 | }, | 2361 | }, |
2526 | [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION] = { | 2362 | [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION] = { |
2527 | .tc_completion_handler = scic_sds_ssp_task_request_await_tc_completion_tc_completion_handler, | 2363 | .tc_completion_handler = scic_sds_ssp_task_request_await_tc_completion_tc_completion_handler, |
2528 | }, | 2364 | }, |
2529 | [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE] = { | 2365 | [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE] = { }, |
2530 | .frame_handler = scic_sds_ssp_task_request_await_tc_response_frame_handler, | ||
2531 | }, | ||
2532 | [SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE] = { | 2366 | [SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE] = { |
2533 | .tc_completion_handler = scic_sds_smp_request_await_response_tc_completion_handler, | 2367 | .tc_completion_handler = scic_sds_smp_request_await_response_tc_completion_handler, |
2534 | .frame_handler = scic_sds_smp_request_await_response_frame_handler, | ||
2535 | }, | 2368 | }, |
2536 | [SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION] = { | 2369 | [SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION] = { |
2537 | .tc_completion_handler = scic_sds_smp_request_await_tc_completion_tc_completion_handler, | 2370 | .tc_completion_handler = scic_sds_smp_request_await_tc_completion_tc_completion_handler, |
2538 | }, | 2371 | }, |
2539 | [SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE] = { | 2372 | [SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE] = { |
2540 | .tc_completion_handler = scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler, | 2373 | .tc_completion_handler = scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler, |
2541 | .frame_handler = scic_sds_stp_request_udma_general_frame_handler, | ||
2542 | }, | ||
2543 | [SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE] = { | ||
2544 | .frame_handler = scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler, | ||
2545 | }, | 2374 | }, |
2375 | [SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE] = { }, | ||
2546 | [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE] = { | 2376 | [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE] = { |
2547 | .tc_completion_handler = scic_sds_stp_request_non_data_await_h2d_tc_completion_handler, | 2377 | .tc_completion_handler = scic_sds_stp_request_non_data_await_h2d_tc_completion_handler, |
2548 | }, | 2378 | }, |
2549 | [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE] = { | 2379 | [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE] = { }, |
2550 | .frame_handler = scic_sds_stp_request_non_data_await_d2h_frame_handler, | ||
2551 | }, | ||
2552 | [SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE] = { | 2380 | [SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE] = { |
2553 | .tc_completion_handler = scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler, | 2381 | .tc_completion_handler = scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler, |
2554 | }, | 2382 | }, |
2555 | [SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE] = { | 2383 | [SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE] = { }, |
2556 | .frame_handler = scic_sds_stp_request_pio_await_frame_frame_handler | ||
2557 | }, | ||
2558 | [SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE] = { | 2384 | [SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE] = { |
2559 | .event_handler = scic_sds_stp_request_pio_data_in_await_data_event_handler, | 2385 | .event_handler = scic_sds_stp_request_pio_data_in_await_data_event_handler, |
2560 | .frame_handler = scic_sds_stp_request_pio_data_in_await_data_frame_handler | ||
2561 | }, | 2386 | }, |
2562 | [SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE] = { | 2387 | [SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE] = { |
2563 | .tc_completion_handler = scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler, | 2388 | .tc_completion_handler = scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler, |
@@ -2568,15 +2393,12 @@ static const struct scic_sds_io_request_state_handler scic_sds_request_state_han | |||
2568 | [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE] = { | 2393 | [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE] = { |
2569 | .tc_completion_handler = scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler, | 2394 | .tc_completion_handler = scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler, |
2570 | }, | 2395 | }, |
2571 | [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE] = { | 2396 | [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE] = { }, |
2572 | .frame_handler = scic_sds_stp_request_soft_reset_await_d2h_frame_handler, | ||
2573 | }, | ||
2574 | [SCI_BASE_REQUEST_STATE_COMPLETED] = { | 2397 | [SCI_BASE_REQUEST_STATE_COMPLETED] = { |
2575 | .complete_handler = scic_sds_request_completed_state_complete_handler, | 2398 | .complete_handler = scic_sds_request_completed_state_complete_handler, |
2576 | }, | 2399 | }, |
2577 | [SCI_BASE_REQUEST_STATE_ABORTING] = { | 2400 | [SCI_BASE_REQUEST_STATE_ABORTING] = { |
2578 | .tc_completion_handler = scic_sds_request_aborting_state_tc_completion_handler, | 2401 | .tc_completion_handler = scic_sds_request_aborting_state_tc_completion_handler, |
2579 | .frame_handler = scic_sds_request_aborting_state_frame_handler, | ||
2580 | }, | 2402 | }, |
2581 | [SCI_BASE_REQUEST_STATE_FINAL] = { }, | 2403 | [SCI_BASE_REQUEST_STATE_FINAL] = { }, |
2582 | }; | 2404 | }; |
diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h index bf8ac1860850..c9070e708948 100644 --- a/drivers/scsi/isci/request.h +++ b/drivers/scsi/isci/request.h | |||
@@ -424,8 +424,6 @@ enum sci_base_request_states { | |||
424 | 424 | ||
425 | typedef enum sci_status (*scic_sds_io_request_handler_t) | 425 | typedef enum sci_status (*scic_sds_io_request_handler_t) |
426 | (struct scic_sds_request *request); | 426 | (struct scic_sds_request *request); |
427 | typedef enum sci_status (*scic_sds_io_request_frame_handler_t) | ||
428 | (struct scic_sds_request *req, u32 frame); | ||
429 | typedef enum sci_status (*scic_sds_io_request_event_handler_t) | 427 | typedef enum sci_status (*scic_sds_io_request_event_handler_t) |
430 | (struct scic_sds_request *req, u32 event); | 428 | (struct scic_sds_request *req, u32 event); |
431 | typedef enum sci_status (*scic_sds_io_request_task_completion_handler_t) | 429 | typedef enum sci_status (*scic_sds_io_request_task_completion_handler_t) |
@@ -446,7 +444,6 @@ struct scic_sds_io_request_state_handler { | |||
446 | 444 | ||
447 | scic_sds_io_request_task_completion_handler_t tc_completion_handler; | 445 | scic_sds_io_request_task_completion_handler_t tc_completion_handler; |
448 | scic_sds_io_request_event_handler_t event_handler; | 446 | scic_sds_io_request_event_handler_t event_handler; |
449 | scic_sds_io_request_frame_handler_t frame_handler; | ||
450 | }; | 447 | }; |
451 | 448 | ||
452 | /** | 449 | /** |
@@ -839,9 +836,6 @@ enum sci_status scic_task_request_construct(struct scic_sds_controller *scic, | |||
839 | struct scic_sds_request *sci_req); | 836 | struct scic_sds_request *sci_req); |
840 | enum sci_status scic_task_request_construct_ssp(struct scic_sds_request *sci_req); | 837 | enum sci_status scic_task_request_construct_ssp(struct scic_sds_request *sci_req); |
841 | enum sci_status scic_task_request_construct_sata(struct scic_sds_request *sci_req); | 838 | enum sci_status scic_task_request_construct_sata(struct scic_sds_request *sci_req); |
842 | enum sci_status scic_sds_stp_udma_request_construct(struct scic_sds_request *sci_req, | ||
843 | u32 transfer_length, | ||
844 | enum dma_data_direction dir); | ||
845 | void scic_stp_io_request_set_ncq_tag(struct scic_sds_request *sci_req, u16 ncq_tag); | 839 | void scic_stp_io_request_set_ncq_tag(struct scic_sds_request *sci_req, u16 ncq_tag); |
846 | void scic_sds_smp_request_copy_response(struct scic_sds_request *sci_req); | 840 | void scic_sds_smp_request_copy_response(struct scic_sds_request *sci_req); |
847 | #endif /* !defined(_ISCI_REQUEST_H_) */ | 841 | #endif /* !defined(_ISCI_REQUEST_H_) */ |