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: releng/11.0/sys/dev/isci/scil/scif_sas_io_request.c 231296 2012-02-09 17:50:24Z jimharris $"); 55230557Sjimharris 56230557Sjimharris/** 57230557Sjimharris * @file 58230557Sjimharris * 59230557Sjimharris * @brief This file contains the implementation of the SCIF_SAS_IO_REQUEST 60230557Sjimharris * object. 61230557Sjimharris */ 62230557Sjimharris 63230557Sjimharris 64230557Sjimharris#include <dev/isci/scil/scic_io_request.h> 65230557Sjimharris#include <dev/isci/scil/scic_remote_device.h> 66230557Sjimharris#include <dev/isci/scil/scic_user_callback.h> 67230557Sjimharris#include <dev/isci/scil/scic_controller.h> 68230557Sjimharris#include <dev/isci/scil/scif_user_callback.h> 69230557Sjimharris 70230557Sjimharris#include <dev/isci/scil/scif_sas_controller.h> 71230557Sjimharris#include <dev/isci/scil/scif_sas_domain.h> 72230557Sjimharris#include <dev/isci/scil/scif_sas_remote_device.h> 73230557Sjimharris#include <dev/isci/scil/scif_sas_io_request.h> 74230557Sjimharris#include <dev/isci/scil/scif_sas_task_request.h> 75230557Sjimharris#include <dev/isci/scil/scif_sas_stp_io_request.h> 76230557Sjimharris#include <dev/isci/scil/scif_sas_logger.h> 77230557Sjimharris#include <dev/isci/scil/scif_sas_smp_io_request.h> 78230557Sjimharris#include <dev/isci/scil/sci_fast_list.h> 79230557Sjimharris#include <dev/isci/scil/sati.h> 80230557Sjimharris#include <dev/isci/scil/intel_sat.h> 81230557Sjimharris#include <dev/isci/scil/sati_translator_sequence.h> 82230557Sjimharris 83230557Sjimharris/** 84230557Sjimharris * @brief This method represents common functionality for the 85230557Sjimharris * scif_io_request_construct() and scif_sas_io_request_continue() 86230557Sjimharris * methods. 87230557Sjimharris * 88230557Sjimharris * @return This method returns an indication as to whether the 89230557Sjimharris * construction succeeded. 90230557Sjimharris */ 91230557Sjimharrisstatic 92230557SjimharrisSCI_STATUS scif_sas_io_request_construct( 93230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device, 94230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io, 95230557Sjimharris U16 io_tag, 96230557Sjimharris void * user_io_request_object, 97230557Sjimharris SCI_IO_REQUEST_HANDLE_T * scif_io_request, 98230557Sjimharris BOOL is_initial_construction 99230557Sjimharris) 100230557Sjimharris{ 101230557Sjimharris SCI_STATUS status; 102230557Sjimharris SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols; 103230557Sjimharris 104230557Sjimharris scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols); 105230557Sjimharris 106230557Sjimharris //Currently, all the io requests sent to smp target are internal. 107230557Sjimharris //so we fail all the external io toward to it. 108230557Sjimharris //Todo: is there a better way to handle external io to smp target? 109230557Sjimharris if (dev_protocols.u.bits.attached_smp_target) 110230557Sjimharris return SCI_FAILURE_INVALID_REMOTE_DEVICE; 111230557Sjimharris 112230557Sjimharris SCIF_LOG_TRACE(( 113230557Sjimharris sci_base_object_get_logger(fw_device), 114230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 115230557Sjimharris "scif_sas_io_request_construct(0x%x,0x%x,0x%x,0x%x,0x%x,0x%x) enter\n", 116230557Sjimharris fw_device, fw_io, io_tag, user_io_request_object, scif_io_request, 117230557Sjimharris is_initial_construction 118230557Sjimharris )); 119230557Sjimharris 120230557Sjimharris // Initialize the users handle to the framework IO request. 121230557Sjimharris *scif_io_request = fw_io; 122230557Sjimharris 123230557Sjimharris // Construct the parent object first in order to ensure logging can 124230557Sjimharris // function. 125230557Sjimharris scif_sas_request_construct( 126230557Sjimharris &fw_io->parent, 127230557Sjimharris fw_device, 128230557Sjimharris sci_base_object_get_logger(fw_device), 129230557Sjimharris scif_sas_io_request_state_table 130230557Sjimharris ); 131230557Sjimharris 132230557Sjimharris status = scic_io_request_construct( 133230557Sjimharris fw_device->domain->controller->core_object, 134230557Sjimharris fw_device->core_object, 135230557Sjimharris io_tag, 136230557Sjimharris fw_io, 137230557Sjimharris ((U8 *)fw_io) + sizeof(SCIF_SAS_IO_REQUEST_T), 138230557Sjimharris &fw_io->parent.core_object 139230557Sjimharris ); 140230557Sjimharris 141230557Sjimharris if (status == SCI_SUCCESS) 142230557Sjimharris { 143230557Sjimharris // These associations must be set early for the core io request 144230557Sjimharris // object construction to complete correctly as there will be 145230557Sjimharris // callbacks into the user driver framework during core construction 146230557Sjimharris sci_object_set_association(fw_io, user_io_request_object); 147230557Sjimharris sci_object_set_association(fw_io->parent.core_object, fw_io); 148230557Sjimharris 149230557Sjimharris // Perform protocol specific core IO request construction. 150230557Sjimharris if (dev_protocols.u.bits.attached_ssp_target) 151230557Sjimharris status = scic_io_request_construct_basic_ssp(fw_io->parent.core_object); 152230557Sjimharris else if (dev_protocols.u.bits.attached_stp_target) 153230557Sjimharris { 154230557Sjimharris if (is_initial_construction == TRUE) 155230557Sjimharris sati_sequence_construct(&fw_io->parent.stp.sequence); 156230557Sjimharris 157230557Sjimharris#if !defined(DISABLE_ATAPI) 158230557Sjimharris if (!scic_remote_device_is_atapi(fw_device->core_object)) 159230557Sjimharris { 160230557Sjimharris#endif 161230557Sjimharris status = scif_sas_stp_io_request_construct(fw_io); 162230557Sjimharris 163230557Sjimharris#if !defined(DISABLE_ATAPI) 164230557Sjimharris } 165230557Sjimharris else 166230557Sjimharris status = scif_sas_stp_packet_io_request_construct(fw_io); 167230557Sjimharris#endif 168230557Sjimharris } 169230557Sjimharris 170230557Sjimharris sci_base_state_machine_logger_initialize( 171230557Sjimharris &fw_io->parent.parent.state_machine_logger, 172230557Sjimharris &fw_io->parent.parent.state_machine, 173230557Sjimharris &fw_io->parent.parent.parent, 174230557Sjimharris scif_cb_logger_log_states, 175230557Sjimharris "SCIF_IO_REQUEST_T", "base_state_machine", 176230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST 177230557Sjimharris ); 178230557Sjimharris } 179230557Sjimharris 180230557Sjimharris return status; 181230557Sjimharris} 182230557Sjimharris 183230557Sjimharris//****************************************************************************** 184230557Sjimharris//* P U B L I C M E T H O D S 185230557Sjimharris//****************************************************************************** 186230557Sjimharris 187230557SjimharrisU32 scif_io_request_get_object_size( 188230557Sjimharris void 189230557Sjimharris) 190230557Sjimharris{ 191230557Sjimharris return (sizeof(SCIF_SAS_IO_REQUEST_T) + scic_io_request_get_object_size()); 192230557Sjimharris} 193230557Sjimharris 194230557Sjimharris// ---------------------------------------------------------------------------- 195230557SjimharrisU32 scif_io_request_get_number_of_bytes_transferred( 196230557Sjimharris SCI_IO_REQUEST_HANDLE_T scif_io_request 197230557Sjimharris) 198230557Sjimharris{ 199230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_request = (SCIF_SAS_IO_REQUEST_T*) scif_io_request; 200230557Sjimharris 201230557Sjimharris if(scic_io_request_get_protocol(scif_io_request_get_scic_handle(scif_io_request)) 202230557Sjimharris == SCIC_STP_PROTOCOL) 203230557Sjimharris { 204230557Sjimharris U16 sati_data_bytes_set = 205230557Sjimharris sati_get_number_data_bytes_set(&(fw_request->parent.stp.sequence)); 206230557Sjimharris 207230557Sjimharris if (sati_data_bytes_set != 0) 208230557Sjimharris return sati_data_bytes_set; 209230557Sjimharris else 210230557Sjimharris { 211230557Sjimharris#if !defined(DISABLE_ATAPI) 212230557Sjimharris U8 sat_protocol = fw_request->parent.stp.sequence.protocol; 213230557Sjimharris if ( sat_protocol & SAT_PROTOCOL_PACKET) 214230557Sjimharris return 215230557Sjimharris scif_sas_stp_packet_io_request_get_number_of_bytes_transferred(fw_request); 216230557Sjimharris else 217230557Sjimharris#endif 218230557Sjimharris return scic_io_request_get_number_of_bytes_transferred( 219230557Sjimharris scif_io_request_get_scic_handle(scif_io_request)); 220230557Sjimharris } 221230557Sjimharris } 222230557Sjimharris else 223230557Sjimharris { 224230557Sjimharris return scic_io_request_get_number_of_bytes_transferred( 225230557Sjimharris scif_io_request_get_scic_handle(scif_io_request)); 226230557Sjimharris } 227230557Sjimharris} 228230557Sjimharris 229230557Sjimharris// --------------------------------------------------------------------------- 230230557Sjimharris 231230557SjimharrisSCI_STATUS scif_io_request_construct( 232230557Sjimharris SCI_CONTROLLER_HANDLE_T scif_controller, 233230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T scif_remote_device, 234230557Sjimharris U16 io_tag, 235230557Sjimharris void * user_io_request_object, 236230557Sjimharris void * io_request_memory, 237230557Sjimharris SCI_IO_REQUEST_HANDLE_T * scif_io_request 238230557Sjimharris) 239230557Sjimharris{ 240230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 241230557Sjimharris io_request_memory; 242230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 243230557Sjimharris scif_remote_device; 244230557Sjimharris 245230557Sjimharris return scif_sas_io_request_construct( 246230557Sjimharris fw_device, 247230557Sjimharris fw_io, 248230557Sjimharris io_tag, 249230557Sjimharris user_io_request_object, 250230557Sjimharris scif_io_request, 251230557Sjimharris TRUE 252230557Sjimharris ); 253230557Sjimharris} 254230557Sjimharris 255230557Sjimharris// --------------------------------------------------------------------------- 256230557Sjimharris 257230557SjimharrisSCI_STATUS scif_request_construct( 258230557Sjimharris SCI_CONTROLLER_HANDLE_T scif_controller, 259230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T scif_remote_device, 260230557Sjimharris U16 io_tag, 261230557Sjimharris void * user_io_request_object, 262230557Sjimharris void * io_request_memory, 263230557Sjimharris SCI_IO_REQUEST_HANDLE_T * scif_io_request 264230557Sjimharris) 265230557Sjimharris{ 266230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 267230557Sjimharris io_request_memory; 268230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 269230557Sjimharris scif_remote_device; 270230557Sjimharris SCI_STATUS status; 271230557Sjimharris 272230557Sjimharris SCIF_LOG_TRACE(( 273230557Sjimharris sci_base_object_get_logger(fw_device), 274230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 275230557Sjimharris "scif_io_request_construct(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) enter\n", 276230557Sjimharris scif_controller, scif_remote_device, io_tag, user_io_request_object, 277230557Sjimharris io_request_memory, scif_io_request 278230557Sjimharris )); 279230557Sjimharris 280230557Sjimharris // Step 1: Create the scif io request. 281230557Sjimharris // Initialize the users handle to the framework IO request. 282230557Sjimharris *scif_io_request = fw_io; 283230557Sjimharris 284230557Sjimharris // Construct the parent object first in order to ensure logging can 285230557Sjimharris // function. 286230557Sjimharris scif_sas_request_construct( 287230557Sjimharris &fw_io->parent, 288230557Sjimharris fw_device, 289230557Sjimharris sci_base_object_get_logger(fw_device), 290230557Sjimharris scif_sas_io_request_state_table 291230557Sjimharris ); 292230557Sjimharris 293230557Sjimharris status = scic_io_request_construct( 294230557Sjimharris (void *) ((SCIF_SAS_CONTROLLER_T *)scif_controller)->core_object, 295230557Sjimharris (void *) fw_device->core_object, 296230557Sjimharris io_tag, 297230557Sjimharris fw_io, 298230557Sjimharris (U8 *)io_request_memory + sizeof(SCIF_SAS_IO_REQUEST_T), 299230557Sjimharris &fw_io->parent.core_object 300230557Sjimharris ); 301230557Sjimharris 302230557Sjimharris if (status == SCI_SUCCESS) 303230557Sjimharris { 304230557Sjimharris // These associations must be set early for the core io request 305230557Sjimharris // object construction to complete correctly as there will be 306230557Sjimharris // callbacks into the user driver framework during core construction 307230557Sjimharris sci_object_set_association(fw_io, user_io_request_object); 308230557Sjimharris sci_object_set_association(fw_io->parent.core_object, fw_io); 309230557Sjimharris 310230557Sjimharris sci_base_state_machine_logger_initialize( 311230557Sjimharris &fw_io->parent.parent.state_machine_logger, 312230557Sjimharris &fw_io->parent.parent.state_machine, 313230557Sjimharris &fw_io->parent.parent.parent, 314230557Sjimharris scif_cb_logger_log_states, 315230557Sjimharris "SCIF_IO_REQUEST_T", "base_state_machine", 316230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST 317230557Sjimharris ); 318230557Sjimharris } 319230557Sjimharris 320230557Sjimharris return status; 321230557Sjimharris} 322230557Sjimharris 323230557Sjimharris// ---------------------------------------------------------------------------- 324230557Sjimharris 325230557SjimharrisSCI_STATUS scif_io_request_construct_with_core ( 326230557Sjimharris SCI_CONTROLLER_HANDLE_T scif_controller, 327230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T scif_remote_device, 328230557Sjimharris void * scic_io_request, 329230557Sjimharris void * user_io_request_object, 330230557Sjimharris void * io_request_memory, 331230557Sjimharris SCI_IO_REQUEST_HANDLE_T * scif_io_request 332230557Sjimharris) 333230557Sjimharris{ 334230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 335230557Sjimharris io_request_memory; 336230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 337230557Sjimharris scif_remote_device; 338230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 339230557Sjimharris 340230557Sjimharris SCIF_LOG_TRACE(( 341230557Sjimharris sci_base_object_get_logger(fw_device), 342230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 343230557Sjimharris "scif_io_request_construct_pass_through(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 344230557Sjimharris scif_remote_device, user_io_request_object, 345230557Sjimharris io_request_memory, scif_io_request 346230557Sjimharris )); 347230557Sjimharris 348230557Sjimharris // Initialize the users handle to the framework IO request. 349230557Sjimharris *scif_io_request = fw_io; 350230557Sjimharris 351230557Sjimharris // Construct the parent object first in order to ensure logging can 352230557Sjimharris // function. 353230557Sjimharris scif_sas_request_construct( 354230557Sjimharris &fw_io->parent, 355230557Sjimharris fw_device, 356230557Sjimharris sci_base_object_get_logger(fw_device), 357230557Sjimharris scif_sas_io_request_state_table 358230557Sjimharris ); 359230557Sjimharris 360230557Sjimharris fw_io->parent.core_object = scic_io_request; 361230557Sjimharris 362230557Sjimharris //set association 363230557Sjimharris sci_object_set_association(fw_io, user_io_request_object); 364230557Sjimharris sci_object_set_association(fw_io->parent.core_object, fw_io); 365230557Sjimharris 366230557Sjimharris 367230557Sjimharris sci_base_state_machine_logger_initialize( 368230557Sjimharris &fw_io->parent.parent.state_machine_logger, 369230557Sjimharris &fw_io->parent.parent.state_machine, 370230557Sjimharris &fw_io->parent.parent.parent, 371230557Sjimharris scif_cb_logger_log_states, 372230557Sjimharris "SCIF_IO_REQUEST_T", "base_state_machine", 373230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST 374230557Sjimharris ); 375230557Sjimharris 376230557Sjimharris return status; 377230557Sjimharris} 378230557Sjimharris 379230557Sjimharris// --------------------------------------------------------------------------- 380230557Sjimharris 381230557Sjimharrisvoid * scif_io_request_get_response_iu_address( 382230557Sjimharris SCI_IO_REQUEST_HANDLE_T scif_io_request 383230557Sjimharris) 384230557Sjimharris{ 385230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*)scif_io_request; 386230557Sjimharris 387230557Sjimharris return (scic_io_request_get_response_iu_address(fw_io->parent.core_object )); 388230557Sjimharris} 389230557Sjimharris 390230557Sjimharris// --------------------------------------------------------------------------- 391230557Sjimharris 392230557SjimharrisSCI_IO_REQUEST_HANDLE_T scif_io_request_get_scic_handle( 393230557Sjimharris SCI_IO_REQUEST_HANDLE_T scif_io_request 394230557Sjimharris) 395230557Sjimharris{ 396230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) scif_io_request; 397230557Sjimharris return fw_io->parent.core_object; 398230557Sjimharris} 399230557Sjimharris 400230557Sjimharris// --------------------------------------------------------------------------- 401230557Sjimharris 402230557Sjimharrisvoid scic_cb_io_request_complete( 403230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 404230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device, 405230557Sjimharris SCI_IO_REQUEST_HANDLE_T io_request, 406230557Sjimharris SCI_IO_STATUS completion_status 407230557Sjimharris) 408230557Sjimharris{ 409230557Sjimharris SCI_STATUS status; 410230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) 411230557Sjimharris sci_object_get_association(controller); 412230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*) 413230557Sjimharris sci_object_get_association(remote_device); 414230557Sjimharris SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) 415230557Sjimharris sci_object_get_association(io_request); 416230557Sjimharris 417230557Sjimharris SCIF_LOG_TRACE(( 418230557Sjimharris sci_base_object_get_logger(controller), 419230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 420230557Sjimharris "scic_cb_io_request_complete(0x%x, 0x%x, 0x%x, 0x%x) enter\n", 421230557Sjimharris controller, remote_device, io_request, completion_status 422230557Sjimharris )); 423230557Sjimharris 424230557Sjimharris // Invoke the common completion handler routine. 425230557Sjimharris // A non-successful return indicates we are not in a correct state to 426230557Sjimharris // receive a completion notification for this request. 427230557Sjimharris status = fw_request->state_handlers->complete_handler(&fw_request->parent); 428230557Sjimharris 429230557Sjimharris // If the status indicates the completion handler was successful, then 430230557Sjimharris // allow protocol specific completion processing to occur. 431230557Sjimharris if (status == SCI_SUCCESS) 432230557Sjimharris { 433230557Sjimharris if (fw_request->protocol_complete_handler != NULL) 434230557Sjimharris { 435230557Sjimharris status = fw_request->protocol_complete_handler( 436230557Sjimharris fw_controller, fw_device, fw_request, (SCI_STATUS *)&completion_status 437230557Sjimharris ); 438230557Sjimharris } 439230557Sjimharris 440230557Sjimharris // If this isn't an internal framework IO request, then simply pass the 441230557Sjimharris // notification up to the SCIF user. 442230557Sjimharris if ( status == SCI_SUCCESS ) 443230557Sjimharris { 444230557Sjimharris if (fw_request->is_high_priority == FALSE) 445230557Sjimharris { 446230557Sjimharris if (fw_request->is_waiting_for_abort_task_set == FALSE) 447230557Sjimharris { 448230557Sjimharris scif_cb_io_request_complete( 449230557Sjimharris fw_controller, fw_device, fw_request, completion_status); 450230557Sjimharris } 451230557Sjimharris else 452230557Sjimharris { 453230557Sjimharris // do nothing - will complete the I/O when the abort task 454230557Sjimharris // set completes 455230557Sjimharris } 456230557Sjimharris } 457230557Sjimharris else 458230557Sjimharris scif_sas_controller_complete_high_priority_io( 459230557Sjimharris fw_controller, fw_device, fw_request); 460230557Sjimharris } 461230557Sjimharris else if ( status == SCI_WARNING_SEQUENCE_INCOMPLETE ) 462230557Sjimharris { 463230557Sjimharris scif_sas_io_request_continue(fw_controller, fw_device, fw_request); 464230557Sjimharris } 465230557Sjimharris } 466230557Sjimharris} 467230557Sjimharris 468230557Sjimharris// --------------------------------------------------------------------------- 469230557Sjimharris 470230557SjimharrisU32 scic_cb_io_request_get_transfer_length( 471230557Sjimharris void * scic_user_io_request 472230557Sjimharris) 473230557Sjimharris{ 474230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 475230557Sjimharris scic_user_io_request; 476230557Sjimharris 477230557Sjimharris return (scif_cb_io_request_get_transfer_length( 478230557Sjimharris fw_io->parent.parent.parent.associated_object 479230557Sjimharris )); 480230557Sjimharris} 481230557Sjimharris 482230557Sjimharris// --------------------------------------------------------------------------- 483230557Sjimharris 484230557SjimharrisSCI_IO_REQUEST_DATA_DIRECTION scic_cb_io_request_get_data_direction( 485230557Sjimharris void * scic_user_io_request 486230557Sjimharris) 487230557Sjimharris{ 488230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 489230557Sjimharris scic_user_io_request; 490230557Sjimharris 491230557Sjimharris return (scif_cb_io_request_get_data_direction( 492230557Sjimharris fw_io->parent.parent.parent.associated_object 493230557Sjimharris )); 494230557Sjimharris} 495230557Sjimharris 496230557Sjimharris// --------------------------------------------------------------------------- 497230557Sjimharris#ifndef SCI_SGL_OPTIMIZATION_ENABLED 498230557Sjimharrisvoid scic_cb_io_request_get_next_sge( 499230557Sjimharris void * scic_user_io_request, 500230557Sjimharris void * current_sge_address, 501230557Sjimharris void **next_sge 502230557Sjimharris) 503230557Sjimharris{ 504230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 505230557Sjimharris scic_user_io_request; 506230557Sjimharris 507230557Sjimharris scif_cb_io_request_get_next_sge( 508230557Sjimharris fw_io->parent.parent.parent.associated_object, 509230557Sjimharris current_sge_address, 510230557Sjimharris next_sge 511230557Sjimharris ); 512230557Sjimharris} 513230557Sjimharris#endif 514230557Sjimharris 515230557Sjimharris// --------------------------------------------------------------------------- 516230557Sjimharris 517230557SjimharrisSCI_PHYSICAL_ADDRESS scic_cb_sge_get_address_field( 518230557Sjimharris void * scic_user_io_request, 519230557Sjimharris void * sge_address 520230557Sjimharris) 521230557Sjimharris{ 522230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 523230557Sjimharris scic_user_io_request; 524230557Sjimharris return scif_cb_sge_get_address_field( 525230557Sjimharris fw_io->parent.parent.parent.associated_object, sge_address 526230557Sjimharris ); 527230557Sjimharris} 528230557Sjimharris 529230557Sjimharris// --------------------------------------------------------------------------- 530230557Sjimharris 531230557SjimharrisU32 scic_cb_sge_get_length_field( 532230557Sjimharris void * scic_user_io_request, 533230557Sjimharris void * sge_address 534230557Sjimharris) 535230557Sjimharris{ 536230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 537230557Sjimharris scic_user_io_request; 538230557Sjimharris 539230557Sjimharris return scif_cb_sge_get_length_field( 540230557Sjimharris fw_io->parent.parent.parent.associated_object, 541230557Sjimharris sge_address 542230557Sjimharris ); 543230557Sjimharris} 544230557Sjimharris 545230557Sjimharris// --------------------------------------------------------------------------- 546230557Sjimharris 547230557Sjimharrisvoid * scic_cb_ssp_io_request_get_cdb_address( 548230557Sjimharris void * scic_user_io_request 549230557Sjimharris) 550230557Sjimharris{ 551230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 552230557Sjimharris scic_user_io_request; 553230557Sjimharris 554230557Sjimharris return scif_cb_io_request_get_cdb_address( 555230557Sjimharris fw_io->parent.parent.parent.associated_object 556230557Sjimharris ); 557230557Sjimharris} 558230557Sjimharris 559230557Sjimharris// --------------------------------------------------------------------------- 560230557Sjimharris 561230557SjimharrisU32 scic_cb_ssp_io_request_get_cdb_length( 562230557Sjimharris void * scic_user_io_request 563230557Sjimharris) 564230557Sjimharris{ 565230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 566230557Sjimharris scic_user_io_request; 567230557Sjimharris 568230557Sjimharris return scif_cb_io_request_get_cdb_length( 569230557Sjimharris fw_io->parent.parent.parent.associated_object 570230557Sjimharris ); 571230557Sjimharris} 572230557Sjimharris 573230557Sjimharris// --------------------------------------------------------------------------- 574230557Sjimharris 575230557Sjimharris#if !defined(DISABLE_ATAPI) 576230557Sjimharrisvoid * scic_cb_stp_packet_io_request_get_cdb_address( 577230557Sjimharris void * scic_user_io_request 578230557Sjimharris) 579230557Sjimharris{ 580230557Sjimharris SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*)scic_user_io_request; 581230557Sjimharris 582230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sati_sequence = &fw_request->stp.sequence; 583230557Sjimharris 584230557Sjimharris if (sati_sequence->state != SATI_SEQUENCE_STATE_INCOMPLETE) 585230557Sjimharris return scif_cb_io_request_get_cdb_address( 586230557Sjimharris fw_request->parent.parent.associated_object 587230557Sjimharris ); 588230557Sjimharris else 589230557Sjimharris return 590230557Sjimharris &(sati_sequence->command_specific_data.sati_atapi_data.request_sense_cdb); 591230557Sjimharris} 592230557Sjimharris#endif 593230557Sjimharris 594230557Sjimharris// --------------------------------------------------------------------------- 595230557Sjimharris 596230557Sjimharris#if !defined(DISABLE_ATAPI) 597230557SjimharrisU32 scic_cb_stp_packet_io_request_get_cdb_length( 598230557Sjimharris void * scic_user_io_request 599230557Sjimharris) 600230557Sjimharris{ 601230557Sjimharris SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) 602230557Sjimharris scic_user_io_request; 603230557Sjimharris 604230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sati_sequence = &fw_request->stp.sequence; 605230557Sjimharris 606230557Sjimharris if (sati_sequence->state != SATI_SEQUENCE_STATE_INCOMPLETE) 607230557Sjimharris return scif_cb_io_request_get_cdb_length( 608230557Sjimharris fw_request->parent.parent.associated_object 609230557Sjimharris ); 610230557Sjimharris else 611230557Sjimharris return SATI_ATAPI_REQUEST_SENSE_CDB_LENGTH; 612230557Sjimharris} 613230557Sjimharris#endif 614230557Sjimharris 615230557Sjimharris// --------------------------------------------------------------------------- 616230557Sjimharris 617230557SjimharrisU32 scic_cb_ssp_io_request_get_lun( 618230557Sjimharris void * scic_user_io_request 619230557Sjimharris) 620230557Sjimharris{ 621230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 622230557Sjimharris scic_user_io_request; 623230557Sjimharris 624230557Sjimharris return scif_cb_io_request_get_lun( 625230557Sjimharris fw_io->parent.parent.parent.associated_object 626230557Sjimharris ); 627230557Sjimharris} 628230557Sjimharris 629230557Sjimharris// --------------------------------------------------------------------------- 630230557Sjimharris 631230557SjimharrisU32 scic_cb_ssp_io_request_get_task_attribute( 632230557Sjimharris void * scic_user_io_request 633230557Sjimharris) 634230557Sjimharris{ 635230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 636230557Sjimharris scic_user_io_request; 637230557Sjimharris 638230557Sjimharris return scif_cb_io_request_get_task_attribute( 639230557Sjimharris fw_io->parent.parent.parent.associated_object 640230557Sjimharris ); 641230557Sjimharris} 642230557Sjimharris 643230557Sjimharris// --------------------------------------------------------------------------- 644230557Sjimharris 645230557SjimharrisU32 scic_cb_ssp_io_request_get_command_priority( 646230557Sjimharris void * scic_user_io_request 647230557Sjimharris) 648230557Sjimharris{ 649230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*) 650230557Sjimharris scic_user_io_request; 651230557Sjimharris 652230557Sjimharris return scif_cb_io_request_get_command_priority( 653230557Sjimharris fw_io->parent.parent.parent.associated_object 654230557Sjimharris ); 655230557Sjimharris} 656230557Sjimharris 657230557Sjimharris// --------------------------------------------------------------------------- 658230557Sjimharris 659230557SjimharrisBOOL scic_cb_request_is_initial_construction( 660230557Sjimharris void * scic_user_io_request 661230557Sjimharris) 662230557Sjimharris{ 663230557Sjimharris SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) 664230557Sjimharris scic_user_io_request; 665230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T* fw_device = fw_request->device; 666230557Sjimharris 667230557Sjimharris SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols; 668230557Sjimharris scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols); 669230557Sjimharris 670230557Sjimharris if (dev_protocols.u.bits.attached_stp_target 671230557Sjimharris && fw_request->stp.sequence.state == SATI_SEQUENCE_STATE_INCOMPLETE) 672230557Sjimharris return FALSE; 673230557Sjimharris 674230557Sjimharris return TRUE; 675230557Sjimharris} 676230557Sjimharris 677230557Sjimharris 678230557Sjimharris//****************************************************************************** 679230557Sjimharris//* P R O T E C T E D M E T H O D S 680230557Sjimharris//****************************************************************************** 681230557Sjimharris/** 682230557Sjimharris * @brief This method constructs an scif sas smp request. 683230557Sjimharris * 684230557Sjimharris * @param[in] fw_controller The framework controller 685230557Sjimharris * @param[in] fw_device The smp device that the smp request targets to. 686230557Sjimharris * @param[in] fw_io_memory The memory space for the smp request. 687230557Sjimharris * @param[in] core_io_memory The memory space for the core request. 688230557Sjimharris * @param[in] io_tag The io tag for the internl io to be constructed. 689230557Sjimharris * @param[in] smp_command A pointer to the smp request data structure according 690230557Sjimharris * to SAS protocol. 691230557Sjimharris * 692230557Sjimharris * @return Indicate if the internal io was successfully constructed. 693230557Sjimharris * @retval SCI_SUCCESS This value is returned if the internal io was 694230557Sjimharris * successfully constructed. 695230557Sjimharris * @retval SCI_FAILURE This value is returned if the internal io was failed to 696230557Sjimharris * be constructed. 697230557Sjimharris */ 698230557SjimharrisSCI_STATUS scif_sas_io_request_construct_smp( 699230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller, 700230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device, 701230557Sjimharris void * fw_io_memory, 702230557Sjimharris void * core_io_memory, 703230557Sjimharris U16 io_tag, 704230557Sjimharris SMP_REQUEST_T * smp_command, 705230557Sjimharris void * user_request_object 706230557Sjimharris) 707230557Sjimharris{ 708230557Sjimharris SCIF_SAS_IO_REQUEST_T * fw_io = 709230557Sjimharris (SCIF_SAS_IO_REQUEST_T*)fw_io_memory; 710230557Sjimharris 711230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 712230557Sjimharris 713230557Sjimharris SCIF_LOG_TRACE(( 714230557Sjimharris sci_base_object_get_logger(fw_device), 715230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 716230557Sjimharris "scif_sas_io_request_construct_smp(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) enter\n", 717230557Sjimharris fw_controller, 718230557Sjimharris fw_device, 719230557Sjimharris fw_io_memory, 720230557Sjimharris core_io_memory, 721230557Sjimharris io_tag, 722230557Sjimharris smp_command, 723230557Sjimharris user_request_object 724230557Sjimharris )); 725230557Sjimharris 726230557Sjimharris // Construct the parent object first in order to ensure logging can 727230557Sjimharris // function. 728230557Sjimharris scif_sas_request_construct( 729230557Sjimharris &fw_io->parent, 730230557Sjimharris fw_device, 731230557Sjimharris sci_base_object_get_logger(fw_controller), 732230557Sjimharris scif_sas_io_request_state_table 733230557Sjimharris ); 734230557Sjimharris 735230557Sjimharris status = scic_io_request_construct( 736230557Sjimharris fw_device->domain->controller->core_object, 737230557Sjimharris fw_device->core_object, 738230557Sjimharris io_tag, 739230557Sjimharris (void*)fw_io, 740230557Sjimharris (U8 *)core_io_memory, 741230557Sjimharris &fw_io->parent.core_object 742230557Sjimharris ); 743230557Sjimharris 744230557Sjimharris if (status == SCI_SUCCESS) 745230557Sjimharris { 746230557Sjimharris //set object association. 747230557Sjimharris sci_object_set_association(fw_io, user_request_object); 748230557Sjimharris sci_object_set_association(fw_io->parent.core_object, fw_io); 749230557Sjimharris 750230557Sjimharris scif_sas_smp_request_construct(&fw_io->parent, smp_command); 751230557Sjimharris 752230557Sjimharris fw_io->parent.is_high_priority = TRUE; 753230557Sjimharris 754230557Sjimharris sci_base_state_machine_logger_initialize( 755230557Sjimharris &fw_io->parent.parent.state_machine_logger, 756230557Sjimharris &fw_io->parent.parent.state_machine, 757230557Sjimharris &fw_io->parent.parent.parent, 758230557Sjimharris scif_cb_logger_log_states, 759230557Sjimharris "SCIF_IO_REQUEST_T", "base_state_machine", 760230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST 761230557Sjimharris ); 762230557Sjimharris } 763230557Sjimharris 764230557Sjimharris return status; 765230557Sjimharris} 766230557Sjimharris 767230557Sjimharris 768230557Sjimharris/** 769230557Sjimharris * @brief This method continues a scif sas request. 770230557Sjimharris * 771230557Sjimharris * @param[in] fw_controller The framework controller 772230557Sjimharris * @param[in] fw_device The device that the IO request targets to. 773230557Sjimharris * @param[in] fw_request The IO request to be continued. 774230557Sjimharris * 775230557Sjimharris * @return Indicate if the internal io was successfully constructed. 776230557Sjimharris * @retval SCI_SUCCESS This value is returned if the internal io was 777230557Sjimharris * successfully continued. 778230557Sjimharris * @retval SCI_FAILURE This value is returned if the io was failed to 779230557Sjimharris * be continued. 780230557Sjimharris */ 781230557SjimharrisSCI_STATUS scif_sas_io_request_continue( 782230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller, 783230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device, 784230557Sjimharris SCIF_SAS_REQUEST_T * fw_request 785230557Sjimharris) 786230557Sjimharris{ 787230557Sjimharris SCI_IO_REQUEST_HANDLE_T dummy_handle; 788230557Sjimharris 789230557Sjimharris SCIF_LOG_TRACE(( 790230557Sjimharris sci_base_object_get_logger(fw_request), 791230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 792230557Sjimharris "scif_sas_io_request_continue(0x%x, 0x%x, 0x%x) enter\n", 793230557Sjimharris fw_controller, 794230557Sjimharris fw_device, 795230557Sjimharris fw_request 796230557Sjimharris )); 797230557Sjimharris 798230557Sjimharris //complete this io request in framework and core. 799230557Sjimharris scif_controller_complete_io(fw_controller, fw_device, fw_request); 800230557Sjimharris 801230557Sjimharris //construct next command in the sequence using the same memory. We pass 802230557Sjimharris //a dummy pointer to let the framework user keep the pointer to this IO 803230557Sjimharris //request untouched. 804230557Sjimharris scif_sas_io_request_construct( 805230557Sjimharris fw_device, 806230557Sjimharris (SCIF_SAS_IO_REQUEST_T*)fw_request, 807230557Sjimharris SCI_CONTROLLER_INVALID_IO_TAG, 808230557Sjimharris (void *)sci_object_get_association(fw_request), 809230557Sjimharris &dummy_handle, 810230557Sjimharris FALSE 811230557Sjimharris ); 812230557Sjimharris 813230557Sjimharris //start the new constructed IO. 814231296Sjimharris return (SCI_STATUS)scif_controller_start_io( 815230557Sjimharris (SCI_CONTROLLER_HANDLE_T) fw_controller, 816230557Sjimharris (SCI_REMOTE_DEVICE_HANDLE_T) fw_device, 817230557Sjimharris (SCI_IO_REQUEST_HANDLE_T) fw_request, 818230557Sjimharris SCI_CONTROLLER_INVALID_IO_TAG 819230557Sjimharris ); 820230557Sjimharris} 821