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#include <dev/isci/scil/scic_sds_smp_request.h> 57230557Sjimharris#include <dev/isci/scil/scic_sds_logger.h> 58230557Sjimharris#include <dev/isci/scil/scic_sds_controller.h> 59230557Sjimharris#include <dev/isci/scil/scic_sds_remote_device.h> 60230557Sjimharris#include <dev/isci/scil/scic_remote_device.h> 61230557Sjimharris#include <dev/isci/scil/sci_util.h> 62230557Sjimharris#include <dev/isci/sci_environment.h> 63230557Sjimharris#include <dev/isci/scil/intel_sas.h> 64230557Sjimharris#include <dev/isci/scil/scic_sds_request.h> 65230557Sjimharris#include <dev/isci/scil/scic_controller.h> 66230557Sjimharris#include <dev/isci/scil/scu_completion_codes.h> 67230557Sjimharris#include <dev/isci/scil/scu_task_context.h> 68230557Sjimharris#include <dev/isci/scil/sci_base_state_machine.h> 69230557Sjimharris 70230557Sjimharris/** 71230557Sjimharris * This method return the memory space required for STP PIO requests. 72230557Sjimharris * 73230557Sjimharris * @return U32 74230557Sjimharris */ 75230557SjimharrisU32 scic_sds_smp_request_get_object_size(void) 76230557Sjimharris{ 77230557Sjimharris return sizeof(SCIC_SDS_REQUEST_T) 78230557Sjimharris + sizeof(SMP_REQUEST_T) 79230557Sjimharris + sizeof(U32) 80230557Sjimharris + sizeof(SMP_RESPONSE_T) 81230557Sjimharris + sizeof(U32) 82230557Sjimharris + sizeof(SCU_TASK_CONTEXT_T) 83230557Sjimharris + CACHE_LINE_SIZE; 84230557Sjimharris} 85230557Sjimharris 86230557Sjimharris/** 87230557Sjimharris * This macro returns the address of the smp command buffer in the smp request 88230557Sjimharris * memory. No need to cast to SMP request type. 89230557Sjimharris */ 90230557Sjimharris#define scic_sds_smp_request_get_command_buffer_unaligned(memory) \ 91230557Sjimharris ( ((char *)(memory)) + sizeof(SCIC_SDS_REQUEST_T) ) 92230557Sjimharris 93230557Sjimharris/** 94230557Sjimharris * This macro aligns the smp command buffer in DWORD alignment 95230557Sjimharris*/ 96230557Sjimharris#define scic_sds_smp_request_align_command_buffer(address) \ 97230557Sjimharris ((char *)( \ 98230557Sjimharris (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \ 99230557Sjimharris & ~(sizeof(U32)- 1) \ 100230557Sjimharris )) 101230557Sjimharris 102230557Sjimharris/** 103230557Sjimharris * This macro returns the DWORD-aligned smp command buffer 104230557Sjimharris*/ 105230557Sjimharris#define scic_sds_smp_request_get_command_buffer(memory) \ 106230557Sjimharris ((char *) \ 107230557Sjimharris ((char *)scic_sds_smp_request_align_command_buffer( \ 108230557Sjimharris (char *) scic_sds_smp_request_get_command_buffer_unaligned(memory) \ 109230557Sjimharris ))) 110230557Sjimharris 111230557Sjimharris/** 112230557Sjimharris * This macro returns the address of the smp response buffer in the smp request 113230557Sjimharris * memory. 114230557Sjimharris */ 115230557Sjimharris#define scic_sds_smp_request_get_response_buffer_unaligned(memory) \ 116230557Sjimharris ( ((char *)(scic_sds_smp_request_get_command_buffer(memory))) \ 117230557Sjimharris + sizeof(SMP_REQUEST_T) ) 118230557Sjimharris 119230557Sjimharris/** 120230557Sjimharris * This macro aligns the smp command buffer in DWORD alignment 121230557Sjimharris*/ 122230557Sjimharris#define scic_sds_smp_request_align_response_buffer(address) \ 123230557Sjimharris ((char *)( \ 124230557Sjimharris (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \ 125230557Sjimharris & ~(sizeof(U32)- 1) \ 126230557Sjimharris )) 127230557Sjimharris 128230557Sjimharris/** 129230557Sjimharris * This macro returns the DWORD-aligned smp resposne buffer 130230557Sjimharris*/ 131230557Sjimharris#define scic_sds_smp_request_get_response_buffer(memory) \ 132230557Sjimharris ((char *) \ 133230557Sjimharris ((char *)scic_sds_smp_request_align_response_buffer( \ 134230557Sjimharris (char *) scic_sds_smp_request_get_response_buffer_unaligned(memory) \ 135230557Sjimharris ))) 136230557Sjimharris 137230557Sjimharris/** 138230557Sjimharris * This macro returs the task context buffer for the SMP request. 139230557Sjimharris */ 140230557Sjimharris#define scic_sds_smp_request_get_task_context_buffer_unaligned(memory) \ 141230557Sjimharris ((SCU_TASK_CONTEXT_T *)( \ 142230557Sjimharris ((char *)(scic_sds_smp_request_get_response_buffer(memory))) \ 143230557Sjimharris + sizeof(SMP_RESPONSE_T) \ 144230557Sjimharris )) 145230557Sjimharris 146230557Sjimharris/** 147230557Sjimharris * This macro returns the dword-aligned smp task context buffer 148230557Sjimharris */ 149230557Sjimharris#define scic_sds_smp_request_get_task_context_buffer(memory) \ 150230557Sjimharris ((SCU_TASK_CONTEXT_T *)( \ 151230557Sjimharris ((char *)scic_sds_request_align_task_context_buffer( \ 152230557Sjimharris (char *)scic_sds_smp_request_get_task_context_buffer_unaligned(memory)) \ 153230557Sjimharris ))) 154230557Sjimharris 155230557Sjimharris/** 156230557Sjimharris * @brief This method build the remainder of the IO request object. 157230557Sjimharris * 158230557Sjimharris * @pre The scic_sds_general_request_construct() must be called before this 159230557Sjimharris * call is valid. 160230557Sjimharris * 161230557Sjimharris * @param[in] this_request This parameter specifies the request object being 162230557Sjimharris * constructed. 163230557Sjimharris * 164230557Sjimharris * @return none 165230557Sjimharris */ 166230557Sjimharris 167230557Sjimharrisvoid scic_sds_smp_request_assign_buffers( 168230557Sjimharris SCIC_SDS_REQUEST_T *this_request 169230557Sjimharris) 170230557Sjimharris{ 171230557Sjimharris // Assign all of the buffer pointers 172230557Sjimharris this_request->command_buffer = 173230557Sjimharris scic_sds_smp_request_get_command_buffer(this_request); 174230557Sjimharris this_request->response_buffer = 175230557Sjimharris scic_sds_smp_request_get_response_buffer(this_request); 176230557Sjimharris this_request->sgl_element_pair_buffer = NULL; 177230557Sjimharris 178230557Sjimharris if (this_request->was_tag_assigned_by_user == FALSE) 179230557Sjimharris { 180230557Sjimharris this_request->task_context_buffer = 181230557Sjimharris scic_sds_smp_request_get_task_context_buffer(this_request); 182230557Sjimharris } 183230557Sjimharris 184230557Sjimharris} 185230557Sjimharris/** 186230557Sjimharris * @brief This method is called by the SCI user to build an SMP 187230557Sjimharris * IO request. 188230557Sjimharris * 189230557Sjimharris * @pre 190230557Sjimharris * - The user must have previously called scic_io_request_construct() 191230557Sjimharris * on the supplied IO request. 192230557Sjimharris * 193230557Sjimharris * @param[in] scic_io_request This parameter specifies the handle to the 194230557Sjimharris * io request object to be built. 195230557Sjimharris * 196230557Sjimharris * @return Indicate if the controller successfully built the IO request. 197230557Sjimharris * @retval SCI_SUCCESS This value is returned if the IO request was 198230557Sjimharris * successfully built. 199230557Sjimharris * @retval SCI_FAILURE_UNSUPPORTED_PROTOCOL This value is returned if the 200230557Sjimharris * remote_device does not support the SMP protocol. 201230557Sjimharris * @retval SCI_FAILURE_INVALID_ASSOCIATION This value is returned if the 202230557Sjimharris * user did not properly set the association between the SCIC IO 203230557Sjimharris * request and the user's IO request. Please refer to the 204230557Sjimharris * sci_object_set_association() routine for more 205230557Sjimharris * information. 206230557Sjimharris */ 207230557SjimharrisSCI_STATUS scic_io_request_construct_smp( 208230557Sjimharris SCI_IO_REQUEST_HANDLE_T scic_smp_request 209230557Sjimharris) 210230557Sjimharris{ 211230557Sjimharris SMP_REQUEST_T smp_request; 212230557Sjimharris 213230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *) scic_smp_request; 214230557Sjimharris SCIC_LOG_TRACE(( 215230557Sjimharris sci_base_object_get_logger(this_request), 216230557Sjimharris SCIC_LOG_OBJECT_SMP_IO_REQUEST, 217230557Sjimharris "scic_io_request_construct_smp(0x%x) enter\n", 218230557Sjimharris this_request 219230557Sjimharris )); 220230557Sjimharris 221230557Sjimharris this_request->protocol = SCIC_SMP_PROTOCOL; 222230557Sjimharris this_request->has_started_substate_machine = TRUE; 223230557Sjimharris 224230557Sjimharris // Construct the started sub-state machine. 225230557Sjimharris sci_base_state_machine_construct( 226230557Sjimharris &this_request->started_substate_machine, 227230557Sjimharris &this_request->parent.parent, 228230557Sjimharris scic_sds_smp_request_started_substate_table, 229230557Sjimharris SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE 230230557Sjimharris ); 231230557Sjimharris 232230557Sjimharris // Construct the SMP SCU Task Context 233230557Sjimharris memcpy((char *)&smp_request, 234230557Sjimharris this_request->command_buffer, 235230557Sjimharris sizeof(SMP_REQUEST_T)); 236230557Sjimharris 237230557Sjimharris // Look at the SMP requests' header fields; for certain SAS 1.x SMP 238230557Sjimharris // functions under SAS 2.0, a zero request length really indicates 239230557Sjimharris // a non-zero default length. 240230557Sjimharris if( smp_request.header.request_length == 0 ) 241230557Sjimharris { 242230557Sjimharris switch( smp_request.header.function ) 243230557Sjimharris { 244230557Sjimharris case SMP_FUNCTION_DISCOVER: 245230557Sjimharris case SMP_FUNCTION_REPORT_PHY_ERROR_LOG: 246230557Sjimharris case SMP_FUNCTION_REPORT_PHY_SATA: 247230557Sjimharris case SMP_FUNCTION_REPORT_ROUTE_INFORMATION: 248230557Sjimharris smp_request.header.request_length = 2; 249230557Sjimharris break; 250230557Sjimharris case SMP_FUNCTION_CONFIGURE_ROUTE_INFORMATION: 251230557Sjimharris case SMP_FUNCTION_PHY_CONTROL: 252230557Sjimharris case SMP_FUNCTION_PHY_TEST: 253230557Sjimharris smp_request.header.request_length = 9; 254230557Sjimharris break; 255230557Sjimharris // Default - zero is a valid default for 2.0. 256230557Sjimharris } 257230557Sjimharris } 258230557Sjimharris 259230557Sjimharris scu_smp_request_construct_task_context( 260230557Sjimharris this_request, 261230557Sjimharris &smp_request 262230557Sjimharris ); 263230557Sjimharris 264230557Sjimharris sci_base_state_machine_change_state( 265230557Sjimharris &this_request->parent.state_machine, 266230557Sjimharris SCI_BASE_REQUEST_STATE_CONSTRUCTED 267230557Sjimharris ); 268230557Sjimharris 269230557Sjimharris return SCI_SUCCESS; 270230557Sjimharris} 271230557Sjimharris 272230557Sjimharris/** 273230557Sjimharris * @brief This method is called by the SCI user to build an SMP pass-through 274230557Sjimharris * IO request. 275230557Sjimharris * 276230557Sjimharris * @pre 277230557Sjimharris * - The user must have previously called scic_io_request_construct() 278230557Sjimharris * on the supplied IO request. 279230557Sjimharris * 280230557Sjimharris * @param[in] scic_smp_request This parameter specifies the handle to the 281230557Sjimharris * io request object to be built. 282230557Sjimharris * 283230557Sjimharris * @param[in] passthru_cb This parameter specifies the pointer to the callback 284230557Sjimharris * structure that contains the function pointers 285230557Sjimharris * 286230557Sjimharris * @return Indicate if the controller successfully built the IO request. 287230557Sjimharris */ 288230557SjimharrisSCI_STATUS scic_io_request_construct_smp_pass_through( 289230557Sjimharris SCI_IO_REQUEST_HANDLE_T scic_smp_request, 290230557Sjimharris SCIC_SMP_PASSTHRU_REQUEST_CALLBACKS_T *passthru_cb 291230557Sjimharris) 292230557Sjimharris{ 293230557Sjimharris SMP_REQUEST_T smp_request; 294230557Sjimharris U8 * request_buffer; 295230557Sjimharris U32 request_buffer_length_in_bytes; 296230557Sjimharris 297230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *) scic_smp_request; 298230557Sjimharris SCIC_LOG_TRACE(( 299230557Sjimharris sci_base_object_get_logger(this_request), 300230557Sjimharris SCIC_LOG_OBJECT_SMP_IO_REQUEST, 301230557Sjimharris "scic_io_request_construct_smp_pass_through(0x%x) enter\n", 302230557Sjimharris this_request 303230557Sjimharris )); 304230557Sjimharris 305230557Sjimharris this_request->protocol = SCIC_SMP_PROTOCOL; 306230557Sjimharris this_request->has_started_substate_machine = TRUE; 307230557Sjimharris 308230557Sjimharris // Call the callback function to retrieve the SMP passthrough request 309230557Sjimharris request_buffer_length_in_bytes = passthru_cb->scic_cb_smp_passthru_get_request ( 310230557Sjimharris (void *)this_request, 311230557Sjimharris &request_buffer 312230557Sjimharris ); 313230557Sjimharris 314230557Sjimharris //copy the request to smp request 315230557Sjimharris memcpy((char *)&smp_request.request.vendor_specific_request, 316230557Sjimharris request_buffer, 317230557Sjimharris request_buffer_length_in_bytes); 318230557Sjimharris 319230557Sjimharris //the header length in smp_request is in dwords - the sas spec has similar way, 320230557Sjimharris //but the csmi header contains the number of bytes, so we need to convert the 321230557Sjimharris //number of bytes to number of dwords 322230557Sjimharris smp_request.header.request_length = (U8) (request_buffer_length_in_bytes / sizeof (U32)); 323230557Sjimharris 324230557Sjimharris //Grab the other needed fields from the smp request using callbacks 325230557Sjimharris smp_request.header.smp_frame_type = passthru_cb->scic_cb_smp_passthru_get_frame_type ((void *)this_request); 326230557Sjimharris smp_request.header.function = passthru_cb->scic_cb_smp_passthru_get_function ((void *)this_request); 327230557Sjimharris smp_request.header.allocated_response_length = passthru_cb->scic_cb_smp_passthru_get_allocated_response_length((void *)this_request); 328230557Sjimharris 329230557Sjimharris // Construct the started sub-state machine. 330230557Sjimharris sci_base_state_machine_construct( 331230557Sjimharris &this_request->started_substate_machine, 332230557Sjimharris &this_request->parent.parent, 333230557Sjimharris scic_sds_smp_request_started_substate_table, 334230557Sjimharris SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE 335230557Sjimharris ); 336230557Sjimharris 337230557Sjimharris // Construct the SMP SCU Task Context 338230557Sjimharris scu_smp_request_construct_task_context (this_request, &smp_request); 339230557Sjimharris 340230557Sjimharris sci_base_state_machine_change_state( 341230557Sjimharris &this_request->parent.state_machine, 342230557Sjimharris SCI_BASE_REQUEST_STATE_CONSTRUCTED 343230557Sjimharris ); 344230557Sjimharris 345230557Sjimharris return SCI_SUCCESS; 346230557Sjimharris} 347230557Sjimharris 348230557Sjimharris/** 349230557Sjimharris * @brief This method will fill in the SCU Task Context for a SMP request. The 350230557Sjimharris * following important settings are utilized: 351230557Sjimharris * 352230557Sjimharris * -# task_type == SCU_TASK_TYPE_SMP. This simply indicates 353230557Sjimharris * that a normal request type (i.e. non-raw frame) is being 354230557Sjimharris * utilized to perform task management. 355230557Sjimharris * -# control_frame == 1. This ensures that the proper endianess 356230557Sjimharris * is set so that the bytes are transmitted in the right order 357230557Sjimharris * for a smp request frame. 358230557Sjimharris * 359230557Sjimharris * @param[in] this_request This parameter specifies the smp request object 360230557Sjimharris * being constructed. 361230557Sjimharris * 362230557Sjimharris * @return none 363230557Sjimharris */ 364230557Sjimharrisvoid scu_smp_request_construct_task_context( 365230557Sjimharris SCIC_SDS_REQUEST_T *this_request, 366230557Sjimharris SMP_REQUEST_T *smp_request 367230557Sjimharris) 368230557Sjimharris{ 369230557Sjimharris SCI_PHYSICAL_ADDRESS physical_address; 370230557Sjimharris SCIC_SDS_CONTROLLER_T *owning_controller; 371230557Sjimharris SCIC_SDS_REMOTE_DEVICE_T *target_device; 372230557Sjimharris SCIC_SDS_PORT_T *target_port; 373230557Sjimharris SCU_TASK_CONTEXT_T *task_context; 374230557Sjimharris 375230557Sjimharris //byte swap the smp request. 376230557Sjimharris scic_word_copy_with_swap( 377230557Sjimharris this_request->command_buffer, 378230557Sjimharris (U32*) smp_request, 379230557Sjimharris sizeof(SMP_REQUEST_T)/sizeof(U32) 380230557Sjimharris ); 381230557Sjimharris 382230557Sjimharris task_context = scic_sds_request_get_task_context(this_request); 383230557Sjimharris 384230557Sjimharris owning_controller = scic_sds_request_get_controller(this_request); 385230557Sjimharris target_device = scic_sds_request_get_device(this_request); 386230557Sjimharris target_port = scic_sds_request_get_port(this_request); 387230557Sjimharris 388230557Sjimharris SCIC_LOG_TRACE(( 389230557Sjimharris sci_base_object_get_logger(this_request), 390230557Sjimharris SCIC_LOG_OBJECT_SMP_IO_REQUEST, 391230557Sjimharris "scu_smp_request_construct_task_context(0x%x) contents\n" 392230557Sjimharris " reqlen=%x; function=%x;\n", 393230557Sjimharris this_request, 394230557Sjimharris smp_request->header.request_length, 395230557Sjimharris smp_request->header.function 396230557Sjimharris )); 397230557Sjimharris 398230557Sjimharris // Fill in the TC with the its required data 399230557Sjimharris // 00h 400230557Sjimharris task_context->priority = 0; 401230557Sjimharris task_context->initiator_request = 1; 402230557Sjimharris task_context->connection_rate = 403230557Sjimharris scic_remote_device_get_connection_rate(target_device); 404230557Sjimharris task_context->protocol_engine_index = 405230557Sjimharris scic_sds_controller_get_protocol_engine_group(owning_controller); 406230557Sjimharris task_context->logical_port_index = 407230557Sjimharris scic_sds_port_get_index(target_port); 408230557Sjimharris task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SMP; 409230557Sjimharris task_context->abort = 0; 410230557Sjimharris task_context->valid = SCU_TASK_CONTEXT_VALID; 411230557Sjimharris task_context->context_type = SCU_TASK_CONTEXT_TYPE; 412230557Sjimharris 413230557Sjimharris //04h 414230557Sjimharris task_context->remote_node_index = this_request->target_device->rnc->remote_node_index; 415230557Sjimharris task_context->command_code = 0; 416230557Sjimharris task_context->task_type = SCU_TASK_TYPE_SMP_REQUEST; 417230557Sjimharris 418230557Sjimharris //08h 419230557Sjimharris task_context->link_layer_control = 0; 420230557Sjimharris task_context->do_not_dma_ssp_good_response = 1; 421230557Sjimharris task_context->strict_ordering = 0; 422230557Sjimharris task_context->control_frame = 1; 423230557Sjimharris task_context->timeout_enable = 0; 424230557Sjimharris task_context->block_guard_enable = 0; 425230557Sjimharris 426230557Sjimharris //0ch 427230557Sjimharris task_context->address_modifier = 0; 428230557Sjimharris 429230557Sjimharris //10h 430230557Sjimharris task_context->ssp_command_iu_length = smp_request->header.request_length; 431230557Sjimharris 432230557Sjimharris //14h 433230557Sjimharris task_context->transfer_length_bytes = 0; 434230557Sjimharris 435230557Sjimharris //18h ~ 30h, protocol specific 436230557Sjimharris // since commandIU has been build by framework at this point, we just 437230557Sjimharris // copy the frist DWord from command IU to this location. 438230557Sjimharris memcpy((void *)(&task_context->type.smp), this_request->command_buffer, sizeof(U32) ); 439230557Sjimharris 440230557Sjimharris //40h 441230557Sjimharris // "For SMP you could program it to zero. We would prefer that way so that 442230557Sjimharris // done code will be consistent." - Venki 443230557Sjimharris task_context->task_phase = 0; 444230557Sjimharris 445230557Sjimharris if (this_request->was_tag_assigned_by_user) 446230557Sjimharris { 447230557Sjimharris // Build the task context now since we have already read the data 448230557Sjimharris this_request->post_context = ( 449230557Sjimharris SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC 450230557Sjimharris | ( 451230557Sjimharris scic_sds_controller_get_protocol_engine_group(owning_controller) 452230557Sjimharris << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT 453230557Sjimharris ) 454230557Sjimharris | ( 455230557Sjimharris scic_sds_port_get_index(target_port) 456230557Sjimharris << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT 457230557Sjimharris ) 458230557Sjimharris | scic_sds_io_tag_get_index(this_request->io_tag) 459230557Sjimharris ); 460230557Sjimharris } 461230557Sjimharris else 462230557Sjimharris { 463230557Sjimharris // Build the task context now since we have already read the data 464230557Sjimharris this_request->post_context = ( 465230557Sjimharris SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC 466230557Sjimharris | ( 467230557Sjimharris scic_sds_controller_get_protocol_engine_group(owning_controller) 468230557Sjimharris << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT 469230557Sjimharris ) 470230557Sjimharris | ( 471230557Sjimharris scic_sds_port_get_index(target_port) 472230557Sjimharris << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT 473230557Sjimharris ) 474230557Sjimharris // This is not assigned because we have to wait until we get a TCi 475230557Sjimharris ); 476230557Sjimharris } 477230557Sjimharris 478230557Sjimharris // Copy the physical address for the command buffer to the SCU Task Context 479230557Sjimharris // command buffer should not contain command header. 480230557Sjimharris scic_cb_io_request_get_physical_address( 481230557Sjimharris scic_sds_request_get_controller(this_request), 482230557Sjimharris this_request, 483230557Sjimharris ((char *)(this_request->command_buffer) + sizeof(U32)), 484230557Sjimharris &physical_address 485230557Sjimharris ); 486230557Sjimharris 487230557Sjimharris task_context->command_iu_upper = 488230557Sjimharris sci_cb_physical_address_upper(physical_address); 489230557Sjimharris task_context->command_iu_lower = 490230557Sjimharris sci_cb_physical_address_lower(physical_address); 491230557Sjimharris 492230557Sjimharris 493230557Sjimharris //SMP response comes as UF, so no need to set response IU address. 494230557Sjimharris task_context->response_iu_upper = 0; 495230557Sjimharris task_context->response_iu_lower = 0; 496230557Sjimharris} 497230557Sjimharris 498230557Sjimharris//****************************************************************************** 499230557Sjimharris//* SMP REQUEST STATE MACHINE 500230557Sjimharris//****************************************************************************** 501230557Sjimharris 502230557Sjimharris/** 503230557Sjimharris * @brief This method processes an unsolicited frame while the SMP request is 504230557Sjimharris * waiting for a response frame. It will copy the response data, release 505230557Sjimharris * the unsolicited frame, and transition the request to the 506230557Sjimharris * SCI_BASE_REQUEST_STATE_COMPLETED state. 507230557Sjimharris * 508230557Sjimharris * @param[in] this_request This parameter specifies the request for which 509230557Sjimharris * the unsolicited frame was received. 510230557Sjimharris * @param[in] frame_index This parameter indicates the unsolicited frame 511230557Sjimharris * index that should contain the response. 512230557Sjimharris * 513230557Sjimharris * @return This method returns an indication of whether the response 514230557Sjimharris * frame was handled successfully or not. 515230557Sjimharris * @retval SCI_SUCCESS Currently this value is always returned and indicates 516230557Sjimharris * successful processing of the TC response. 517230557Sjimharris */ 518230557Sjimharrisstatic 519230557SjimharrisSCI_STATUS scic_sds_smp_request_await_response_frame_handler( 520230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 521230557Sjimharris U32 frame_index 522230557Sjimharris) 523230557Sjimharris{ 524230557Sjimharris SCI_STATUS status; 525230557Sjimharris void * frame_header; 526230557Sjimharris SMP_RESPONSE_HEADER_T * this_frame_header; 527230557Sjimharris U8 * user_smp_buffer = this_request->response_buffer; 528230557Sjimharris 529230557Sjimharris // Save off the controller, so that we do not touch the request after it 530230557Sjimharris // is completed. 531230557Sjimharris SCIC_SDS_CONTROLLER_T * controller = scic_sds_request_get_controller(this_request); 532230557Sjimharris 533230557Sjimharris SCIC_LOG_TRACE(( 534230557Sjimharris sci_base_object_get_logger(this_request), 535230557Sjimharris SCIC_LOG_OBJECT_SMP_IO_REQUEST, 536230557Sjimharris "scic_sds_smp_request_await_response_frame_handler(0x%x, 0x%x) enter\n", 537230557Sjimharris this_request, frame_index 538230557Sjimharris )); 539230557Sjimharris 540230557Sjimharris status = scic_sds_unsolicited_frame_control_get_header( 541230557Sjimharris &(controller->uf_control), 542230557Sjimharris frame_index, 543230557Sjimharris &frame_header 544230557Sjimharris ); 545230557Sjimharris 546230557Sjimharris //byte swap the header. 547230557Sjimharris scic_word_copy_with_swap( 548230557Sjimharris (U32*) user_smp_buffer, 549230557Sjimharris frame_header, 550230557Sjimharris sizeof(SMP_RESPONSE_HEADER_T)/sizeof(U32) 551230557Sjimharris ); 552230557Sjimharris this_frame_header = (SMP_RESPONSE_HEADER_T*) user_smp_buffer; 553230557Sjimharris 554230557Sjimharris if (this_frame_header->smp_frame_type == SMP_FRAME_TYPE_RESPONSE) 555230557Sjimharris { 556230557Sjimharris void * smp_response_buffer; 557230557Sjimharris 558230557Sjimharris status = scic_sds_unsolicited_frame_control_get_buffer( 559230557Sjimharris &(controller->uf_control), 560230557Sjimharris frame_index, 561230557Sjimharris &smp_response_buffer 562230557Sjimharris ); 563230557Sjimharris 564230557Sjimharris scic_word_copy_with_swap( 565230557Sjimharris (U32*) (user_smp_buffer + sizeof(SMP_RESPONSE_HEADER_T)), 566230557Sjimharris smp_response_buffer, 567230557Sjimharris sizeof(SMP_RESPONSE_BODY_T)/sizeof(U32) 568230557Sjimharris ); 569230557Sjimharris if (this_frame_header->function == SMP_FUNCTION_DISCOVER) 570230557Sjimharris { 571230557Sjimharris SMP_RESPONSE_T * this_smp_response; 572230557Sjimharris 573230557Sjimharris this_smp_response = (SMP_RESPONSE_T *)user_smp_buffer; 574230557Sjimharris 575230557Sjimharris // Some expanders only report an attached SATA device, and 576230557Sjimharris // not an STP target. Since the core depends on the STP 577230557Sjimharris // target attribute to correctly build I/O, set the bit now 578230557Sjimharris // if necessary. 579230557Sjimharris if (this_smp_response->response.discover.protocols.u.bits.attached_sata_device 580230557Sjimharris && !this_smp_response->response.discover.protocols.u.bits.attached_stp_target) 581230557Sjimharris { 582230557Sjimharris this_smp_response->response.discover.protocols.u.bits.attached_stp_target = 1; 583230557Sjimharris 584230557Sjimharris SCIC_LOG_TRACE(( 585230557Sjimharris sci_base_object_get_logger(this_request), 586230557Sjimharris SCIC_LOG_OBJECT_SMP_IO_REQUEST, 587230557Sjimharris "scic_sds_smp_request_await_response_frame_handler(0x%x) Found SATA dev, setting STP bit.\n", 588230557Sjimharris this_request 589230557Sjimharris )); 590230557Sjimharris } 591230557Sjimharris } 592230557Sjimharris 593230557Sjimharris //Don't need to copy to user space. User instead will refer to 594230557Sjimharris //core request's response buffer. 595230557Sjimharris 596230557Sjimharris //copy the smp response to framework smp request's response buffer. 597230557Sjimharris //scic_sds_smp_request_copy_response(this_request); 598230557Sjimharris 599230557Sjimharris scic_sds_request_set_status( 600230557Sjimharris this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 601230557Sjimharris ); 602230557Sjimharris 603230557Sjimharris sci_base_state_machine_change_state( 604230557Sjimharris &this_request->started_substate_machine, 605230557Sjimharris SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION 606230557Sjimharris ); 607230557Sjimharris } 608230557Sjimharris else 609230557Sjimharris { 610230557Sjimharris // This was not a response frame why did it get forwarded? 611230557Sjimharris SCIC_LOG_ERROR(( 612230557Sjimharris sci_base_object_get_logger(this_request), 613230557Sjimharris SCIC_LOG_OBJECT_SMP_IO_REQUEST, 614230557Sjimharris "SCIC SMP Request 0x%08x received unexpected frame %d type 0x%02x\n", 615230557Sjimharris this_request, frame_index, this_frame_header->smp_frame_type 616230557Sjimharris )); 617230557Sjimharris 618230557Sjimharris scic_sds_request_set_status( 619230557Sjimharris this_request, 620230557Sjimharris SCU_TASK_DONE_SMP_FRM_TYPE_ERR, 621230557Sjimharris SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 622230557Sjimharris ); 623230557Sjimharris 624230557Sjimharris sci_base_state_machine_change_state( 625230557Sjimharris &this_request->parent.state_machine, 626230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 627230557Sjimharris ); 628230557Sjimharris } 629230557Sjimharris 630230557Sjimharris scic_sds_controller_release_frame( 631230557Sjimharris controller, frame_index 632230557Sjimharris ); 633230557Sjimharris 634230557Sjimharris return SCI_SUCCESS; 635230557Sjimharris} 636230557Sjimharris 637230557Sjimharris 638230557Sjimharris/** 639230557Sjimharris * @brief This method processes an abnormal TC completion while the SMP 640230557Sjimharris * request is waiting for a response frame. It decides what 641230557Sjimharris * happened to the IO based on TC completion status. 642230557Sjimharris * 643230557Sjimharris * @param[in] this_request This parameter specifies the request for which 644230557Sjimharris * the TC completion was received. 645230557Sjimharris * @param[in] completion_code This parameter indicates the completion status 646230557Sjimharris * information for the TC. 647230557Sjimharris * 648230557Sjimharris * @return Indicate if the tc completion handler was successful. 649230557Sjimharris * @retval SCI_SUCCESS currently this method always returns success. 650230557Sjimharris */ 651230557Sjimharrisstatic 652230557SjimharrisSCI_STATUS scic_sds_smp_request_await_response_tc_completion_handler( 653230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 654230557Sjimharris U32 completion_code 655230557Sjimharris) 656230557Sjimharris{ 657230557Sjimharris SCIC_LOG_TRACE(( 658230557Sjimharris sci_base_object_get_logger(this_request), 659230557Sjimharris SCIC_LOG_OBJECT_SMP_IO_REQUEST, 660230557Sjimharris "scic_sds_smp_request_await_response_tc_completion_handler(0x%x, 0x%x) enter\n", 661230557Sjimharris this_request, completion_code 662230557Sjimharris )); 663230557Sjimharris 664230557Sjimharris switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 665230557Sjimharris { 666230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 667230557Sjimharris //In the AWAIT RESPONSE state, any TC completion is unexpected. 668230557Sjimharris //but if the TC has success status, we complete the IO anyway. 669230557Sjimharris scic_sds_request_set_status( 670230557Sjimharris this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 671230557Sjimharris ); 672230557Sjimharris 673230557Sjimharris sci_base_state_machine_change_state( 674230557Sjimharris &this_request->parent.state_machine, 675230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 676230557Sjimharris ); 677230557Sjimharris break; 678230557Sjimharris 679230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_RESP_TO_ERR): 680230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_UFI_ERR): 681230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_FRM_TYPE_ERR): 682230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_LL_RX_ERR): 683230557Sjimharris //These status has been seen in a specific LSI expander, which sometimes 684230557Sjimharris //is not able to send smp response within 2 ms. This causes our hardware 685230557Sjimharris //break the connection and set TC completion with one of these SMP_XXX_XX_ERR 686230557Sjimharris //status. For these type of error, we ask scic user to retry the request. 687230557Sjimharris scic_sds_request_set_status( 688230557Sjimharris this_request, SCU_TASK_DONE_SMP_RESP_TO_ERR, SCI_FAILURE_RETRY_REQUIRED 689230557Sjimharris ); 690230557Sjimharris 691230557Sjimharris sci_base_state_machine_change_state( 692230557Sjimharris &this_request->parent.state_machine, 693230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 694230557Sjimharris ); 695230557Sjimharris break; 696230557Sjimharris 697230557Sjimharris default: 698230557Sjimharris // All other completion status cause the IO to be complete. If a NAK 699230557Sjimharris // was received, then it is up to the user to retry the request. 700230557Sjimharris scic_sds_request_set_status( 701230557Sjimharris this_request, 702230557Sjimharris SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 703230557Sjimharris SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 704230557Sjimharris ); 705230557Sjimharris 706230557Sjimharris sci_base_state_machine_change_state( 707230557Sjimharris &this_request->parent.state_machine, 708230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 709230557Sjimharris ); 710230557Sjimharris break; 711230557Sjimharris } 712230557Sjimharris 713230557Sjimharris return SCI_SUCCESS; 714230557Sjimharris} 715230557Sjimharris 716230557Sjimharris 717230557Sjimharris/** 718230557Sjimharris * @brief This method processes the completions transport layer (TL) status 719230557Sjimharris * to determine if the SMP request was sent successfully. If the SMP 720230557Sjimharris * request was sent successfully, then the state for the SMP request 721230557Sjimharris * transits to waiting for a response frame. 722230557Sjimharris * 723230557Sjimharris * @param[in] this_request This parameter specifies the request for which 724230557Sjimharris * the TC completion was received. 725230557Sjimharris * @param[in] completion_code This parameter indicates the completion status 726230557Sjimharris * information for the TC. 727230557Sjimharris * 728230557Sjimharris * @return Indicate if the tc completion handler was successful. 729230557Sjimharris * @retval SCI_SUCCESS currently this method always returns success. 730230557Sjimharris */ 731230557Sjimharrisstatic 732230557SjimharrisSCI_STATUS scic_sds_smp_request_await_tc_completion_tc_completion_handler( 733230557Sjimharris SCIC_SDS_REQUEST_T * this_request, 734230557Sjimharris U32 completion_code 735230557Sjimharris) 736230557Sjimharris{ 737230557Sjimharris SCIC_LOG_TRACE(( 738230557Sjimharris sci_base_object_get_logger(this_request), 739230557Sjimharris SCIC_LOG_OBJECT_SMP_IO_REQUEST, 740230557Sjimharris "scic_sds_smp_request_await_tc_completion_tc_completion_handler(0x%x, 0x%x) enter\n", 741230557Sjimharris this_request, completion_code 742230557Sjimharris )); 743230557Sjimharris 744230557Sjimharris switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 745230557Sjimharris { 746230557Sjimharris case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 747230557Sjimharris scic_sds_request_set_status( 748230557Sjimharris this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 749230557Sjimharris ); 750230557Sjimharris 751230557Sjimharris sci_base_state_machine_change_state( 752230557Sjimharris &this_request->parent.state_machine, 753230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 754230557Sjimharris ); 755230557Sjimharris break; 756230557Sjimharris 757230557Sjimharris default: 758230557Sjimharris // All other completion status cause the IO to be complete. If a NAK 759230557Sjimharris // was received, then it is up to the user to retry the request. 760230557Sjimharris scic_sds_request_set_status( 761230557Sjimharris this_request, 762230557Sjimharris SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 763230557Sjimharris SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 764230557Sjimharris ); 765230557Sjimharris 766230557Sjimharris sci_base_state_machine_change_state( 767230557Sjimharris &this_request->parent.state_machine, 768230557Sjimharris SCI_BASE_REQUEST_STATE_COMPLETED 769230557Sjimharris ); 770230557Sjimharris break; 771230557Sjimharris } 772230557Sjimharris 773230557Sjimharris return SCI_SUCCESS; 774230557Sjimharris} 775230557Sjimharris 776230557Sjimharris 777230557SjimharrisSCIC_SDS_IO_REQUEST_STATE_HANDLER_T 778230557Sjimharrisscic_sds_smp_request_started_substate_handler_table 779230557Sjimharris[SCIC_SDS_SMP_REQUEST_STARTED_MAX_SUBSTATES] = 780230557Sjimharris{ 781230557Sjimharris // SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE 782230557Sjimharris { 783230557Sjimharris { 784230557Sjimharris scic_sds_request_default_start_handler, 785230557Sjimharris scic_sds_request_started_state_abort_handler, 786230557Sjimharris scic_sds_request_default_complete_handler, 787230557Sjimharris scic_sds_request_default_destruct_handler 788230557Sjimharris }, 789230557Sjimharris scic_sds_smp_request_await_response_tc_completion_handler, 790230557Sjimharris scic_sds_request_default_event_handler, 791230557Sjimharris scic_sds_smp_request_await_response_frame_handler 792230557Sjimharris }, 793230557Sjimharris // SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION 794230557Sjimharris { 795230557Sjimharris { 796230557Sjimharris scic_sds_request_default_start_handler, 797230557Sjimharris scic_sds_request_started_state_abort_handler, 798230557Sjimharris scic_sds_request_default_complete_handler, 799230557Sjimharris scic_sds_request_default_destruct_handler 800230557Sjimharris }, 801230557Sjimharris scic_sds_smp_request_await_tc_completion_tc_completion_handler, 802230557Sjimharris scic_sds_request_default_event_handler, 803230557Sjimharris scic_sds_request_default_frame_handler 804230557Sjimharris } 805230557Sjimharris}; 806230557Sjimharris 807230557Sjimharris/** 808230557Sjimharris * @brief This method performs the actions required when entering the 809230557Sjimharris * SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_RESPONSE sub-state. 810230557Sjimharris * This includes setting the IO request state handlers for this 811230557Sjimharris * sub-state. 812230557Sjimharris * 813230557Sjimharris * @param[in] object This parameter specifies the request object for which 814230557Sjimharris * the sub-state change is occuring. 815230557Sjimharris * 816230557Sjimharris * @return none. 817230557Sjimharris */ 818230557Sjimharrisstatic 819230557Sjimharrisvoid scic_sds_smp_request_started_await_response_substate_enter( 820230557Sjimharris SCI_BASE_OBJECT_T *object 821230557Sjimharris) 822230557Sjimharris{ 823230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 824230557Sjimharris 825230557Sjimharris SET_STATE_HANDLER( 826230557Sjimharris this_request, 827230557Sjimharris scic_sds_smp_request_started_substate_handler_table, 828230557Sjimharris SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE 829230557Sjimharris ); 830230557Sjimharris} 831230557Sjimharris 832230557Sjimharris/** 833230557Sjimharris * @brief This method performs the actions required when entering the 834230557Sjimharris * SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION 835230557Sjimharris * sub-state. This includes setting the SMP request state handlers for 836230557Sjimharris * this sub-state. 837230557Sjimharris * 838230557Sjimharris * @param[in] object This parameter specifies the request object for which 839230557Sjimharris * the sub-state change is occuring. 840230557Sjimharris * 841230557Sjimharris * @return none. 842230557Sjimharris */ 843230557Sjimharrisstatic 844230557Sjimharrisvoid scic_sds_smp_request_started_await_tc_completion_substate_enter( 845230557Sjimharris SCI_BASE_OBJECT_T *object 846230557Sjimharris) 847230557Sjimharris{ 848230557Sjimharris SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 849230557Sjimharris 850230557Sjimharris SET_STATE_HANDLER( 851230557Sjimharris this_request, 852230557Sjimharris scic_sds_smp_request_started_substate_handler_table, 853230557Sjimharris SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION 854230557Sjimharris ); 855230557Sjimharris} 856230557Sjimharris 857230557SjimharrisSCI_BASE_STATE_T scic_sds_smp_request_started_substate_table 858230557Sjimharris[SCIC_SDS_SMP_REQUEST_STARTED_MAX_SUBSTATES] = 859230557Sjimharris{ 860230557Sjimharris { 861230557Sjimharris SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE, 862230557Sjimharris scic_sds_smp_request_started_await_response_substate_enter, 863230557Sjimharris NULL 864230557Sjimharris }, 865230557Sjimharris { 866230557Sjimharris SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION, 867230557Sjimharris scic_sds_smp_request_started_await_tc_completion_substate_enter, 868230557Sjimharris NULL 869230557Sjimharris } 870230557Sjimharris}; 871230557Sjimharris 872230557Sjimharris 873