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/** 57230557Sjimharris * @file 58230557Sjimharris * 59230557Sjimharris * @brief This file contains the method implementations for the 60230557Sjimharris * SCIF_SAS_STP_IO_REQUEST object. The contents will implement 61230557Sjimharris * SATA/STP specific functionality. 62230557Sjimharris */ 63230557Sjimharris 64230557Sjimharris#include <dev/isci/scil/scif_sas_stp_io_request.h> 65230557Sjimharris#include <dev/isci/scil/scif_sas_stp_remote_device.h> 66230557Sjimharris#include <dev/isci/scil/scif_sas_logger.h> 67230557Sjimharris#include <dev/isci/scil/scif_sas_controller.h> 68230557Sjimharris 69230557Sjimharris#include <dev/isci/scil/sci_status.h> 70230557Sjimharris#include <dev/isci/scil/scic_io_request.h> 71230557Sjimharris 72230557Sjimharris#include <dev/isci/scil/sati.h> 73230557Sjimharris#include <dev/isci/scil/sati_atapi.h> 74230557Sjimharris#include <dev/isci/scil/intel_sat.h> 75230557Sjimharris#include <dev/isci/scil/sati_util.h> 76230557Sjimharris#include <dev/isci/scil/sati_callbacks.h> 77230557Sjimharris 78230557Sjimharris//****************************************************************************** 79230557Sjimharris// P R I V A T E M E T H O D S 80230557Sjimharris//****************************************************************************** 81230557Sjimharris 82230557Sjimharris/** 83230557Sjimharris * @brief This method provides SATA/STP CONSTRUCTED state specific handling 84230557Sjimharris * for when the user attempts to start the supplied IO request. It 85230557Sjimharris * will allocate NCQ tags if necessary. 86230557Sjimharris * 87230557Sjimharris * @param[in] io_request This parameter specifies the IO request object 88230557Sjimharris * to be started. 89230557Sjimharris * 90230557Sjimharris * @return This method returns a value indicating if the IO request was 91230557Sjimharris * successfully started or not. 92230557Sjimharris * @retval SCI_SUCCESS This return value indicates successful starting 93230557Sjimharris * of the IO request. 94230557Sjimharris */ 95230557Sjimharrisstatic 96230557SjimharrisSCI_STATUS scif_sas_stp_io_request_constructed_start_handler( 97230557Sjimharris SCI_BASE_REQUEST_T * io_request 98230557Sjimharris) 99230557Sjimharris{ 100230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *) io_request; 101230557Sjimharris 102230557Sjimharris SCIF_LOG_TRACE(( 103230557Sjimharris sci_base_object_get_logger(io_request), 104230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 105230557Sjimharris "scif_sas_stp_io_request_constructed_start_handler(0x%x) enter\n", 106230557Sjimharris io_request 107230557Sjimharris )); 108230557Sjimharris 109230557Sjimharris if (fw_io->parent.stp.sequence.protocol == SAT_PROTOCOL_FPDMA) 110230557Sjimharris { 111230557Sjimharris SATA_FIS_REG_H2D_T * fis; 112230557Sjimharris 113230557Sjimharris // For NCQ, we need to attempt to allocate an available tag. 114230557Sjimharris fw_io->parent.stp.ncq_tag = scif_sas_stp_remote_device_allocate_ncq_tag( 115230557Sjimharris fw_io->parent.device 116230557Sjimharris ); 117230557Sjimharris 118230557Sjimharris if (fw_io->parent.stp.ncq_tag == SCIF_SAS_INVALID_NCQ_TAG) 119230557Sjimharris return SCI_FAILURE_NO_NCQ_TAG_AVAILABLE; 120230557Sjimharris 121230557Sjimharris // Set the NCQ tag in the host to device register FIS (upper 5 bits 122230557Sjimharris // of the 8-bit sector count register). 123230557Sjimharris fis = scic_stp_io_request_get_h2d_reg_address(fw_io->parent.core_object); 124230557Sjimharris fis->sector_count = (fw_io->parent.stp.ncq_tag << 3); 125230557Sjimharris 126230557Sjimharris // The Core also requires that we inform it separately regarding the 127230557Sjimharris // NCQ tag for this IO. 128230557Sjimharris scic_stp_io_request_set_ncq_tag( 129230557Sjimharris fw_io->parent.core_object, fw_io->parent.stp.ncq_tag 130230557Sjimharris ); 131230557Sjimharris } 132230557Sjimharris 133230557Sjimharris return SCI_SUCCESS; 134230557Sjimharris} 135230557Sjimharris 136230557Sjimharris/** 137230557Sjimharris * @brief This method provides SATA/STP CONSTRUCTED state specific handling 138230557Sjimharris * for when the user attempts to complete the supplied IO request. 139230557Sjimharris * This method will be invoked in the event the call to start the 140230557Sjimharris * core IO request fails for some reason. In this situation, the 141230557Sjimharris * NCQ tag will be freed. 142230557Sjimharris * 143230557Sjimharris * @param[in] io_request This parameter specifies the IO request object 144230557Sjimharris * to be started. 145230557Sjimharris * 146230557Sjimharris * @return This method returns a value indicating if the IO request was 147230557Sjimharris * successfully started or not. 148230557Sjimharris * @retval SCI_SUCCESS This return value indicates successful starting 149230557Sjimharris * of the IO request. 150230557Sjimharris */ 151230557Sjimharrisstatic 152230557SjimharrisSCI_STATUS scif_sas_stp_io_request_constructed_complete_handler( 153230557Sjimharris SCI_BASE_REQUEST_T * io_request 154230557Sjimharris) 155230557Sjimharris{ 156230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *) io_request; 157230557Sjimharris 158230557Sjimharris SCIF_LOG_TRACE(( 159230557Sjimharris sci_base_object_get_logger(io_request), 160230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 161230557Sjimharris "scif_sas_stp_io_request_constructed_complete_handler(0x%x) enter\n", 162230557Sjimharris io_request 163230557Sjimharris )); 164230557Sjimharris 165230557Sjimharris if (fw_io->parent.stp.sequence.protocol == SAT_PROTOCOL_FPDMA) 166230557Sjimharris { 167230557Sjimharris // For NCQ, we need to return the tag back to the free pool. 168230557Sjimharris if (fw_io->parent.stp.ncq_tag != SCIF_SAS_INVALID_NCQ_TAG) 169230557Sjimharris scif_sas_stp_remote_device_free_ncq_tag( 170230557Sjimharris fw_io->parent.device, fw_io->parent.stp.ncq_tag 171230557Sjimharris ); 172230557Sjimharris } 173230557Sjimharris 174239545Sjimharris sati_sequence_terminate(&fw_io->parent.stp.sequence, fw_io, fw_io); 175239545Sjimharris 176230557Sjimharris return SCI_SUCCESS; 177230557Sjimharris} 178230557Sjimharris/** 179230557Sjimharris * @brief This method provides SATA/STP STARTED state specific handling for 180230557Sjimharris * when the user attempts to complete the supplied IO request. 181230557Sjimharris * It will perform data/response translation and free NCQ tags 182230557Sjimharris * if necessary. 183230557Sjimharris * 184230557Sjimharris * @param[in] io_request This parameter specifies the IO request object 185230557Sjimharris * to be started. 186230557Sjimharris * 187230557Sjimharris * @return This method returns a value indicating if the IO request was 188230557Sjimharris * successfully completed or not. 189230557Sjimharris */ 190230557Sjimharrisstatic 191230557SjimharrisSCI_STATUS scif_sas_stp_core_cb_io_request_complete_handler( 192230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller, 193230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device, 194230557Sjimharris SCIF_SAS_REQUEST_T * fw_request, 195230557Sjimharris SCI_STATUS * completion_status 196230557Sjimharris) 197230557Sjimharris{ 198230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *) fw_request; 199230557Sjimharris 200230557Sjimharris SCIF_LOG_TRACE(( 201230557Sjimharris sci_base_object_get_logger(fw_controller), 202230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 203230557Sjimharris "scif_sas_stp_core_cb_io_request_complete_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 204230557Sjimharris fw_controller, fw_device, fw_request, *completion_status 205230557Sjimharris )); 206230557Sjimharris 207230557Sjimharris if (fw_io->parent.stp.sequence.protocol == SAT_PROTOCOL_FPDMA) 208230557Sjimharris scif_sas_stp_remote_device_free_ncq_tag( 209230557Sjimharris fw_request->device, fw_io->parent.stp.ncq_tag 210230557Sjimharris ); 211230557Sjimharris 212230557Sjimharris // Translating the response is only necessary if: 213230557Sjimharris // - some sort of error occurred resulting in having the error bit 214230557Sjimharris // set in the ATA status register and values to decode in the 215230557Sjimharris // ATA error register. 216230557Sjimharris // - the command returns information in the register FIS itself, 217230557Sjimharris // which requires translation. 218230557Sjimharris // - the request completed ok but the sequence requires a callback 219230557Sjimharris // to possibly continue the translation 220230557Sjimharris if ((*completion_status == SCI_FAILURE_IO_RESPONSE_VALID) || 221230557Sjimharris ((sati_cb_do_translate_response(fw_request)) && 222230557Sjimharris (*completion_status != SCI_FAILURE_IO_TERMINATED))) 223230557Sjimharris { 224230557Sjimharris SATI_STATUS sati_status = sati_translate_command_response( 225230557Sjimharris &fw_io->parent.stp.sequence, fw_io, fw_io 226230557Sjimharris ); 227230557Sjimharris if (sati_status == SATI_COMPLETE) 228230557Sjimharris *completion_status = SCI_SUCCESS; 229230557Sjimharris else if (sati_status == SATI_FAILURE_CHECK_RESPONSE_DATA) 230230557Sjimharris *completion_status = SCI_FAILURE_IO_RESPONSE_VALID; 231230557Sjimharris else if (sati_status == SATI_SEQUENCE_INCOMPLETE) 232230557Sjimharris { 233230557Sjimharris // The translation indicates that additional SATA requests are 234230557Sjimharris // necessary to finish the original SCSI request. As a result, 235230557Sjimharris // do not complete the IO and begin the next stage of the 236230557Sjimharris // translation. 237230557Sjimharris return SCI_WARNING_SEQUENCE_INCOMPLETE; 238230557Sjimharris } 239230557Sjimharris else if (sati_status == SATI_COMPLETE_IO_DONE_EARLY) 240230557Sjimharris *completion_status = SCI_SUCCESS_IO_DONE_EARLY; 241230557Sjimharris else 242230557Sjimharris { 243230557Sjimharris // Something unexpected occurred during translation. Fail the 244230557Sjimharris // IO request to the user. 245230557Sjimharris *completion_status = SCI_FAILURE; 246230557Sjimharris } 247230557Sjimharris } 248230557Sjimharris else if (*completion_status != SCI_SUCCESS) 249230557Sjimharris { 250230557Sjimharris SCIF_LOG_INFO(( 251230557Sjimharris sci_base_object_get_logger(fw_controller), 252230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 253230557Sjimharris "Sequence Terminated(0x%x, 0x%x, 0x%x)\n", 254230557Sjimharris fw_controller, fw_device, fw_request 255230557Sjimharris )); 256230557Sjimharris 257230557Sjimharris sati_sequence_terminate(&fw_io->parent.stp.sequence, fw_io, fw_io); 258230557Sjimharris } 259230557Sjimharris 260230557Sjimharris return SCI_SUCCESS; 261230557Sjimharris} 262230557Sjimharris 263230557Sjimharris#if !defined(DISABLE_ATAPI) 264230557Sjimharris/** 265230557Sjimharris * @brief This method provides STP PACKET io request STARTED state specific handling for 266230557Sjimharris * when the user attempts to complete the supplied IO request. 267230557Sjimharris * It will perform data/response translation. 268230557Sjimharris * 269230557Sjimharris * @param[in] io_request This parameter specifies the IO request object 270230557Sjimharris * to be started. 271230557Sjimharris * 272230557Sjimharris * @return This method returns a value indicating if the IO request was 273230557Sjimharris * successfully completed or not. 274230557Sjimharris */ 275230557Sjimharrisstatic 276230557SjimharrisSCI_STATUS scif_sas_stp_core_cb_packet_io_request_complete_handler( 277230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller, 278230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device, 279230557Sjimharris SCIF_SAS_REQUEST_T * fw_request, 280230557Sjimharris SCI_STATUS * completion_status 281230557Sjimharris) 282230557Sjimharris{ 283230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *) fw_request; 284230557Sjimharris SATI_STATUS sati_status; 285230557Sjimharris 286230557Sjimharris SCIF_LOG_TRACE(( 287230557Sjimharris sci_base_object_get_logger(fw_controller), 288230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 289230557Sjimharris "scif_sas_stp_packet_core_cb_io_request_complete_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 290230557Sjimharris fw_controller, fw_device, fw_request, *completion_status 291230557Sjimharris )); 292230557Sjimharris 293230557Sjimharris if (*completion_status == SCI_FAILURE_IO_RESPONSE_VALID) 294230557Sjimharris { 295230557Sjimharris sati_status = sati_atapi_translate_command_response( 296230557Sjimharris &fw_io->parent.stp.sequence, fw_io, fw_io 297230557Sjimharris ); 298230557Sjimharris 299230557Sjimharris if (sati_status == SATI_COMPLETE) 300230557Sjimharris *completion_status = SCI_SUCCESS; 301230557Sjimharris else if (sati_status == SATI_FAILURE_CHECK_RESPONSE_DATA) 302230557Sjimharris *completion_status = SCI_FAILURE_IO_RESPONSE_VALID; 303230557Sjimharris else if (sati_status == SATI_SEQUENCE_INCOMPLETE) 304230557Sjimharris { 305230557Sjimharris // The translation indicates that additional REQUEST SENSE command is 306230557Sjimharris // necessary to finish the original SCSI request. As a result, 307230557Sjimharris // do not complete the IO and begin the next stage of the IO. 308230557Sjimharris return SCI_WARNING_SEQUENCE_INCOMPLETE; 309230557Sjimharris } 310230557Sjimharris else 311230557Sjimharris { 312230557Sjimharris // Something unexpected occurred during translation. Fail the 313230557Sjimharris // IO request to the user. 314230557Sjimharris *completion_status = SCI_FAILURE; 315230557Sjimharris } 316230557Sjimharris } 317230557Sjimharris else if (*completion_status == SCI_SUCCESS && 318230557Sjimharris fw_request->stp.sequence.state == SATI_SEQUENCE_STATE_INCOMPLETE) 319230557Sjimharris { 320230557Sjimharris //The internal Request Sense command is completed successfully. 321230557Sjimharris sati_atapi_translate_request_sense_response( 322230557Sjimharris &fw_io->parent.stp.sequence, fw_io, fw_io 323230557Sjimharris ); 324230557Sjimharris 325230557Sjimharris *completion_status = SCI_FAILURE_IO_RESPONSE_VALID; 326230557Sjimharris } 327230557Sjimharris 328230557Sjimharris return SCI_SUCCESS; 329230557Sjimharris} 330230557Sjimharris#endif // !defined(DISABLE_ATAPI) 331230557Sjimharris 332230557Sjimharris//****************************************************************************** 333230557Sjimharris// P R O T E C T E D M E T H O D S 334230557Sjimharris//****************************************************************************** 335230557Sjimharris 336230557Sjimharris/** 337230557Sjimharris * @brief This method will construct the SATA/STP specific IO request 338230557Sjimharris * object utilizing the SATI. 339230557Sjimharris * 340230557Sjimharris * @pre The scif_sas_request_construct() method should be invoked before 341230557Sjimharris * calling this method. 342230557Sjimharris * 343230557Sjimharris * @param[in,out] stp_io_request This parameter specifies the stp_io_request 344230557Sjimharris * to be constructed. 345230557Sjimharris * 346230557Sjimharris * @return Indicate if the construction was successful. 347230557Sjimharris * @return SCI_FAILURE_NO_NCQ_TAG_AVAILABLE 348230557Sjimharris * @return SCI_SUCCESS_IO_COMPLETE_BEFORE_START 349230557Sjimharris * @return SCI_FAILURE_IO_RESPONSE_VALID 350230557Sjimharris * @return SCI_FAILURE This return value indicates a change in the translator 351230557Sjimharris * where a new return code has been given, but is not yet understood 352230557Sjimharris * by this routine. 353230557Sjimharris */ 354230557SjimharrisSCI_STATUS scif_sas_stp_io_request_construct( 355230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io 356230557Sjimharris) 357230557Sjimharris{ 358230557Sjimharris SATI_STATUS sati_status; 359230557Sjimharris SCI_STATUS sci_status = SCI_FAILURE; 360230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = fw_io->parent.device; 361230557Sjimharris 362230557Sjimharris SCIF_LOG_TRACE(( 363230557Sjimharris sci_base_object_get_logger(fw_io), 364230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 365230557Sjimharris "scif_sas_stp_io_request_construct(0x%x) enter\n", 366230557Sjimharris fw_io 367230557Sjimharris )); 368230557Sjimharris 369230557Sjimharris // The translator will indirectly invoke core methods to set the fields 370230557Sjimharris // of the ATA register FIS inside of this method. 371230557Sjimharris sati_status = sati_translate_command( 372230557Sjimharris &fw_io->parent.stp.sequence, 373230557Sjimharris &fw_device->protocol_device.stp_device.sati_device, 374230557Sjimharris fw_io, 375230557Sjimharris fw_io 376230557Sjimharris ); 377230557Sjimharris 378230557Sjimharris if (sati_status == SATI_SUCCESS) 379230557Sjimharris { 380230557Sjimharris // Allow the core to finish construction of the IO request. 381230557Sjimharris sci_status = scic_io_request_construct_basic_sata(fw_io->parent.core_object); 382230557Sjimharris fw_io->parent.state_handlers = &stp_io_request_constructed_handlers; 383230557Sjimharris fw_io->parent.protocol_complete_handler 384230557Sjimharris = scif_sas_stp_core_cb_io_request_complete_handler; 385230557Sjimharris } 386230557Sjimharris else if (sati_status == SATI_SUCCESS_SGL_TRANSLATED) 387230557Sjimharris { 388230557Sjimharris SCIC_IO_SATA_PARAMETERS_T parms; 389230557Sjimharris parms.do_translate_sgl = FALSE; 390230557Sjimharris 391230557Sjimharris // The translation actually already caused translation of the 392230557Sjimharris // scatter gather list. So, call into the core through an API 393230557Sjimharris // that will not attempt to translate the SGL. 394230557Sjimharris scic_io_request_construct_advanced_sata( 395230557Sjimharris fw_io->parent.core_object, &parms 396230557Sjimharris ); 397230557Sjimharris fw_io->parent.state_handlers = &stp_io_request_constructed_handlers; 398230557Sjimharris fw_io->parent.protocol_complete_handler 399230557Sjimharris = scif_sas_stp_core_cb_io_request_complete_handler; 400230557Sjimharris // Done with translation 401231296Sjimharris sci_status = SCI_SUCCESS; 402230557Sjimharris } 403230557Sjimharris else if (sati_status == SATI_COMPLETE) 404230557Sjimharris sci_status = SCI_SUCCESS_IO_COMPLETE_BEFORE_START; 405230557Sjimharris else if (sati_status == SATI_FAILURE_CHECK_RESPONSE_DATA) 406230557Sjimharris sci_status = SCI_FAILURE_IO_RESPONSE_VALID; 407230557Sjimharris else 408230557Sjimharris { 409230557Sjimharris SCIF_LOG_ERROR(( 410230557Sjimharris sci_base_object_get_logger(fw_io), 411230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 412230557Sjimharris "Unexpected SAT translation failure 0x%x\n", 413230557Sjimharris fw_io 414230557Sjimharris )); 415230557Sjimharris } 416230557Sjimharris 417230557Sjimharris return sci_status; 418230557Sjimharris} 419230557Sjimharris 420230557Sjimharris 421230557Sjimharris#if !defined(DISABLE_ATAPI) 422230557Sjimharris/** 423230557Sjimharris * @brief This method will construct the STP PACKET protocol specific IO 424230557Sjimharris * request object. 425230557Sjimharris * 426230557Sjimharris * @pre The scif_sas_request_construct() method should be invoked before 427230557Sjimharris * calling this method. 428230557Sjimharris * 429230557Sjimharris * @param[in,out] fw_io This parameter specifies the stp packet io request 430230557Sjimharris * to be constructed. 431230557Sjimharris * 432230557Sjimharris * @return Indicate if the construction was successful. 433230557Sjimharris * @return SCI_SUCCESS_IO_COMPLETE_BEFORE_START 434230557Sjimharris * @return SCI_FAILURE_IO_RESPONSE_VALID 435230557Sjimharris * @return SCI_FAILURE This return value indicates a change in the translator 436230557Sjimharris * where a new return code has been given, but is not yet understood 437230557Sjimharris * by this routine. 438230557Sjimharris */ 439230557SjimharrisSCI_STATUS scif_sas_stp_packet_io_request_construct( 440230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io 441230557Sjimharris) 442230557Sjimharris{ 443230557Sjimharris SATI_STATUS sati_status; 444230557Sjimharris SCI_STATUS sci_status = SCI_FAILURE; 445230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = fw_io->parent.device; 446230557Sjimharris 447230557Sjimharris SCIF_LOG_TRACE(( 448230557Sjimharris sci_base_object_get_logger(fw_io), 449230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 450230557Sjimharris "scif_sas_stp_packet_io_request_construct(0x%x) enter\n", 451230557Sjimharris fw_io 452230557Sjimharris )); 453230557Sjimharris 454230557Sjimharris sati_status = sati_atapi_translate_command( 455230557Sjimharris &fw_io->parent.stp.sequence, 456230557Sjimharris &fw_device->protocol_device.stp_device.sati_device, 457230557Sjimharris fw_io, 458230557Sjimharris fw_io 459230557Sjimharris ); 460230557Sjimharris 461230557Sjimharris if (sati_status == SATI_SUCCESS) 462230557Sjimharris { 463230557Sjimharris // Allow the core to finish construction of the IO request. 464230557Sjimharris sci_status = scic_io_request_construct_basic_sata(fw_io->parent.core_object); 465230557Sjimharris 466230557Sjimharris fw_io->parent.protocol_complete_handler 467230557Sjimharris = scif_sas_stp_core_cb_packet_io_request_complete_handler; 468230557Sjimharris } 469230557Sjimharris else if (sati_status == SATI_COMPLETE) 470230557Sjimharris sci_status = SCI_SUCCESS_IO_COMPLETE_BEFORE_START; 471230557Sjimharris else if (sati_status == SATI_FAILURE_CHECK_RESPONSE_DATA) 472230557Sjimharris sci_status = SCI_FAILURE_IO_RESPONSE_VALID; 473230557Sjimharris else 474230557Sjimharris { 475230557Sjimharris SCIF_LOG_ERROR(( 476230557Sjimharris sci_base_object_get_logger(fw_io), 477230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 478230557Sjimharris "Unexpected SAT ATAPI translation failure 0x%x\n", 479230557Sjimharris fw_io 480230557Sjimharris )); 481230557Sjimharris } 482230557Sjimharris 483230557Sjimharris return sci_status; 484230557Sjimharris} 485230557Sjimharris#endif 486230557Sjimharris 487230557Sjimharris 488230557Sjimharris#if !defined(DISABLE_ATAPI) 489230557Sjimharris/** 490230557Sjimharris * @brief This method will get the number of bytes transferred in an packet IO. 491230557Sjimharris * 492230557Sjimharris * @param[in] fw_io This parameter specifies the stp packet io request whose 493230557Sjimharris * actual transferred length is to be retrieved. 494230557Sjimharris * 495230557Sjimharris * @return Actual length of transferred data. 496230557Sjimharris */ 497230557SjimharrisU32 scif_sas_stp_packet_io_request_get_number_of_bytes_transferred( 498230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io 499230557Sjimharris) 500230557Sjimharris{ 501230557Sjimharris SCI_IO_REQUEST_HANDLE_T scic_io = scif_io_request_get_scic_handle(fw_io); 502230557Sjimharris SCI_IO_STATUS io_status = scic_request_get_sci_status (scic_io); 503230557Sjimharris U32 actual_data_length; 504230557Sjimharris 505230557Sjimharris if (io_status == SCI_IO_FAILURE_RESPONSE_VALID) 506230557Sjimharris actual_data_length = 0; 507230557Sjimharris else if (io_status == SCI_IO_SUCCESS_IO_DONE_EARLY) 508230557Sjimharris { 509230557Sjimharris actual_data_length = sati_atapi_translate_number_of_bytes_transferred( 510230557Sjimharris &fw_io->parent.stp.sequence, fw_io, fw_io); 511230557Sjimharris 512230557Sjimharris if (actual_data_length == 0) 513230557Sjimharris actual_data_length = 514230557Sjimharris scic_io_request_get_number_of_bytes_transferred(scic_io); 515230557Sjimharris } 516230557Sjimharris else 517230557Sjimharris actual_data_length = 518230557Sjimharris scic_io_request_get_number_of_bytes_transferred(scic_io); 519230557Sjimharris 520230557Sjimharris return actual_data_length; 521230557Sjimharris} 522230557Sjimharris#endif 523230557Sjimharris 524230557Sjimharris 525230557Sjimharris//****************************************************************************** 526230557Sjimharris// P U B L I C M E T H O D S 527230557Sjimharris//****************************************************************************** 528230557Sjimharris 529230557SjimharrisBOOL scic_cb_io_request_do_copy_rx_frames( 530230557Sjimharris void * scic_user_io_request 531230557Sjimharris) 532230557Sjimharris{ 533230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) scic_user_io_request; 534230557Sjimharris 535230557Sjimharris SCIF_LOG_TRACE(( 536230557Sjimharris sci_base_object_get_logger(fw_io), 537230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 538230557Sjimharris "scic_cb_io_request_do_copy_rx_frames(0x%x) enter\n", 539230557Sjimharris fw_io 540230557Sjimharris )); 541230557Sjimharris 542230557Sjimharris // If the translation was a PIO DATA IN (i.e. read) and the request 543230557Sjimharris // was actually a READ payload operation, then copy the data, since 544230557Sjimharris // there will be SGL space allocated for the transfer. 545230557Sjimharris if (fw_io->parent.stp.sequence.protocol == SAT_PROTOCOL_PIO_DATA_IN) 546230557Sjimharris { 547230557Sjimharris if ( 548230557Sjimharris (fw_io->parent.stp.sequence.type == SATI_SEQUENCE_ATA_PASSTHROUGH_12) 549230557Sjimharris || (fw_io->parent.stp.sequence.type == SATI_SEQUENCE_ATA_PASSTHROUGH_16) 550230557Sjimharris || ( 551230557Sjimharris (fw_io->parent.stp.sequence.type >= SATI_SEQUENCE_TYPE_READ_MIN) 552230557Sjimharris && (fw_io->parent.stp.sequence.type <= SATI_SEQUENCE_TYPE_READ_MAX) 553230557Sjimharris ) 554230557Sjimharris ) 555230557Sjimharris { 556230557Sjimharris SCIF_LOG_TRACE(( 557230557Sjimharris sci_base_object_get_logger(fw_io), 558230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 559230557Sjimharris "scic_cb_io_request_do_copy_rx_frames(0x%x) TRUE\n", 560230557Sjimharris fw_io 561230557Sjimharris )); 562230557Sjimharris return TRUE; 563230557Sjimharris } 564230557Sjimharris } 565230557Sjimharris 566230557Sjimharris // For all other requests we leave the data in the core buffers. 567230557Sjimharris // This allows the translation to translate without having to have 568230557Sjimharris // separate space allocated into which to copy the data. 569230557Sjimharris return FALSE; 570230557Sjimharris} 571230557Sjimharris 572230557Sjimharris// --------------------------------------------------------------------------- 573230557Sjimharris 574230557SjimharrisU8 scic_cb_request_get_sat_protocol( 575230557Sjimharris void * scic_user_io_request 576230557Sjimharris) 577230557Sjimharris{ 578230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) scic_user_io_request; 579230557Sjimharris 580230557Sjimharris return fw_io->parent.stp.sequence.protocol; 581230557Sjimharris} 582230557Sjimharris 583230557SjimharrisU8 *scic_cb_io_request_get_virtual_address_from_sgl( 584230557Sjimharris void * scic_user_io_request, 585230557Sjimharris U32 byte_offset 586230557Sjimharris) 587230557Sjimharris{ 588230557Sjimharris SCIF_SAS_REQUEST_T *fw_request = 589230557Sjimharris (SCIF_SAS_REQUEST_T *) sci_object_get_association(scic_user_io_request); 590230557Sjimharris 591230557Sjimharris return scif_cb_io_request_get_virtual_address_from_sgl( 592230557Sjimharris sci_object_get_association(fw_request), 593230557Sjimharris byte_offset 594230557Sjimharris ); 595230557Sjimharris} 596230557Sjimharris 597230557Sjimharris#ifdef ENABLE_OSSL_COPY_BUFFER 598230557Sjimharrisvoid scic_cb_io_request_copy_buffer( 599230557Sjimharris void * scic_user_io_request, 600230557Sjimharris U8 *source_addr, 601230557Sjimharris U32 offset, 602230557Sjimharris U32 length 603230557Sjimharris) 604230557Sjimharris{ 605230557Sjimharris SCIF_SAS_REQUEST_T *fw_request = 606230557Sjimharris (SCIF_SAS_REQUEST_T *)sci_object_get_association(scic_user_io_request); 607230557Sjimharris 608230557Sjimharris return scif_cb_io_request_copy_buffer( 609230557Sjimharris sci_object_get_association(fw_request), 610230557Sjimharris source_addr, 611230557Sjimharris offset, 612230557Sjimharris length 613230557Sjimharris ); 614230557Sjimharris} 615230557Sjimharris#endif 616230557Sjimharris// --------------------------------------------------------------------------- 617230557Sjimharris 618230557SjimharrisSCI_BASE_REQUEST_STATE_HANDLER_T stp_io_request_constructed_handlers = 619230557Sjimharris{ 620230557Sjimharris scif_sas_stp_io_request_constructed_start_handler, 621230557Sjimharris scif_sas_io_request_constructed_abort_handler, 622230557Sjimharris scif_sas_stp_io_request_constructed_complete_handler, 623230557Sjimharris scif_sas_io_request_default_destruct_handler 624230557Sjimharris}; 625230557Sjimharris 626