scic_sds_request.c revision 230557
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 implementation for the operations on an 60230557Sjimharris * SCIC_SDS_IO_REQUEST object. 61230557Sjimharris */ 62230557Sjimharris 63230557Sjimharris#include <dev/isci/scil/intel_sat.h> 64230557Sjimharris#include <dev/isci/scil/intel_sata.h> 65230557Sjimharris#include <dev/isci/scil/intel_sas.h> 66230557Sjimharris#include <dev/isci/scil/sci_util.h> 67230557Sjimharris#include <dev/isci/scil/sci_base_request.h> 68230557Sjimharris#include <dev/isci/scil/scic_controller.h> 69230557Sjimharris#include <dev/isci/scil/scic_io_request.h> 70230557Sjimharris#include <dev/isci/scil/scic_remote_device.h> 71230557Sjimharris#include <dev/isci/scil/scic_user_callback.h> 72230557Sjimharris#include <dev/isci/scil/scic_sds_logger.h> 73230557Sjimharris#include <dev/isci/scil/scic_sds_request.h> 74230557Sjimharris#include <dev/isci/scil/scic_sds_pci.h> 75230557Sjimharris#include <dev/isci/scil/scic_sds_stp_request.h> 76230557Sjimharris#include <dev/isci/scil/scic_sds_controller.h> 77230557Sjimharris#include <dev/isci/scil/scic_sds_controller_registers.h> 78230557Sjimharris#include <dev/isci/scil/scic_sds_remote_device.h> 79230557Sjimharris#include <dev/isci/scil/scic_sds_port.h> 80230557Sjimharris#include <dev/isci/scil/scic_task_request.h> 81230557Sjimharris#include <dev/isci/scil/scu_constants.h> 82230557Sjimharris#include <dev/isci/scil/scu_task_context.h> 83230557Sjimharris#include <dev/isci/scil/scic_sds_smp_request.h> 84230557Sjimharris#include <dev/isci/sci_environment.h> 85230557Sjimharris#include <dev/isci/scil/scic_sds_unsolicited_frame_control.h> 86230557Sjimharris#include <dev/isci/scil/sci_types.h> 87230557Sjimharris#include <dev/isci/scil/scu_completion_codes.h> 88230557Sjimharris#include <dev/isci/scil/intel_scsi.h> 89230557Sjimharris 90230557Sjimharris#if !defined(DISABLE_ATAPI) 91230557Sjimharris#include <dev/isci/scil/scic_sds_stp_packet_request.h> 92230557Sjimharris#endif 93230557Sjimharris 94230557Sjimharris/** 95230557Sjimharris* @struct SCI_SINGLE_LEVEL_LUN 96230557Sjimharris* 97230557Sjimharris* @brief this struct decribes the single level LUN structure 98230557Sjimharris* as per the SAM 4. 99230557Sjimharris*/ 100230557Sjimharristypedef struct SCI_SINGLE_LEVEL_LUN 101230557Sjimharris{ 102230557Sjimharris U8 bus_id : 6; 103230557Sjimharris U8 address_method : 2; 104230557Sjimharris U8 lun_number; 105230557Sjimharris U8 second_level_lun[2]; 106230557Sjimharris U8 third_level_lun[2]; 107230557Sjimharris U8 forth_level_lun[2]; 108230557Sjimharris 109230557Sjimharris} SCI_SINGLE_LEVEL_LUN_T; 110230557Sjimharris 111230557Sjimharris 112230557Sjimharris//**************************************************************************** 113230557Sjimharris//* SCIC SDS IO REQUEST CONSTANTS 114230557Sjimharris//**************************************************************************** 115230557Sjimharris 116230557Sjimharris/** 117230557Sjimharris * We have no timer requirements for IO requests right now 118230557Sjimharris */ 119230557Sjimharris#define SCIC_SDS_IO_REQUEST_MINIMUM_TIMER_COUNT (0) 120230557Sjimharris#define SCIC_SDS_IO_REQUEST_MAXIMUM_TIMER_COUNT (0) 121230557Sjimharris 122230557Sjimharris//**************************************************************************** 123230557Sjimharris//* SCIC SDS IO REQUEST MACROS 124230557Sjimharris//**************************************************************************** 125230557Sjimharris 126230557Sjimharris/** 127230557Sjimharris * This is a helper macro to return the os handle for this request object. 128230557Sjimharris */ 129230557Sjimharris#define scic_sds_request_get_user_request(request) \ 130230557Sjimharris ((request)->user_request) 131230557Sjimharris 132230557Sjimharris 133230557Sjimharris/** 134230557Sjimharris * This macro returns the sizeof memory required to store the an SSP IO 135230557Sjimharris * request. This does not include the size of the SGL or SCU Task Context 136230557Sjimharris * memory.The sizeof(U32) are needed for DWORD alignment of the command IU 137230557Sjimharris * and response IU 138230557Sjimharris */ 139230557Sjimharris#define scic_ssp_io_request_get_object_size() \ 140230557Sjimharris ( \ 141230557Sjimharris sizeof(SCI_SSP_COMMAND_IU_T) \ 142230557Sjimharris + sizeof (U32) \ 143230557Sjimharris + sizeof(SCI_SSP_RESPONSE_IU_T) \ 144230557Sjimharris + sizeof (U32) \ 145230557Sjimharris ) 146230557Sjimharris 147230557Sjimharris/** 148230557Sjimharris * This macro returns the address of the ssp command buffer in the io 149230557Sjimharris * request memory 150230557Sjimharris */ 151230557Sjimharris#define scic_sds_ssp_request_get_command_buffer_unaligned(memory) \ 152230557Sjimharris ((SCI_SSP_COMMAND_IU_T *)( \ 153230557Sjimharris ((char *)(memory)) + sizeof(SCIC_SDS_REQUEST_T) \ 154230557Sjimharris )) 155230557Sjimharris 156230557Sjimharris/** 157230557Sjimharris * This macro aligns the ssp command buffer in DWORD alignment 158230557Sjimharris*/ 159230557Sjimharris#define scic_sds_ssp_request_align_command_buffer(address) \ 160230557Sjimharris ((SCI_SSP_COMMAND_IU_T *)( \ 161230557Sjimharris (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \ 162230557Sjimharris & ~(sizeof(U32)- 1) \ 163230557Sjimharris )) 164230557Sjimharris 165230557Sjimharris/** 166230557Sjimharris * This macro returns the DWORD-aligned ssp command buffer 167230557Sjimharris*/ 168230557Sjimharris#define scic_sds_ssp_request_get_command_buffer(memory) \ 169230557Sjimharris ((SCI_SSP_COMMAND_IU_T *) \ 170230557Sjimharris ((char *)scic_sds_ssp_request_align_command_buffer( \ 171230557Sjimharris (char *) scic_sds_ssp_request_get_command_buffer_unaligned(memory) \ 172230557Sjimharris ))) 173230557Sjimharris 174230557Sjimharris/** 175230557Sjimharris * This macro returns the address of the ssp response buffer in the io 176230557Sjimharris * request memory 177230557Sjimharris */ 178230557Sjimharris#define scic_sds_ssp_request_get_response_buffer_unaligned(memory) \ 179230557Sjimharris ((SCI_SSP_RESPONSE_IU_T *)( \ 180230557Sjimharris ((char *)(scic_sds_ssp_request_get_command_buffer(memory))) \ 181230557Sjimharris + sizeof(SCI_SSP_COMMAND_IU_T) \ 182230557Sjimharris )) 183230557Sjimharris 184230557Sjimharris/** 185230557Sjimharris * This macro aligns the ssp response buffer in DWORD-aligned fashion 186230557Sjimharris */ 187230557Sjimharris#define scic_sds_ssp_request_align_response_buffer(memory) \ 188230557Sjimharris ((SCI_SSP_RESPONSE_IU_T *)( \ 189230557Sjimharris (((POINTER_UINT)(memory)) + (sizeof(U32) - 1)) \ 190230557Sjimharris & ~(sizeof(U32)- 1) \ 191230557Sjimharris )) 192230557Sjimharris 193230557Sjimharris/** 194230557Sjimharris * This macro returns the DWORD-aligned ssp response buffer 195230557Sjimharris*/ 196230557Sjimharris#define scic_sds_ssp_request_get_response_buffer(memory) \ 197230557Sjimharris ((SCI_SSP_RESPONSE_IU_T *) \ 198230557Sjimharris ((char *)scic_sds_ssp_request_align_response_buffer ( \ 199230557Sjimharris (char *)scic_sds_ssp_request_get_response_buffer_unaligned(memory) \ 200230557Sjimharris ))) 201230557Sjimharris 202230557Sjimharris/** 203230557Sjimharris * This macro returns the address of the task context buffer in the io 204230557Sjimharris * request memory 205230557Sjimharris */ 206230557Sjimharris#define scic_sds_ssp_request_get_task_context_buffer_unaligned(memory) \ 207230557Sjimharris ((SCU_TASK_CONTEXT_T *)( \ 208230557Sjimharris ((char *)(scic_sds_ssp_request_get_response_buffer(memory))) \ 209230557Sjimharris + sizeof(SCI_SSP_RESPONSE_IU_T) \ 210230557Sjimharris )) 211230557Sjimharris 212230557Sjimharris/** 213230557Sjimharris * This macro returns the aligned task context buffer 214230557Sjimharris */ 215230557Sjimharris#define scic_sds_ssp_request_get_task_context_buffer(memory) \ 216230557Sjimharris ((SCU_TASK_CONTEXT_T *)( \ 217230557Sjimharris ((char *)scic_sds_request_align_task_context_buffer( \ 218230557Sjimharris (char *)scic_sds_ssp_request_get_task_context_buffer_unaligned(memory)) \ 219230557Sjimharris ))) 220230557Sjimharris 221230557Sjimharris/** 222230557Sjimharris * This macro returns the address of the sgl elment pairs in the io request 223230557Sjimharris * memory buffer 224230557Sjimharris */ 225230557Sjimharris#define scic_sds_ssp_request_get_sgl_element_buffer(memory) \ 226230557Sjimharris ((SCU_SGL_ELEMENT_PAIR_T *)( \ 227230557Sjimharris ((char *)(scic_sds_ssp_request_get_task_context_buffer(memory))) \ 228230557Sjimharris + sizeof(SCU_TASK_CONTEXT_T) \ 229230557Sjimharris )) 230230557Sjimharris 231230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT) 232230557Sjimharris 233230557Sjimharris/** 234230557Sjimharris * This macro returns the sizeof of memory required to store an SSP Task 235230557Sjimharris * request. This does not include the size of the SCU Task Context memory. 236230557Sjimharris */ 237230557Sjimharris#define scic_ssp_task_request_get_object_size() \ 238230557Sjimharris ( \ 239230557Sjimharris sizeof(SCI_SSP_TASK_IU_T) \ 240230557Sjimharris + sizeof(SCI_SSP_RESPONSE_IU_T) \ 241230557Sjimharris ) 242230557Sjimharris 243230557Sjimharris/** 244230557Sjimharris * This macro returns the address of the ssp command buffer in the task 245230557Sjimharris * request memory. Yes its the same as the above macro except for the 246230557Sjimharris * name. 247230557Sjimharris */ 248230557Sjimharris#define scic_sds_ssp_task_request_get_command_buffer(memory) \ 249230557Sjimharris ((SCI_SSP_TASK_IU_T *)( \ 250230557Sjimharris ((char *)(memory)) + sizeof(SCIC_SDS_REQUEST_T) \ 251230557Sjimharris )) 252230557Sjimharris 253230557Sjimharris/** 254230557Sjimharris * This macro returns the address of the ssp response buffer in the task 255230557Sjimharris * request memory. 256230557Sjimharris */ 257230557Sjimharris#define scic_sds_ssp_task_request_get_response_buffer(memory) \ 258230557Sjimharris ((SCI_SSP_RESPONSE_IU_T *)( \ 259230557Sjimharris ((char *)(scic_sds_ssp_task_request_get_command_buffer(memory))) \ 260230557Sjimharris + sizeof(SCI_SSP_TASK_IU_T) \ 261230557Sjimharris )) 262230557Sjimharris 263230557Sjimharris/** 264230557Sjimharris * This macro returs the task context buffer for the SSP task request. 265230557Sjimharris */ 266230557Sjimharris#define scic_sds_ssp_task_request_get_task_context_buffer(memory) \ 267230557Sjimharris ((SCU_TASK_CONTEXT_T *)( \ 268230557Sjimharris ((char *)(scic_sds_ssp_task_request_get_response_buffer(memory))) \ 269230557Sjimharris + sizeof(SCI_SSP_RESPONSE_IU_T) \ 270230557Sjimharris )) 271230557Sjimharris 272230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT) 273230557Sjimharris 274230557Sjimharris 275230557Sjimharris//**************************************************************************** 276230557Sjimharris//* SCIC SDS IO REQUEST PRIVATE METHODS 277230557Sjimharris//**************************************************************************** 278230557Sjimharris 279230557Sjimharris#ifdef SCI_LOGGING 280230557Sjimharris/** 281230557Sjimharris * This method will initialize state transition logging for the task request 282230557Sjimharris * object. 283230557Sjimharris * 284230557Sjimharris * @param[in] this_request This is the request for which to track state 285230557Sjimharris * transitions. 286230557Sjimharris */ 287230557Sjimharrisvoid scic_sds_request_initialize_state_logging( 288230557Sjimharris SCIC_SDS_REQUEST_T *this_request 289230557Sjimharris) 290230557Sjimharris{ 291230557Sjimharris sci_base_state_machine_logger_initialize( 292230557Sjimharris &this_request->parent.state_machine_logger, 293230557Sjimharris &this_request->parent.state_machine, 294230557Sjimharris &this_request->parent.parent, 295230557Sjimharris scic_cb_logger_log_states, 296230557Sjimharris this_request->is_task_management_request ? 297230557Sjimharris "SCIC_SDS_IO_REQUEST_T(Task)" : "SCIC_SDS_IO_REQUEST_T(IO)", 298230557Sjimharris "base state machine", 299230557Sjimharris SCIC_LOG_OBJECT_SMP_IO_REQUEST | 300230557Sjimharris SCIC_LOG_OBJECT_STP_IO_REQUEST | 301230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST 302230557Sjimharris ); 303230557Sjimharris 304230557Sjimharris if (this_request->has_started_substate_machine) 305230557Sjimharris { 306230557Sjimharris sci_base_state_machine_logger_initialize( 307230557Sjimharris &this_request->started_substate_machine_logger, 308230557Sjimharris &this_request->started_substate_machine, 309230557Sjimharris &this_request->parent.parent, 310230557Sjimharris scic_cb_logger_log_states, 311230557Sjimharris "SCIC_SDS_IO_REQUEST_T(Task)", "starting substate machine", 312230557Sjimharris SCIC_LOG_OBJECT_SMP_IO_REQUEST | 313230557Sjimharris SCIC_LOG_OBJECT_STP_IO_REQUEST | 314230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST 315230557Sjimharris ); 316230557Sjimharris } 317230557Sjimharris} 318230557Sjimharris 319230557Sjimharris/** 320230557Sjimharris * This method will stop the state transition logging for the task request 321230557Sjimharris * object. 322230557Sjimharris * 323230557Sjimharris * @param[in] this_request The task request object on which to stop state 324230557Sjimharris * transition logging. 325230557Sjimharris */ 326230557Sjimharrisvoid scic_sds_request_deinitialize_state_logging( 327230557Sjimharris SCIC_SDS_REQUEST_T *this_request 328230557Sjimharris) 329230557Sjimharris{ 330230557Sjimharris sci_base_state_machine_logger_deinitialize( 331230557Sjimharris &this_request->parent.state_machine_logger, 332230557Sjimharris &this_request->parent.state_machine 333230557Sjimharris ); 334230557Sjimharris 335230557Sjimharris if (this_request->has_started_substate_machine) 336230557Sjimharris { 337230557Sjimharris sci_base_state_machine_logger_deinitialize( 338230557Sjimharris &this_request->started_substate_machine_logger, 339230557Sjimharris &this_request->started_substate_machine 340230557Sjimharris ); 341230557Sjimharris } 342230557Sjimharris} 343230557Sjimharris#endif // SCI_LOGGING 344230557Sjimharris 345230557Sjimharris/** 346230557Sjimharris * This method returns the size required to store an SSP IO request object. 347230557Sjimharris * 348230557Sjimharris * @return U32 349230557Sjimharris */ 350230557Sjimharrisstatic 351230557SjimharrisU32 scic_sds_ssp_request_get_object_size(void) 352230557Sjimharris{ 353230557Sjimharris return sizeof(SCIC_SDS_REQUEST_T) 354230557Sjimharris + scic_ssp_io_request_get_object_size() 355230557Sjimharris + sizeof(SCU_TASK_CONTEXT_T) 356230557Sjimharris + CACHE_LINE_SIZE 357230557Sjimharris + sizeof(SCU_SGL_ELEMENT_PAIR_T) * SCU_MAX_SGL_ELEMENT_PAIRS; 358230557Sjimharris} 359230557Sjimharris 360230557Sjimharris/** 361230557Sjimharris * @brief This method returns the sgl element pair for the specificed 362230557Sjimharris * sgl_pair index. 363230557Sjimharris * 364230557Sjimharris * @param[in] this_request This parameter specifies the IO request for which 365230557Sjimharris * to retrieve the Scatter-Gather List element pair. 366230557Sjimharris * @param[in] sgl_pair_index This parameter specifies the index into the SGL 367230557Sjimharris * element pair to be retrieved. 368230557Sjimharris * 369230557Sjimharris * @return This method returns a pointer to an SCU_SGL_ELEMENT_PAIR. 370230557Sjimharris */ 371230557SjimharrisSCU_SGL_ELEMENT_PAIR_T *scic_sds_request_get_sgl_element_pair( 372230557Sjimharris SCIC_SDS_REQUEST_T *this_request, 373230557Sjimharris U32 sgl_pair_index 374230557Sjimharris) 375230557Sjimharris{ 376230557Sjimharris SCU_TASK_CONTEXT_T *task_context; 377230557Sjimharris 378230557Sjimharris task_context = (SCU_TASK_CONTEXT_T *)this_request->task_context_buffer; 379230557Sjimharris 380230557Sjimharris if (sgl_pair_index == 0) 381230557Sjimharris { 382230557Sjimharris return &task_context->sgl_pair_ab; 383230557Sjimharris } 384230557Sjimharris else if (sgl_pair_index == 1) 385230557Sjimharris { 386230557Sjimharris return &task_context->sgl_pair_cd; 387230557Sjimharris } 388230557Sjimharris 389230557Sjimharris return &this_request->sgl_element_pair_buffer[sgl_pair_index - 2]; 390230557Sjimharris} 391230557Sjimharris 392230557Sjimharris/** 393230557Sjimharris * @brief This function will build the SGL list for an IO request. 394230557Sjimharris * 395230557Sjimharris * @param[in] this_request This parameter specifies the IO request for which 396230557Sjimharris * to build the Scatter-Gather List. 397230557Sjimharris * 398230557Sjimharris * @return none 399230557Sjimharris */ 400230557Sjimharrisvoid scic_sds_request_build_sgl( 401230557Sjimharris SCIC_SDS_REQUEST_T *this_request 402230557Sjimharris) 403230557Sjimharris{ 404230557Sjimharris void *os_sge; 405230557Sjimharris void *os_handle; 406230557Sjimharris SCI_PHYSICAL_ADDRESS physical_address; 407230557Sjimharris U32 sgl_pair_index = 0; 408230557Sjimharris SCU_SGL_ELEMENT_PAIR_T *scu_sgl_list = NULL; 409230557Sjimharris SCU_SGL_ELEMENT_PAIR_T *previous_pair = NULL; 410230557Sjimharris 411230557Sjimharris os_handle = scic_sds_request_get_user_request(this_request); 412230557Sjimharris scic_cb_io_request_get_next_sge(os_handle, NULL, &os_sge); 413230557Sjimharris 414230557Sjimharris while (os_sge != NULL) 415230557Sjimharris { 416230557Sjimharris scu_sgl_list = 417230557Sjimharris scic_sds_request_get_sgl_element_pair(this_request, sgl_pair_index); 418230557Sjimharris 419230557Sjimharris SCU_SGL_COPY(os_handle, scu_sgl_list->A, os_sge); 420230557Sjimharris 421230557Sjimharris scic_cb_io_request_get_next_sge(os_handle, os_sge, &os_sge); 422230557Sjimharris 423230557Sjimharris if (os_sge != NULL) 424230557Sjimharris { 425230557Sjimharris SCU_SGL_COPY(os_handle, scu_sgl_list->B, os_sge); 426230557Sjimharris 427230557Sjimharris scic_cb_io_request_get_next_sge(os_handle, os_sge, &os_sge); 428230557Sjimharris } 429230557Sjimharris else 430230557Sjimharris { 431230557Sjimharris SCU_SGL_ZERO(scu_sgl_list->B); 432230557Sjimharris } 433230557Sjimharris 434230557Sjimharris if (previous_pair != NULL) 435230557Sjimharris { 436230557Sjimharris scic_cb_io_request_get_physical_address( 437230557Sjimharris scic_sds_request_get_controller(this_request), 438230557Sjimharris this_request, 439230557Sjimharris scu_sgl_list, 440230557Sjimharris &physical_address 441230557Sjimharris ); 442230557Sjimharris 443230557Sjimharris previous_pair->next_pair_upper = 444230557Sjimharris sci_cb_physical_address_upper(physical_address); 445230557Sjimharris previous_pair->next_pair_lower = 446230557Sjimharris sci_cb_physical_address_lower(physical_address); 447230557Sjimharris } 448230557Sjimharris 449230557Sjimharris previous_pair = scu_sgl_list; 450230557Sjimharris sgl_pair_index++; 451230557Sjimharris } 452230557Sjimharris 453230557Sjimharris if (scu_sgl_list != NULL) 454230557Sjimharris { 455230557Sjimharris scu_sgl_list->next_pair_upper = 0; 456230557Sjimharris scu_sgl_list->next_pair_lower = 0; 457230557Sjimharris } 458230557Sjimharris} 459230557Sjimharris 460230557Sjimharris/** 461230557Sjimharris * @brief This method initializes common portions of the io request object. 462230557Sjimharris * This includes construction of the SCI_BASE_REQUEST_T parent. 463230557Sjimharris * 464230557Sjimharris * @param[in] the_controller This parameter specifies the controller for which 465230557Sjimharris * the request is being constructed. 466230557Sjimharris * @param[in] the_target This parameter specifies the remote device for which 467230557Sjimharris * the request is being constructed. 468230557Sjimharris * @param[in] io_tag This parameter specifies the IO tag to be utilized for 469230557Sjimharris * this request. This parameter can be set to 470230557Sjimharris * SCI_CONTROLLER_INVALID_IO_TAG. 471230557Sjimharris * @param[in] user_io_request_object This parameter specifies the user 472230557Sjimharris * request object for which the request is being constructed. 473230557Sjimharris * @param[in] this_request This parameter specifies the request being 474230557Sjimharris * constructed. 475230557Sjimharris * 476230557Sjimharris * @return none 477230557Sjimharris */ 478230557Sjimharrisstatic 479230557Sjimharrisvoid scic_sds_general_request_construct( 480230557Sjimharris SCIC_SDS_CONTROLLER_T * the_controller, 481230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T * the_target, 482230557Sjimharris U16 io_tag, 483230557Sjimharris void * user_io_request_object, 484230557Sjimharris SCIC_SDS_REQUEST_T * this_request 485230557Sjimharris) 486230557Sjimharris{ 487230557Sjimharris sci_base_request_construct( 488230557Sjimharris &this_request->parent, 489230557Sjimharris sci_base_object_get_logger(the_controller), 490230557Sjimharris scic_sds_request_state_table 491230557Sjimharris ); 492230557Sjimharris 493230557Sjimharris this_request->io_tag = io_tag; 494230557Sjimharris this_request->user_request = user_io_request_object; 495230557Sjimharris this_request->owning_controller = the_controller; 496230557Sjimharris this_request->target_device = the_target; 497230557Sjimharris this_request->has_started_substate_machine = FALSE; 498230557Sjimharris this_request->protocol = SCIC_NO_PROTOCOL; 499230557Sjimharris this_request->sat_protocol = 0xFF; 500230557Sjimharris this_request->saved_rx_frame_index = SCU_INVALID_FRAME_INDEX; 501230557Sjimharris this_request->device_sequence = scic_sds_remote_device_get_sequence(the_target); 502230557Sjimharris 503230557Sjimharris this_request->sci_status = SCI_SUCCESS; 504230557Sjimharris this_request->scu_status = 0; 505230557Sjimharris this_request->post_context = 0xFFFFFFFF; 506230557Sjimharris 507230557Sjimharris this_request->is_task_management_request = FALSE; 508230557Sjimharris 509230557Sjimharris if (io_tag == SCI_CONTROLLER_INVALID_IO_TAG) 510230557Sjimharris { 511230557Sjimharris this_request->was_tag_assigned_by_user = FALSE; 512230557Sjimharris this_request->task_context_buffer = NULL; 513230557Sjimharris } 514230557Sjimharris else 515230557Sjimharris { 516230557Sjimharris this_request->was_tag_assigned_by_user = TRUE; 517230557Sjimharris 518230557Sjimharris this_request->task_context_buffer = 519230557Sjimharris scic_sds_controller_get_task_context_buffer( 520230557Sjimharris this_request->owning_controller, io_tag); 521230557Sjimharris } 522230557Sjimharris} 523230557Sjimharris 524230557Sjimharris/** 525230557Sjimharris * @brief This method build the remainder of the IO request object. 526230557Sjimharris * 527230557Sjimharris * @pre The scic_sds_general_request_construct() must be called before this 528230557Sjimharris * call is valid. 529230557Sjimharris * 530230557Sjimharris * @param[in] this_request This parameter specifies the request object being 531230557Sjimharris * constructed. 532230557Sjimharris * 533230557Sjimharris * @return none 534230557Sjimharris */ 535230557Sjimharrisvoid scic_sds_ssp_io_request_assign_buffers( 536230557Sjimharris SCIC_SDS_REQUEST_T *this_request 537230557Sjimharris) 538230557Sjimharris{ 539230557Sjimharris this_request->command_buffer = 540230557Sjimharris scic_sds_ssp_request_get_command_buffer(this_request); 541230557Sjimharris this_request->response_buffer = 542230557Sjimharris scic_sds_ssp_request_get_response_buffer(this_request); 543230557Sjimharris this_request->sgl_element_pair_buffer = 544230557Sjimharris scic_sds_ssp_request_get_sgl_element_buffer(this_request); 545230557Sjimharris this_request->sgl_element_pair_buffer = 546230557Sjimharris scic_sds_request_align_sgl_element_buffer(this_request->sgl_element_pair_buffer); 547230557Sjimharris 548230557Sjimharris if (this_request->was_tag_assigned_by_user == FALSE) 549230557Sjimharris { 550230557Sjimharris this_request->task_context_buffer = 551230557Sjimharris scic_sds_ssp_request_get_task_context_buffer(this_request); 552230557Sjimharris } 553230557Sjimharris} 554230557Sjimharris 555230557Sjimharris/** 556230557Sjimharris * @brief This method constructs the SSP Command IU data for this io 557230557Sjimharris * request object. 558230557Sjimharris * 559230557Sjimharris * @param[in] this_request This parameter specifies the request object for 560230557Sjimharris * which the SSP command information unit is being built. 561230557Sjimharris * 562230557Sjimharris * @return none 563230557Sjimharris */ 564230557Sjimharrisstatic 565230557Sjimharrisvoid scic_sds_io_request_build_ssp_command_iu( 566230557Sjimharris SCIC_SDS_REQUEST_T *this_request 567230557Sjimharris) 568230557Sjimharris{ 569230557Sjimharris SCI_SINGLE_LEVEL_LUN_T lun; 570230557Sjimharris SCI_SSP_COMMAND_IU_T *command_frame; 571230557Sjimharris void *os_handle; 572230557Sjimharris U32 cdb_length; 573230557Sjimharris U32 *cdb_buffer; 574230557Sjimharris 575230557Sjimharris command_frame = 576230557Sjimharris (SCI_SSP_COMMAND_IU_T *)this_request->command_buffer; 577230557Sjimharris 578230557Sjimharris os_handle = scic_sds_request_get_user_request(this_request); 579230557Sjimharris 580230557Sjimharris ((U32 *)&lun)[0] = 0; 581230557Sjimharris ((U32 *)&lun)[1] = 0; 582230557Sjimharris lun.lun_number = scic_cb_ssp_io_request_get_lun(os_handle) &0xff; 583230557Sjimharris /// @todo Is it ok to leave junk at the end of the cdb buffer? 584230557Sjimharris scic_word_copy_with_swap( 585230557Sjimharris (U32 *)command_frame->lun, 586230557Sjimharris (U32 *)&lun, 587230557Sjimharris sizeof(lun)); 588230557Sjimharris 589230557Sjimharris ((U32 *)command_frame)[2] = 0; 590230557Sjimharris 591230557Sjimharris cdb_length = scic_cb_ssp_io_request_get_cdb_length(os_handle); 592230557Sjimharris cdb_buffer = (U32 *)scic_cb_ssp_io_request_get_cdb_address(os_handle); 593230557Sjimharris 594230557Sjimharris if (cdb_length > 16) 595230557Sjimharris { 596230557Sjimharris command_frame->additional_cdb_length = cdb_length - 16; 597230557Sjimharris } 598230557Sjimharris 599230557Sjimharris /// @todo Is it ok to leave junk at the end of the cdb buffer? 600230557Sjimharris scic_word_copy_with_swap( 601230557Sjimharris (U32 *)(&command_frame->cdb), 602230557Sjimharris (U32 *)(cdb_buffer), 603230557Sjimharris (cdb_length + 3) / sizeof(U32) 604230557Sjimharris ); 605230557Sjimharris 606230557Sjimharris command_frame->enable_first_burst = 0; 607230557Sjimharris command_frame->task_priority = 608230557Sjimharris scic_cb_ssp_io_request_get_command_priority(os_handle); 609230557Sjimharris command_frame->task_attribute = 610230557Sjimharris scic_cb_ssp_io_request_get_task_attribute(os_handle); 611230557Sjimharris} 612230557Sjimharris 613230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT) 614230557Sjimharris 615230557Sjimharris/** 616230557Sjimharris * @brief This method constructs the SSP Task IU data for this io request 617230557Sjimharris * object. 618230557Sjimharris * 619230557Sjimharris * @param[in] this_request 620230557Sjimharris * 621230557Sjimharris * @return none 622230557Sjimharris */ 623230557Sjimharrisstatic 624230557Sjimharrisvoid scic_sds_task_request_build_ssp_task_iu( 625230557Sjimharris SCIC_SDS_REQUEST_T *this_request 626230557Sjimharris) 627230557Sjimharris{ 628230557Sjimharris SCI_SSP_TASK_IU_T *command_frame; 629230557Sjimharris void *os_handle; 630230557Sjimharris 631230557Sjimharris command_frame = 632230557Sjimharris (SCI_SSP_TASK_IU_T *)this_request->command_buffer; 633230557Sjimharris 634230557Sjimharris os_handle = scic_sds_request_get_user_request(this_request); 635230557Sjimharris 636230557Sjimharris command_frame->lun_upper = 0; 637230557Sjimharris command_frame->lun_lower = scic_cb_ssp_task_request_get_lun(os_handle); 638230557Sjimharris 639230557Sjimharris ((U32 *)command_frame)[2] = 0; 640230557Sjimharris 641230557Sjimharris command_frame->task_function = 642230557Sjimharris scic_cb_ssp_task_request_get_function(os_handle); 643230557Sjimharris command_frame->task_tag = 644230557Sjimharris scic_cb_ssp_task_request_get_io_tag_to_manage(os_handle); 645230557Sjimharris} 646230557Sjimharris 647230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT) 648230557Sjimharris 649230557Sjimharris/** 650230557Sjimharris * @brief This method is will fill in the SCU Task Context for any type of 651230557Sjimharris * SSP request. 652230557Sjimharris * 653230557Sjimharris * @param[in] this_request 654230557Sjimharris * @param[in] task_context 655230557Sjimharris * 656230557Sjimharris * @return none 657230557Sjimharris */ 658230557Sjimharrisstatic 659230557Sjimharrisvoid scu_ssp_reqeust_construct_task_context( 660230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 661230557Sjimharris SCU_TASK_CONTEXT_T * task_context 662230557Sjimharris) 663230557Sjimharris{ 664230557Sjimharris SCI_PHYSICAL_ADDRESS physical_address; 665230557Sjimharris SCIC_SDS_CONTROLLER_T *owning_controller; 666230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T *target_device; 667230557Sjimharris SCIC_SDS_PORT_T *target_port; 668230557Sjimharris 669230557Sjimharris owning_controller = scic_sds_request_get_controller(this_request); 670230557Sjimharris target_device = scic_sds_request_get_device(this_request); 671230557Sjimharris target_port = scic_sds_request_get_port(this_request); 672230557Sjimharris 673230557Sjimharris // Fill in the TC with the its required data 674230557Sjimharris task_context->abort = 0; 675230557Sjimharris task_context->priority = 0; 676230557Sjimharris task_context->initiator_request = 1; 677230557Sjimharris task_context->connection_rate = 678230557Sjimharris scic_remote_device_get_connection_rate(target_device); 679230557Sjimharris task_context->protocol_engine_index = 680230557Sjimharris scic_sds_controller_get_protocol_engine_group(owning_controller); 681230557Sjimharris task_context->logical_port_index = 682230557Sjimharris scic_sds_port_get_index(target_port); 683230557Sjimharris task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP; 684230557Sjimharris task_context->valid = SCU_TASK_CONTEXT_VALID; 685230557Sjimharris task_context->context_type = SCU_TASK_CONTEXT_TYPE; 686230557Sjimharris 687230557Sjimharris task_context->remote_node_index = 688230557Sjimharris scic_sds_remote_device_get_index(this_request->target_device); 689230557Sjimharris task_context->command_code = 0; 690230557Sjimharris 691230557Sjimharris task_context->link_layer_control = 0; 692230557Sjimharris task_context->do_not_dma_ssp_good_response = 1; 693230557Sjimharris task_context->strict_ordering = 0; 694230557Sjimharris task_context->control_frame = 0; 695230557Sjimharris task_context->timeout_enable = 0; 696230557Sjimharris task_context->block_guard_enable = 0; 697230557Sjimharris 698230557Sjimharris task_context->address_modifier = 0; 699230557Sjimharris 700230557Sjimharris //task_context->type.ssp.tag = this_request->io_tag; 701230557Sjimharris task_context->task_phase = 0x01; 702230557Sjimharris 703230557Sjimharris if (this_request->was_tag_assigned_by_user) 704230557Sjimharris { 705230557Sjimharris // Build the task context now since we have already read the data 706230557Sjimharris this_request->post_context = ( 707230557Sjimharris SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC 708230557Sjimharris | ( 709230557Sjimharris scic_sds_controller_get_protocol_engine_group(owning_controller) 710230557Sjimharris << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT 711230557Sjimharris ) 712230557Sjimharris | ( 713230557Sjimharris scic_sds_port_get_index(target_port) 714230557Sjimharris << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT 715230557Sjimharris ) 716230557Sjimharris | scic_sds_io_tag_get_index(this_request->io_tag) 717230557Sjimharris ); 718230557Sjimharris } 719230557Sjimharris else 720230557Sjimharris { 721230557Sjimharris // Build the task context now since we have already read the data 722230557Sjimharris this_request->post_context = ( 723230557Sjimharris SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC 724230557Sjimharris | ( 725230557Sjimharris scic_sds_controller_get_protocol_engine_group(owning_controller) 726230557Sjimharris << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT 727230557Sjimharris ) 728230557Sjimharris | ( 729230557Sjimharris scic_sds_port_get_index(target_port) 730230557Sjimharris << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT 731230557Sjimharris ) 732230557Sjimharris // This is not assigned because we have to wait until we get a TCi 733230557Sjimharris ); 734230557Sjimharris } 735230557Sjimharris 736230557Sjimharris // Copy the physical address for the command buffer to the SCU Task Context 737230557Sjimharris scic_cb_io_request_get_physical_address( 738230557Sjimharris scic_sds_request_get_controller(this_request), 739230557Sjimharris this_request, 740230557Sjimharris this_request->command_buffer, 741230557Sjimharris &physical_address 742230557Sjimharris ); 743230557Sjimharris 744230557Sjimharris task_context->command_iu_upper = 745230557Sjimharris sci_cb_physical_address_upper(physical_address); 746230557Sjimharris task_context->command_iu_lower = 747230557Sjimharris sci_cb_physical_address_lower(physical_address); 748230557Sjimharris 749230557Sjimharris // Copy the physical address for the response buffer to the SCU Task Context 750230557Sjimharris scic_cb_io_request_get_physical_address( 751230557Sjimharris scic_sds_request_get_controller(this_request), 752230557Sjimharris this_request, 753230557Sjimharris this_request->response_buffer, 754230557Sjimharris &physical_address 755230557Sjimharris ); 756230557Sjimharris 757230557Sjimharris task_context->response_iu_upper = 758230557Sjimharris sci_cb_physical_address_upper(physical_address); 759230557Sjimharris task_context->response_iu_lower = 760230557Sjimharris sci_cb_physical_address_lower(physical_address); 761230557Sjimharris} 762230557Sjimharris 763230557Sjimharris/** 764230557Sjimharris * @brief This method is will fill in the SCU Task Context for a SSP IO 765230557Sjimharris * request. 766230557Sjimharris * 767230557Sjimharris * @param[in] this_request 768230557Sjimharris * 769230557Sjimharris * @return none 770230557Sjimharris */ 771230557Sjimharrisstatic 772230557Sjimharrisvoid scu_ssp_io_request_construct_task_context( 773230557Sjimharris SCIC_SDS_REQUEST_T *this_request, 774230557Sjimharris SCI_IO_REQUEST_DATA_DIRECTION data_direction, 775230557Sjimharris U32 transfer_length_bytes 776230557Sjimharris) 777230557Sjimharris{ 778230557Sjimharris SCU_TASK_CONTEXT_T *task_context; 779230557Sjimharris 780230557Sjimharris task_context = scic_sds_request_get_task_context(this_request); 781230557Sjimharris 782230557Sjimharris scu_ssp_reqeust_construct_task_context(this_request, task_context); 783230557Sjimharris 784230557Sjimharris task_context->ssp_command_iu_length = sizeof(SCI_SSP_COMMAND_IU_T) / sizeof(U32); 785230557Sjimharris task_context->type.ssp.frame_type = SCI_SAS_COMMAND_FRAME; 786230557Sjimharris 787230557Sjimharris switch (data_direction) 788230557Sjimharris { 789230557Sjimharris case SCI_IO_REQUEST_DATA_IN: 790230557Sjimharris case SCI_IO_REQUEST_NO_DATA: 791230557Sjimharris task_context->task_type = SCU_TASK_TYPE_IOREAD; 792230557Sjimharris break; 793230557Sjimharris case SCI_IO_REQUEST_DATA_OUT: 794230557Sjimharris task_context->task_type = SCU_TASK_TYPE_IOWRITE; 795230557Sjimharris break; 796230557Sjimharris } 797230557Sjimharris 798230557Sjimharris task_context->transfer_length_bytes = transfer_length_bytes; 799230557Sjimharris 800230557Sjimharris if (task_context->transfer_length_bytes > 0) 801230557Sjimharris { 802230557Sjimharris scic_sds_request_build_sgl(this_request); 803230557Sjimharris } 804230557Sjimharris} 805230557Sjimharris 806230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT) 807230557Sjimharris 808230557Sjimharris/** 809230557Sjimharris * @brief This method will fill in the remainder of the io request object 810230557Sjimharris * for SSP Task requests. 811230557Sjimharris * 812230557Sjimharris * @param[in] this_request 813230557Sjimharris * 814230557Sjimharris * @return none 815230557Sjimharris */ 816230557Sjimharrisvoid scic_sds_ssp_task_request_assign_buffers( 817230557Sjimharris SCIC_SDS_REQUEST_T *this_request 818230557Sjimharris) 819230557Sjimharris{ 820230557Sjimharris // Assign all of the buffer pointers 821230557Sjimharris this_request->command_buffer = 822230557Sjimharris scic_sds_ssp_task_request_get_command_buffer(this_request); 823230557Sjimharris this_request->response_buffer = 824230557Sjimharris scic_sds_ssp_task_request_get_response_buffer(this_request); 825230557Sjimharris this_request->sgl_element_pair_buffer = NULL; 826230557Sjimharris 827230557Sjimharris if (this_request->was_tag_assigned_by_user == FALSE) 828230557Sjimharris { 829230557Sjimharris this_request->task_context_buffer = 830230557Sjimharris scic_sds_ssp_task_request_get_task_context_buffer(this_request); 831230557Sjimharris this_request->task_context_buffer = 832230557Sjimharris scic_sds_request_align_task_context_buffer(this_request->task_context_buffer); 833230557Sjimharris } 834230557Sjimharris} 835230557Sjimharris 836230557Sjimharris/** 837230557Sjimharris * @brief This method will fill in the SCU Task Context for a SSP Task 838230557Sjimharris * request. The following important settings are utilized: 839230557Sjimharris * -# priority == SCU_TASK_PRIORITY_HIGH. This ensures that the 840230557Sjimharris * task request is issued ahead of other task destined for the 841230557Sjimharris * same Remote Node. 842230557Sjimharris * -# task_type == SCU_TASK_TYPE_IOREAD. This simply indicates 843230557Sjimharris * that a normal request type (i.e. non-raw frame) is being 844230557Sjimharris * utilized to perform task management. 845230557Sjimharris * -# control_frame == 1. This ensures that the proper endianess 846230557Sjimharris * is set so that the bytes are transmitted in the right order 847230557Sjimharris * for a task frame. 848230557Sjimharris * 849230557Sjimharris * @param[in] this_request This parameter specifies the task request object 850230557Sjimharris * being constructed. 851230557Sjimharris * 852230557Sjimharris * @return none 853230557Sjimharris */ 854230557Sjimharrisstatic 855230557Sjimharrisvoid scu_ssp_task_request_construct_task_context( 856230557Sjimharris SCIC_SDS_REQUEST_T *this_request 857230557Sjimharris) 858230557Sjimharris{ 859230557Sjimharris SCU_TASK_CONTEXT_T *task_context; 860230557Sjimharris 861230557Sjimharris task_context = scic_sds_request_get_task_context(this_request); 862230557Sjimharris 863230557Sjimharris scu_ssp_reqeust_construct_task_context(this_request, task_context); 864230557Sjimharris 865230557Sjimharris task_context->control_frame = 1; 866230557Sjimharris task_context->priority = SCU_TASK_PRIORITY_HIGH; 867230557Sjimharris task_context->task_type = SCU_TASK_TYPE_RAW_FRAME; 868230557Sjimharris task_context->transfer_length_bytes = 0; 869230557Sjimharris task_context->type.ssp.frame_type = SCI_SAS_TASK_FRAME; 870230557Sjimharris task_context->ssp_command_iu_length = sizeof(SCI_SSP_TASK_IU_T) / sizeof(U32); 871230557Sjimharris} 872230557Sjimharris 873230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT) 874230557Sjimharris 875230557Sjimharris#if !defined(DISABLE_PASS_THROUGH) 876230557Sjimharris/** 877230557Sjimharris * @brief This method constructs the SSP Command IU data for this 878230557Sjimharris * ssp passthrough comand request object. 879230557Sjimharris * 880230557Sjimharris * @param[in] this_request This parameter specifies the request object for 881230557Sjimharris * which the SSP command information unit is being built. 882230557Sjimharris * 883230557Sjimharris * @return SCI_STATUS, returns invalid parameter is cdb > 16 884230557Sjimharris */ 885230557Sjimharrisstatic 886230557SjimharrisSCI_STATUS scic_sds_io_request_build_ssp_command_iu_pass_through( 887230557Sjimharris SCIC_SDS_REQUEST_T *this_request, 888230557Sjimharris SCIC_SSP_PASSTHRU_REQUEST_CALLBACKS_T *ssp_passthru_cb 889230557Sjimharris) 890230557Sjimharris{ 891230557Sjimharris SCI_SSP_COMMAND_IU_T *command_frame; 892230557Sjimharris U32 cdb_length = 0, additional_cdb_length = 0; 893230557Sjimharris U8 *cdb_buffer, *additional_cdb_buffer; 894230557Sjimharris U8 *scsi_lun; 895230557Sjimharris SCI_STATUS sci_status = SCI_SUCCESS; 896230557Sjimharris SCI_SINGLE_LEVEL_LUN_T lun; 897230557Sjimharris 898230557Sjimharris command_frame = 899230557Sjimharris (SCI_SSP_COMMAND_IU_T *)this_request->command_buffer; 900230557Sjimharris 901230557Sjimharris //get the lun 902230557Sjimharris ssp_passthru_cb->scic_cb_ssp_passthru_get_lun ( 903230557Sjimharris this_request, 904230557Sjimharris &scsi_lun 905230557Sjimharris ); 906230557Sjimharris memset(&lun, 0, sizeof(lun)); 907230557Sjimharris lun.lun_number = *scsi_lun; 908230557Sjimharris scic_word_copy_with_swap( 909230557Sjimharris (U32 *)command_frame->lun, 910230557Sjimharris (U32 *)&lun, 911230557Sjimharris sizeof(lun)); 912230557Sjimharris 913230557Sjimharris ((U32 *)command_frame)[2] = 0; 914230557Sjimharris 915230557Sjimharris ssp_passthru_cb->scic_cb_ssp_passthru_get_cdb( 916230557Sjimharris this_request, 917230557Sjimharris &cdb_length, 918230557Sjimharris &cdb_buffer, 919230557Sjimharris &additional_cdb_length, 920230557Sjimharris &additional_cdb_buffer 921230557Sjimharris ); 922230557Sjimharris 923230557Sjimharris command_frame->additional_cdb_length = additional_cdb_length; 924230557Sjimharris 925230557Sjimharris // ----------- TODO 926230557Sjimharris ///todo: what to do with additional cdb length and buffer as the current command buffer is 927230557Sjimharris // 16 bytes in intel_sas.h 928230557Sjimharris // ??? see the SAS command IU 929230557Sjimharris if (additional_cdb_length > 0) 930230557Sjimharris { 931230557Sjimharris return SCI_FAILURE_INVALID_PARAMETER_VALUE; 932230557Sjimharris } 933230557Sjimharris 934230557Sjimharris /// @todo Is it ok to leave junk at the end of the cdb buffer? 935230557Sjimharris scic_word_copy_with_swap( 936230557Sjimharris (U32 *)(&command_frame->cdb), 937230557Sjimharris (U32 *)(cdb_buffer), 938230557Sjimharris (cdb_length + 3) / sizeof(U32) 939230557Sjimharris ); 940230557Sjimharris 941230557Sjimharris /////-------- End fo TODO 942230557Sjimharris 943230557Sjimharris command_frame->enable_first_burst = 0; 944230557Sjimharris command_frame->task_priority = 0; //todo: check with Richard ???? 945230557Sjimharris 946230557Sjimharris //get the task attribute 947230557Sjimharris command_frame->task_attribute = ssp_passthru_cb->scic_cb_ssp_passthru_get_task_attribute ( 948230557Sjimharris this_request 949230557Sjimharris ); 950230557Sjimharris 951230557Sjimharris return sci_status; 952230557Sjimharris} 953230557Sjimharris#endif // !defined(DISABLE_PASS_THROUGH) 954230557Sjimharris 955230557Sjimharris//**************************************************************************** 956230557Sjimharris//* SCIC Interface Implementation 957230557Sjimharris//**************************************************************************** 958230557Sjimharris 959230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT) 960230557Sjimharris/** 961230557Sjimharris * This method returns the size required to store an SSP task request object. 962230557Sjimharris * 963230557Sjimharris * @return U32 964230557Sjimharris */ 965230557Sjimharrisstatic 966230557SjimharrisU32 scic_sds_ssp_task_request_get_object_size(void) 967230557Sjimharris{ 968230557Sjimharris return sizeof(SCIC_SDS_REQUEST_T) 969230557Sjimharris + scic_ssp_task_request_get_object_size() 970230557Sjimharris + sizeof(SCU_TASK_CONTEXT_T) 971230557Sjimharris + CACHE_LINE_SIZE; 972230557Sjimharris} 973230557Sjimharris 974230557Sjimharris 975230557SjimharrisU32 scic_task_request_get_object_size(void) 976230557Sjimharris{ 977230557Sjimharris U32 ssp_task_request_size; 978230557Sjimharris U32 stp_task_request_size; 979230557Sjimharris 980230557Sjimharris ssp_task_request_size = scic_sds_ssp_task_request_get_object_size(); 981230557Sjimharris stp_task_request_size = scic_sds_stp_task_request_get_object_size(); 982230557Sjimharris 983230557Sjimharris return MAX(ssp_task_request_size, stp_task_request_size); 984230557Sjimharris} 985230557Sjimharris 986230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT) 987230557Sjimharris 988230557Sjimharris// --------------------------------------------------------------------------- 989230557Sjimharris 990230557SjimharrisU32 scic_io_request_get_object_size(void) 991230557Sjimharris{ 992230557Sjimharris U32 ssp_request_size; 993230557Sjimharris U32 stp_request_size; 994230557Sjimharris U32 smp_request_size; 995230557Sjimharris 996230557Sjimharris ssp_request_size = scic_sds_ssp_request_get_object_size(); 997230557Sjimharris stp_request_size = scic_sds_stp_request_get_object_size(); 998230557Sjimharris smp_request_size = scic_sds_smp_request_get_object_size(); 999230557Sjimharris 1000230557Sjimharris return MAX(ssp_request_size, MAX(stp_request_size, smp_request_size)); 1001230557Sjimharris} 1002230557Sjimharris 1003230557Sjimharris// --------------------------------------------------------------------------- 1004230557Sjimharris 1005230557SjimharrisSCIC_TRANSPORT_PROTOCOL scic_io_request_get_protocol( 1006230557Sjimharris SCI_IO_REQUEST_HANDLE_T scic_io_request 1007230557Sjimharris) 1008230557Sjimharris{ 1009230557Sjimharris SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T * )scic_io_request; 1010230557Sjimharris return this_request->protocol; 1011230557Sjimharris} 1012230557Sjimharris 1013230557Sjimharris// --------------------------------------------------------------------------- 1014230557Sjimharris 1015230557SjimharrisU32 scic_sds_request_get_min_timer_count(void) 1016230557Sjimharris{ 1017230557Sjimharris return SCIC_SDS_IO_REQUEST_MINIMUM_TIMER_COUNT; 1018230557Sjimharris} 1019230557Sjimharris 1020230557Sjimharris// --------------------------------------------------------------------------- 1021230557Sjimharris 1022230557SjimharrisU32 scic_sds_request_get_max_timer_count(void) 1023230557Sjimharris{ 1024230557Sjimharris return SCIC_SDS_IO_REQUEST_MAXIMUM_TIMER_COUNT; 1025230557Sjimharris} 1026230557Sjimharris 1027230557Sjimharris// --------------------------------------------------------------------------- 1028230557Sjimharris 1029230557SjimharrisSCI_STATUS scic_io_request_construct( 1030230557Sjimharris SCI_CONTROLLER_HANDLE_T scic_controller, 1031230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T scic_remote_device, 1032230557Sjimharris U16 io_tag, 1033230557Sjimharris void * user_io_request_object, 1034230557Sjimharris void * scic_io_request_memory, 1035230557Sjimharris SCI_IO_REQUEST_HANDLE_T * new_scic_io_request_handle 1036230557Sjimharris) 1037230557Sjimharris{ 1038230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 1039230557Sjimharris SCIC_SDS_REQUEST_T * this_request; 1040230557Sjimharris SMP_DISCOVER_RESPONSE_PROTOCOLS_T device_protocol; 1041230557Sjimharris 1042230557Sjimharris this_request = (SCIC_SDS_REQUEST_T * )scic_io_request_memory; 1043230557Sjimharris 1044230557Sjimharris SCIC_LOG_TRACE(( 1045230557Sjimharris sci_base_object_get_logger(scic_controller), 1046230557Sjimharris (SCIC_LOG_OBJECT_SSP_IO_REQUEST 1047230557Sjimharris |SCIC_LOG_OBJECT_SMP_IO_REQUEST 1048230557Sjimharris |SCIC_LOG_OBJECT_STP_IO_REQUEST), 1049230557Sjimharris "scic_io_request_construct(0x%x, 0x%x, 0x02x, 0x%x, 0x%x, 0x%x) enter\n", 1050230557Sjimharris scic_controller, scic_remote_device, 1051230557Sjimharris io_tag, user_io_request_object, 1052230557Sjimharris this_request, new_scic_io_request_handle 1053230557Sjimharris )); 1054230557Sjimharris 1055230557Sjimharris // Build the common part of the request 1056230557Sjimharris scic_sds_general_request_construct( 1057230557Sjimharris (SCIC_SDS_CONTROLLER_T *)scic_controller, 1058230557Sjimharris (SCIC_SDS_REMOTE_DEVICE_T *)scic_remote_device, 1059230557Sjimharris io_tag, 1060230557Sjimharris user_io_request_object, 1061230557Sjimharris this_request 1062230557Sjimharris ); 1063230557Sjimharris 1064230557Sjimharris if ( 1065230557Sjimharris scic_sds_remote_device_get_index((SCIC_SDS_REMOTE_DEVICE_T *)scic_remote_device) 1066230557Sjimharris == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX 1067230557Sjimharris ) 1068230557Sjimharris { 1069230557Sjimharris return SCI_FAILURE_INVALID_REMOTE_DEVICE; 1070230557Sjimharris } 1071230557Sjimharris 1072230557Sjimharris scic_remote_device_get_protocols(scic_remote_device, &device_protocol); 1073230557Sjimharris 1074230557Sjimharris if (device_protocol.u.bits.attached_ssp_target) 1075230557Sjimharris { 1076230557Sjimharris scic_sds_ssp_io_request_assign_buffers(this_request); 1077230557Sjimharris } 1078230557Sjimharris else if (device_protocol.u.bits.attached_stp_target) 1079230557Sjimharris { 1080230557Sjimharris scic_sds_stp_request_assign_buffers(this_request); 1081230557Sjimharris memset(this_request->command_buffer, 0, sizeof(SATA_FIS_REG_H2D_T)); 1082230557Sjimharris } 1083230557Sjimharris else if (device_protocol.u.bits.attached_smp_target) 1084230557Sjimharris { 1085230557Sjimharris scic_sds_smp_request_assign_buffers(this_request); 1086230557Sjimharris memset(this_request->command_buffer, 0, sizeof(SMP_REQUEST_T)); 1087230557Sjimharris } 1088230557Sjimharris else 1089230557Sjimharris { 1090230557Sjimharris status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; 1091230557Sjimharris } 1092230557Sjimharris 1093230557Sjimharris if (status == SCI_SUCCESS) 1094230557Sjimharris { 1095230557Sjimharris memset( 1096230557Sjimharris this_request->task_context_buffer, 1097230557Sjimharris 0, 1098230557Sjimharris SCI_FIELD_OFFSET(SCU_TASK_CONTEXT_T, sgl_pair_ab) 1099230557Sjimharris ); 1100230557Sjimharris *new_scic_io_request_handle = scic_io_request_memory; 1101230557Sjimharris } 1102230557Sjimharris 1103230557Sjimharris return status; 1104230557Sjimharris} 1105230557Sjimharris 1106230557Sjimharris// --------------------------------------------------------------------------- 1107230557Sjimharris 1108230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT) 1109230557Sjimharris 1110230557SjimharrisSCI_STATUS scic_task_request_construct( 1111230557Sjimharris SCI_CONTROLLER_HANDLE_T controller, 1112230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device, 1113230557Sjimharris U16 io_tag, 1114230557Sjimharris void *user_io_request_object, 1115230557Sjimharris void *scic_task_request_memory, 1116230557Sjimharris SCI_TASK_REQUEST_HANDLE_T *new_scic_task_request_handle 1117230557Sjimharris) 1118230557Sjimharris{ 1119230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 1120230557Sjimharris SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *) 1121230557Sjimharris scic_task_request_memory; 1122230557Sjimharris SMP_DISCOVER_RESPONSE_PROTOCOLS_T device_protocol; 1123230557Sjimharris 1124230557Sjimharris SCIC_LOG_TRACE(( 1125230557Sjimharris sci_base_object_get_logger(controller), 1126230557Sjimharris (SCIC_LOG_OBJECT_SSP_IO_REQUEST 1127230557Sjimharris |SCIC_LOG_OBJECT_SMP_IO_REQUEST 1128230557Sjimharris |SCIC_LOG_OBJECT_STP_IO_REQUEST), 1129230557Sjimharris "scic_task_request_construct(0x%x, 0x%x, 0x02x, 0x%x, 0x%x, 0x%x) enter\n", 1130230557Sjimharris controller, remote_device, 1131230557Sjimharris io_tag, user_io_request_object, 1132230557Sjimharris scic_task_request_memory, new_scic_task_request_handle 1133230557Sjimharris )); 1134230557Sjimharris 1135230557Sjimharris // Build the common part of the request 1136230557Sjimharris scic_sds_general_request_construct( 1137230557Sjimharris (SCIC_SDS_CONTROLLER_T *)controller, 1138230557Sjimharris (SCIC_SDS_REMOTE_DEVICE_T *)remote_device, 1139230557Sjimharris io_tag, 1140230557Sjimharris user_io_request_object, 1141230557Sjimharris this_request 1142230557Sjimharris ); 1143230557Sjimharris 1144230557Sjimharris scic_remote_device_get_protocols(remote_device, &device_protocol); 1145230557Sjimharris 1146230557Sjimharris if (device_protocol.u.bits.attached_ssp_target) 1147230557Sjimharris { 1148230557Sjimharris scic_sds_ssp_task_request_assign_buffers(this_request); 1149230557Sjimharris 1150230557Sjimharris this_request->has_started_substate_machine = TRUE; 1151230557Sjimharris 1152230557Sjimharris // Construct the started sub-state machine. 1153230557Sjimharris sci_base_state_machine_construct( 1154230557Sjimharris &this_request->started_substate_machine, 1155230557Sjimharris &this_request->parent.parent, 1156230557Sjimharris scic_sds_io_request_started_task_mgmt_substate_table, 1157230557Sjimharris SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION 1158230557Sjimharris ); 1159230557Sjimharris } 1160230557Sjimharris else if (device_protocol.u.bits.attached_stp_target) 1161230557Sjimharris { 1162230557Sjimharris scic_sds_stp_request_assign_buffers(this_request); 1163230557Sjimharris } 1164230557Sjimharris else 1165230557Sjimharris { 1166230557Sjimharris status = SCI_FAILURE_UNSUPPORTED_PROTOCOL; 1167230557Sjimharris } 1168230557Sjimharris 1169230557Sjimharris if (status == SCI_SUCCESS) 1170230557Sjimharris { 1171230557Sjimharris this_request->is_task_management_request = TRUE; 1172230557Sjimharris memset(this_request->task_context_buffer, 0x00, sizeof(SCU_TASK_CONTEXT_T)); 1173230557Sjimharris *new_scic_task_request_handle = scic_task_request_memory; 1174230557Sjimharris } 1175230557Sjimharris 1176230557Sjimharris return status; 1177230557Sjimharris} 1178230557Sjimharris 1179230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT) 1180230557Sjimharris 1181230557Sjimharris// --------------------------------------------------------------------------- 1182230557Sjimharris 1183230557SjimharrisSCI_STATUS scic_io_request_construct_basic_ssp( 1184230557Sjimharris SCI_IO_REQUEST_HANDLE_T scic_io_request 1185230557Sjimharris) 1186230557Sjimharris{ 1187230557Sjimharris void *os_handle; 1188230557Sjimharris SCIC_SDS_REQUEST_T *this_request; 1189230557Sjimharris this_request = (SCIC_SDS_REQUEST_T *)scic_io_request; 1190230557Sjimharris 1191230557Sjimharris SCIC_LOG_TRACE(( 1192230557Sjimharris sci_base_object_get_logger(this_request), 1193230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST, 1194230557Sjimharris "scic_io_request_construct_basic_ssp(0x%x) enter\n", 1195230557Sjimharris this_request 1196230557Sjimharris )); 1197230557Sjimharris 1198230557Sjimharris this_request->protocol = SCIC_SSP_PROTOCOL; 1199230557Sjimharris 1200230557Sjimharris os_handle = scic_sds_request_get_user_request(this_request); 1201230557Sjimharris 1202230557Sjimharris scu_ssp_io_request_construct_task_context( 1203230557Sjimharris this_request, 1204230557Sjimharris scic_cb_io_request_get_data_direction(os_handle), 1205230557Sjimharris scic_cb_io_request_get_transfer_length(os_handle) 1206230557Sjimharris ); 1207230557Sjimharris 1208230557Sjimharris 1209230557Sjimharris scic_sds_io_request_build_ssp_command_iu(this_request); 1210230557Sjimharris 1211230557Sjimharris scic_sds_request_initialize_state_logging(this_request); 1212230557Sjimharris 1213230557Sjimharris sci_base_state_machine_change_state( 1214230557Sjimharris &this_request->parent.state_machine, 1215230557Sjimharris SCI_BASE_REQUEST_STATE_CONSTRUCTED 1216230557Sjimharris ); 1217230557Sjimharris 1218230557Sjimharris return SCI_SUCCESS; 1219230557Sjimharris} 1220230557Sjimharris 1221230557Sjimharris// --------------------------------------------------------------------------- 1222230557Sjimharris 1223230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT) 1224230557Sjimharris 1225230557SjimharrisSCI_STATUS scic_task_request_construct_ssp( 1226230557Sjimharris SCI_TASK_REQUEST_HANDLE_T scic_task_request 1227230557Sjimharris) 1228230557Sjimharris{ 1229230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *) 1230230557Sjimharris scic_task_request; 1231230557Sjimharris 1232230557Sjimharris SCIC_LOG_TRACE(( 1233230557Sjimharris sci_base_object_get_logger(this_request), 1234230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST, 1235230557Sjimharris "scic_task_request_construct_ssp(0x%x) enter\n", 1236230557Sjimharris this_request 1237230557Sjimharris )); 1238230557Sjimharris 1239230557Sjimharris // Construct the SSP Task SCU Task Context 1240230557Sjimharris scu_ssp_task_request_construct_task_context(this_request); 1241230557Sjimharris 1242230557Sjimharris // Fill in the SSP Task IU 1243230557Sjimharris scic_sds_task_request_build_ssp_task_iu(this_request); 1244230557Sjimharris 1245230557Sjimharris scic_sds_request_initialize_state_logging(this_request); 1246230557Sjimharris 1247230557Sjimharris sci_base_state_machine_change_state( 1248230557Sjimharris &this_request->parent.state_machine, 1249230557Sjimharris SCI_BASE_REQUEST_STATE_CONSTRUCTED 1250230557Sjimharris ); 1251230557Sjimharris 1252230557Sjimharris return SCI_SUCCESS; 1253230557Sjimharris} 1254230557Sjimharris 1255230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT) 1256230557Sjimharris 1257230557Sjimharris// --------------------------------------------------------------------------- 1258230557Sjimharris 1259230557SjimharrisSCI_STATUS scic_io_request_construct_advanced_ssp( 1260230557Sjimharris SCI_IO_REQUEST_HANDLE_T scic_io_request, 1261230557Sjimharris SCIC_IO_SSP_PARAMETERS_T * io_parameters 1262230557Sjimharris) 1263230557Sjimharris{ 1264230557Sjimharris SCIC_LOG_TRACE(( 1265230557Sjimharris sci_base_object_get_logger(scic_io_request), 1266230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST, 1267230557Sjimharris "scic_io_request_construct_advanced_ssp(0x%x, 0x%x) enter\n", 1268230557Sjimharris io_parameters, scic_io_request 1269230557Sjimharris )); 1270230557Sjimharris 1271230557Sjimharris /// @todo Implement after 1.1 1272230557Sjimharris return SCI_FAILURE; 1273230557Sjimharris} 1274230557Sjimharris 1275230557Sjimharris// --------------------------------------------------------------------------- 1276230557Sjimharris 1277230557Sjimharris#if !defined(DISABLE_PASS_THROUGH) 1278230557SjimharrisSCI_STATUS scic_io_request_construct_ssp_pass_through ( 1279230557Sjimharris void * scic_io_request, 1280230557Sjimharris SCIC_SSP_PASSTHRU_REQUEST_CALLBACKS_T *ssp_passthru_cb 1281230557Sjimharris) 1282230557Sjimharris{ 1283230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 1284230557Sjimharris SCIC_SDS_REQUEST_T * this_request; 1285230557Sjimharris 1286230557Sjimharris this_request = (SCIC_SDS_REQUEST_T * )scic_io_request; 1287230557Sjimharris 1288230557Sjimharris SCIC_LOG_TRACE(( 1289230557Sjimharris sci_base_object_get_logger(scic_io_request), 1290230557Sjimharris SCIC_LOG_OBJECT_STP_IO_REQUEST, 1291230557Sjimharris "scic_io_request_construct_ssp_pass_through(0x%x) enter\n", 1292230557Sjimharris scic_io_request 1293230557Sjimharris )); 1294230557Sjimharris 1295230557Sjimharris //build the task context from the pass through buffer 1296230557Sjimharris scu_ssp_io_request_construct_task_context( 1297230557Sjimharris this_request, 1298230557Sjimharris ssp_passthru_cb->common_callbacks.scic_cb_passthru_get_data_direction (this_request), 1299230557Sjimharris ssp_passthru_cb->common_callbacks.scic_cb_passthru_get_transfer_length(this_request) 1300230557Sjimharris ); 1301230557Sjimharris 1302230557Sjimharris //build the ssp command iu from the pass through buffer 1303230557Sjimharris status = scic_sds_io_request_build_ssp_command_iu_pass_through ( 1304230557Sjimharris this_request, 1305230557Sjimharris ssp_passthru_cb 1306230557Sjimharris ); 1307230557Sjimharris if (status != SCI_SUCCESS) 1308230557Sjimharris { 1309230557Sjimharris return status; 1310230557Sjimharris } 1311230557Sjimharris 1312230557Sjimharris /* initialize the logging */ 1313230557Sjimharris scic_sds_request_initialize_state_logging(this_request); 1314230557Sjimharris 1315230557Sjimharris sci_base_state_machine_change_state( 1316230557Sjimharris &this_request->parent.state_machine, 1317230557Sjimharris SCI_BASE_REQUEST_STATE_CONSTRUCTED 1318230557Sjimharris ); 1319230557Sjimharris 1320230557Sjimharris return status; 1321230557Sjimharris} 1322230557Sjimharris#endif // !defined(DISABLE_PASS_THROUGH) 1323230557Sjimharris 1324230557Sjimharris// --------------------------------------------------------------------------- 1325230557Sjimharris 1326230557Sjimharris#if !defined(DISABLE_TASK_MANAGEMENT) 1327230557Sjimharris 1328230557SjimharrisSCI_STATUS scic_task_request_construct_sata( 1329230557Sjimharris SCI_TASK_REQUEST_HANDLE_T scic_task_request 1330230557Sjimharris) 1331230557Sjimharris{ 1332230557Sjimharris SCI_STATUS status; 1333230557Sjimharris SCIC_SDS_REQUEST_T * this_request; 1334230557Sjimharris U8 sat_protocol; 1335230557Sjimharris 1336230557Sjimharris this_request = (SCIC_SDS_REQUEST_T *)scic_task_request; 1337230557Sjimharris 1338230557Sjimharris SCIC_LOG_TRACE(( 1339230557Sjimharris sci_base_object_get_logger(this_request), 1340230557Sjimharris SCIC_LOG_OBJECT_STP_IO_REQUEST, 1341230557Sjimharris "scic_task_request_construct_sata(0x%x) enter\n", 1342230557Sjimharris this_request 1343230557Sjimharris )); 1344230557Sjimharris 1345230557Sjimharris sat_protocol = 1346230557Sjimharris scic_cb_request_get_sat_protocol(this_request->user_request); 1347230557Sjimharris 1348230557Sjimharris this_request->sat_protocol = sat_protocol; 1349230557Sjimharris 1350230557Sjimharris switch (sat_protocol) 1351230557Sjimharris { 1352230557Sjimharris case SAT_PROTOCOL_ATA_HARD_RESET: 1353230557Sjimharris case SAT_PROTOCOL_SOFT_RESET: 1354230557Sjimharris status = scic_sds_stp_soft_reset_request_construct(this_request); 1355230557Sjimharris break; 1356230557Sjimharris 1357230557Sjimharris case SAT_PROTOCOL_PIO_DATA_IN: 1358230557Sjimharris status = scic_sds_stp_pio_request_construct(this_request, sat_protocol, FALSE); 1359230557Sjimharris break; 1360230557Sjimharris 1361230557Sjimharris default: 1362230557Sjimharris SCIC_LOG_ERROR(( 1363230557Sjimharris sci_base_object_get_logger(this_request), 1364230557Sjimharris SCIC_LOG_OBJECT_STP_IO_REQUEST, 1365230557Sjimharris "SCIC IO Request 0x%x received un-handled SAT Protocl %d.\n", 1366230557Sjimharris this_request, sat_protocol 1367230557Sjimharris )); 1368230557Sjimharris 1369230557Sjimharris status = SCI_FAILURE; 1370230557Sjimharris break; 1371230557Sjimharris } 1372230557Sjimharris 1373230557Sjimharris if (status == SCI_SUCCESS) 1374230557Sjimharris { 1375230557Sjimharris scic_sds_request_initialize_state_logging(this_request); 1376230557Sjimharris 1377230557Sjimharris sci_base_state_machine_change_state( 1378230557Sjimharris &this_request->parent.state_machine, 1379230557Sjimharris SCI_BASE_REQUEST_STATE_CONSTRUCTED 1380230557Sjimharris ); 1381230557Sjimharris } 1382230557Sjimharris 1383230557Sjimharris return status; 1384230557Sjimharris} 1385230557Sjimharris 1386230557Sjimharris#endif // !defined(DISABLE_TASK_MANAGEMENT) 1387230557Sjimharris 1388230557Sjimharris// --------------------------------------------------------------------------- 1389230557Sjimharris 1390230557Sjimharris#if !defined(DISABLE_PASS_THROUGH) 1391230557SjimharrisSCI_STATUS scic_io_request_construct_sata_pass_through( 1392230557Sjimharris SCI_IO_REQUEST_HANDLE_T scic_io_request, 1393230557Sjimharris SCIC_STP_PASSTHRU_REQUEST_CALLBACKS_T *passthru_cb 1394230557Sjimharris) 1395230557Sjimharris{ 1396230557Sjimharris SCI_STATUS status = SCI_SUCCESS; 1397230557Sjimharris SCIC_SDS_REQUEST_T * this_request; 1398230557Sjimharris U8 sat_protocol; 1399230557Sjimharris U8 * reg_fis; 1400230557Sjimharris U32 transfer_length; 1401230557Sjimharris SCI_IO_REQUEST_DATA_DIRECTION data_direction; 1402230557Sjimharris 1403230557Sjimharris this_request = (SCIC_SDS_REQUEST_T * )scic_io_request; 1404230557Sjimharris 1405230557Sjimharris SCIC_LOG_TRACE(( 1406230557Sjimharris sci_base_object_get_logger(scic_io_request), 1407230557Sjimharris SCIC_LOG_OBJECT_STP_IO_REQUEST, 1408230557Sjimharris "scic_io_request_construct_sata_pass_through(0x%x) enter\n", 1409230557Sjimharris scic_io_request 1410230557Sjimharris )); 1411230557Sjimharris 1412230557Sjimharris passthru_cb->scic_cb_stp_passthru_get_register_fis(this_request, ®_fis); 1413230557Sjimharris 1414230557Sjimharris if (reg_fis == NULL) 1415230557Sjimharris { 1416230557Sjimharris status = SCI_FAILURE_INVALID_PARAMETER_VALUE; 1417230557Sjimharris } 1418230557Sjimharris 1419230557Sjimharris if (status == SCI_SUCCESS) 1420230557Sjimharris { 1421230557Sjimharris //copy the H2D Reg fis blindly from the request to the SCU command buffer 1422230557Sjimharris memcpy ((U8 *)this_request->command_buffer, (U8 *)reg_fis, sizeof(SATA_FIS_REG_H2D_T)); 1423230557Sjimharris 1424230557Sjimharris //continue to create the request 1425230557Sjimharris sat_protocol = passthru_cb->scic_cb_stp_passthru_get_protocol(this_request); 1426230557Sjimharris transfer_length = passthru_cb->common_callbacks.scic_cb_passthru_get_transfer_length(this_request); 1427230557Sjimharris data_direction = passthru_cb->common_callbacks.scic_cb_passthru_get_data_direction(this_request); 1428230557Sjimharris 1429230557Sjimharris status = scic_sds_io_request_construct_sata( 1430230557Sjimharris this_request, 1431230557Sjimharris sat_protocol, 1432230557Sjimharris transfer_length, 1433230557Sjimharris data_direction, 1434230557Sjimharris TRUE, 1435230557Sjimharris TRUE 1436230557Sjimharris ); 1437230557Sjimharris 1438230557Sjimharris this_request->protocol = SCIC_STP_PROTOCOL; 1439230557Sjimharris } 1440230557Sjimharris 1441230557Sjimharris return status; 1442230557Sjimharris} 1443230557Sjimharris#endif // !defined(DISABLE_PASS_THROUGH) 1444230557Sjimharris 1445230557Sjimharris// --------------------------------------------------------------------------- 1446230557Sjimharris 1447230557SjimharrisU16 scic_io_request_get_io_tag( 1448230557Sjimharris SCI_IO_REQUEST_HANDLE_T scic_io_request 1449230557Sjimharris) 1450230557Sjimharris{ 1451230557Sjimharris SCIC_SDS_REQUEST_T *this_request; 1452230557Sjimharris this_request = (SCIC_SDS_REQUEST_T *)scic_io_request; 1453230557Sjimharris 1454230557Sjimharris SCIC_LOG_TRACE(( 1455230557Sjimharris sci_base_object_get_logger(scic_io_request), 1456230557Sjimharris SCIC_LOG_OBJECT_SMP_IO_REQUEST, 1457230557Sjimharris "scic_io_request_get_io_tag(0x%x) enter\n", 1458230557Sjimharris scic_io_request 1459230557Sjimharris )); 1460230557Sjimharris 1461230557Sjimharris return this_request->io_tag; 1462230557Sjimharris} 1463230557Sjimharris 1464230557Sjimharris// --------------------------------------------------------------------------- 1465230557Sjimharris 1466230557SjimharrisU32 scic_request_get_controller_status( 1467230557Sjimharris SCI_IO_REQUEST_HANDLE_T io_request 1468230557Sjimharris) 1469230557Sjimharris{ 1470230557Sjimharris SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T*)io_request; 1471230557Sjimharris return this_request->scu_status; 1472230557Sjimharris} 1473230557Sjimharris 1474230557SjimharrisU32 scic_request_get_sci_status( 1475230557Sjimharris SCI_IO_REQUEST_HANDLE_T io_request 1476230557Sjimharris) 1477230557Sjimharris{ 1478230557Sjimharris SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T*)io_request; 1479230557Sjimharris return this_request->sci_status; 1480230557Sjimharris} 1481230557Sjimharris 1482230557Sjimharris// --------------------------------------------------------------------------- 1483230557Sjimharris 1484230557Sjimharrisvoid * scic_io_request_get_rx_frame( 1485230557Sjimharris SCI_IO_REQUEST_HANDLE_T scic_io_request, 1486230557Sjimharris U32 offset 1487230557Sjimharris) 1488230557Sjimharris{ 1489230557Sjimharris void * frame_buffer = NULL; 1490230557Sjimharris SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request; 1491230557Sjimharris 1492230557Sjimharris ASSERT(offset < SCU_UNSOLICITED_FRAME_BUFFER_SIZE); 1493230557Sjimharris 1494230557Sjimharris if (this_request->saved_rx_frame_index != SCU_INVALID_FRAME_INDEX) 1495230557Sjimharris { 1496230557Sjimharris scic_sds_unsolicited_frame_control_get_buffer( 1497230557Sjimharris &(this_request->owning_controller->uf_control), 1498230557Sjimharris this_request->saved_rx_frame_index, 1499230557Sjimharris &frame_buffer 1500230557Sjimharris ); 1501230557Sjimharris } 1502230557Sjimharris 1503230557Sjimharris return frame_buffer; 1504230557Sjimharris} 1505230557Sjimharris 1506230557Sjimharrisvoid * scic_io_request_get_command_iu_address( 1507230557Sjimharris SCI_IO_REQUEST_HANDLE_T scic_io_request 1508230557Sjimharris) 1509230557Sjimharris{ 1510230557Sjimharris SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request; 1511230557Sjimharris 1512230557Sjimharris return this_request->command_buffer; 1513230557Sjimharris} 1514230557Sjimharris 1515230557Sjimharris// --------------------------------------------------------------------------- 1516230557Sjimharris 1517230557Sjimharrisvoid * scic_io_request_get_response_iu_address( 1518230557Sjimharris SCI_IO_REQUEST_HANDLE_T scic_io_request 1519230557Sjimharris) 1520230557Sjimharris{ 1521230557Sjimharris SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request; 1522230557Sjimharris 1523230557Sjimharris return this_request->response_buffer; 1524230557Sjimharris} 1525230557Sjimharris 1526230557Sjimharris// --------------------------------------------------------------------------- 1527230557Sjimharris#define SCU_TASK_CONTEXT_SRAM 0x200000 1528230557SjimharrisU32 scic_io_request_get_number_of_bytes_transferred ( 1529230557Sjimharris SCI_IO_REQUEST_HANDLE_T scic_io_request 1530230557Sjimharris) 1531230557Sjimharris{ 1532230557Sjimharris U32 ret_val = 0; 1533230557Sjimharris SCIC_SDS_REQUEST_T * scic_sds_request; 1534230557Sjimharris 1535230557Sjimharris scic_sds_request = (SCIC_SDS_REQUEST_T *) scic_io_request; 1536230557Sjimharris 1537230557Sjimharris if ( SMU_AMR_READ (scic_sds_request->owning_controller) == 0) 1538230557Sjimharris { 1539230557Sjimharris //get the bytes of data from the Address == BAR1 + 20002Ch + (256*TCi) where 1540230557Sjimharris // BAR1 is the scu_registers 1541230557Sjimharris // 0x20002C = 0x200000 + 0x2c 1542230557Sjimharris // = start of task context SRAM + offset of (type.ssp.data_offset) 1543230557Sjimharris // TCi is the io_tag of SCIC_SDS_REQUEST 1544230557Sjimharris ret_val = scic_sds_pci_read_scu_dword( 1545230557Sjimharris scic_sds_request->owning_controller, 1546230557Sjimharris ( 1547230557Sjimharris (U8 *) scic_sds_request->owning_controller->scu_registers + 1548230557Sjimharris ( SCU_TASK_CONTEXT_SRAM + SCI_FIELD_OFFSET(SCU_TASK_CONTEXT_T, type.ssp.data_offset) ) + 1549230557Sjimharris ( ( sizeof (SCU_TASK_CONTEXT_T) ) * scic_sds_io_tag_get_index (scic_sds_request->io_tag)) 1550230557Sjimharris ) 1551230557Sjimharris ); 1552230557Sjimharris } 1553230557Sjimharris 1554230557Sjimharris return ret_val; 1555230557Sjimharris} 1556230557Sjimharris 1557230557Sjimharris//**************************************************************************** 1558230557Sjimharris//* SCIC SDS Interface Implementation 1559230557Sjimharris//**************************************************************************** 1560230557Sjimharris 1561230557Sjimharris/** 1562230557Sjimharris * This method invokes the base state start request handler for the 1563230557Sjimharris * SCIC_SDS_IO_REQUEST_T object. 1564230557Sjimharris * 1565230557Sjimharris * @param[in] this_request The SCIC_SDS_IO_REQUEST_T object for which the 1566230557Sjimharris * start operation is to be executed. 1567230557Sjimharris * 1568230557Sjimharris * @return SCI_STATUS 1569230557Sjimharris */ 1570230557SjimharrisSCI_STATUS scic_sds_request_start( 1571230557Sjimharris SCIC_SDS_REQUEST_T *this_request 1572230557Sjimharris) 1573230557Sjimharris{ 1574230557Sjimharris if ( 1575230557Sjimharris this_request->device_sequence 1576230557Sjimharris == scic_sds_remote_device_get_sequence(this_request->target_device) 1577230557Sjimharris ) 1578230557Sjimharris { 1579230557Sjimharris return this_request->state_handlers->parent.start_handler( 1580230557Sjimharris &this_request->parent 1581230557Sjimharris ); 1582230557Sjimharris } 1583230557Sjimharris 1584230557Sjimharris return SCI_FAILURE; 1585230557Sjimharris} 1586230557Sjimharris 1587230557Sjimharris/** 1588230557Sjimharris * This method invokes the base state terminate request handber for the 1589230557Sjimharris * SCIC_SDS_IO_REQUEST_T object. 1590230557Sjimharris * 1591230557Sjimharris * @param[in] this_request The SCIC_SDS_IO_REQUEST_T object for which the 1592230557Sjimharris * start operation is to be executed. 1593230557Sjimharris * 1594230557Sjimharris * @return SCI_STATUS 1595230557Sjimharris */ 1596230557SjimharrisSCI_STATUS scic_sds_io_request_terminate( 1597230557Sjimharris SCIC_SDS_REQUEST_T *this_request 1598230557Sjimharris) 1599230557Sjimharris{ 1600230557Sjimharris return this_request->state_handlers->parent.abort_handler( 1601230557Sjimharris &this_request->parent); 1602230557Sjimharris} 1603230557Sjimharris 1604230557Sjimharris/** 1605230557Sjimharris * This method invokes the base state request completion handler for the 1606230557Sjimharris * SCIC_SDS_IO_REQUEST_T object. 1607230557Sjimharris * 1608230557Sjimharris * @param[in] this_request The SCIC_SDS_IO_REQUEST_T object for which the 1609230557Sjimharris * start operation is to be executed. 1610230557Sjimharris * 1611230557Sjimharris * @return SCI_STATUS 1612230557Sjimharris */ 1613230557SjimharrisSCI_STATUS scic_sds_io_request_complete( 1614230557Sjimharris SCIC_SDS_REQUEST_T *this_request 1615230557Sjimharris) 1616230557Sjimharris{ 1617230557Sjimharris return this_request->state_handlers->parent.complete_handler( 1618230557Sjimharris &this_request->parent); 1619230557Sjimharris} 1620230557Sjimharris 1621230557Sjimharris/** 1622230557Sjimharris * This method invokes the core state handler for the SCIC_SDS_IO_REQUEST_T 1623230557Sjimharris * object. 1624230557Sjimharris * 1625230557Sjimharris * @param[in] this_request The SCIC_SDS_IO_REQUEST_T object for which the 1626230557Sjimharris * start operation is to be executed. 1627230557Sjimharris * @param[in] event_code The event code returned by the hardware for the task 1628230557Sjimharris * reqeust. 1629230557Sjimharris * 1630230557Sjimharris * @return SCI_STATUS 1631230557Sjimharris */ 1632230557SjimharrisSCI_STATUS scic_sds_io_request_event_handler( 1633230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 1634230557Sjimharris U32 event_code 1635230557Sjimharris) 1636230557Sjimharris{ 1637230557Sjimharris return this_request->state_handlers->event_handler(this_request, event_code); 1638230557Sjimharris} 1639230557Sjimharris 1640230557Sjimharris/** 1641230557Sjimharris * This method invokes the core state frame handler for the 1642230557Sjimharris * SCIC_SDS_IO_REQUEST_T object. 1643230557Sjimharris * 1644230557Sjimharris * @param[in] this_request The SCIC_SDS_IO_REQUEST_T object for which the 1645230557Sjimharris * start operation is to be executed. 1646230557Sjimharris * @param[in] frame_index The frame index returned by the hardware for the 1647230557Sjimharris * reqeust object. 1648230557Sjimharris * 1649230557Sjimharris * @return SCI_STATUS 1650230557Sjimharris */ 1651230557SjimharrisSCI_STATUS scic_sds_io_request_frame_handler( 1652230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 1653230557Sjimharris U32 frame_index 1654230557Sjimharris) 1655230557Sjimharris{ 1656230557Sjimharris return this_request->state_handlers->frame_handler(this_request, frame_index); 1657230557Sjimharris} 1658230557Sjimharris 1659230557Sjimharris/** 1660230557Sjimharris * This method invokes the core state task complete handler for the 1661230557Sjimharris * SCIC_SDS_IO_REQUEST_T object. 1662230557Sjimharris * 1663230557Sjimharris * @param[in] this_request The SCIC_SDS_IO_REQUEST_T object for which the task 1664230557Sjimharris * start operation is to be executed. 1665230557Sjimharris * 1666230557Sjimharris * @return SCI_STATUS 1667230557Sjimharris */ 1668230557SjimharrisSCI_STATUS scic_sds_task_request_complete( 1669230557Sjimharris SCIC_SDS_REQUEST_T *this_request 1670230557Sjimharris) 1671230557Sjimharris{ 1672230557Sjimharris return this_request->state_handlers->parent.complete_handler(&this_request->parent); 1673230557Sjimharris} 1674230557Sjimharris 1675230557Sjimharris//**************************************************************************** 1676230557Sjimharris//* SCIC SDS PROTECTED METHODS 1677230557Sjimharris//**************************************************************************** 1678230557Sjimharris 1679230557Sjimharris/** 1680230557Sjimharris * @brief This method copies response data for requests returning response 1681230557Sjimharris * data instead of sense data. 1682230557Sjimharris * 1683230557Sjimharris * @param[in] this_request This parameter specifies the request object for 1684230557Sjimharris * which to copy the response data. 1685230557Sjimharris * 1686230557Sjimharris * @return none 1687230557Sjimharris */ 1688230557Sjimharrisvoid scic_sds_io_request_copy_response( 1689230557Sjimharris SCIC_SDS_REQUEST_T *this_request 1690230557Sjimharris) 1691230557Sjimharris{ 1692230557Sjimharris void * response_buffer; 1693230557Sjimharris U32 user_response_length; 1694230557Sjimharris U32 core_response_length; 1695230557Sjimharris SCI_SSP_RESPONSE_IU_T * ssp_response; 1696230557Sjimharris 1697230557Sjimharris ssp_response = (SCI_SSP_RESPONSE_IU_T *)this_request->response_buffer; 1698230557Sjimharris 1699230557Sjimharris response_buffer = scic_cb_ssp_task_request_get_response_data_address( 1700230557Sjimharris this_request->user_request 1701230557Sjimharris ); 1702230557Sjimharris 1703230557Sjimharris user_response_length = scic_cb_ssp_task_request_get_response_data_length( 1704230557Sjimharris this_request->user_request 1705230557Sjimharris ); 1706230557Sjimharris 1707230557Sjimharris core_response_length = sci_ssp_get_response_data_length( 1708230557Sjimharris ssp_response->response_data_length 1709230557Sjimharris ); 1710230557Sjimharris 1711230557Sjimharris user_response_length = MIN(user_response_length, core_response_length); 1712230557Sjimharris 1713230557Sjimharris memcpy(response_buffer, ssp_response->data, user_response_length); 1714230557Sjimharris} 1715230557Sjimharris 1716230557Sjimharris//****************************************************************************** 1717230557Sjimharris//* REQUEST STATE MACHINE 1718230557Sjimharris//****************************************************************************** 1719230557Sjimharris 1720230557Sjimharris//***************************************************************************** 1721230557Sjimharris//* DEFAULT STATE HANDLERS 1722230557Sjimharris//***************************************************************************** 1723230557Sjimharris 1724230557Sjimharris/** 1725230557Sjimharris * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T 1726230557Sjimharris * object receives a scic_sds_request_start() request. The default action is 1727230557Sjimharris * to log a warning and return a failure status. 1728230557Sjimharris * 1729230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 1730230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 1731230557Sjimharris * requested. 1732230557Sjimharris * 1733230557Sjimharris * @return SCI_STATUS 1734230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 1735230557Sjimharris */ 1736230557SjimharrisSCI_STATUS scic_sds_request_default_start_handler( 1737230557Sjimharris SCI_BASE_REQUEST_T *request 1738230557Sjimharris) 1739230557Sjimharris{ 1740230557Sjimharris SCIC_LOG_WARNING(( 1741230557Sjimharris sci_base_object_get_logger((SCIC_SDS_REQUEST_T *)request), 1742230557Sjimharris ( 1743230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST 1744230557Sjimharris | SCIC_LOG_OBJECT_STP_IO_REQUEST 1745230557Sjimharris | SCIC_LOG_OBJECT_SMP_IO_REQUEST 1746230557Sjimharris ), 1747230557Sjimharris "SCIC IO Request requested to start while in wrong state %d\n", 1748230557Sjimharris sci_base_state_machine_get_state( 1749230557Sjimharris &((SCIC_SDS_REQUEST_T *)request)->parent.state_machine) 1750230557Sjimharris )); 1751230557Sjimharris 1752230557Sjimharris return SCI_FAILURE_INVALID_STATE; 1753230557Sjimharris} 1754230557Sjimharris 1755230557Sjimharris/** 1756230557Sjimharris * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T 1757230557Sjimharris * object receives a scic_sds_request_terminate() request. The default action 1758230557Sjimharris * is to log a warning and return a failure status. 1759230557Sjimharris * 1760230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 1761230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 1762230557Sjimharris * requested. 1763230557Sjimharris * 1764230557Sjimharris * @return SCI_STATUS 1765230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 1766230557Sjimharris */ 1767230557SjimharrisSCI_STATUS scic_sds_request_default_abort_handler( 1768230557Sjimharris SCI_BASE_REQUEST_T *request 1769230557Sjimharris) 1770230557Sjimharris{ 1771230557Sjimharris SCIC_LOG_WARNING(( 1772230557Sjimharris sci_base_object_get_logger((SCIC_SDS_REQUEST_T *)request), 1773230557Sjimharris ( 1774230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST 1775230557Sjimharris | SCIC_LOG_OBJECT_STP_IO_REQUEST 1776230557Sjimharris | SCIC_LOG_OBJECT_SMP_IO_REQUEST 1777230557Sjimharris ), 1778230557Sjimharris "SCIC IO Request requested to abort while in wrong state %d\n", 1779230557Sjimharris sci_base_state_machine_get_state( 1780230557Sjimharris &((SCIC_SDS_REQUEST_T *)request)->parent.state_machine) 1781230557Sjimharris )); 1782230557Sjimharris 1783230557Sjimharris return SCI_FAILURE_INVALID_STATE; 1784230557Sjimharris} 1785230557Sjimharris 1786230557Sjimharris/** 1787230557Sjimharris * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T 1788230557Sjimharris * object receives a scic_sds_request_complete() request. The default action 1789230557Sjimharris * is to log a warning and return a failure status. 1790230557Sjimharris * 1791230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 1792230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 1793230557Sjimharris * requested. 1794230557Sjimharris * 1795230557Sjimharris * @return SCI_STATUS 1796230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 1797230557Sjimharris */ 1798230557SjimharrisSCI_STATUS scic_sds_request_default_complete_handler( 1799230557Sjimharris SCI_BASE_REQUEST_T *request 1800230557Sjimharris) 1801230557Sjimharris{ 1802230557Sjimharris SCIC_LOG_WARNING(( 1803230557Sjimharris sci_base_object_get_logger((SCIC_SDS_REQUEST_T *)request), 1804230557Sjimharris ( 1805230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST 1806230557Sjimharris | SCIC_LOG_OBJECT_STP_IO_REQUEST 1807230557Sjimharris | SCIC_LOG_OBJECT_SMP_IO_REQUEST 1808230557Sjimharris ), 1809230557Sjimharris "SCIC IO Request requested to complete while in wrong state %d\n", 1810230557Sjimharris sci_base_state_machine_get_state( 1811230557Sjimharris &((SCIC_SDS_REQUEST_T *)request)->parent.state_machine) 1812230557Sjimharris )); 1813230557Sjimharris 1814230557Sjimharris return SCI_FAILURE_INVALID_STATE; 1815230557Sjimharris} 1816230557Sjimharris 1817230557Sjimharris/** 1818230557Sjimharris * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T 1819230557Sjimharris * object receives a scic_sds_request_complete() request. The default action 1820230557Sjimharris * is to log a warning and return a failure status. 1821230557Sjimharris * 1822230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 1823230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 1824230557Sjimharris * requested. 1825230557Sjimharris * 1826230557Sjimharris * @return SCI_STATUS 1827230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 1828230557Sjimharris */ 1829230557SjimharrisSCI_STATUS scic_sds_request_default_destruct_handler( 1830230557Sjimharris SCI_BASE_REQUEST_T *request 1831230557Sjimharris) 1832230557Sjimharris{ 1833230557Sjimharris SCIC_LOG_WARNING(( 1834230557Sjimharris sci_base_object_get_logger((SCIC_SDS_REQUEST_T *)request), 1835230557Sjimharris ( 1836230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST 1837230557Sjimharris | SCIC_LOG_OBJECT_STP_IO_REQUEST 1838230557Sjimharris | SCIC_LOG_OBJECT_SMP_IO_REQUEST 1839230557Sjimharris ), 1840230557Sjimharris "SCIC IO Request requested to destroy while in wrong state %d\n", 1841230557Sjimharris sci_base_state_machine_get_state( 1842230557Sjimharris &((SCIC_SDS_REQUEST_T *)request)->parent.state_machine) 1843230557Sjimharris )); 1844230557Sjimharris 1845230557Sjimharris return SCI_FAILURE_INVALID_STATE; 1846230557Sjimharris} 1847230557Sjimharris 1848230557Sjimharris/** 1849230557Sjimharris * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T 1850230557Sjimharris * object receives a scic_sds_task_request_complete() request. The default 1851230557Sjimharris * action is to log a warning and return a failure status. 1852230557Sjimharris * 1853230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 1854230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 1855230557Sjimharris * requested. 1856230557Sjimharris * 1857230557Sjimharris * @return SCI_STATUS 1858230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 1859230557Sjimharris */ 1860230557SjimharrisSCI_STATUS scic_sds_request_default_tc_completion_handler( 1861230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 1862230557Sjimharris U32 completion_code 1863230557Sjimharris) 1864230557Sjimharris{ 1865230557Sjimharris SCIC_LOG_WARNING(( 1866230557Sjimharris sci_base_object_get_logger(this_request), 1867230557Sjimharris ( 1868230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST 1869230557Sjimharris | SCIC_LOG_OBJECT_STP_IO_REQUEST 1870230557Sjimharris | SCIC_LOG_OBJECT_SMP_IO_REQUEST 1871230557Sjimharris ), 1872230557Sjimharris "SCIC IO Request given task completion notification %x while in wrong state %d\n", 1873230557Sjimharris completion_code, 1874230557Sjimharris sci_base_state_machine_get_state(&this_request->parent.state_machine) 1875230557Sjimharris )); 1876230557Sjimharris 1877230557Sjimharris return SCI_FAILURE_INVALID_STATE; 1878230557Sjimharris 1879230557Sjimharris} 1880230557Sjimharris 1881230557Sjimharris/** 1882230557Sjimharris * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T 1883230557Sjimharris * object receives a scic_sds_request_event_handler() request. The default 1884230557Sjimharris * action is to log a warning and return a failure status. 1885230557Sjimharris * 1886230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 1887230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 1888230557Sjimharris * requested. 1889230557Sjimharris * 1890230557Sjimharris * @return SCI_STATUS 1891230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 1892230557Sjimharris */ 1893230557SjimharrisSCI_STATUS scic_sds_request_default_event_handler( 1894230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 1895230557Sjimharris U32 event_code 1896230557Sjimharris) 1897230557Sjimharris{ 1898230557Sjimharris SCIC_LOG_WARNING(( 1899230557Sjimharris sci_base_object_get_logger(this_request), 1900230557Sjimharris ( 1901230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST 1902230557Sjimharris | SCIC_LOG_OBJECT_STP_IO_REQUEST 1903230557Sjimharris | SCIC_LOG_OBJECT_SMP_IO_REQUEST 1904230557Sjimharris ), 1905230557Sjimharris "SCIC IO Request given event code notification %x while in wrong state %d\n", 1906230557Sjimharris event_code, 1907230557Sjimharris sci_base_state_machine_get_state(&this_request->parent.state_machine) 1908230557Sjimharris )); 1909230557Sjimharris 1910230557Sjimharris return SCI_FAILURE_INVALID_STATE; 1911230557Sjimharris} 1912230557Sjimharris 1913230557Sjimharris/** 1914230557Sjimharris * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T 1915230557Sjimharris * object receives a scic_sds_request_event_handler() request. The default 1916230557Sjimharris * action is to log a warning and return a failure status. 1917230557Sjimharris * 1918230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 1919230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 1920230557Sjimharris * requested. 1921230557Sjimharris * 1922230557Sjimharris * @return SCI_STATUS 1923230557Sjimharris * @retval SCI_FAILURE_INVALID_STATE 1924230557Sjimharris */ 1925230557SjimharrisSCI_STATUS scic_sds_request_default_frame_handler( 1926230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 1927230557Sjimharris U32 frame_index 1928230557Sjimharris) 1929230557Sjimharris{ 1930230557Sjimharris SCIC_LOG_WARNING(( 1931230557Sjimharris sci_base_object_get_logger(this_request), 1932230557Sjimharris ( 1933230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST 1934230557Sjimharris | SCIC_LOG_OBJECT_STP_IO_REQUEST 1935230557Sjimharris | SCIC_LOG_OBJECT_SMP_IO_REQUEST 1936230557Sjimharris ), 1937230557Sjimharris "SCIC IO Request given unexpected frame %x while in state %d\n", 1938230557Sjimharris frame_index, 1939230557Sjimharris sci_base_state_machine_get_state(&this_request->parent.state_machine) 1940230557Sjimharris )); 1941230557Sjimharris 1942230557Sjimharris scic_sds_controller_release_frame( 1943230557Sjimharris this_request->owning_controller, frame_index); 1944230557Sjimharris 1945230557Sjimharris return SCI_FAILURE_INVALID_STATE; 1946230557Sjimharris} 1947230557Sjimharris 1948230557Sjimharris//***************************************************************************** 1949230557Sjimharris//* CONSTRUCTED STATE HANDLERS 1950230557Sjimharris//***************************************************************************** 1951230557Sjimharris 1952230557Sjimharris/** 1953230557Sjimharris * This method implements the action taken when a constructed 1954230557Sjimharris * SCIC_SDS_IO_REQUEST_T object receives a scic_sds_request_start() request. 1955230557Sjimharris * 1956230557Sjimharris * This method will, if necessary, allocate a TCi for the io request object 1957230557Sjimharris * and then will, if necessary, copy the constructed TC data into the actual 1958230557Sjimharris * TC buffer. If everything is successful the post context field is updated 1959230557Sjimharris * with the TCi so the controller can post the request to the hardware. 1960230557Sjimharris * 1961230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 1962230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 1963230557Sjimharris * requested. 1964230557Sjimharris * 1965230557Sjimharris * @return SCI_STATUS 1966230557Sjimharris * @retval SCI_SUCCESS 1967230557Sjimharris * @retval SCI_FAILURE_INSUFFICIENT_RESOURCES 1968230557Sjimharris */ 1969230557Sjimharrisstatic 1970230557SjimharrisSCI_STATUS scic_sds_request_constructed_state_start_handler( 1971230557Sjimharris SCI_BASE_REQUEST_T *request 1972230557Sjimharris) 1973230557Sjimharris{ 1974230557Sjimharris SCU_TASK_CONTEXT_T *task_context; 1975230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)request; 1976230557Sjimharris 1977230557Sjimharris if (this_request->io_tag == SCI_CONTROLLER_INVALID_IO_TAG) 1978230557Sjimharris { 1979230557Sjimharris this_request->io_tag = 1980230557Sjimharris scic_controller_allocate_io_tag(this_request->owning_controller); 1981230557Sjimharris } 1982230557Sjimharris 1983230557Sjimharris // Record the IO Tag in the request 1984230557Sjimharris if (this_request->io_tag != SCI_CONTROLLER_INVALID_IO_TAG) 1985230557Sjimharris { 1986230557Sjimharris task_context = this_request->task_context_buffer; 1987230557Sjimharris 1988230557Sjimharris task_context->task_index = scic_sds_io_tag_get_index(this_request->io_tag); 1989230557Sjimharris 1990230557Sjimharris switch (task_context->protocol_type) 1991230557Sjimharris { 1992230557Sjimharris case SCU_TASK_CONTEXT_PROTOCOL_SMP: 1993230557Sjimharris case SCU_TASK_CONTEXT_PROTOCOL_SSP: 1994230557Sjimharris // SSP/SMP Frame 1995230557Sjimharris task_context->type.ssp.tag = this_request->io_tag; 1996230557Sjimharris task_context->type.ssp.target_port_transfer_tag = 0xFFFF; 1997230557Sjimharris break; 1998230557Sjimharris 1999230557Sjimharris case SCU_TASK_CONTEXT_PROTOCOL_STP: 2000230557Sjimharris // STP/SATA Frame 2001230557Sjimharris //task_context->type.stp.ncq_tag = this_request->ncq_tag; 2002230557Sjimharris break; 2003230557Sjimharris 2004230557Sjimharris case SCU_TASK_CONTEXT_PROTOCOL_NONE: 2005230557Sjimharris /// @todo When do we set no protocol type? 2006230557Sjimharris break; 2007230557Sjimharris 2008230557Sjimharris default: 2009230557Sjimharris // This should never happen since we build the IO requests 2010230557Sjimharris break; 2011230557Sjimharris } 2012230557Sjimharris 2013230557Sjimharris // Check to see if we need to copy the task context buffer 2014230557Sjimharris // or have been building into the task context buffer 2015230557Sjimharris if (this_request->was_tag_assigned_by_user == FALSE) 2016230557Sjimharris { 2017230557Sjimharris scic_sds_controller_copy_task_context( 2018230557Sjimharris this_request->owning_controller, this_request 2019230557Sjimharris ); 2020230557Sjimharris } 2021230557Sjimharris 2022230557Sjimharris // Add to the post_context the io tag value 2023230557Sjimharris this_request->post_context |= scic_sds_io_tag_get_index(this_request->io_tag); 2024230557Sjimharris 2025230557Sjimharris // Everything is good go ahead and change state 2026230557Sjimharris sci_base_state_machine_change_state( 2027230557Sjimharris &this_request->parent.state_machine, 2028230557Sjimharris SCI_BASE_REQUEST_STATE_STARTED 2029230557Sjimharris ); 2030230557Sjimharris 2031230557Sjimharris return SCI_SUCCESS; 2032230557Sjimharris } 2033230557Sjimharris 2034230557Sjimharris return SCI_FAILURE_INSUFFICIENT_RESOURCES; 2035230557Sjimharris} 2036230557Sjimharris 2037230557Sjimharris/** 2038230557Sjimharris * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T 2039230557Sjimharris * object receives a scic_sds_request_terminate() request. 2040230557Sjimharris * 2041230557Sjimharris * Since the request has not yet been posted to the hardware the request 2042230557Sjimharris * transitions to the completed state. 2043230557Sjimharris * 2044230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 2045230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 2046230557Sjimharris * requested. 2047230557Sjimharris * 2048230557Sjimharris * @return SCI_STATUS 2049230557Sjimharris * @retval SCI_SUCCESS 2050230557Sjimharris */ 2051230557Sjimharrisstatic 2052230557SjimharrisSCI_STATUS scic_sds_request_constructed_state_abort_handler( 2053230557Sjimharris SCI_BASE_REQUEST_T *request 2054230557Sjimharris) 2055230557Sjimharris{ 2056230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)request; 2057230557Sjimharris 2058230557Sjimharris // This request has been terminated by the user make sure that the correct 2059230557Sjimharris // status code is returned 2060230557Sjimharris scic_sds_request_set_status( 2061230557Sjimharris this_request, 2062230557Sjimharris SCU_TASK_DONE_TASK_ABORT, 2063230557Sjimharris SCI_FAILURE_IO_TERMINATED 2064230557Sjimharris ); 2065230557Sjimharris 2066230557Sjimharris sci_base_state_machine_change_state( 2067230557Sjimharris &this_request->parent.state_machine, 2068230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 2069230557Sjimharris ); 2070230557Sjimharris 2071230557Sjimharris return SCI_SUCCESS; 2072230557Sjimharris} 2073230557Sjimharris 2074230557Sjimharris//***************************************************************************** 2075230557Sjimharris//* STARTED STATE HANDLERS 2076230557Sjimharris//***************************************************************************** 2077230557Sjimharris 2078230557Sjimharris/** 2079230557Sjimharris * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T 2080230557Sjimharris * object receives a scic_sds_request_terminate() request. 2081230557Sjimharris * 2082230557Sjimharris * Since the request has been posted to the hardware the io request state is 2083230557Sjimharris * changed to the aborting state. 2084230557Sjimharris * 2085230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 2086230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 2087230557Sjimharris * requested. 2088230557Sjimharris * 2089230557Sjimharris * @return SCI_STATUS 2090230557Sjimharris * @retval SCI_SUCCESS 2091230557Sjimharris */ 2092230557SjimharrisSCI_STATUS scic_sds_request_started_state_abort_handler( 2093230557Sjimharris SCI_BASE_REQUEST_T *request 2094230557Sjimharris) 2095230557Sjimharris{ 2096230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)request; 2097230557Sjimharris 2098230557Sjimharris if (this_request->has_started_substate_machine) 2099230557Sjimharris { 2100230557Sjimharris sci_base_state_machine_stop(&this_request->started_substate_machine); 2101230557Sjimharris } 2102230557Sjimharris 2103230557Sjimharris sci_base_state_machine_change_state( 2104230557Sjimharris &this_request->parent.state_machine, 2105230557Sjimharris SCI_BASE_REQUEST_STATE_ABORTING 2106230557Sjimharris ); 2107230557Sjimharris 2108230557Sjimharris return SCI_SUCCESS; 2109230557Sjimharris} 2110230557Sjimharris 2111230557Sjimharris/** 2112230557Sjimharris * @brief This method process TC (task context) completions for normal IO 2113230557Sjimharris * request (i.e. Task/Abort Completions of type 0). This method will 2114230557Sjimharris * update the SCIC_SDS_IO_REQUEST_T::status field. 2115230557Sjimharris * 2116230557Sjimharris * @param[in] this_request This parameter specifies the request for which 2117230557Sjimharris * a completion occurred. 2118230557Sjimharris * @param[in] completion_code This parameter specifies the completion code 2119230557Sjimharris * recieved from the SCU. 2120230557Sjimharris * 2121230557Sjimharris * @return none 2122230557Sjimharris */ 2123230557SjimharrisSCI_STATUS scic_sds_request_started_state_tc_completion_handler( 2124230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 2125230557Sjimharris U32 completion_code 2126230557Sjimharris) 2127230557Sjimharris{ 2128230557Sjimharris U8 data_present; 2129230557Sjimharris SCI_SSP_RESPONSE_IU_T * response_buffer; 2130230557Sjimharris 2131230557Sjimharris /** 2132230557Sjimharris * @todo Any SDMA return code of other than 0 is bad 2133230557Sjimharris * decode 0x003C0000 to determine SDMA status 2134230557Sjimharris */ 2135230557Sjimharris switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 2136230557Sjimharris { 2137230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 2138230557Sjimharris scic_sds_request_set_status( 2139230557Sjimharris this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 2140230557Sjimharris ); 2141230557Sjimharris break; 2142230557Sjimharris 2143230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EARLY_RESP): 2144230557Sjimharris { 2145230557Sjimharris // There are times when the SCU hardware will return an early response 2146230557Sjimharris // because the io request specified more data than is returned by the 2147230557Sjimharris // target device (mode pages, inquiry data, etc.). We must check the 2148230557Sjimharris // response stats to see if this is truly a failed request or a good 2149230557Sjimharris // request that just got completed early. 2150230557Sjimharris SCI_SSP_RESPONSE_IU_T *response = (SCI_SSP_RESPONSE_IU_T *) 2151230557Sjimharris this_request->response_buffer; 2152230557Sjimharris scic_word_copy_with_swap( 2153230557Sjimharris this_request->response_buffer, 2154230557Sjimharris this_request->response_buffer, 2155230557Sjimharris sizeof(SCI_SSP_RESPONSE_IU_T) / sizeof(U32) 2156230557Sjimharris ); 2157230557Sjimharris 2158230557Sjimharris if (response->status == 0) 2159230557Sjimharris { 2160230557Sjimharris scic_sds_request_set_status( 2161230557Sjimharris this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS_IO_DONE_EARLY 2162230557Sjimharris ); 2163230557Sjimharris } 2164230557Sjimharris else 2165230557Sjimharris { 2166230557Sjimharris scic_sds_request_set_status( 2167230557Sjimharris this_request, 2168230557Sjimharris SCU_TASK_DONE_CHECK_RESPONSE, 2169230557Sjimharris SCI_FAILURE_IO_RESPONSE_VALID 2170230557Sjimharris ); 2171230557Sjimharris } 2172230557Sjimharris } 2173230557Sjimharris break; 2174230557Sjimharris 2175230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CHECK_RESPONSE): 2176230557Sjimharris scic_word_copy_with_swap( 2177230557Sjimharris this_request->response_buffer, 2178230557Sjimharris this_request->response_buffer, 2179230557Sjimharris sizeof(SCI_SSP_RESPONSE_IU_T) / sizeof(U32) 2180230557Sjimharris ); 2181230557Sjimharris 2182230557Sjimharris scic_sds_request_set_status( 2183230557Sjimharris this_request, 2184230557Sjimharris SCU_TASK_DONE_CHECK_RESPONSE, 2185230557Sjimharris SCI_FAILURE_IO_RESPONSE_VALID 2186230557Sjimharris ); 2187230557Sjimharris break; 2188230557Sjimharris 2189230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RESP_LEN_ERR): 2190230557Sjimharris /// @todo With TASK_DONE_RESP_LEN_ERR is the response frame guaranteed 2191230557Sjimharris /// to be received before this completion status is posted? 2192230557Sjimharris response_buffer = 2193230557Sjimharris (SCI_SSP_RESPONSE_IU_T *)this_request->response_buffer; 2194230557Sjimharris data_present = 2195230557Sjimharris response_buffer->data_present & SCI_SSP_RESPONSE_IU_DATA_PRESENT_MASK; 2196230557Sjimharris 2197230557Sjimharris if ((data_present == 0x01) || (data_present == 0x02)) 2198230557Sjimharris { 2199230557Sjimharris scic_sds_request_set_status( 2200230557Sjimharris this_request, 2201230557Sjimharris SCU_TASK_DONE_CHECK_RESPONSE, 2202230557Sjimharris SCI_FAILURE_IO_RESPONSE_VALID 2203230557Sjimharris ); 2204230557Sjimharris } 2205230557Sjimharris else 2206230557Sjimharris { 2207230557Sjimharris scic_sds_request_set_status( 2208230557Sjimharris this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 2209230557Sjimharris ); 2210230557Sjimharris } 2211230557Sjimharris break; 2212230557Sjimharris 2213230557Sjimharris //only stp device gets suspended. 2214230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_ACK_NAK_TO): 2215230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_PERR): 2216230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_NAK_ERR): 2217230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_DATA_LEN_ERR): 2218230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_ABORT_ERR): 2219230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_XR_WD_LEN): 2220230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR): 2221230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_RESP): 2222230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_SDBFIS): 2223230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR): 2224230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDB_ERR): 2225230557Sjimharris if (this_request->protocol == SCIC_STP_PROTOCOL) 2226230557Sjimharris { 2227230557Sjimharris SCIC_LOG_ERROR(( 2228230557Sjimharris sci_base_object_get_logger(this_request), 2229230557Sjimharris SCIC_LOG_OBJECT_STP_IO_REQUEST, 2230230557Sjimharris "SCIC IO Request 0x%x returning REMOTE_DEVICE_RESET_REQUIRED for completion code 0x%x\n", 2231230557Sjimharris this_request, completion_code 2232230557Sjimharris )); 2233230557Sjimharris scic_sds_request_set_status( 2234230557Sjimharris this_request, 2235230557Sjimharris SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT, 2236230557Sjimharris SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED 2237230557Sjimharris ); 2238230557Sjimharris } 2239230557Sjimharris else 2240230557Sjimharris { 2241230557Sjimharris SCIC_LOG_ERROR(( 2242230557Sjimharris sci_base_object_get_logger(this_request), 2243230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST, 2244230557Sjimharris "SCIC IO Request 0x%x returning CONTROLLER_SPECIFIC_IO_ERR for completion code 0x%x\n", 2245230557Sjimharris this_request, completion_code 2246230557Sjimharris )); 2247230557Sjimharris scic_sds_request_set_status( 2248230557Sjimharris this_request, 2249230557Sjimharris SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT, 2250230557Sjimharris SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 2251230557Sjimharris ); 2252230557Sjimharris } 2253230557Sjimharris break; 2254230557Sjimharris 2255230557Sjimharris //both stp/ssp device gets suspended 2256230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LF_ERR): 2257230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_WRONG_DESTINATION): 2258230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1): 2259230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2): 2260230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3): 2261230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_BAD_DESTINATION): 2262230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_ZONE_VIOLATION): 2263230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY): 2264230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED): 2265230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED): 2266230557Sjimharris scic_sds_request_set_status( 2267230557Sjimharris this_request, 2268230557Sjimharris SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT, 2269230557Sjimharris SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED 2270230557Sjimharris ); 2271230557Sjimharris break; 2272230557Sjimharris 2273230557Sjimharris //neither ssp nor stp gets suspended. 2274230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_NAK_CMD_ERR): 2275230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_XR): 2276230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_XR_IU_LEN_ERR): 2277230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDMA_ERR): 2278230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_OFFSET_ERR): 2279230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EXCESS_DATA): 2280230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_RESP_TO_ERR): 2281230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_UFI_ERR): 2282230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_FRM_TYPE_ERR): 2283230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_LL_RX_ERR): 2284230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_DATA): 2285230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_OPEN_FAIL): 2286230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_VIIT_ENTRY_NV): 2287230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_IIT_ENTRY_NV): 2288230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RNCNV_OUTBOUND): 2289230557Sjimharris default: 2290230557Sjimharris SCIC_LOG_ERROR(( 2291230557Sjimharris sci_base_object_get_logger(this_request), 2292230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST | SCIC_LOG_OBJECT_STP_IO_REQUEST, 2293230557Sjimharris "SCIC IO Request 0x%x returning CONTROLLER_SPECIFIC_IO_ERR for completion code 0x%x\n", 2294230557Sjimharris this_request, completion_code 2295230557Sjimharris )); 2296230557Sjimharris scic_sds_request_set_status( 2297230557Sjimharris this_request, 2298230557Sjimharris SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT, 2299230557Sjimharris SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 2300230557Sjimharris ); 2301230557Sjimharris break; 2302230557Sjimharris } 2303230557Sjimharris 2304230557Sjimharris /** 2305230557Sjimharris * @todo This is probably wrong for ACK/NAK timeout conditions 2306230557Sjimharris */ 2307230557Sjimharris 2308230557Sjimharris // In all cases we will treat this as the completion of the IO request. 2309230557Sjimharris sci_base_state_machine_change_state( 2310230557Sjimharris &this_request->parent.state_machine, 2311230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 2312230557Sjimharris ); 2313230557Sjimharris 2314230557Sjimharris return SCI_SUCCESS; 2315230557Sjimharris} 2316230557Sjimharris 2317230557Sjimharris/** 2318230557Sjimharris * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T 2319230557Sjimharris * object receives a scic_sds_request_frame_handler() request. 2320230557Sjimharris * 2321230557Sjimharris * This method first determines the frame type received. If this is a 2322230557Sjimharris * response frame then the response data is copied to the io request response 2323230557Sjimharris * buffer for processing at completion time. 2324230557Sjimharris * 2325230557Sjimharris * If the frame type is not a response buffer an error is logged. 2326230557Sjimharris * 2327230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 2328230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 2329230557Sjimharris * requested. 2330230557Sjimharris * @param[in] frame_index This is the index of the unsolicited frame to be 2331230557Sjimharris * processed. 2332230557Sjimharris * 2333230557Sjimharris * @return SCI_STATUS 2334230557Sjimharris * @retval SCI_SUCCESS 2335230557Sjimharris * @retval SCI_FAILURE_INVALID_PARAMETER_VALUE 2336230557Sjimharris */ 2337230557Sjimharrisstatic 2338230557SjimharrisSCI_STATUS scic_sds_request_started_state_frame_handler( 2339230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 2340230557Sjimharris U32 frame_index 2341230557Sjimharris) 2342230557Sjimharris{ 2343230557Sjimharris SCI_STATUS status; 2344230557Sjimharris SCI_SSP_FRAME_HEADER_T *frame_header; 2345230557Sjimharris 2346230557Sjimharris /// @todo If this is a response frame we must record that we received it 2347230557Sjimharris status = scic_sds_unsolicited_frame_control_get_header( 2348230557Sjimharris &(scic_sds_request_get_controller(this_request)->uf_control), 2349230557Sjimharris frame_index, 2350230557Sjimharris (void**) &frame_header 2351230557Sjimharris ); 2352230557Sjimharris 2353230557Sjimharris if (frame_header->frame_type == SCI_SAS_RESPONSE_FRAME) 2354230557Sjimharris { 2355230557Sjimharris SCI_SSP_RESPONSE_IU_T *response_buffer; 2356230557Sjimharris 2357230557Sjimharris status = scic_sds_unsolicited_frame_control_get_buffer( 2358230557Sjimharris &(scic_sds_request_get_controller(this_request)->uf_control), 2359230557Sjimharris frame_index, 2360230557Sjimharris (void**) &response_buffer 2361230557Sjimharris ); 2362230557Sjimharris 2363230557Sjimharris scic_word_copy_with_swap( 2364230557Sjimharris this_request->response_buffer, 2365230557Sjimharris (U32 *)response_buffer, 2366230557Sjimharris sizeof(SCI_SSP_RESPONSE_IU_T) 2367230557Sjimharris ); 2368230557Sjimharris 2369230557Sjimharris response_buffer = (SCI_SSP_RESPONSE_IU_T *)this_request->response_buffer; 2370230557Sjimharris 2371230557Sjimharris if ( 2372230557Sjimharris (response_buffer->data_present == 0x01) 2373230557Sjimharris || (response_buffer->data_present == 0x02) 2374230557Sjimharris ) 2375230557Sjimharris { 2376230557Sjimharris scic_sds_request_set_status( 2377230557Sjimharris this_request, 2378230557Sjimharris SCU_TASK_DONE_CHECK_RESPONSE, 2379230557Sjimharris SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 2380230557Sjimharris ); 2381230557Sjimharris } 2382230557Sjimharris else 2383230557Sjimharris { 2384230557Sjimharris scic_sds_request_set_status( 2385230557Sjimharris this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 2386230557Sjimharris ); 2387230557Sjimharris } 2388230557Sjimharris 2389230557Sjimharris } 2390230557Sjimharris else 2391230557Sjimharris { 2392230557Sjimharris // This was not a response frame why did it get forwarded? 2393230557Sjimharris SCIC_LOG_ERROR(( 2394230557Sjimharris sci_base_object_get_logger(this_request), 2395230557Sjimharris SCIC_LOG_OBJECT_SSP_IO_REQUEST, 2396230557Sjimharris "SCIC IO Request 0x%x received unexpected frame %d type 0x%02x\n", 2397230557Sjimharris this_request, frame_index, frame_header->frame_type 2398230557Sjimharris )); 2399230557Sjimharris } 2400230557Sjimharris 2401230557Sjimharris // In any case we are done with this frame buffer return it to the 2402230557Sjimharris // controller 2403230557Sjimharris scic_sds_controller_release_frame( 2404230557Sjimharris this_request->owning_controller, frame_index 2405230557Sjimharris ); 2406230557Sjimharris 2407230557Sjimharris return SCI_SUCCESS; 2408230557Sjimharris} 2409230557Sjimharris 2410230557Sjimharris//***************************************************************************** 2411230557Sjimharris//* COMPLETED STATE HANDLERS 2412230557Sjimharris//***************************************************************************** 2413230557Sjimharris 2414230557Sjimharris 2415230557Sjimharris/** 2416230557Sjimharris * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T 2417230557Sjimharris * object receives a scic_sds_request_complete() request. 2418230557Sjimharris * 2419230557Sjimharris * This method frees up any io request resources that have been allocated and 2420230557Sjimharris * transitions the request to its final state. 2421230557Sjimharris * 2422230557Sjimharris * @todo Consider stopping the state machine instead of transitioning to the 2423230557Sjimharris * final state? 2424230557Sjimharris * 2425230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 2426230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 2427230557Sjimharris * requested. 2428230557Sjimharris * 2429230557Sjimharris * @return SCI_STATUS 2430230557Sjimharris * @retval SCI_SUCCESS 2431230557Sjimharris */ 2432230557Sjimharrisstatic 2433230557SjimharrisSCI_STATUS scic_sds_request_completed_state_complete_handler( 2434230557Sjimharris SCI_BASE_REQUEST_T *request 2435230557Sjimharris) 2436230557Sjimharris{ 2437230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)request; 2438230557Sjimharris 2439230557Sjimharris if (this_request->was_tag_assigned_by_user != TRUE) 2440230557Sjimharris { 2441230557Sjimharris scic_controller_free_io_tag( 2442230557Sjimharris this_request->owning_controller, this_request->io_tag 2443230557Sjimharris ); 2444230557Sjimharris } 2445230557Sjimharris 2446230557Sjimharris if (this_request->saved_rx_frame_index != SCU_INVALID_FRAME_INDEX) 2447230557Sjimharris { 2448230557Sjimharris scic_sds_controller_release_frame( 2449230557Sjimharris this_request->owning_controller, this_request->saved_rx_frame_index); 2450230557Sjimharris } 2451230557Sjimharris 2452230557Sjimharris sci_base_state_machine_change_state( 2453230557Sjimharris &this_request->parent.state_machine, 2454230557Sjimharris SCI_BASE_REQUEST_STATE_FINAL 2455230557Sjimharris ); 2456230557Sjimharris 2457230557Sjimharris scic_sds_request_deinitialize_state_logging(this_request); 2458230557Sjimharris 2459230557Sjimharris return SCI_SUCCESS; 2460230557Sjimharris} 2461230557Sjimharris 2462230557Sjimharris//***************************************************************************** 2463230557Sjimharris//* ABORTING STATE HANDLERS 2464230557Sjimharris//***************************************************************************** 2465230557Sjimharris 2466230557Sjimharris/** 2467230557Sjimharris * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T 2468230557Sjimharris * object receives a scic_sds_request_terminate() request. 2469230557Sjimharris * 2470230557Sjimharris * This method is the io request aborting state abort handlers. On receipt of 2471230557Sjimharris * a multiple terminate requests the io request will transition to the 2472230557Sjimharris * completed state. This should not happen in normal operation. 2473230557Sjimharris * 2474230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 2475230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 2476230557Sjimharris * requested. 2477230557Sjimharris * 2478230557Sjimharris * @return SCI_STATUS 2479230557Sjimharris * @retval SCI_SUCCESS 2480230557Sjimharris */ 2481230557Sjimharrisstatic 2482230557SjimharrisSCI_STATUS scic_sds_request_aborting_state_abort_handler( 2483230557Sjimharris SCI_BASE_REQUEST_T *request 2484230557Sjimharris) 2485230557Sjimharris{ 2486230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)request; 2487230557Sjimharris 2488230557Sjimharris sci_base_state_machine_change_state( 2489230557Sjimharris &this_request->parent.state_machine, 2490230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 2491230557Sjimharris ); 2492230557Sjimharris 2493230557Sjimharris return SCI_SUCCESS; 2494230557Sjimharris} 2495230557Sjimharris 2496230557Sjimharris/** 2497230557Sjimharris * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T 2498230557Sjimharris * object receives a scic_sds_request_task_completion() request. 2499230557Sjimharris * 2500230557Sjimharris * This method decodes the completion type waiting for the abort task complete 2501230557Sjimharris * notification. When the abort task complete is received the io request 2502230557Sjimharris * transitions to the completed state. 2503230557Sjimharris * 2504230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 2505230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 2506230557Sjimharris * requested. 2507230557Sjimharris * 2508230557Sjimharris * @return SCI_STATUS 2509230557Sjimharris * @retval SCI_SUCCESS 2510230557Sjimharris */ 2511230557Sjimharrisstatic 2512230557SjimharrisSCI_STATUS scic_sds_request_aborting_state_tc_completion_handler( 2513230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 2514230557Sjimharris U32 completion_code 2515230557Sjimharris) 2516230557Sjimharris{ 2517230557Sjimharris SCIC_LOG_TRACE(( 2518230557Sjimharris sci_base_object_get_logger(this_request), 2519230557Sjimharris SCIC_LOG_OBJECT_TASK_MANAGEMENT, 2520230557Sjimharris "scic_sds_request_aborting_state_tc_completion_handler(0x%x,0x%x) enter\n", 2521230557Sjimharris this_request, completion_code 2522230557Sjimharris )); 2523230557Sjimharris 2524230557Sjimharris switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 2525230557Sjimharris { 2526230557Sjimharris case (SCU_TASK_DONE_GOOD << SCU_COMPLETION_TL_STATUS_SHIFT): 2527230557Sjimharris case (SCU_TASK_DONE_TASK_ABORT << SCU_COMPLETION_TL_STATUS_SHIFT): 2528230557Sjimharris scic_sds_request_set_status( 2529230557Sjimharris this_request, SCU_TASK_DONE_TASK_ABORT, SCI_FAILURE_IO_TERMINATED 2530230557Sjimharris ); 2531230557Sjimharris 2532230557Sjimharris sci_base_state_machine_change_state( 2533230557Sjimharris &this_request->parent.state_machine, 2534230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 2535230557Sjimharris ); 2536230557Sjimharris break; 2537230557Sjimharris 2538230557Sjimharris default: 2539230557Sjimharris // Unless we get some strange error wait for the task abort to complete 2540230557Sjimharris // TODO: Should there be a state change for this completion? 2541230557Sjimharris break; 2542230557Sjimharris } 2543230557Sjimharris 2544230557Sjimharris return SCI_SUCCESS; 2545230557Sjimharris} 2546230557Sjimharris 2547230557Sjimharris/** 2548230557Sjimharris * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T 2549230557Sjimharris * object receives a scic_sds_request_frame_handler() request. 2550230557Sjimharris * 2551230557Sjimharris * This method discards the unsolicited frame since we are waiting for the 2552230557Sjimharris * abort task completion. 2553230557Sjimharris * 2554230557Sjimharris * @param[in] request This is the SCI_BASE_REQUEST_T object that is cast to 2555230557Sjimharris * the SCIC_SDS_IO_REQUEST_T object for which the start operation is 2556230557Sjimharris * requested. 2557230557Sjimharris * 2558230557Sjimharris * @return SCI_STATUS 2559230557Sjimharris * @retval SCI_SUCCESS 2560230557Sjimharris */ 2561230557Sjimharrisstatic 2562230557SjimharrisSCI_STATUS scic_sds_request_aborting_state_frame_handler( 2563230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 2564230557Sjimharris U32 frame_index 2565230557Sjimharris) 2566230557Sjimharris{ 2567230557Sjimharris // TODO: Is it even possible to get an unsolicited frame in the aborting state? 2568230557Sjimharris 2569230557Sjimharris scic_sds_controller_release_frame( 2570230557Sjimharris this_request->owning_controller, frame_index); 2571230557Sjimharris 2572230557Sjimharris return SCI_SUCCESS; 2573230557Sjimharris} 2574230557Sjimharris 2575230557Sjimharris// --------------------------------------------------------------------------- 2576230557Sjimharris 2577230557SjimharrisSCIC_SDS_IO_REQUEST_STATE_HANDLER_T 2578230557Sjimharris scic_sds_request_state_handler_table[SCI_BASE_REQUEST_MAX_STATES] = 2579230557Sjimharris{ 2580230557Sjimharris // SCI_BASE_REQUEST_STATE_INITIAL 2581230557Sjimharris { 2582230557Sjimharris { 2583230557Sjimharris scic_sds_request_default_start_handler, 2584230557Sjimharris scic_sds_request_default_abort_handler, 2585230557Sjimharris scic_sds_request_default_complete_handler, 2586230557Sjimharris scic_sds_request_default_destruct_handler 2587230557Sjimharris }, 2588230557Sjimharris scic_sds_request_default_tc_completion_handler, 2589230557Sjimharris scic_sds_request_default_event_handler, 2590230557Sjimharris scic_sds_request_default_frame_handler 2591230557Sjimharris }, 2592230557Sjimharris // SCI_BASE_REQUEST_STATE_CONSTRUCTED 2593230557Sjimharris { 2594230557Sjimharris { 2595230557Sjimharris scic_sds_request_constructed_state_start_handler, 2596230557Sjimharris scic_sds_request_constructed_state_abort_handler, 2597230557Sjimharris scic_sds_request_default_complete_handler, 2598230557Sjimharris scic_sds_request_default_destruct_handler 2599230557Sjimharris }, 2600230557Sjimharris scic_sds_request_default_tc_completion_handler, 2601230557Sjimharris scic_sds_request_default_event_handler, 2602230557Sjimharris scic_sds_request_default_frame_handler 2603230557Sjimharris }, 2604230557Sjimharris // SCI_BASE_REQUEST_STATE_STARTED 2605230557Sjimharris { 2606230557Sjimharris { 2607230557Sjimharris scic_sds_request_default_start_handler, 2608230557Sjimharris scic_sds_request_started_state_abort_handler, 2609230557Sjimharris scic_sds_request_default_complete_handler, 2610230557Sjimharris scic_sds_request_default_destruct_handler 2611230557Sjimharris }, 2612230557Sjimharris scic_sds_request_started_state_tc_completion_handler, 2613230557Sjimharris scic_sds_request_default_event_handler, 2614230557Sjimharris scic_sds_request_started_state_frame_handler 2615230557Sjimharris }, 2616230557Sjimharris // SCI_BASE_REQUEST_STATE_COMPLETED 2617230557Sjimharris { 2618230557Sjimharris { 2619230557Sjimharris scic_sds_request_default_start_handler, 2620230557Sjimharris scic_sds_request_default_abort_handler, 2621230557Sjimharris scic_sds_request_completed_state_complete_handler, 2622230557Sjimharris scic_sds_request_default_destruct_handler 2623230557Sjimharris }, 2624230557Sjimharris scic_sds_request_default_tc_completion_handler, 2625230557Sjimharris scic_sds_request_default_event_handler, 2626230557Sjimharris scic_sds_request_default_frame_handler 2627230557Sjimharris }, 2628230557Sjimharris // SCI_BASE_REQUEST_STATE_ABORTING 2629230557Sjimharris { 2630230557Sjimharris { 2631230557Sjimharris scic_sds_request_default_start_handler, 2632230557Sjimharris scic_sds_request_aborting_state_abort_handler, 2633230557Sjimharris scic_sds_request_default_complete_handler, 2634230557Sjimharris scic_sds_request_default_destruct_handler 2635230557Sjimharris }, 2636230557Sjimharris scic_sds_request_aborting_state_tc_completion_handler, 2637230557Sjimharris scic_sds_request_default_event_handler, 2638230557Sjimharris scic_sds_request_aborting_state_frame_handler, 2639230557Sjimharris }, 2640230557Sjimharris // SCI_BASE_REQUEST_STATE_FINAL 2641230557Sjimharris { 2642230557Sjimharris { 2643230557Sjimharris scic_sds_request_default_start_handler, 2644230557Sjimharris scic_sds_request_default_abort_handler, 2645230557Sjimharris scic_sds_request_default_complete_handler, 2646230557Sjimharris scic_sds_request_default_destruct_handler 2647230557Sjimharris }, 2648230557Sjimharris scic_sds_request_default_tc_completion_handler, 2649230557Sjimharris scic_sds_request_default_event_handler, 2650230557Sjimharris scic_sds_request_default_frame_handler 2651230557Sjimharris } 2652230557Sjimharris}; 2653230557Sjimharris 2654230557Sjimharris/** 2655230557Sjimharris * This method implements the actions taken when entering the 2656230557Sjimharris * SCI_BASE_REQUEST_STATE_INITIAL state. This state is entered when the 2657230557Sjimharris * initial base request is constructed. Entry into the initial state sets all 2658230557Sjimharris * handlers for the io request object to their default handlers. 2659230557Sjimharris * 2660230557Sjimharris * @param[in] object This parameter specifies the base object for which the 2661230557Sjimharris * state transition is occurring. 2662230557Sjimharris * 2663230557Sjimharris * @return none 2664230557Sjimharris */ 2665230557Sjimharrisstatic 2666230557Sjimharrisvoid scic_sds_request_initial_state_enter( 2667230557Sjimharris SCI_BASE_OBJECT_T *object 2668230557Sjimharris) 2669230557Sjimharris{ 2670230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2671230557Sjimharris 2672230557Sjimharris SET_STATE_HANDLER( 2673230557Sjimharris this_request, 2674230557Sjimharris scic_sds_request_state_handler_table, 2675230557Sjimharris SCI_BASE_REQUEST_STATE_INITIAL 2676230557Sjimharris ); 2677230557Sjimharris} 2678230557Sjimharris 2679230557Sjimharris/** 2680230557Sjimharris * This method implements the actions taken when entering the 2681230557Sjimharris * SCI_BASE_REQUEST_STATE_CONSTRUCTED state. 2682230557Sjimharris * The method sets the state handlers for the the constructed state. 2683230557Sjimharris * 2684230557Sjimharris * @param[in] object The io request object that is to enter the constructed 2685230557Sjimharris * state. 2686230557Sjimharris * 2687230557Sjimharris * @return none 2688230557Sjimharris */ 2689230557Sjimharrisstatic 2690230557Sjimharrisvoid scic_sds_request_constructed_state_enter( 2691230557Sjimharris SCI_BASE_OBJECT_T *object 2692230557Sjimharris) 2693230557Sjimharris{ 2694230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2695230557Sjimharris 2696230557Sjimharris SET_STATE_HANDLER( 2697230557Sjimharris this_request, 2698230557Sjimharris scic_sds_request_state_handler_table, 2699230557Sjimharris SCI_BASE_REQUEST_STATE_CONSTRUCTED 2700230557Sjimharris ); 2701230557Sjimharris} 2702230557Sjimharris 2703230557Sjimharris/** 2704230557Sjimharris * This method implements the actions taken when entering the 2705230557Sjimharris * SCI_BASE_REQUEST_STATE_STARTED state. If the io request object type is a 2706230557Sjimharris * SCSI Task request we must enter the started substate machine. 2707230557Sjimharris * 2708230557Sjimharris * @param[in] object This parameter specifies the base object for which the 2709230557Sjimharris * state transition is occuring. This is cast into a 2710230557Sjimharris * SCIC_SDS_IO_REQUEST object. 2711230557Sjimharris * 2712230557Sjimharris * @return none 2713230557Sjimharris */ 2714230557Sjimharrisstatic 2715230557Sjimharrisvoid scic_sds_request_started_state_enter( 2716230557Sjimharris SCI_BASE_OBJECT_T *object 2717230557Sjimharris) 2718230557Sjimharris{ 2719230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2720230557Sjimharris 2721230557Sjimharris SET_STATE_HANDLER( 2722230557Sjimharris this_request, 2723230557Sjimharris scic_sds_request_state_handler_table, 2724230557Sjimharris SCI_BASE_REQUEST_STATE_STARTED 2725230557Sjimharris ); 2726230557Sjimharris 2727230557Sjimharris // Most of the request state machines have a started substate machine so 2728230557Sjimharris // start its execution on the entry to the started state. 2729230557Sjimharris if (this_request->has_started_substate_machine == TRUE) 2730230557Sjimharris sci_base_state_machine_start(&this_request->started_substate_machine); 2731230557Sjimharris} 2732230557Sjimharris 2733230557Sjimharris/** 2734230557Sjimharris * This method implements the actions taken when exiting the 2735230557Sjimharris * SCI_BASE_REQUEST_STATE_STARTED state. For task requests the action will be 2736230557Sjimharris * to stop the started substate machine. 2737230557Sjimharris * 2738230557Sjimharris * @param[in] object This parameter specifies the base object for which the 2739230557Sjimharris * state transition is occuring. This object is cast into a 2740230557Sjimharris * SCIC_SDS_IO_REQUEST object. 2741230557Sjimharris * 2742230557Sjimharris * @return none 2743230557Sjimharris */ 2744230557Sjimharrisstatic 2745230557Sjimharrisvoid scic_sds_request_started_state_exit( 2746230557Sjimharris SCI_BASE_OBJECT_T *object 2747230557Sjimharris) 2748230557Sjimharris{ 2749230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2750230557Sjimharris 2751230557Sjimharris if (this_request->has_started_substate_machine == TRUE) 2752230557Sjimharris sci_base_state_machine_stop(&this_request->started_substate_machine); 2753230557Sjimharris} 2754230557Sjimharris 2755230557Sjimharris/** 2756230557Sjimharris * This method implements the actions taken when entering the 2757230557Sjimharris * SCI_BASE_REQUEST_STATE_COMPLETED state. This state is entered when the 2758230557Sjimharris * SCIC_SDS_IO_REQUEST has completed. The method will decode the request 2759230557Sjimharris * completion status and convert it to an SCI_STATUS to return in the 2760230557Sjimharris * completion callback function. 2761230557Sjimharris * 2762230557Sjimharris * @param[in] object This parameter specifies the base object for which the 2763230557Sjimharris * state transition is occuring. This object is cast into a 2764230557Sjimharris * SCIC_SDS_IO_REQUEST object. 2765230557Sjimharris * 2766230557Sjimharris * @return none 2767230557Sjimharris */ 2768230557Sjimharrisstatic 2769230557Sjimharrisvoid scic_sds_request_completed_state_enter( 2770230557Sjimharris SCI_BASE_OBJECT_T *object 2771230557Sjimharris) 2772230557Sjimharris{ 2773230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2774230557Sjimharris 2775230557Sjimharris SET_STATE_HANDLER( 2776230557Sjimharris this_request, 2777230557Sjimharris scic_sds_request_state_handler_table, 2778230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 2779230557Sjimharris ); 2780230557Sjimharris 2781230557Sjimharris // Tell the SCI_USER that the IO request is complete 2782230557Sjimharris if (this_request->is_task_management_request == FALSE) 2783230557Sjimharris { 2784230557Sjimharris scic_cb_io_request_complete( 2785230557Sjimharris scic_sds_request_get_controller(this_request), 2786230557Sjimharris scic_sds_request_get_device(this_request), 2787230557Sjimharris this_request, 2788230557Sjimharris this_request->sci_status 2789230557Sjimharris ); 2790230557Sjimharris } 2791230557Sjimharris else 2792230557Sjimharris { 2793230557Sjimharris scic_cb_task_request_complete( 2794230557Sjimharris scic_sds_request_get_controller(this_request), 2795230557Sjimharris scic_sds_request_get_device(this_request), 2796230557Sjimharris this_request, 2797230557Sjimharris this_request->sci_status 2798230557Sjimharris ); 2799230557Sjimharris } 2800230557Sjimharris} 2801230557Sjimharris 2802230557Sjimharris/** 2803230557Sjimharris * This method implements the actions taken when entering the 2804230557Sjimharris * SCI_BASE_REQUEST_STATE_ABORTING state. 2805230557Sjimharris * 2806230557Sjimharris * @param[in] object This parameter specifies the base object for which the 2807230557Sjimharris * state transition is occuring. This object is cast into a 2808230557Sjimharris * SCIC_SDS_IO_REQUEST object. 2809230557Sjimharris * 2810230557Sjimharris * @return none 2811230557Sjimharris */ 2812230557Sjimharrisstatic 2813230557Sjimharrisvoid scic_sds_request_aborting_state_enter( 2814230557Sjimharris SCI_BASE_OBJECT_T *object 2815230557Sjimharris) 2816230557Sjimharris{ 2817230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2818230557Sjimharris 2819230557Sjimharris // Setting the abort bit in the Task Context is required by the silicon. 2820230557Sjimharris this_request->task_context_buffer->abort = 1; 2821230557Sjimharris 2822230557Sjimharris SET_STATE_HANDLER( 2823230557Sjimharris this_request, 2824230557Sjimharris scic_sds_request_state_handler_table, 2825230557Sjimharris SCI_BASE_REQUEST_STATE_ABORTING 2826230557Sjimharris ); 2827230557Sjimharris} 2828230557Sjimharris 2829230557Sjimharris/** 2830230557Sjimharris * This method implements the actions taken when entering the 2831230557Sjimharris * SCI_BASE_REQUEST_STATE_FINAL state. The only action required is to put the 2832230557Sjimharris * state handlers in place. 2833230557Sjimharris * 2834230557Sjimharris * @param[in] object This parameter specifies the base object for which the 2835230557Sjimharris * state transition is occuring. This is cast into a 2836230557Sjimharris * SCIC_SDS_IO_REQUEST object. 2837230557Sjimharris * 2838230557Sjimharris * @return none 2839230557Sjimharris */ 2840230557Sjimharrisstatic 2841230557Sjimharrisvoid scic_sds_request_final_state_enter( 2842230557Sjimharris SCI_BASE_OBJECT_T *object 2843230557Sjimharris) 2844230557Sjimharris{ 2845230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2846230557Sjimharris 2847230557Sjimharris SET_STATE_HANDLER( 2848230557Sjimharris this_request, 2849230557Sjimharris scic_sds_request_state_handler_table, 2850230557Sjimharris SCI_BASE_REQUEST_STATE_FINAL 2851230557Sjimharris ); 2852230557Sjimharris} 2853230557Sjimharris 2854230557Sjimharris// --------------------------------------------------------------------------- 2855230557Sjimharris 2856230557SjimharrisSCI_BASE_STATE_T 2857230557Sjimharris scic_sds_request_state_table[SCI_BASE_REQUEST_MAX_STATES] = 2858230557Sjimharris{ 2859230557Sjimharris { 2860230557Sjimharris SCI_BASE_REQUEST_STATE_INITIAL, 2861230557Sjimharris scic_sds_request_initial_state_enter, 2862230557Sjimharris NULL 2863230557Sjimharris }, 2864230557Sjimharris { 2865230557Sjimharris SCI_BASE_REQUEST_STATE_CONSTRUCTED, 2866230557Sjimharris scic_sds_request_constructed_state_enter, 2867230557Sjimharris NULL 2868230557Sjimharris }, 2869230557Sjimharris { 2870230557Sjimharris SCI_BASE_REQUEST_STATE_STARTED, 2871230557Sjimharris scic_sds_request_started_state_enter, 2872230557Sjimharris scic_sds_request_started_state_exit 2873230557Sjimharris }, 2874230557Sjimharris { 2875230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED, 2876230557Sjimharris scic_sds_request_completed_state_enter, 2877230557Sjimharris NULL 2878230557Sjimharris }, 2879230557Sjimharris { 2880230557Sjimharris SCI_BASE_REQUEST_STATE_ABORTING, 2881230557Sjimharris scic_sds_request_aborting_state_enter, 2882230557Sjimharris NULL 2883230557Sjimharris }, 2884230557Sjimharris { 2885230557Sjimharris SCI_BASE_REQUEST_STATE_FINAL, 2886230557Sjimharris scic_sds_request_final_state_enter, 2887230557Sjimharris NULL 2888230557Sjimharris } 2889230557Sjimharris}; 2890230557Sjimharris 2891