1230557Sjimharris/*- 2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license. When using or 3230557Sjimharris * redistributing this file, you may do so under either license. 4230557Sjimharris * 5230557Sjimharris * GPL LICENSE SUMMARY 6230557Sjimharris * 7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8230557Sjimharris * 9230557Sjimharris * This program is free software; you can redistribute it and/or modify 10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as 11230557Sjimharris * published by the Free Software Foundation. 12230557Sjimharris * 13230557Sjimharris * This program is distributed in the hope that it will be useful, but 14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of 15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16230557Sjimharris * General Public License for more details. 17230557Sjimharris * 18230557Sjimharris * You should have received a copy of the GNU General Public License 19230557Sjimharris * along with this program; if not, write to the Free Software 20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21230557Sjimharris * The full GNU General Public License is included in this distribution 22230557Sjimharris * in the file called LICENSE.GPL. 23230557Sjimharris * 24230557Sjimharris * BSD LICENSE 25230557Sjimharris * 26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27230557Sjimharris * All rights reserved. 28230557Sjimharris * 29230557Sjimharris * Redistribution and use in source and binary forms, with or without 30230557Sjimharris * modification, are permitted provided that the following conditions 31230557Sjimharris * are met: 32230557Sjimharris * 33230557Sjimharris * * Redistributions of source code must retain the above copyright 34230557Sjimharris * notice, this list of conditions and the following disclaimer. 35230557Sjimharris * * Redistributions in binary form must reproduce the above copyright 36230557Sjimharris * notice, this list of conditions and the following disclaimer in 37230557Sjimharris * the documentation and/or other materials provided with the 38230557Sjimharris * distribution. 39230557Sjimharris * 40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51230557Sjimharris */ 52230557Sjimharris 53230557Sjimharris#include <sys/cdefs.h> 54230557Sjimharris__FBSDID("$FreeBSD$"); 55230557Sjimharris 56230557Sjimharris#if !defined(DISABLE_ATAPI) 57230557Sjimharris 58230557Sjimharris#include <dev/isci/scil/scic_sds_stp_packet_request.h> 59230557Sjimharris#include <dev/isci/scil/scic_sds_logger.h> 60230557Sjimharris#include <dev/isci/scil/scic_sds_controller.h> 61230557Sjimharris#include <dev/isci/scil/scic_sds_remote_device.h> 62230557Sjimharris#include <dev/isci/scil/scic_remote_device.h> 63230557Sjimharris#include <dev/isci/scil/sci_util.h> 64230557Sjimharris#include <dev/isci/scil/intel_sas.h> 65230557Sjimharris#include <dev/isci/scil/intel_ata.h> 66230557Sjimharris#include <dev/isci/scil/intel_sata.h> 67230557Sjimharris#include <dev/isci/scil/scic_user_callback.h> 68230557Sjimharris#include <dev/isci/sci_environment.h> 69230557Sjimharris#include <dev/isci/scil/intel_sat.h> 70230557Sjimharris#include <dev/isci/scil/scic_sds_request.h> 71230557Sjimharris#include <dev/isci/scil/scic_controller.h> 72230557Sjimharris#include <dev/isci/scil/scu_completion_codes.h> 73230557Sjimharris#include <dev/isci/scil/scu_task_context.h> 74230557Sjimharris#include <dev/isci/scil/scic_sds_stp_packet_request.h> 75230557Sjimharris#include <dev/isci/scil/sci_base_state.h> 76230557Sjimharris 77230557Sjimharris/** 78230557Sjimharris * @brief This method will fill in the SCU Task Context for a PACKET fis. And 79230557Sjimharris * construct the request STARTED sub-state machine for Packet Protocol 80230557Sjimharris * IO. 81230557Sjimharris * 82230557Sjimharris * @param[in] this_request This parameter specifies the stp packet request object 83230557Sjimharris * being constructed. 84230557Sjimharris * 85230557Sjimharris * @return none 86230557Sjimharris */ 87230557SjimharrisSCI_STATUS scic_sds_stp_packet_request_construct( 88230557Sjimharris SCIC_SDS_REQUEST_T *this_request 89230557Sjimharris) 90230557Sjimharris{ 91230557Sjimharris SATA_FIS_REG_H2D_T * h2d_fis = 92230557Sjimharris scic_stp_io_request_get_h2d_reg_address( 93230557Sjimharris this_request 94230557Sjimharris ); 95230557Sjimharris 96230557Sjimharris // Work around, we currently only support PACKET DMA protocol, so we 97230557Sjimharris // need to make change to Packet Fis features field. 98230557Sjimharris h2d_fis->features = h2d_fis->features | ATA_PACKET_FEATURE_DMA; 99230557Sjimharris 100230557Sjimharris scic_sds_stp_non_ncq_request_construct(this_request); 101230557Sjimharris 102230557Sjimharris // Build the Packet Fis task context structure 103230557Sjimharris scu_stp_raw_request_construct_task_context( 104230557Sjimharris (SCIC_SDS_STP_REQUEST_T*) this_request, 105230557Sjimharris this_request->task_context_buffer 106230557Sjimharris ); 107230557Sjimharris 108230557Sjimharris sci_base_state_machine_construct( 109230557Sjimharris &this_request->started_substate_machine, 110230557Sjimharris &this_request->parent.parent, 111230557Sjimharris scic_sds_stp_packet_request_started_substate_table, 112230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE 113230557Sjimharris ); 114230557Sjimharris 115230557Sjimharris return SCI_SUCCESS; 116230557Sjimharris} 117230557Sjimharris 118230557Sjimharris 119230557Sjimharris/** 120230557Sjimharris * @brief This method will fill in the SCU Task Context for a Packet request 121230557Sjimharris * command phase in PACKET DMA DATA (IN/OUT) type. The following 122230557Sjimharris * important settings are utilized: 123230557Sjimharris * 124230557Sjimharris * -# task_type == SCU_TASK_TYPE_PACKET_DMA. This simply indicates 125230557Sjimharris * that a normal request type (i.e. non-raw frame) is being 126230557Sjimharris * utilized to perform task management. 127230557Sjimharris * -# control_frame == 1. This ensures that the proper endianess 128230557Sjimharris * is set so that the bytes are transmitted in the right order 129230557Sjimharris * for a smp request frame. 130230557Sjimharris * 131230557Sjimharris * @param[in] this_request This parameter specifies the smp request object 132230557Sjimharris * being constructed. 133230557Sjimharris * @param[in] task_context The task_context to be reconstruct for packet 134230557Sjimharris * request command phase. 135230557Sjimharris * @return none 136230557Sjimharris */ 137230557Sjimharrisvoid scu_stp_packet_request_command_phase_construct_task_context( 138230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 139230557Sjimharris SCU_TASK_CONTEXT_T * task_context 140230557Sjimharris) 141230557Sjimharris{ 142230557Sjimharris void * atapi_cdb; 143230557Sjimharris U32 atapi_cdb_length; 144230557Sjimharris SCIC_SDS_STP_REQUEST_T * stp_request = (SCIC_SDS_STP_REQUEST_T *)this_request; 145230557Sjimharris 146230557Sjimharris // reference: SSTL 1.13.4.2 147230557Sjimharris // task_type, sata_direction 148230557Sjimharris if ( scic_cb_io_request_get_data_direction(this_request->user_request) 149230557Sjimharris == SCI_IO_REQUEST_DATA_OUT ) 150230557Sjimharris { 151230557Sjimharris task_context->task_type = SCU_TASK_TYPE_PACKET_DMA_OUT; 152230557Sjimharris task_context->sata_direction = 0; 153230557Sjimharris } 154230557Sjimharris else // todo: for NO_DATA command, we need to send out raw frame. 155230557Sjimharris { 156230557Sjimharris task_context->task_type = SCU_TASK_TYPE_PACKET_DMA_IN; 157230557Sjimharris task_context->sata_direction = 1; 158230557Sjimharris } 159230557Sjimharris 160230557Sjimharris // sata header 161230557Sjimharris memset(&(task_context->type.stp), 0, sizeof(struct STP_TASK_CONTEXT)); 162230557Sjimharris task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA; 163230557Sjimharris 164230557Sjimharris // Copy in the command IU with CDB so that the commandIU address doesn't 165230557Sjimharris // change. 166230557Sjimharris memset(this_request->command_buffer, 0, sizeof(SATA_FIS_REG_H2D_T)); 167230557Sjimharris 168230557Sjimharris atapi_cdb = 169230557Sjimharris scic_cb_stp_packet_io_request_get_cdb_address(this_request->user_request); 170230557Sjimharris 171230557Sjimharris atapi_cdb_length = 172230557Sjimharris scic_cb_stp_packet_io_request_get_cdb_length(this_request->user_request); 173230557Sjimharris 174230557Sjimharris memcpy(((U8 *)this_request->command_buffer+sizeof(U32)), atapi_cdb, atapi_cdb_length); 175230557Sjimharris 176230557Sjimharris atapi_cdb_length = 177230557Sjimharris MAX(atapi_cdb_length, stp_request->type.packet.device_preferred_cdb_length); 178230557Sjimharris 179230557Sjimharris task_context->ssp_command_iu_length = 180230557Sjimharris ((atapi_cdb_length % 4) == 0) ? 181230557Sjimharris (atapi_cdb_length / 4) : ((atapi_cdb_length / 4) + 1); 182230557Sjimharris 183230557Sjimharris // task phase is set to TX_CMD 184230557Sjimharris task_context->task_phase = 0x1; 185230557Sjimharris 186230557Sjimharris // retry counter 187230557Sjimharris task_context->stp_retry_count = 0; 188230557Sjimharris 189230557Sjimharris if (scic_cb_request_is_initial_construction(this_request->user_request)) 190230557Sjimharris { 191230557Sjimharris // data transfer size. 192230557Sjimharris task_context->transfer_length_bytes = 193230557Sjimharris scic_cb_io_request_get_transfer_length(this_request->user_request); 194230557Sjimharris 195230792Sjimharris // sgls were already built when request was constructed, so don't need to 196230792Sjimharris // to do it here 197230557Sjimharris } 198230557Sjimharris else 199230557Sjimharris { 200230557Sjimharris // data transfer size, need to be 4 bytes aligned. 201230557Sjimharris task_context->transfer_length_bytes = (SCSI_FIXED_SENSE_DATA_BASE_LENGTH + 2); 202230557Sjimharris 203230557Sjimharris scic_sds_stp_packet_internal_request_sense_build_sgl(this_request); 204230557Sjimharris } 205230557Sjimharris} 206230557Sjimharris 207230557Sjimharris/** 208230557Sjimharris * @brief This method will fill in the SCU Task Context for a DATA fis 209230557Sjimharris * containing CDB in Raw Frame type. The TC for previous Packet 210230557Sjimharris * fis was already there, we only need to change the H2D fis content. 211230557Sjimharris * 212230557Sjimharris * @param[in] this_request This parameter specifies the smp request object 213230557Sjimharris * being constructed. 214230557Sjimharris * @param[in] task_context The task_context to be reconstruct for packet 215230557Sjimharris * request command phase. 216230557Sjimharris * @return none 217230557Sjimharris */ 218230557Sjimharrisvoid scu_stp_packet_request_command_phase_reconstruct_raw_frame_task_context( 219230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 220230557Sjimharris SCU_TASK_CONTEXT_T * task_context 221230557Sjimharris) 222230557Sjimharris{ 223230557Sjimharris void * atapi_cdb = 224230557Sjimharris scic_cb_stp_packet_io_request_get_cdb_address(this_request->user_request); 225230557Sjimharris 226230557Sjimharris U32 atapi_cdb_length = 227230557Sjimharris scic_cb_stp_packet_io_request_get_cdb_length(this_request->user_request); 228230557Sjimharris 229230557Sjimharris memset(this_request->command_buffer, 0, sizeof(SATA_FIS_REG_H2D_T)); 230230557Sjimharris memcpy( ((U8 *)this_request->command_buffer+sizeof(U32)), atapi_cdb, atapi_cdb_length); 231230557Sjimharris 232230557Sjimharris memset(&(task_context->type.stp), 0, sizeof(struct STP_TASK_CONTEXT)); 233230557Sjimharris task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA; 234230557Sjimharris 235230557Sjimharris //Note the data send out has to be 4 bytes aligned. Or else out hardware will 236230557Sjimharris //patch non-zero bytes and cause the target device unhappy. 237230557Sjimharris task_context->transfer_length_bytes = 12; 238230557Sjimharris} 239230557Sjimharris 240230557Sjimharris 241230557Sjimharris/* 242230557Sjimharris *@brief This methods decode the D2H status FIS and retrieve the sense data, 243230557Sjimharris * then pass the sense data to user request. 244230557Sjimharris * 245230557Sjimharris *@param[in] this_request The request receive D2H status FIS. 246230557Sjimharris *@param[in] status_fis The D2H status fis to be processed. 247230557Sjimharris * 248230557Sjimharris */ 249230557SjimharrisSCI_STATUS scic_sds_stp_packet_request_process_status_fis( 250230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 251230557Sjimharris SATA_FIS_REG_D2H_T * status_fis 252230557Sjimharris) 253230557Sjimharris{ 254230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 255230557Sjimharris 256230557Sjimharris //TODO: Process the error status fis, retrieve sense data. 257230557Sjimharris if (status_fis->status & ATA_STATUS_REG_ERROR_BIT) 258230557Sjimharris status = SCI_FAILURE_IO_RESPONSE_VALID; 259230557Sjimharris 260230557Sjimharris return status; 261230557Sjimharris} 262230557Sjimharris 263230557Sjimharris/* 264230557Sjimharris *@brief This methods builds sgl for internal REQUEST SENSE stp packet 265230557Sjimharris * command using this request response buffer, only one sge is 266230557Sjimharris * needed. 267230557Sjimharris * 268230557Sjimharris *@param[in] this_request The request receive request sense data. 269230557Sjimharris * 270230557Sjimharris */ 271230557Sjimharrisvoid scic_sds_stp_packet_internal_request_sense_build_sgl( 272230557Sjimharris SCIC_SDS_REQUEST_T * this_request 273230557Sjimharris) 274230557Sjimharris{ 275230557Sjimharris void *sge; 276230557Sjimharris SCU_SGL_ELEMENT_PAIR_T *scu_sgl_list = NULL; 277230557Sjimharris SCU_TASK_CONTEXT_T *task_context; 278230557Sjimharris SCI_PHYSICAL_ADDRESS physical_address; 279230557Sjimharris 280230557Sjimharris SCI_SSP_RESPONSE_IU_T * rsp_iu = 281230557Sjimharris (SCI_SSP_RESPONSE_IU_T *)this_request->response_buffer; 282230557Sjimharris sge = (void*)&rsp_iu->data[0]; 283230557Sjimharris 284230557Sjimharris task_context = (SCU_TASK_CONTEXT_T *)this_request->task_context_buffer; 285230557Sjimharris scu_sgl_list = &task_context->sgl_pair_ab; 286230557Sjimharris 287230557Sjimharris scic_cb_io_request_get_physical_address( 288230557Sjimharris scic_sds_request_get_controller(this_request), 289230557Sjimharris this_request, 290230557Sjimharris ((char *)sge), 291230557Sjimharris &physical_address 292230557Sjimharris ); 293230557Sjimharris 294230557Sjimharris scu_sgl_list->A.address_upper = sci_cb_physical_address_upper(physical_address); 295230557Sjimharris scu_sgl_list->A.address_lower = sci_cb_physical_address_lower(physical_address); 296230557Sjimharris scu_sgl_list->A.length = task_context->transfer_length_bytes; 297230557Sjimharris scu_sgl_list->A.address_modifier = 0; 298230557Sjimharris 299230557Sjimharris SCU_SGL_ZERO(scu_sgl_list->B); 300230557Sjimharris} 301230557Sjimharris 302230557Sjimharris//****************************************************************************** 303230557Sjimharris//* STP PACKET REQUEST STATE MACHINES 304230557Sjimharris//****************************************************************************** 305230557Sjimharris 306230557Sjimharris/** 307230557Sjimharris* @brief This method processes the completions transport layer (TL) status 308230557Sjimharris* to determine if the Packet FIS was sent successfully. If the Packet 309230557Sjimharris* FIS was sent successfully, then the state for the Packet request 310230557Sjimharris* transits to waiting for a PIO SETUP frame. 311230557Sjimharris* 312230557Sjimharris* @param[in] this_request This parameter specifies the request for which 313230557Sjimharris* the TC completion was received. 314230557Sjimharris* @param[in] completion_code This parameter indicates the completion status 315230557Sjimharris* information for the TC. 316230557Sjimharris* 317230557Sjimharris* @return Indicate if the tc completion handler was successful. 318230557Sjimharris* @retval SCI_SUCCESS currently this method always returns success. 319230557Sjimharris*/ 320230557Sjimharrisstatic 321230557SjimharrisSCI_STATUS scic_sds_stp_packet_request_packet_phase_await_tc_completion_tc_completion_handler( 322230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 323230557Sjimharris U32 completion_code 324230557Sjimharris) 325230557Sjimharris{ 326230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 327230557Sjimharris 328230557Sjimharris SCIC_LOG_TRACE(( 329230557Sjimharris sci_base_object_get_logger(this_request), 330230557Sjimharris SCIC_LOG_OBJECT_STP_IO_REQUEST, 331230557Sjimharris "scic_sds_stp_packet_request_packet_phase_await_tc_completion_tc_completion_handler(0x%x, 0x%x) enter\n", 332230557Sjimharris this_request, completion_code 333230557Sjimharris )); 334230557Sjimharris 335230557Sjimharris switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 336230557Sjimharris { 337230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 338230557Sjimharris scic_sds_request_set_status( 339230557Sjimharris this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 340230557Sjimharris ); 341230557Sjimharris 342230557Sjimharris sci_base_state_machine_change_state( 343230557Sjimharris &this_request->started_substate_machine, 344230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE 345230557Sjimharris ); 346230557Sjimharris break; 347230557Sjimharris 348230557Sjimharris default: 349230557Sjimharris // All other completion status cause the IO to be complete. If a NAK 350230557Sjimharris // was received, then it is up to the user to retry the request. 351230557Sjimharris scic_sds_request_set_status( 352230557Sjimharris this_request, 353230557Sjimharris SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 354230557Sjimharris SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 355230557Sjimharris ); 356230557Sjimharris 357230557Sjimharris sci_base_state_machine_change_state( 358230557Sjimharris &this_request->parent.state_machine, 359230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 360230557Sjimharris ); 361230557Sjimharris break; 362230557Sjimharris } 363230557Sjimharris 364230557Sjimharris return status; 365230557Sjimharris} 366230557Sjimharris 367230557Sjimharris 368230557Sjimharris/** 369230557Sjimharris * @brief This method processes an unsolicited frame while the Packet request 370230557Sjimharris * is waiting for a PIO SETUP FIS. It will release 371230557Sjimharris * the unsolicited frame, and transition the request to the 372230557Sjimharris * COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE state. 373230557Sjimharris * 374230557Sjimharris * @param[in] this_request This parameter specifies the request for which 375230557Sjimharris * the unsolicited frame was received. 376230557Sjimharris * @param[in] frame_index This parameter indicates the unsolicited frame 377230557Sjimharris * index that should contain the response. 378230557Sjimharris * 379230557Sjimharris * @return This method returns an indication of whether the pio setup 380230557Sjimharris * frame was handled successfully or not. 381230557Sjimharris * @retval SCI_SUCCESS Currently this value is always returned and indicates 382230557Sjimharris * successful processing of the TC response. 383230557Sjimharris * 384230557Sjimharris */ 385230557Sjimharrisstatic 386230557SjimharrisSCI_STATUS scic_sds_stp_packet_request_packet_phase_await_pio_setup_frame_handler( 387230557Sjimharris SCIC_SDS_REQUEST_T * request, 388230557Sjimharris U32 frame_index 389230557Sjimharris) 390230557Sjimharris{ 391230557Sjimharris SCI_STATUS status; 392230557Sjimharris SATA_FIS_HEADER_T * frame_header; 393230557Sjimharris U32 * frame_buffer; 394230557Sjimharris SCIC_SDS_STP_REQUEST_T * this_request; 395230557Sjimharris 396230557Sjimharris this_request = (SCIC_SDS_STP_REQUEST_T *)request; 397230557Sjimharris 398230557Sjimharris SCIC_LOG_TRACE(( 399230557Sjimharris sci_base_object_get_logger(this_request), 400230557Sjimharris SCIC_LOG_OBJECT_STP_IO_REQUEST, 401230557Sjimharris "scic_sds_stp_packet_request_packet_phase_await_pio_setup_frame_handler(0x%x, 0x%x) enter\n", 402230557Sjimharris this_request, frame_index 403230557Sjimharris )); 404230557Sjimharris 405230557Sjimharris status = scic_sds_unsolicited_frame_control_get_header( 406230557Sjimharris &(this_request->parent.owning_controller->uf_control), 407230557Sjimharris frame_index, 408230557Sjimharris (void**) &frame_header 409230557Sjimharris ); 410230557Sjimharris 411230557Sjimharris if (status == SCI_SUCCESS) 412230557Sjimharris { 413230557Sjimharris ASSERT(frame_header->fis_type == SATA_FIS_TYPE_PIO_SETUP); 414230557Sjimharris 415230557Sjimharris // Get from the frame buffer the PIO Setup Data, although we don't need 416230557Sjimharris // any info from this pio setup fis. 417230557Sjimharris scic_sds_unsolicited_frame_control_get_buffer( 418230557Sjimharris &(this_request->parent.owning_controller->uf_control), 419230557Sjimharris frame_index, 420230557Sjimharris (void**) &frame_buffer 421230557Sjimharris ); 422230557Sjimharris 423230557Sjimharris // Get the data from the PIO Setup 424230557Sjimharris // The SCU Hardware returns first word in the frame_header and the rest 425230557Sjimharris // of the data is in the frame buffer so we need to back up one dword 426230557Sjimharris this_request->type.packet.device_preferred_cdb_length = 427230557Sjimharris (U16)((SATA_FIS_PIO_SETUP_T *)(&frame_buffer[-1]))->transfter_count; 428230557Sjimharris 429230557Sjimharris // Frame has been decoded return it to the controller 430230557Sjimharris scic_sds_controller_release_frame( 431230557Sjimharris this_request->parent.owning_controller, frame_index 432230557Sjimharris ); 433230557Sjimharris 434230557Sjimharris sci_base_state_machine_change_state( 435230557Sjimharris &this_request->parent.started_substate_machine, 436230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE 437230557Sjimharris ); 438230557Sjimharris } 439230557Sjimharris else 440230557Sjimharris { 441230557Sjimharris SCIC_LOG_ERROR(( 442230557Sjimharris sci_base_object_get_logger(this_request), 443230557Sjimharris SCIC_LOG_OBJECT_STP_IO_REQUEST, 444230557Sjimharris "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n", 445230557Sjimharris this_request, frame_index, status 446230557Sjimharris )); 447230557Sjimharris } 448230557Sjimharris 449230557Sjimharris return status; 450230557Sjimharris} 451230557Sjimharris 452230557Sjimharris 453230557Sjimharris/** 454230557Sjimharris * @brief This method processes the completions transport layer (TL) status 455230557Sjimharris * to determine if the PACKET command data FIS was sent successfully. 456230557Sjimharris * If successfully, then the state for the packet request 457230557Sjimharris * transits to COMPLETE state. If not successfuly, the request transits 458230557Sjimharris * to COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE. 459230557Sjimharris * 460230557Sjimharris * @param[in] this_request This parameter specifies the request for which 461230557Sjimharris * the TC completion was received. 462230557Sjimharris * @param[in] completion_code This parameter indicates the completion status 463230557Sjimharris * information for the TC. 464230557Sjimharris * 465230557Sjimharris * @return Indicate if the tc completion handler was successful. 466230557Sjimharris * @retval SCI_SUCCESS currently this method always returns success. 467230557Sjimharris */ 468230557Sjimharrisstatic 469230557SjimharrisSCI_STATUS scic_sds_stp_packet_request_command_phase_await_tc_completion_tc_completion_handler( 470230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 471230557Sjimharris U32 completion_code 472230557Sjimharris) 473230557Sjimharris{ 474230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 475230557Sjimharris U8 sat_packet_protocol = this_request->sat_protocol; 476230557Sjimharris 477230557Sjimharris SCIC_LOG_TRACE(( 478230557Sjimharris sci_base_object_get_logger(this_request), 479230557Sjimharris SCIC_LOG_OBJECT_STP_IO_REQUEST, 480230557Sjimharris "scic_sds_stp_packet_request_command_phase_await_tc_completion_tc_completion_handler(0x%x, 0x%x) enter\n", 481230557Sjimharris this_request, completion_code 482230557Sjimharris )); 483230557Sjimharris 484230557Sjimharris switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 485230557Sjimharris { 486230557Sjimharris case (SCU_TASK_DONE_GOOD << SCU_COMPLETION_TL_STATUS_SHIFT): 487230557Sjimharris scic_sds_request_set_status( 488230557Sjimharris this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 489230557Sjimharris ); 490230557Sjimharris 491230557Sjimharris if ( sat_packet_protocol == SAT_PROTOCOL_PACKET_DMA_DATA_IN 492230557Sjimharris || sat_packet_protocol == SAT_PROTOCOL_PACKET_DMA_DATA_OUT 493230557Sjimharris ) 494230557Sjimharris sci_base_state_machine_change_state( 495230557Sjimharris &this_request->parent.state_machine, 496230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 497230557Sjimharris ); 498230557Sjimharris else 499230557Sjimharris sci_base_state_machine_change_state( 500230557Sjimharris &this_request->started_substate_machine, 501230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE 502230557Sjimharris ); 503230557Sjimharris break; 504230557Sjimharris 505230557Sjimharris case (SCU_TASK_DONE_UNEXP_FIS << SCU_COMPLETION_TL_STATUS_SHIFT): 506230557Sjimharris if (scic_io_request_get_number_of_bytes_transferred(this_request) < 507230557Sjimharris scic_cb_io_request_get_transfer_length(this_request->user_request)) 508230557Sjimharris { 509230557Sjimharris scic_sds_request_set_status( 510230557Sjimharris this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS_IO_DONE_EARLY 511230557Sjimharris ); 512230557Sjimharris 513230557Sjimharris sci_base_state_machine_change_state( 514230557Sjimharris &this_request->started_substate_machine, 515230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE 516230557Sjimharris ); 517230557Sjimharris 518230557Sjimharris //change the device state to ATAPI_ERROR. 519230557Sjimharris sci_base_state_machine_change_state( 520230557Sjimharris &this_request->target_device->ready_substate_machine, 521230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR 522230557Sjimharris ); 523230557Sjimharris 524230557Sjimharris status = this_request->sci_status; 525230557Sjimharris } 526230557Sjimharris break; 527230557Sjimharris 528230557Sjimharris case (SCU_TASK_DONE_EXCESS_DATA << SCU_COMPLETION_TL_STATUS_SHIFT): 529230557Sjimharris //In this case, there is no UF coming after. compelte the IO now. 530230557Sjimharris scic_sds_request_set_status( 531230557Sjimharris this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 532230557Sjimharris ); 533230557Sjimharris 534230557Sjimharris sci_base_state_machine_change_state( 535230557Sjimharris &this_request->parent.state_machine, 536230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 537230557Sjimharris ); 538230557Sjimharris 539230557Sjimharris break; 540230557Sjimharris 541230557Sjimharris default: 542230557Sjimharris if (this_request->sci_status != SCI_SUCCESS) 543230557Sjimharris { //The io status was set already. This means an UF for the status 544230557Sjimharris //fis was received already. 545230557Sjimharris 546230557Sjimharris //A device suspension event is expected, we need to have the device 547230557Sjimharris //coming out of suspension, then complete the IO. 548230557Sjimharris sci_base_state_machine_change_state( 549230557Sjimharris &this_request->started_substate_machine, 550230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE 551230557Sjimharris ); 552230557Sjimharris 553230557Sjimharris //change the device state to ATAPI_ERROR. 554230557Sjimharris sci_base_state_machine_change_state( 555230557Sjimharris &this_request->target_device->ready_substate_machine, 556230557Sjimharris SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR 557230557Sjimharris ); 558230557Sjimharris 559230557Sjimharris status = this_request->sci_status; 560230557Sjimharris } 561230557Sjimharris else 562230557Sjimharris { //If receiving any non-sucess TC status, no UF received yet, then an UF for 563230557Sjimharris //the status fis is coming after. 564230557Sjimharris scic_sds_request_set_status( 565230557Sjimharris this_request, 566230557Sjimharris SCU_TASK_DONE_CHECK_RESPONSE, 567230557Sjimharris SCI_FAILURE_IO_RESPONSE_VALID 568230557Sjimharris ); 569230557Sjimharris 570230557Sjimharris sci_base_state_machine_change_state( 571230557Sjimharris &this_request->started_substate_machine, 572230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE 573230557Sjimharris ); 574230557Sjimharris } 575230557Sjimharris break; 576230557Sjimharris } 577230557Sjimharris 578230557Sjimharris return status; 579230557Sjimharris} 580230557Sjimharris 581230557Sjimharris 582230557Sjimharris/** 583230557Sjimharris* @brief This method processes an unsolicited frame. 584230557Sjimharris* 585230557Sjimharris* @param[in] this_request This parameter specifies the request for which 586230557Sjimharris* the unsolicited frame was received. 587230557Sjimharris* @param[in] frame_index This parameter indicates the unsolicited frame 588230557Sjimharris* index that should contain the response. 589230557Sjimharris* 590230557Sjimharris* @return This method returns an indication of whether the UF 591230557Sjimharris* frame was handled successfully or not. 592230557Sjimharris* @retval SCI_SUCCESS Currently this value is always returned and indicates 593230557Sjimharris* successful processing of the TC response. 594230557Sjimharris* 595230557Sjimharris*/ 596230557Sjimharrisstatic 597230557SjimharrisSCI_STATUS scic_sds_stp_packet_request_command_phase_common_frame_handler( 598230557Sjimharris SCIC_SDS_REQUEST_T * request, 599230557Sjimharris U32 frame_index 600230557Sjimharris) 601230557Sjimharris{ 602230557Sjimharris SCI_STATUS status; 603230557Sjimharris SATA_FIS_HEADER_T * frame_header; 604230557Sjimharris U32 * frame_buffer; 605230557Sjimharris SCIC_SDS_STP_REQUEST_T * this_request; 606230557Sjimharris 607230557Sjimharris this_request = (SCIC_SDS_STP_REQUEST_T *)request; 608230557Sjimharris 609230557Sjimharris SCIC_LOG_TRACE(( 610230557Sjimharris sci_base_object_get_logger(this_request), 611230557Sjimharris SCIC_LOG_OBJECT_STP_IO_REQUEST, 612230557Sjimharris "scic_sds_stp_packet_request_command_phase_await_d2h_frame_handler(0x%x, 0x%x) enter\n", 613230557Sjimharris this_request, frame_index 614230557Sjimharris )); 615230557Sjimharris 616230557Sjimharris status = scic_sds_unsolicited_frame_control_get_header( 617230557Sjimharris &(this_request->parent.owning_controller->uf_control), 618230557Sjimharris frame_index, 619230557Sjimharris (void**) &frame_header 620230557Sjimharris ); 621230557Sjimharris 622230557Sjimharris if (status == SCI_SUCCESS) 623230557Sjimharris { 624230557Sjimharris ASSERT(frame_header->fis_type == SATA_FIS_TYPE_REGD2H); 625230557Sjimharris 626230557Sjimharris // Get from the frame buffer the PIO Setup Data, although we don't need 627230557Sjimharris // any info from this pio setup fis. 628230557Sjimharris scic_sds_unsolicited_frame_control_get_buffer( 629230557Sjimharris &(this_request->parent.owning_controller->uf_control), 630230557Sjimharris frame_index, 631230557Sjimharris (void**) &frame_buffer 632230557Sjimharris ); 633230557Sjimharris 634230557Sjimharris scic_sds_controller_copy_sata_response( 635230557Sjimharris &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer 636230557Sjimharris ); 637230557Sjimharris 638230557Sjimharris // Frame has been decoded return it to the controller 639230557Sjimharris scic_sds_controller_release_frame( 640230557Sjimharris this_request->parent.owning_controller, frame_index 641230557Sjimharris ); 642230557Sjimharris } 643230557Sjimharris 644230557Sjimharris return status; 645230557Sjimharris} 646230557Sjimharris 647230557Sjimharris/** 648230557Sjimharris* @brief This method processes an unsolicited frame while the packet request is 649230557Sjimharris* expecting TC completion. It will process the FIS and construct sense 650230557Sjimharris* data. 651230557Sjimharris* 652230557Sjimharris* @param[in] this_request This parameter specifies the request for which 653230557Sjimharris* the unsolicited frame was received. 654230557Sjimharris* @param[in] frame_index This parameter indicates the unsolicited frame 655230557Sjimharris* index that should contain the response. 656230557Sjimharris* 657230557Sjimharris* @return This method returns an indication of whether the UF 658230557Sjimharris* frame was handled successfully or not. 659230557Sjimharris* @retval SCI_SUCCESS Currently this value is always returned and indicates 660230557Sjimharris* successful processing of the TC response. 661230557Sjimharris* 662230557Sjimharris*/ 663230557Sjimharrisstatic 664230557SjimharrisSCI_STATUS scic_sds_stp_packet_request_command_phase_await_tc_completion_frame_handler( 665230557Sjimharris SCIC_SDS_REQUEST_T * request, 666230557Sjimharris U32 frame_index 667230557Sjimharris) 668230557Sjimharris{ 669230557Sjimharris SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request; 670230557Sjimharris 671230557Sjimharris SCI_STATUS status = 672230557Sjimharris scic_sds_stp_packet_request_command_phase_common_frame_handler( 673230557Sjimharris request, frame_index); 674230557Sjimharris 675230557Sjimharris if (status == SCI_SUCCESS) 676230557Sjimharris { 677230557Sjimharris // The command has completed with error status from target device. 678230557Sjimharris status = scic_sds_stp_packet_request_process_status_fis( 679230557Sjimharris request, &this_request->d2h_reg_fis); 680230557Sjimharris 681230557Sjimharris if (status != SCI_SUCCESS) 682230557Sjimharris { 683230557Sjimharris scic_sds_request_set_status( 684230557Sjimharris &this_request->parent, 685230557Sjimharris SCU_TASK_DONE_CHECK_RESPONSE, 686230557Sjimharris status 687230557Sjimharris ); 688230557Sjimharris } 689230557Sjimharris else 690230557Sjimharris scic_sds_request_set_status( 691230557Sjimharris &this_request->parent, SCU_TASK_DONE_GOOD, SCI_SUCCESS 692230557Sjimharris ); 693230557Sjimharris } 694230557Sjimharris 695230557Sjimharris return status; 696230557Sjimharris} 697230557Sjimharris 698230557Sjimharris 699230557Sjimharris/** 700230557Sjimharris* @brief This method processes an unsolicited frame while the packet request is 701230557Sjimharris* expecting TC completion. It will process the FIS and construct sense 702230557Sjimharris* data. 703230557Sjimharris* 704230557Sjimharris* @param[in] this_request This parameter specifies the request for which 705230557Sjimharris* the unsolicited frame was received. 706230557Sjimharris* @param[in] frame_index This parameter indicates the unsolicited frame 707230557Sjimharris* index that should contain the response. 708230557Sjimharris* 709230557Sjimharris* @return This method returns an indication of whether the UF 710230557Sjimharris* frame was handled successfully or not. 711230557Sjimharris* @retval SCI_SUCCESS Currently this value is always returned and indicates 712230557Sjimharris* successful processing of the TC response. 713230557Sjimharris* 714230557Sjimharris*/ 715230557Sjimharrisstatic 716230557SjimharrisSCI_STATUS scic_sds_stp_packet_request_command_phase_await_d2h_fis_frame_handler( 717230557Sjimharris SCIC_SDS_REQUEST_T * request, 718230557Sjimharris U32 frame_index 719230557Sjimharris) 720230557Sjimharris{ 721230557Sjimharris SCI_STATUS status = 722230557Sjimharris scic_sds_stp_packet_request_command_phase_common_frame_handler( 723230557Sjimharris request, frame_index); 724230557Sjimharris 725230557Sjimharris SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request; 726230557Sjimharris 727230557Sjimharris if (status == SCI_SUCCESS) 728230557Sjimharris { 729230557Sjimharris // The command has completed with error status from target device. 730230557Sjimharris status = scic_sds_stp_packet_request_process_status_fis( 731230557Sjimharris request, &this_request->d2h_reg_fis); 732230557Sjimharris 733230557Sjimharris if (status != SCI_SUCCESS) 734230557Sjimharris { 735230557Sjimharris scic_sds_request_set_status( 736230557Sjimharris request, 737230557Sjimharris SCU_TASK_DONE_CHECK_RESPONSE, 738230557Sjimharris status 739230557Sjimharris ); 740230557Sjimharris } 741230557Sjimharris else 742230557Sjimharris scic_sds_request_set_status( 743230557Sjimharris request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 744230557Sjimharris ); 745230557Sjimharris 746230557Sjimharris //Always complete the NON_DATA command right away, no need to delay completion 747230557Sjimharris //even an error status fis came from target device. 748230557Sjimharris sci_base_state_machine_change_state( 749230557Sjimharris &request->parent.state_machine, 750230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 751230557Sjimharris ); 752230557Sjimharris } 753230557Sjimharris 754230557Sjimharris return status; 755230557Sjimharris} 756230557Sjimharris 757230557Sjimharrisstatic 758230557SjimharrisSCI_STATUS scic_sds_stp_packet_request_started_completion_delay_complete_handler( 759230557Sjimharris SCI_BASE_REQUEST_T *request 760230557Sjimharris) 761230557Sjimharris{ 762230557Sjimharris SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)request; 763230557Sjimharris 764230557Sjimharris sci_base_state_machine_change_state( 765230557Sjimharris &this_request->parent.state_machine, 766230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 767230557Sjimharris ); 768230557Sjimharris 769230557Sjimharris return this_request->sci_status; 770230557Sjimharris} 771230557Sjimharris 772230557Sjimharris// --------------------------------------------------------------------------- 773230557Sjimharris 774230557SjimharrisSCIC_SDS_IO_REQUEST_STATE_HANDLER_T 775230557Sjimharrisscic_sds_stp_packet_request_started_substate_handler_table 776230557Sjimharris[SCIC_SDS_STP_PACKET_REQUEST_STARTED_MAX_SUBSTATES] = 777230557Sjimharris{ 778230557Sjimharris // SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE 779230557Sjimharris { 780230557Sjimharris { 781230557Sjimharris scic_sds_request_default_start_handler, 782230557Sjimharris scic_sds_request_started_state_abort_handler, 783230557Sjimharris scic_sds_request_default_complete_handler, 784230557Sjimharris scic_sds_request_default_destruct_handler 785230557Sjimharris }, 786230557Sjimharris scic_sds_stp_packet_request_packet_phase_await_tc_completion_tc_completion_handler, 787230557Sjimharris scic_sds_request_default_event_handler, 788230557Sjimharris scic_sds_request_default_frame_handler 789230557Sjimharris }, 790230557Sjimharris // SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE 791230557Sjimharris { 792230557Sjimharris { 793230557Sjimharris scic_sds_request_default_start_handler, 794230557Sjimharris scic_sds_request_started_state_abort_handler, 795230557Sjimharris scic_sds_request_default_complete_handler, 796230557Sjimharris scic_sds_request_default_destruct_handler 797230557Sjimharris }, 798230557Sjimharris scic_sds_request_default_tc_completion_handler, 799230557Sjimharris scic_sds_request_default_event_handler, 800230557Sjimharris scic_sds_stp_packet_request_packet_phase_await_pio_setup_frame_handler 801230557Sjimharris }, 802230557Sjimharris // SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE 803230557Sjimharris { 804230557Sjimharris { 805230557Sjimharris scic_sds_request_default_start_handler, 806230557Sjimharris scic_sds_request_started_state_abort_handler, 807230557Sjimharris scic_sds_request_default_complete_handler, 808230557Sjimharris scic_sds_request_default_destruct_handler 809230557Sjimharris }, 810230557Sjimharris scic_sds_stp_packet_request_command_phase_await_tc_completion_tc_completion_handler, 811230557Sjimharris scic_sds_request_default_event_handler, 812230557Sjimharris scic_sds_stp_packet_request_command_phase_await_tc_completion_frame_handler 813230557Sjimharris }, 814230557Sjimharris // SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE 815230557Sjimharris { 816230557Sjimharris { 817230557Sjimharris scic_sds_request_default_start_handler, 818230557Sjimharris scic_sds_request_started_state_abort_handler, 819230557Sjimharris scic_sds_request_default_complete_handler, 820230557Sjimharris scic_sds_request_default_destruct_handler 821230557Sjimharris }, 822230557Sjimharris scic_sds_request_default_tc_completion_handler, 823230557Sjimharris scic_sds_request_default_event_handler, 824230557Sjimharris scic_sds_stp_packet_request_command_phase_await_d2h_fis_frame_handler 825230557Sjimharris }, 826230557Sjimharris // SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE 827230557Sjimharris { 828230557Sjimharris { 829230557Sjimharris scic_sds_request_default_start_handler, 830230557Sjimharris scic_sds_request_started_state_abort_handler, 831230557Sjimharris scic_sds_stp_packet_request_started_completion_delay_complete_handler, 832230557Sjimharris scic_sds_request_default_destruct_handler 833230557Sjimharris }, 834230557Sjimharris scic_sds_request_default_tc_completion_handler, 835230557Sjimharris scic_sds_request_default_event_handler, 836230557Sjimharris scic_sds_request_default_frame_handler 837230557Sjimharris } 838230557Sjimharris}; 839230557Sjimharris 840230557Sjimharris/** 841230557Sjimharris * @file 842230557Sjimharris * 843230557Sjimharris * @brief This file contains the Packet IO started substate machine 844230557Sjimharris * for the SCIC_SDS_IO_REQUEST object. 845230557Sjimharris */ 846230557Sjimharrisstatic 847230557Sjimharrisvoid scic_sds_stp_packet_request_started_packet_phase_await_tc_completion_enter( 848230557Sjimharris SCI_BASE_OBJECT_T *object 849230557Sjimharris) 850230557Sjimharris{ 851230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 852230557Sjimharris 853230557Sjimharris SET_STATE_HANDLER( 854230557Sjimharris this_request, 855230557Sjimharris scic_sds_stp_packet_request_started_substate_handler_table, 856230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE 857230557Sjimharris ); 858230557Sjimharris 859230557Sjimharris scic_sds_remote_device_set_working_request( 860230557Sjimharris this_request->target_device, this_request 861230557Sjimharris ); 862230557Sjimharris} 863230557Sjimharris 864230557Sjimharrisstatic 865230557Sjimharrisvoid scic_sds_stp_packet_request_started_packet_phase_await_pio_setup_enter( 866230557Sjimharris SCI_BASE_OBJECT_T *object 867230557Sjimharris) 868230557Sjimharris{ 869230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 870230557Sjimharris 871230557Sjimharris SET_STATE_HANDLER( 872230557Sjimharris this_request, 873230557Sjimharris scic_sds_stp_packet_request_started_substate_handler_table, 874230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE 875230557Sjimharris ); 876230557Sjimharris} 877230557Sjimharris 878230557Sjimharrisstatic 879230557Sjimharrisvoid scic_sds_stp_packet_request_started_command_phase_await_tc_completion_enter( 880230557Sjimharris SCI_BASE_OBJECT_T *object 881230557Sjimharris) 882230557Sjimharris{ 883230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 884230557Sjimharris U8 sat_packet_protocol = this_request->sat_protocol; 885230557Sjimharris 886230557Sjimharris SCU_TASK_CONTEXT_T *task_context; 887230557Sjimharris SCI_STATUS status; 888230557Sjimharris 889230557Sjimharris // Recycle the TC and reconstruct it for sending out data fis containing 890230557Sjimharris // CDB. 891230557Sjimharris task_context = scic_sds_controller_get_task_context_buffer( 892230557Sjimharris this_request->owning_controller, this_request->io_tag); 893230557Sjimharris 894230557Sjimharris if (sat_packet_protocol == SAT_PROTOCOL_PACKET_NON_DATA) 895230557Sjimharris scu_stp_packet_request_command_phase_reconstruct_raw_frame_task_context( 896230557Sjimharris this_request, task_context); 897230557Sjimharris else 898230557Sjimharris scu_stp_packet_request_command_phase_construct_task_context( 899230557Sjimharris this_request, task_context); 900230557Sjimharris 901230557Sjimharris // send the new TC out. 902230557Sjimharris status = this_request->owning_controller->state_handlers->parent.continue_io_handler( 903230557Sjimharris &this_request->owning_controller->parent, 904230557Sjimharris &this_request->target_device->parent, 905230557Sjimharris &this_request->parent 906230557Sjimharris ); 907230557Sjimharris 908230557Sjimharris if (status == SCI_SUCCESS) 909230557Sjimharris SET_STATE_HANDLER( 910230557Sjimharris this_request, 911230557Sjimharris scic_sds_stp_packet_request_started_substate_handler_table, 912230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE 913230557Sjimharris ); 914230557Sjimharris} 915230557Sjimharris 916230557Sjimharrisstatic 917230557Sjimharrisvoid scic_sds_stp_packet_request_started_command_phase_await_d2h_fis_enter( 918230557Sjimharris SCI_BASE_OBJECT_T *object 919230557Sjimharris) 920230557Sjimharris{ 921230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 922230557Sjimharris 923230557Sjimharris SET_STATE_HANDLER( 924230557Sjimharris this_request, 925230557Sjimharris scic_sds_stp_packet_request_started_substate_handler_table, 926230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE 927230557Sjimharris ); 928230557Sjimharris} 929230557Sjimharris 930230557Sjimharrisstatic 931230557Sjimharrisvoid scic_sds_stp_packet_request_started_completion_delay_enter( 932230557Sjimharris SCI_BASE_OBJECT_T *object 933230557Sjimharris) 934230557Sjimharris{ 935230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 936230557Sjimharris 937230557Sjimharris SET_STATE_HANDLER( 938230557Sjimharris this_request, 939230557Sjimharris scic_sds_stp_packet_request_started_substate_handler_table, 940230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE 941230557Sjimharris ); 942230557Sjimharris} 943230557Sjimharris 944230557Sjimharris 945230557Sjimharris// --------------------------------------------------------------------------- 946230557SjimharrisSCI_BASE_STATE_T 947230557Sjimharris scic_sds_stp_packet_request_started_substate_table 948230557Sjimharris [SCIC_SDS_STP_PACKET_REQUEST_STARTED_MAX_SUBSTATES] = 949230557Sjimharris{ 950230557Sjimharris { 951230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE, 952230557Sjimharris scic_sds_stp_packet_request_started_packet_phase_await_tc_completion_enter, 953230557Sjimharris NULL 954230557Sjimharris }, 955230557Sjimharris { 956230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE, 957230557Sjimharris scic_sds_stp_packet_request_started_packet_phase_await_pio_setup_enter, 958230557Sjimharris NULL 959230557Sjimharris }, 960230557Sjimharris { 961230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE, 962230557Sjimharris scic_sds_stp_packet_request_started_command_phase_await_tc_completion_enter, 963230557Sjimharris NULL 964230557Sjimharris }, 965230557Sjimharris { 966230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE, 967230557Sjimharris scic_sds_stp_packet_request_started_command_phase_await_d2h_fis_enter, 968230557Sjimharris NULL 969230557Sjimharris }, 970230557Sjimharris { 971230557Sjimharris SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE, 972230557Sjimharris scic_sds_stp_packet_request_started_completion_delay_enter, 973230557Sjimharris NULL 974230557Sjimharris } 975230557Sjimharris}; 976230557Sjimharris 977230557Sjimharris#endif //#if !defined(DISABLE_ATAPI) 978230557Sjimharris 979