1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0 3 * 4 * This file is provided under a dual BSD/GPLv2 license. When using or 5 * redistributing this file, you may do so under either license. 6 * 7 * GPL LICENSE SUMMARY 8 * 9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of version 2 of the GNU General Public License as 13 * published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 23 * The full GNU General Public License is included in this distribution 24 * in the file called LICENSE.GPL. 25 * 26 * BSD LICENSE 27 * 28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 29 * All rights reserved. 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions 33 * are met: 34 * 35 * * Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * * Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in 39 * the documentation and/or other materials provided with the 40 * distribution. 41 * 42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 45 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 46 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 48 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 */ 54 55 #include <sys/cdefs.h> 56 __FBSDID("$FreeBSD$"); 57 58 #include <dev/isci/scil/intel_sat.h> 59 #include <dev/isci/scil/intel_sata.h> 60 #include <dev/isci/scil/sci_types.h> 61 #include <dev/isci/scil/scic_remote_device.h> 62 #include <dev/isci/scil/scic_user_callback.h> 63 #include <dev/isci/scil/scic_sds_controller.h> 64 #include <dev/isci/scil/scic_sds_remote_device.h> 65 #include <dev/isci/scil/scic_sds_stp_request.h> 66 #include <dev/isci/scil/scic_sds_stp_pio_request.h> 67 #include <dev/isci/scil/scic_sds_logger.h> 68 #include <dev/isci/sci_environment.h> 69 #include <dev/isci/scil/sci_base_state_machine.h> 70 #include <dev/isci/scil/scu_task_context.h> 71 #include <dev/isci/scil/intel_ata.h> 72 #include <dev/isci/scil/sci_util.h> 73 #include <dev/isci/scil/scic_sds_logger.h> 74 #include <dev/isci/scil/scic_sds_request.h> 75 #include <dev/isci/scil/scic_sds_stp_request.h> 76 #include <dev/isci/scil/scu_completion_codes.h> 77 #include <dev/isci/scil/scu_event_codes.h> 78 #include <dev/isci/scil/sci_base_state.h> 79 #include <dev/isci/scil/scic_sds_unsolicited_frame_control.h> 80 #include <dev/isci/scil/scic_io_request.h> 81 82 #if !defined(DISABLE_ATAPI) 83 #include <dev/isci/scil/scic_sds_stp_packet_request.h> 84 #endif 85 86 /** 87 * This macro returns the address of the stp h2d reg fis buffer in the io 88 * request memory 89 */ 90 #define scic_sds_stp_request_get_h2d_reg_buffer_unaligned(memory) \ 91 ((SATA_FIS_REG_H2D_T *)( \ 92 ((char *)(memory)) + sizeof(SCIC_SDS_STP_REQUEST_T) \ 93 )) 94 95 /** 96 * This macro aligns the stp command buffer in DWORD alignment 97 */ 98 #define scic_sds_stp_request_align_h2d_reg_buffer(address) \ 99 ((SATA_FIS_REG_H2D_T *)( \ 100 (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \ 101 & ~(sizeof(U32)- 1) \ 102 )) 103 104 /** 105 * This macro returns the DWORD-aligned stp command buffer 106 */ 107 #define scic_sds_stp_request_get_h2d_reg_buffer(memory) \ 108 ((SATA_FIS_REG_H2D_T *) \ 109 ((char *)scic_sds_stp_request_align_h2d_reg_buffer( \ 110 (char *) scic_sds_stp_request_get_h2d_reg_buffer_unaligned(memory) \ 111 ))) 112 113 /** 114 * This macro returns the address of the stp response buffer in the io 115 * request memory 116 */ 117 #define scic_sds_stp_request_get_response_buffer_unaligned(memory) \ 118 ((SATA_FIS_REG_D2H_T *)( \ 119 ((char *)(scic_sds_stp_request_get_h2d_reg_buffer(memory))) \ 120 + sizeof(SATA_FIS_REG_H2D_T) \ 121 )) 122 123 124 /** 125 * This macro aligns the stp response buffer in DWORD alignment 126 */ 127 #define scic_sds_stp_request_align_response_buffer(address) \ 128 ((SATA_FIS_REG_D2H_T *)( \ 129 (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \ 130 & ~(sizeof(U32)- 1) \ 131 )) 132 133 /** 134 * This macro returns the DWORD-aligned stp response buffer 135 */ 136 #define scic_sds_stp_request_get_response_buffer(memory) \ 137 ((SATA_FIS_REG_D2H_T *) \ 138 ((char *)scic_sds_stp_request_align_response_buffer( \ 139 (char *)scic_sds_stp_request_get_response_buffer_unaligned(memory) \ 140 ))) 141 142 143 /** 144 * This macro returns the address of the task context buffer in the io 145 * request memory 146 */ 147 #define scic_sds_stp_request_get_task_context_buffer_unaligned(memory) \ 148 ((SCU_TASK_CONTEXT_T *)( \ 149 ((char *)(scic_sds_stp_request_get_response_buffer(memory))) \ 150 + sizeof(SCI_SSP_RESPONSE_IU_T) \ 151 )) 152 153 /** 154 * This macro returns the aligned task context buffer 155 */ 156 #define scic_sds_stp_request_get_task_context_buffer(memory) \ 157 ((SCU_TASK_CONTEXT_T *)( \ 158 ((char *)scic_sds_request_align_task_context_buffer( \ 159 (char *)scic_sds_stp_request_get_task_context_buffer_unaligned(memory)) \ 160 ))) 161 162 /** 163 * This macro returns the address of the sgl elment pairs in the io request 164 * memory buffer 165 */ 166 #define scic_sds_stp_request_get_sgl_element_buffer(memory) \ 167 ((SCU_SGL_ELEMENT_PAIR_T *)( \ 168 ((char *)(scic_sds_stp_request_get_task_context_buffer(memory))) \ 169 + sizeof(SCU_TASK_CONTEXT_T) \ 170 )) 171 172 173 /** 174 * This method return the memory space commonly required for STP IO and 175 * task requests. 176 * 177 * @return U32 178 */ 179 static 180 U32 scic_sds_stp_common_request_get_object_size(void) 181 { 182 return sizeof(SCIC_SDS_STP_REQUEST_T) 183 + sizeof(SATA_FIS_REG_H2D_T) 184 + sizeof(U32) 185 + sizeof(SATA_FIS_REG_D2H_T) 186 + sizeof(U32) 187 + sizeof(SCU_TASK_CONTEXT_T) 188 + CACHE_LINE_SIZE; 189 } 190 191 192 /** 193 * This method return the memory space required for STP PIO requests. 194 * 195 * @return U32 196 */ 197 U32 scic_sds_stp_request_get_object_size(void) 198 { 199 return scic_sds_stp_common_request_get_object_size() 200 + sizeof(SCU_SGL_ELEMENT_PAIR_T) * SCU_MAX_SGL_ELEMENT_PAIRS; 201 } 202 203 204 /** 205 * This method return the memory space required for STP task requests. 206 * 207 * @return U32 208 */ 209 U32 scic_sds_stp_task_request_get_object_size(void) 210 { 211 return scic_sds_stp_common_request_get_object_size(); 212 } 213 214 215 /** 216 * 217 * 218 * @param[in] this_request 219 */ 220 void scic_sds_stp_request_assign_buffers( 221 SCIC_SDS_REQUEST_T * request 222 ) 223 { 224 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request; 225 226 this_request->parent.command_buffer = 227 scic_sds_stp_request_get_h2d_reg_buffer(this_request); 228 this_request->parent.response_buffer = 229 scic_sds_stp_request_get_response_buffer(this_request); 230 this_request->parent.sgl_element_pair_buffer = 231 scic_sds_stp_request_get_sgl_element_buffer(this_request); 232 this_request->parent.sgl_element_pair_buffer = 233 scic_sds_request_align_sgl_element_buffer(this_request->parent.sgl_element_pair_buffer); 234 235 if (this_request->parent.was_tag_assigned_by_user == FALSE) 236 { 237 this_request->parent.task_context_buffer = 238 scic_sds_stp_request_get_task_context_buffer(this_request); 239 } 240 } 241 242 /** 243 * @brief This method is will fill in the SCU Task Context for any type of 244 * SATA request. This is called from the various SATA constructors. 245 * 246 * @pre The general io request construction is complete. 247 * @pre The buffer assignment for the command buffer is complete. 248 * 249 * @param[in] this_request The general IO request object which is to be used 250 * in constructing the SCU task context. 251 * @param[in] task_context The buffer pointer for the SCU task context which 252 * is being constructed. 253 * 254 * @return none 255 * 256 * @todo Revisit task context construction to determine what is common for 257 * SSP/SMP/STP task context structures. 258 */ 259 void scu_sata_reqeust_construct_task_context( 260 SCIC_SDS_REQUEST_T * this_request, 261 SCU_TASK_CONTEXT_T * task_context 262 ) 263 { 264 SCI_PHYSICAL_ADDRESS physical_address; 265 SCIC_SDS_CONTROLLER_T *owning_controller; 266 SCIC_SDS_REMOTE_DEVICE_T *target_device; 267 SCIC_SDS_PORT_T *target_port; 268 269 owning_controller = scic_sds_request_get_controller(this_request); 270 target_device = scic_sds_request_get_device(this_request); 271 target_port = scic_sds_request_get_port(this_request); 272 273 // Fill in the TC with the its required data 274 task_context->abort = 0; 275 task_context->priority = SCU_TASK_PRIORITY_NORMAL; 276 task_context->initiator_request = 1; 277 task_context->connection_rate = 278 scic_remote_device_get_connection_rate(target_device); 279 task_context->protocol_engine_index = 280 scic_sds_controller_get_protocol_engine_group(owning_controller); 281 task_context->logical_port_index = 282 scic_sds_port_get_index(target_port); 283 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_STP; 284 task_context->valid = SCU_TASK_CONTEXT_VALID; 285 task_context->context_type = SCU_TASK_CONTEXT_TYPE; 286 287 task_context->remote_node_index = 288 scic_sds_remote_device_get_index(this_request->target_device); 289 task_context->command_code = 0; 290 291 task_context->link_layer_control = 0; 292 task_context->do_not_dma_ssp_good_response = 1; 293 task_context->strict_ordering = 0; 294 task_context->control_frame = 0; 295 task_context->timeout_enable = 0; 296 task_context->block_guard_enable = 0; 297 298 task_context->address_modifier = 0; 299 task_context->task_phase = 0x01; 300 301 task_context->ssp_command_iu_length = 302 (sizeof(SATA_FIS_REG_H2D_T) - sizeof(U32)) / sizeof(U32); 303 304 // Set the first word of the H2D REG FIS 305 task_context->type.words[0] = *(U32 *)this_request->command_buffer; 306 307 if (this_request->was_tag_assigned_by_user) 308 { 309 // Build the task context now since we have already read the data 310 this_request->post_context = ( 311 SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC 312 | ( 313 scic_sds_controller_get_protocol_engine_group(owning_controller) 314 << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT 315 ) 316 | ( 317 scic_sds_port_get_index(target_port) 318 << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT 319 ) 320 | scic_sds_io_tag_get_index(this_request->io_tag) 321 ); 322 } 323 else 324 { 325 // Build the task context now since we have already read the data 326 this_request->post_context = ( 327 SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC 328 | ( 329 scic_sds_controller_get_protocol_engine_group(owning_controller) 330 << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT 331 ) 332 | ( 333 scic_sds_port_get_index(target_port) 334 << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT 335 ) 336 // This is not assigned because we have to wait until we get a TCi 337 ); 338 } 339 340 // Copy the physical address for the command buffer to the SCU Task Context 341 // We must offset the command buffer by 4 bytes because the first 4 bytes are 342 // transferred in the body of the TC 343 scic_cb_io_request_get_physical_address( 344 scic_sds_request_get_controller(this_request), 345 this_request, 346 ((char *)this_request->command_buffer) + sizeof(U32), 347 &physical_address 348 ); 349 350 task_context->command_iu_upper = 351 sci_cb_physical_address_upper(physical_address); 352 task_context->command_iu_lower = 353 sci_cb_physical_address_lower(physical_address); 354 355 // SATA Requests do not have a response buffer 356 task_context->response_iu_upper = 0; 357 task_context->response_iu_lower = 0; 358 } 359 360 /** 361 * This method will perform any general sata request construction. 362 * 363 * @todo What part of SATA IO request construction is general? 364 * 365 * @param[in] this_request 366 * 367 * @return none 368 */ 369 void scic_sds_stp_non_ncq_request_construct( 370 SCIC_SDS_REQUEST_T * this_request 371 ) 372 { 373 this_request->has_started_substate_machine = TRUE; 374 } 375 376 /** 377 * This method will perform request construction common to all types of 378 * STP requests that are optimized by the silicon (i.e. UDMA, NCQ). 379 * 380 * @param[in,out] this_request This parameter specifies the request to be 381 * constructed as an optimized request. 382 * @param[in] optimized_task_type This parameter specifies whether the 383 * request is to be an UDMA request or a NCQ request. 384 * - A value of 0 indicates UDMA. 385 * - A value of 1 indicates NCQ. 386 * 387 * @return This method returns an indication as to whether the construction 388 * was successful. 389 */ 390 static 391 void scic_sds_stp_optimized_request_construct( 392 SCIC_SDS_REQUEST_T * this_request, 393 U8 optimized_task_type, 394 U32 transfer_length, 395 SCI_IO_REQUEST_DATA_DIRECTION data_direction 396 ) 397 { 398 SCU_TASK_CONTEXT_T * task_context = this_request->task_context_buffer; 399 400 // Build the STP task context structure 401 scu_sata_reqeust_construct_task_context(this_request, task_context); 402 403 // Copy over the number of bytes to be transferred 404 task_context->transfer_length_bytes = transfer_length; 405 406 if ( data_direction == SCI_IO_REQUEST_DATA_OUT ) 407 { 408 // The difference between the DMA IN and DMA OUT request task type 409 // values are consistent with the difference between FPDMA READ 410 // and FPDMA WRITE values. Add the supplied task type parameter 411 // to this difference to set the task type properly for this 412 // DATA OUT (WRITE) case. 413 task_context->task_type = optimized_task_type + (SCU_TASK_TYPE_DMA_OUT 414 - SCU_TASK_TYPE_DMA_IN); 415 } 416 else 417 { 418 // For the DATA IN (READ) case, simply save the supplied 419 // optimized task type. 420 task_context->task_type = optimized_task_type; 421 } 422 } 423 424 /** 425 * This method performs the operations common to all SATA/STP requests 426 * utilizing the raw frame method. 427 * 428 * @param[in] this_request This parameter specifies the STP request object 429 * for which to construct a RAW command frame task context. 430 * @param[in] task_context This parameter specifies the SCU specific 431 * task context buffer to construct. 432 * 433 * @return none 434 */ 435 void scu_stp_raw_request_construct_task_context( 436 SCIC_SDS_STP_REQUEST_T * this_request, 437 SCU_TASK_CONTEXT_T * task_context 438 ) 439 { 440 scu_sata_reqeust_construct_task_context(&this_request->parent, task_context); 441 442 task_context->control_frame = 0; 443 task_context->priority = SCU_TASK_PRIORITY_NORMAL; 444 task_context->task_type = SCU_TASK_TYPE_SATA_RAW_FRAME; 445 task_context->type.stp.fis_type = SATA_FIS_TYPE_REGH2D; 446 task_context->transfer_length_bytes = sizeof(SATA_FIS_REG_H2D_T) - sizeof(U32); 447 } 448 449 /** 450 * This method will construct the STP Non-data request and its associated 451 * TC data. A non-data request essentially behaves like a 0 length read 452 * request in the SCU. 453 * 454 * @param[in] this_request This parameter specifies the core request 455 * object to construction into an STP/SATA non-data request. 456 * 457 * @return This method currently always returns SCI_SUCCESS 458 */ 459 SCI_STATUS scic_sds_stp_non_data_request_construct( 460 SCIC_SDS_REQUEST_T * this_request 461 ) 462 { 463 scic_sds_stp_non_ncq_request_construct(this_request); 464 465 // Build the STP task context structure 466 scu_stp_raw_request_construct_task_context( 467 (SCIC_SDS_STP_REQUEST_T*) this_request, 468 this_request->task_context_buffer 469 ); 470 471 sci_base_state_machine_construct( 472 &this_request->started_substate_machine, 473 &this_request->parent.parent, 474 scic_sds_stp_request_started_non_data_substate_table, 475 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE 476 ); 477 478 return SCI_SUCCESS; 479 } 480 481 482 SCI_STATUS scic_sds_stp_soft_reset_request_construct( 483 SCIC_SDS_REQUEST_T * this_request 484 ) 485 { 486 scic_sds_stp_non_ncq_request_construct(this_request); 487 488 // Build the STP task context structure 489 scu_stp_raw_request_construct_task_context( 490 (SCIC_SDS_STP_REQUEST_T*) this_request, 491 this_request->task_context_buffer 492 ); 493 494 sci_base_state_machine_construct( 495 &this_request->started_substate_machine, 496 &this_request->parent.parent, 497 scic_sds_stp_request_started_soft_reset_substate_table, 498 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE 499 ); 500 501 return SCI_SUCCESS; 502 } 503 504 /** 505 * @brief This method constructs the SATA request object. 506 * 507 * @param[in] this_request 508 * @param[in] sat_protocol 509 * @param[in] transfer_length 510 * @param[in] data_direction 511 * @param[in] copy_rx_frame 512 * @param[in] do_translate_sgl This parameter specifies whether SGL 513 * translation should be performed or if the user is handling 514 * it. 515 * 516 * @return SCI_STATUS 517 */ 518 SCI_STATUS scic_sds_io_request_construct_sata( 519 SCIC_SDS_REQUEST_T * this_request, 520 U8 sat_protocol, 521 U32 transfer_length, 522 SCI_IO_REQUEST_DATA_DIRECTION data_direction, 523 BOOL copy_rx_frame, 524 BOOL do_translate_sgl 525 ) 526 { 527 SCI_STATUS status = SCI_SUCCESS; 528 529 this_request->protocol = SCIC_STP_PROTOCOL; 530 531 this_request->sat_protocol = sat_protocol; 532 533 switch (sat_protocol) 534 { 535 case SAT_PROTOCOL_FPDMA: 536 scic_sds_stp_optimized_request_construct( 537 this_request, 538 SCU_TASK_TYPE_FPDMAQ_READ, 539 transfer_length, 540 data_direction 541 ); 542 543 // Copy over the SGL elements 544 if (do_translate_sgl == TRUE) 545 scic_sds_request_build_sgl(this_request); 546 break; 547 548 case SAT_PROTOCOL_UDMA_DATA_IN: 549 case SAT_PROTOCOL_UDMA_DATA_OUT: 550 scic_sds_stp_non_ncq_request_construct(this_request); 551 552 scic_sds_stp_optimized_request_construct( 553 this_request, SCU_TASK_TYPE_DMA_IN, transfer_length, data_direction 554 ); 555 556 // Copy over the SGL elements 557 if (do_translate_sgl == TRUE) 558 scic_sds_request_build_sgl(this_request); 559 560 sci_base_state_machine_construct( 561 &this_request->started_substate_machine, 562 &this_request->parent.parent, 563 scic_sds_stp_request_started_udma_substate_table, 564 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE 565 ); 566 break; 567 568 case SAT_PROTOCOL_PIO_DATA_IN: 569 case SAT_PROTOCOL_PIO_DATA_OUT: 570 status = scic_sds_stp_pio_request_construct( 571 this_request, sat_protocol, copy_rx_frame); 572 break; 573 574 case SAT_PROTOCOL_ATA_HARD_RESET: 575 case SAT_PROTOCOL_SOFT_RESET: 576 status = scic_sds_stp_soft_reset_request_construct(this_request); 577 break; 578 579 case SAT_PROTOCOL_NON_DATA: 580 status = scic_sds_stp_non_data_request_construct(this_request); 581 break; 582 583 #if !defined(DISABLE_ATAPI) 584 case SAT_PROTOCOL_PACKET_NON_DATA: 585 case SAT_PROTOCOL_PACKET_DMA_DATA_IN: 586 case SAT_PROTOCOL_PACKET_DMA_DATA_OUT: 587 case SAT_PROTOCOL_PACKET_PIO_DATA_IN: 588 case SAT_PROTOCOL_PACKET_PIO_DATA_OUT: 589 status = scic_sds_stp_packet_request_construct(this_request); 590 if (do_translate_sgl == TRUE) 591 scic_sds_request_build_sgl(this_request); 592 break; 593 #endif 594 595 case SAT_PROTOCOL_DMA_QUEUED: 596 case SAT_PROTOCOL_DMA: 597 case SAT_PROTOCOL_DEVICE_DIAGNOSTIC: 598 case SAT_PROTOCOL_DEVICE_RESET: 599 case SAT_PROTOCOL_RETURN_RESPONSE_INFO: 600 default: 601 SCIC_LOG_ERROR(( 602 sci_base_object_get_logger(this_request), 603 SCIC_LOG_OBJECT_STP_IO_REQUEST, 604 "SCIC IO Request 0x%x received un-handled SAT Protocol %d.\n", 605 this_request, sat_protocol 606 )); 607 608 status = SCI_FAILURE; 609 break; 610 } 611 612 if (status == SCI_SUCCESS) 613 { 614 scic_sds_request_initialize_state_logging(this_request); 615 616 sci_base_state_machine_change_state( 617 &this_request->parent.state_machine, 618 SCI_BASE_REQUEST_STATE_CONSTRUCTED 619 ); 620 } 621 622 return status; 623 } 624 625 //**************************************************************************** 626 //* SCIC Interface Implementation 627 //**************************************************************************** 628 629 void scic_stp_io_request_set_ncq_tag( 630 SCI_IO_REQUEST_HANDLE_T scic_io_request, 631 U16 ncq_tag 632 ) 633 { 634 /** 635 * @note This could be made to return an error to the user if the user 636 * attempts to set the NCQ tag in the wrong state. 637 */ 638 SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request; 639 this_request->task_context_buffer->type.stp.ncq_tag = ncq_tag; 640 } 641 642 // --------------------------------------------------------------------------- 643 644 void * scic_stp_io_request_get_h2d_reg_address( 645 SCI_IO_REQUEST_HANDLE_T scic_io_request 646 ) 647 { 648 SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request; 649 650 return this_request->command_buffer; 651 } 652 653 // --------------------------------------------------------------------------- 654 655 void * scic_stp_io_request_get_d2h_reg_address( 656 SCI_IO_REQUEST_HANDLE_T scic_io_request 657 ) 658 { 659 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)scic_io_request; 660 661 return &this_request->d2h_reg_fis; 662 } 663 664 /** 665 * Get the next SGL element from the request. 666 * - Check on which SGL element pair we are working 667 * - if working on SLG pair element A 668 * - advance to element B 669 * - else 670 * - check to see if there are more SGL element pairs 671 * for this IO request 672 * - if there are more SGL element pairs 673 * - advance to the next pair and return element A 674 * 675 * @param[in] this_request 676 * 677 * @return SCU_SGL_ELEMENT_T* 678 */ 679 SCU_SGL_ELEMENT_T * scic_sds_stp_request_pio_get_next_sgl( 680 SCIC_SDS_STP_REQUEST_T * this_request 681 ) 682 { 683 SCU_SGL_ELEMENT_T * current_sgl; 684 685 if (this_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) 686 { 687 if ( 688 (this_request->type.pio.request_current.sgl_pair->B.address_lower == 0) 689 && (this_request->type.pio.request_current.sgl_pair->B.address_upper == 0) 690 ) 691 { 692 current_sgl = NULL; 693 } 694 else 695 { 696 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_B; 697 current_sgl = &(this_request->type.pio.request_current.sgl_pair->B); 698 } 699 } 700 else 701 { 702 if ( 703 (this_request->type.pio.request_current.sgl_pair->next_pair_lower == 0) 704 && (this_request->type.pio.request_current.sgl_pair->next_pair_upper == 0) 705 ) 706 { 707 current_sgl = NULL; 708 } 709 else 710 { 711 this_request->type.pio.request_current.sgl_pair = 712 scic_sds_request_get_sgl_element_pair( 713 &(this_request->parent), 714 ++this_request->type.pio.sgl_pair_index 715 ); 716 717 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A; 718 719 current_sgl = &(this_request->type.pio.request_current.sgl_pair->A); 720 } 721 } 722 723 return current_sgl; 724 } 725 726 /** 727 * This method will construct the SATA PIO request. 728 * 729 * @param[in] scic_io_request The core request object which is cast to a SATA 730 * PIO request object. 731 * 732 * @return This method returns an indication as to whether the construction 733 * was successful. 734 * @retval SCI_SUCCESS Currently this method always returns this value. 735 */ 736 SCI_STATUS scic_sds_stp_pio_request_construct( 737 SCIC_SDS_REQUEST_T * scic_io_request, 738 U8 sat_protocol, 739 BOOL copy_rx_frame 740 ) 741 { 742 SCIC_SDS_STP_REQUEST_T * this_request; 743 744 this_request = (SCIC_SDS_STP_REQUEST_T *)scic_io_request; 745 746 scic_sds_stp_non_ncq_request_construct(&this_request->parent); 747 748 scu_stp_raw_request_construct_task_context( 749 this_request, this_request->parent.task_context_buffer 750 ); 751 752 this_request->type.pio.current_transfer_bytes = 0; 753 this_request->type.pio.ending_error = 0; 754 this_request->type.pio.ending_status = 0; 755 756 this_request->type.pio.request_current.sgl_offset = 0; 757 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A; 758 this_request->type.pio.sat_protocol = sat_protocol; 759 this_request->type.pio.sgl_pair_index = 0; 760 761 if ((copy_rx_frame) || (sat_protocol == SAT_PROTOCOL_PIO_DATA_OUT)) 762 { 763 scic_sds_request_build_sgl(&this_request->parent); 764 // Since the IO request copy of the TC contains the same data as 765 // the actual TC this pointer is vaild for either. 766 this_request->type.pio.request_current.sgl_pair = 767 &this_request->parent.task_context_buffer->sgl_pair_ab; 768 } 769 else 770 { 771 // The user does not want the data copied to the SGL buffer location 772 this_request->type.pio.request_current.sgl_pair = NULL; 773 } 774 775 sci_base_state_machine_construct( 776 &this_request->parent.started_substate_machine, 777 &this_request->parent.parent.parent, 778 scic_sds_stp_request_started_pio_substate_table, 779 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE 780 ); 781 782 return SCI_SUCCESS; 783 } 784 785 //****************************************************************************** 786 //* STP NON-DATA STATE MACHINE 787 //****************************************************************************** 788 789 /** 790 * This method processes a TC completion. The expected TC completion is 791 * for the transmission of the H2D register FIS containing the SATA/STP 792 * non-data request. 793 * 794 * @param[in] this_request 795 * @param[in] completion_code 796 * 797 * @return This method always successfully processes the TC completion. 798 * @retval SCI_SUCCESS This value is always returned. 799 */ 800 static 801 SCI_STATUS scic_sds_stp_request_non_data_await_h2d_tc_completion_handler( 802 SCIC_SDS_REQUEST_T * this_request, 803 U32 completion_code 804 ) 805 { 806 SCIC_LOG_TRACE(( 807 sci_base_object_get_logger(this_request), 808 SCIC_LOG_OBJECT_STP_IO_REQUEST, 809 "scic_sds_stp_request_non_data_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n", 810 this_request, completion_code 811 )); 812 813 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 814 { 815 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 816 scic_sds_request_set_status( 817 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 818 ); 819 820 sci_base_state_machine_change_state( 821 &this_request->started_substate_machine, 822 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE 823 ); 824 break; 825 826 default: 827 // All other completion status cause the IO to be complete. If a NAK 828 // was received, then it is up to the user to retry the request. 829 scic_sds_request_set_status( 830 this_request, 831 SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 832 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 833 ); 834 835 sci_base_state_machine_change_state( 836 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED 837 ); 838 break; 839 } 840 841 return SCI_SUCCESS; 842 } 843 844 /** 845 * This method processes frames received from the target while waiting 846 * for a device to host register FIS. If a non-register FIS is received 847 * during this time, it is treated as a protocol violation from an 848 * IO perspective. 849 * 850 * @param[in] request This parameter specifies the request for which a 851 * frame has been received. 852 * @param[in] frame_index This parameter specifies the index of the frame 853 * that has been received. 854 * 855 * @return Indicate if the received frame was processed successfully. 856 */ 857 static 858 SCI_STATUS scic_sds_stp_request_non_data_await_d2h_frame_handler( 859 SCIC_SDS_REQUEST_T * request, 860 U32 frame_index 861 ) 862 { 863 SCI_STATUS status; 864 SATA_FIS_HEADER_T * frame_header; 865 U32 * frame_buffer; 866 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request; 867 868 // Save off the controller, so that we do not touch the request after it 869 // is completed. 870 SCIC_SDS_CONTROLLER_T * owning_controller = this_request->parent.owning_controller; 871 872 SCIC_LOG_TRACE(( 873 sci_base_object_get_logger(this_request), 874 SCIC_LOG_OBJECT_STP_IO_REQUEST, 875 "scic_sds_stp_request_non_data_await_d2h_frame_handler(0x%x, 0x%x) enter\n", 876 this_request, frame_index 877 )); 878 879 status = scic_sds_unsolicited_frame_control_get_header( 880 &(owning_controller->uf_control), 881 frame_index, 882 (void**) &frame_header 883 ); 884 885 if (status == SCI_SUCCESS) 886 { 887 switch (frame_header->fis_type) 888 { 889 case SATA_FIS_TYPE_REGD2H: 890 scic_sds_unsolicited_frame_control_get_buffer( 891 &(owning_controller->uf_control), 892 frame_index, 893 (void**) &frame_buffer 894 ); 895 896 scic_sds_controller_copy_sata_response( 897 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer 898 ); 899 900 // The command has completed with error 901 scic_sds_request_set_status( 902 &this_request->parent, 903 SCU_TASK_DONE_CHECK_RESPONSE, 904 SCI_FAILURE_IO_RESPONSE_VALID 905 ); 906 break; 907 908 default: 909 SCIC_LOG_WARNING(( 910 sci_base_object_get_logger(this_request), 911 SCIC_LOG_OBJECT_STP_IO_REQUEST, 912 "IO Request:0x%x Frame Id:%d protocol violation occurred\n", 913 this_request, frame_index 914 )); 915 916 scic_sds_request_set_status( 917 &this_request->parent, 918 SCU_TASK_DONE_UNEXP_FIS, 919 SCI_FAILURE_PROTOCOL_VIOLATION 920 ); 921 break; 922 } 923 924 sci_base_state_machine_change_state( 925 &this_request->parent.parent.state_machine, 926 SCI_BASE_REQUEST_STATE_COMPLETED 927 ); 928 929 // Frame has been decoded return it to the controller 930 scic_sds_controller_release_frame( 931 owning_controller, frame_index 932 ); 933 } 934 else 935 { 936 SCIC_LOG_ERROR(( 937 sci_base_object_get_logger(this_request), 938 SCIC_LOG_OBJECT_STP_IO_REQUEST, 939 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n", 940 this_request, frame_index, status 941 )); 942 } 943 944 return status; 945 } 946 947 // --------------------------------------------------------------------------- 948 949 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T 950 scic_sds_stp_request_started_non_data_substate_handler_table 951 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_MAX_SUBSTATES] = 952 { 953 // SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE 954 { 955 { 956 scic_sds_request_default_start_handler, 957 scic_sds_request_started_state_abort_handler, 958 scic_sds_request_default_complete_handler, 959 scic_sds_request_default_destruct_handler 960 }, 961 scic_sds_stp_request_non_data_await_h2d_tc_completion_handler, 962 scic_sds_request_default_event_handler, 963 scic_sds_request_default_frame_handler 964 }, 965 // SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE 966 { 967 { 968 scic_sds_request_default_start_handler, 969 scic_sds_request_started_state_abort_handler, 970 scic_sds_request_default_complete_handler, 971 scic_sds_request_default_destruct_handler 972 }, 973 scic_sds_request_default_tc_completion_handler, 974 scic_sds_request_default_event_handler, 975 scic_sds_stp_request_non_data_await_d2h_frame_handler 976 } 977 }; 978 979 static 980 void scic_sds_stp_request_started_non_data_await_h2d_completion_enter( 981 SCI_BASE_OBJECT_T *object 982 ) 983 { 984 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 985 986 SET_STATE_HANDLER( 987 this_request, 988 scic_sds_stp_request_started_non_data_substate_handler_table, 989 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE 990 ); 991 992 scic_sds_remote_device_set_working_request( 993 this_request->target_device, this_request 994 ); 995 } 996 997 static 998 void scic_sds_stp_request_started_non_data_await_d2h_enter( 999 SCI_BASE_OBJECT_T *object 1000 ) 1001 { 1002 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 1003 1004 SET_STATE_HANDLER( 1005 this_request, 1006 scic_sds_stp_request_started_non_data_substate_handler_table, 1007 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE 1008 ); 1009 } 1010 1011 // --------------------------------------------------------------------------- 1012 1013 SCI_BASE_STATE_T scic_sds_stp_request_started_non_data_substate_table 1014 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_MAX_SUBSTATES] = 1015 { 1016 { 1017 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE, 1018 scic_sds_stp_request_started_non_data_await_h2d_completion_enter, 1019 NULL 1020 }, 1021 { 1022 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE, 1023 scic_sds_stp_request_started_non_data_await_d2h_enter, 1024 NULL 1025 } 1026 }; 1027 1028 //****************************************************************************** 1029 //* STP PIO STATE MACHINE 1030 //****************************************************************************** 1031 1032 #define SCU_MAX_FRAME_BUFFER_SIZE 0x400 // 1K is the maximum SCU frame data payload 1033 1034 /** 1035 * This function will transmit DATA_FIS from (current sgl + offset) for input parameter length. 1036 * current sgl and offset is alreay stored in the IO request 1037 * 1038 * @param[in] this_request 1039 * @param[in] length 1040 * 1041 * @return SCI_STATUS 1042 */ 1043 static 1044 SCI_STATUS scic_sds_stp_request_pio_data_out_trasmit_data_frame ( 1045 SCIC_SDS_REQUEST_T * this_request, 1046 U32 length 1047 ) 1048 { 1049 SCI_STATUS status = SCI_SUCCESS; 1050 SCU_SGL_ELEMENT_T * current_sgl; 1051 SCIC_SDS_STP_REQUEST_T * this_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *)this_request; 1052 1053 // Recycle the TC and reconstruct it for sending out DATA FIS containing 1054 // for the data from current_sgl+offset for the input length 1055 SCU_TASK_CONTEXT_T * task_context = scic_sds_controller_get_task_context_buffer( 1056 this_request->owning_controller, 1057 this_request->io_tag 1058 ); 1059 1060 if (this_sds_stp_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) 1061 { 1062 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->A); 1063 } 1064 else 1065 { 1066 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->B); 1067 } 1068 1069 //update the TC 1070 task_context->command_iu_upper = current_sgl->address_upper; 1071 task_context->command_iu_lower = current_sgl->address_lower; 1072 task_context->transfer_length_bytes = length; 1073 task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA; 1074 1075 // send the new TC out. 1076 status = this_request->owning_controller->state_handlers->parent.continue_io_handler( 1077 &this_request->owning_controller->parent, 1078 &this_request->target_device->parent, 1079 &this_request->parent 1080 ); 1081 1082 return status; 1083 1084 } 1085 1086 /** 1087 * 1088 * 1089 * @param[in] this_request 1090 * 1091 * @return SCI_STATUS 1092 */ 1093 static 1094 SCI_STATUS scic_sds_stp_request_pio_data_out_transmit_data( 1095 SCIC_SDS_REQUEST_T * this_sds_request 1096 ) 1097 { 1098 1099 SCU_SGL_ELEMENT_T * current_sgl; 1100 U32 sgl_offset; 1101 U32 remaining_bytes_in_current_sgl = 0; 1102 SCI_STATUS status = SCI_SUCCESS; 1103 1104 SCIC_SDS_STP_REQUEST_T * this_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *)this_sds_request; 1105 1106 sgl_offset = this_sds_stp_request->type.pio.request_current.sgl_offset; 1107 1108 if (this_sds_stp_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) 1109 { 1110 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->A); 1111 remaining_bytes_in_current_sgl = this_sds_stp_request->type.pio.request_current.sgl_pair->A.length - sgl_offset; 1112 } 1113 else 1114 { 1115 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->B); 1116 remaining_bytes_in_current_sgl = this_sds_stp_request->type.pio.request_current.sgl_pair->B.length - sgl_offset; 1117 } 1118 1119 1120 if (this_sds_stp_request->type.pio.pio_transfer_bytes > 0) 1121 { 1122 if (this_sds_stp_request->type.pio.pio_transfer_bytes >= remaining_bytes_in_current_sgl ) 1123 { 1124 //recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = remaining_bytes_in_current_sgl 1125 status = scic_sds_stp_request_pio_data_out_trasmit_data_frame (this_sds_request, remaining_bytes_in_current_sgl); 1126 if (status == SCI_SUCCESS) 1127 { 1128 this_sds_stp_request->type.pio.pio_transfer_bytes -= remaining_bytes_in_current_sgl; 1129 sgl_offset = 0; 1130 } 1131 } 1132 else if (this_sds_stp_request->type.pio.pio_transfer_bytes < remaining_bytes_in_current_sgl ) 1133 { 1134 //recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = type.pio.pio_transfer_bytes 1135 scic_sds_stp_request_pio_data_out_trasmit_data_frame (this_sds_request, this_sds_stp_request->type.pio.pio_transfer_bytes); 1136 1137 if (status == SCI_SUCCESS) 1138 { 1139 //Sgl offset will be adjusted and saved for future 1140 sgl_offset += this_sds_stp_request->type.pio.pio_transfer_bytes; 1141 current_sgl->address_lower += this_sds_stp_request->type.pio.pio_transfer_bytes; 1142 this_sds_stp_request->type.pio.pio_transfer_bytes = 0; 1143 } 1144 } 1145 } 1146 1147 if (status == SCI_SUCCESS) 1148 { 1149 this_sds_stp_request->type.pio.request_current.sgl_offset = sgl_offset; 1150 } 1151 1152 return status; 1153 } 1154 1155 /** 1156 * Copy the data from the buffer for the length specified to the IO reqeust 1157 * SGL specified data region. 1158 * 1159 * @param[in] this_request The request that is used for the SGL processing. 1160 * @param[in] data_buffer The buffer of data to be copied. 1161 * @param[in] length The length of the data transfer. 1162 * 1163 * @return SCI_STATUS 1164 */ 1165 static 1166 SCI_STATUS scic_sds_stp_request_pio_data_in_copy_data_buffer( 1167 SCIC_SDS_STP_REQUEST_T * this_request, 1168 U8 * data_buffer, 1169 U32 length 1170 ) 1171 { 1172 SCI_STATUS status; 1173 SCU_SGL_ELEMENT_T * current_sgl; 1174 U32 sgl_offset; 1175 U32 data_offset; 1176 U8 * source_address; 1177 1178 // Initial setup to get the current working SGL and the offset within the buffer 1179 current_sgl = 1180 (this_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) ? 1181 &(this_request->type.pio.request_current.sgl_pair->A) : 1182 &(this_request->type.pio.request_current.sgl_pair->B) ; 1183 1184 sgl_offset = this_request->type.pio.request_current.sgl_offset; 1185 1186 source_address = data_buffer; 1187 data_offset = this_request->type.pio.current_transfer_bytes; 1188 status = SCI_SUCCESS; 1189 1190 // While we are still doing Ok and there is more data to transfer 1191 while ( 1192 (length > 0) 1193 && (status == SCI_SUCCESS) 1194 ) 1195 { 1196 if (current_sgl->length == sgl_offset) 1197 { 1198 // This SGL has been exauhasted so we need to get the next SGL 1199 current_sgl = scic_sds_stp_request_pio_get_next_sgl(this_request); 1200 1201 if (current_sgl == NULL) 1202 status = SCI_FAILURE; 1203 else 1204 sgl_offset = 0; 1205 } 1206 else 1207 { 1208 #ifdef ENABLE_OSSL_COPY_BUFFER 1209 scic_cb_io_request_copy_buffer(this_request, data_buffer, data_offset, length); 1210 length = 0; 1211 #else 1212 U8 * destination_address; 1213 U32 copy_length; 1214 1215 destination_address = (U8 *)scic_cb_io_request_get_virtual_address_from_sgl( 1216 this_request, 1217 data_offset 1218 ); 1219 1220 copy_length = MIN(length, current_sgl->length - sgl_offset); 1221 1222 memcpy(destination_address, source_address, copy_length); 1223 1224 length -= copy_length; 1225 sgl_offset += copy_length; 1226 data_offset += copy_length; 1227 source_address += copy_length; 1228 #endif 1229 } 1230 } 1231 1232 this_request->type.pio.request_current.sgl_offset = sgl_offset; 1233 1234 return status; 1235 } 1236 1237 /** 1238 * Copy the data buffer to the io request data region. 1239 * 1240 * @param[in] this_request The PIO DATA IN request that is to receive the 1241 * data. 1242 * @param[in] data_buffer The buffer to copy from. 1243 * 1244 * @return SCI_STATUS 1245 */ 1246 static 1247 SCI_STATUS scic_sds_stp_request_pio_data_in_copy_data( 1248 SCIC_SDS_STP_REQUEST_T * this_request, 1249 U8 * data_buffer 1250 ) 1251 { 1252 SCI_STATUS status; 1253 1254 // If there is less than 1K remaining in the transfer request 1255 // copy just the data for the transfer 1256 if (this_request->type.pio.pio_transfer_bytes < SCU_MAX_FRAME_BUFFER_SIZE) 1257 { 1258 status = scic_sds_stp_request_pio_data_in_copy_data_buffer( 1259 this_request,data_buffer,this_request->type.pio.pio_transfer_bytes); 1260 1261 if (status == SCI_SUCCESS) 1262 { 1263 // All data for this PIO request has now been copied, so we don't 1264 // technically need to update current_transfer_bytes here - just 1265 // doing it for completeness. 1266 this_request->type.pio.current_transfer_bytes += this_request->type.pio.pio_transfer_bytes; 1267 this_request->type.pio.pio_transfer_bytes = 0; 1268 } 1269 } 1270 else 1271 { 1272 // We are transferring the whole frame so copy 1273 status = scic_sds_stp_request_pio_data_in_copy_data_buffer( 1274 this_request, data_buffer, SCU_MAX_FRAME_BUFFER_SIZE); 1275 1276 if (status == SCI_SUCCESS) 1277 { 1278 this_request->type.pio.pio_transfer_bytes -= SCU_MAX_FRAME_BUFFER_SIZE; 1279 this_request->type.pio.current_transfer_bytes += SCU_MAX_FRAME_BUFFER_SIZE; 1280 } 1281 } 1282 1283 return status; 1284 } 1285 1286 /** 1287 * 1288 * 1289 * @param[in] this_request 1290 * @param[in] completion_code 1291 * 1292 * @return SCI_STATUS 1293 */ 1294 static 1295 SCI_STATUS scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler( 1296 SCIC_SDS_REQUEST_T * this_request, 1297 U32 completion_code 1298 ) 1299 { 1300 SCI_STATUS status = SCI_SUCCESS; 1301 1302 SCIC_LOG_TRACE(( 1303 sci_base_object_get_logger(this_request), 1304 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1305 "scic_sds_stp_request_pio_data_in_await_h2d_completion_tc_completion_handler(0x%x, 0x%x) enter\n", 1306 this_request, completion_code 1307 )); 1308 1309 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 1310 { 1311 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 1312 scic_sds_request_set_status( 1313 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 1314 ); 1315 1316 sci_base_state_machine_change_state( 1317 &this_request->started_substate_machine, 1318 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE 1319 ); 1320 break; 1321 1322 default: 1323 // All other completion status cause the IO to be complete. If a NAK 1324 // was received, then it is up to the user to retry the request. 1325 scic_sds_request_set_status( 1326 this_request, 1327 SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 1328 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 1329 ); 1330 1331 sci_base_state_machine_change_state( 1332 &this_request->parent.state_machine, 1333 SCI_BASE_REQUEST_STATE_COMPLETED 1334 ); 1335 break; 1336 } 1337 1338 return status; 1339 } 1340 1341 /** 1342 * 1343 * 1344 * @param[in] this_request 1345 * @param[in] frame_index 1346 * 1347 * @return SCI_STATUS 1348 */ 1349 static 1350 SCI_STATUS scic_sds_stp_request_pio_await_frame_frame_handler( 1351 SCIC_SDS_REQUEST_T * request, 1352 U32 frame_index 1353 ) 1354 { 1355 SCI_STATUS status; 1356 SATA_FIS_HEADER_T * frame_header; 1357 U32 * frame_buffer; 1358 SCIC_SDS_STP_REQUEST_T * this_request; 1359 SCIC_SDS_CONTROLLER_T * owning_controller; 1360 1361 this_request = (SCIC_SDS_STP_REQUEST_T *)request; 1362 1363 // Save off the controller, so that we do not touch the request after it 1364 // is completed. 1365 owning_controller = this_request->parent.owning_controller; 1366 1367 SCIC_LOG_TRACE(( 1368 sci_base_object_get_logger(this_request), 1369 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1370 "scic_sds_stp_request_pio_data_in_await_frame_frame_handler(0x%x, 0x%x) enter\n", 1371 this_request, frame_index 1372 )); 1373 1374 status = scic_sds_unsolicited_frame_control_get_header( 1375 &(owning_controller->uf_control), 1376 frame_index, 1377 (void**) &frame_header 1378 ); 1379 1380 if (status == SCI_SUCCESS) 1381 { 1382 switch (frame_header->fis_type) 1383 { 1384 case SATA_FIS_TYPE_PIO_SETUP: 1385 // Get from the frame buffer the PIO Setup Data 1386 scic_sds_unsolicited_frame_control_get_buffer( 1387 &(owning_controller->uf_control), 1388 frame_index, 1389 (void**) &frame_buffer 1390 ); 1391 1392 // Get the data from the PIO Setup 1393 // The SCU Hardware returns first word in the frame_header and the rest 1394 // of the data is in the frame buffer so we need to back up one dword 1395 this_request->type.pio.pio_transfer_bytes = 1396 (U16)((SATA_FIS_PIO_SETUP_T *)(&frame_buffer[-1]))->transfter_count; 1397 this_request->type.pio.ending_status = 1398 (U8)((SATA_FIS_PIO_SETUP_T *)(&frame_buffer[-1]))->ending_status; 1399 1400 scic_sds_controller_copy_sata_response( 1401 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer 1402 ); 1403 1404 this_request->d2h_reg_fis.status = 1405 this_request->type.pio.ending_status; 1406 1407 //The next state is dependent on whether the request was PIO Data-in or Data out 1408 if (this_request->type.pio.sat_protocol == SAT_PROTOCOL_PIO_DATA_IN) 1409 { 1410 sci_base_state_machine_change_state( 1411 &this_request->parent.started_substate_machine, 1412 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE 1413 ); 1414 } 1415 else if (this_request->type.pio.sat_protocol == SAT_PROTOCOL_PIO_DATA_OUT) 1416 { 1417 //Transmit data 1418 status = scic_sds_stp_request_pio_data_out_transmit_data ( request); 1419 if (status == SCI_SUCCESS) 1420 { 1421 sci_base_state_machine_change_state( 1422 &this_request->parent.started_substate_machine, 1423 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE 1424 ); 1425 } 1426 } 1427 break; 1428 1429 case SATA_FIS_TYPE_SETDEVBITS: 1430 sci_base_state_machine_change_state( 1431 &this_request->parent.started_substate_machine, 1432 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE 1433 ); 1434 break; 1435 1436 case SATA_FIS_TYPE_REGD2H: 1437 if ( (frame_header->status & ATA_STATUS_REG_BSY_BIT) == 0) 1438 { 1439 scic_sds_unsolicited_frame_control_get_buffer( 1440 &(owning_controller->uf_control), 1441 frame_index, 1442 (void**) &frame_buffer 1443 ); 1444 1445 scic_sds_controller_copy_sata_response( 1446 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer); 1447 1448 scic_sds_request_set_status( 1449 &this_request->parent, 1450 SCU_TASK_DONE_CHECK_RESPONSE, 1451 SCI_FAILURE_IO_RESPONSE_VALID 1452 ); 1453 1454 sci_base_state_machine_change_state( 1455 &this_request->parent.parent.state_machine, 1456 SCI_BASE_REQUEST_STATE_COMPLETED 1457 ); 1458 } 1459 else 1460 { 1461 // Now why is the drive sending a D2H Register FIS when it is still busy? 1462 // Do nothing since we are still in the right state. 1463 SCIC_LOG_INFO(( 1464 sci_base_object_get_logger(this_request), 1465 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1466 "SCIC PIO Request 0x%x received D2H Register FIS with BSY status 0x%x\n", 1467 this_request, frame_header->status 1468 )); 1469 } 1470 break; 1471 1472 default: 1473 break; 1474 } 1475 1476 // Frame is decoded return it to the controller 1477 scic_sds_controller_release_frame( 1478 owning_controller, 1479 frame_index 1480 ); 1481 } 1482 else 1483 { 1484 SCIC_LOG_ERROR(( 1485 sci_base_object_get_logger(this_request), 1486 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1487 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n", 1488 this_request, frame_index, status 1489 )); 1490 } 1491 1492 return status; 1493 } 1494 1495 /** 1496 * 1497 * 1498 * @param[in] this_request 1499 * @param[in] frame_index 1500 * 1501 * @return SCI_STATUS 1502 */ 1503 static 1504 SCI_STATUS scic_sds_stp_request_pio_data_in_await_data_frame_handler( 1505 SCIC_SDS_REQUEST_T * request, 1506 U32 frame_index 1507 ) 1508 { 1509 SCI_STATUS status; 1510 SATA_FIS_HEADER_T * frame_header; 1511 SATA_FIS_DATA_T * frame_buffer; 1512 SCIC_SDS_STP_REQUEST_T * this_request; 1513 SCIC_SDS_CONTROLLER_T * owning_controller; 1514 1515 this_request = (SCIC_SDS_STP_REQUEST_T *)request; 1516 1517 // Save off the controller, so that we do not touch the request after it 1518 // is completed. 1519 owning_controller = this_request->parent.owning_controller; 1520 1521 SCIC_LOG_TRACE(( 1522 sci_base_object_get_logger(this_request), 1523 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1524 "scic_sds_stp_request_pio_data_in_await_data_frame_handler(0x%x, 0x%x) enter\n", 1525 this_request, frame_index 1526 )); 1527 1528 status = scic_sds_unsolicited_frame_control_get_header( 1529 &(owning_controller->uf_control), 1530 frame_index, 1531 (void**) &frame_header 1532 ); 1533 1534 if (status == SCI_SUCCESS) 1535 { 1536 if (frame_header->fis_type == SATA_FIS_TYPE_DATA) 1537 { 1538 if (this_request->type.pio.request_current.sgl_pair == NULL) 1539 { 1540 this_request->parent.saved_rx_frame_index = frame_index; 1541 this_request->type.pio.pio_transfer_bytes = 0; 1542 } 1543 else 1544 { 1545 status = scic_sds_unsolicited_frame_control_get_buffer( 1546 &(owning_controller->uf_control), 1547 frame_index, 1548 (void**) &frame_buffer 1549 ); 1550 1551 status = scic_sds_stp_request_pio_data_in_copy_data(this_request, (U8 *)frame_buffer); 1552 1553 // Frame is decoded return it to the controller 1554 scic_sds_controller_release_frame( 1555 owning_controller, 1556 frame_index 1557 ); 1558 } 1559 1560 // Check for the end of the transfer, are there more bytes remaining 1561 // for this data transfer 1562 if ( 1563 (status == SCI_SUCCESS) 1564 && (this_request->type.pio.pio_transfer_bytes == 0) 1565 ) 1566 { 1567 if ((this_request->type.pio.ending_status & ATA_STATUS_REG_BSY_BIT) == 0) 1568 { 1569 scic_sds_request_set_status( 1570 &this_request->parent, 1571 SCU_TASK_DONE_CHECK_RESPONSE, 1572 SCI_FAILURE_IO_RESPONSE_VALID 1573 ); 1574 1575 sci_base_state_machine_change_state( 1576 &this_request->parent.parent.state_machine, 1577 SCI_BASE_REQUEST_STATE_COMPLETED 1578 ); 1579 } 1580 else 1581 { 1582 sci_base_state_machine_change_state( 1583 &this_request->parent.started_substate_machine, 1584 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE 1585 ); 1586 } 1587 } 1588 } 1589 else 1590 { 1591 SCIC_LOG_ERROR(( 1592 sci_base_object_get_logger(this_request), 1593 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1594 "SCIC PIO Request 0x%x received frame %d with fis type 0x%02x when expecting a data fis.\n", 1595 this_request, frame_index, frame_header->fis_type 1596 )); 1597 1598 scic_sds_request_set_status( 1599 &this_request->parent, 1600 SCU_TASK_DONE_GOOD, 1601 SCI_FAILURE_IO_REQUIRES_SCSI_ABORT 1602 ); 1603 1604 sci_base_state_machine_change_state( 1605 &this_request->parent.parent.state_machine, 1606 SCI_BASE_REQUEST_STATE_COMPLETED 1607 ); 1608 1609 // Frame is decoded return it to the controller 1610 scic_sds_controller_release_frame( 1611 owning_controller, 1612 frame_index 1613 ); 1614 } 1615 } 1616 else 1617 { 1618 SCIC_LOG_ERROR(( 1619 sci_base_object_get_logger(this_request), 1620 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1621 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n", 1622 this_request, frame_index, status 1623 )); 1624 } 1625 1626 return status; 1627 } 1628 1629 1630 /** 1631 * 1632 * 1633 * @param[in] this_request 1634 * @param[in] completion_code 1635 * 1636 * @return SCI_STATUS 1637 */ 1638 static 1639 SCI_STATUS scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler( 1640 1641 SCIC_SDS_REQUEST_T * this_request, 1642 U32 completion_code 1643 ) 1644 { 1645 SCI_STATUS status = SCI_SUCCESS; 1646 BOOL all_frames_transferred = FALSE; 1647 1648 SCIC_SDS_STP_REQUEST_T *this_scic_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *) this_request; 1649 1650 SCIC_LOG_TRACE(( 1651 sci_base_object_get_logger(this_request), 1652 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1653 "scic_sds_stp_request_pio_data_in_await_h2d_completion_tc_completion_handler(0x%x, 0x%x) enter\n", 1654 this_request, completion_code 1655 )); 1656 1657 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 1658 { 1659 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 1660 //Transmit data 1661 if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes != 0) 1662 { 1663 status = scic_sds_stp_request_pio_data_out_transmit_data ( this_request); 1664 if (status == SCI_SUCCESS) 1665 { 1666 if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes == 0) 1667 all_frames_transferred = TRUE; 1668 } 1669 } 1670 else if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes == 0) 1671 { 1672 //this will happen if the all data is written at the first time after the pio setup fis is received 1673 all_frames_transferred = TRUE; 1674 } 1675 1676 //all data transferred. 1677 if (all_frames_transferred) 1678 { 1679 //Change the state to SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_FRAME_SUBSTATE 1680 //and wait for PIO_SETUP fis / or D2H REg fis. 1681 sci_base_state_machine_change_state( 1682 &this_request->started_substate_machine, 1683 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE 1684 ); 1685 } 1686 break; 1687 1688 default: 1689 // All other completion status cause the IO to be complete. If a NAK 1690 // was received, then it is up to the user to retry the request. 1691 scic_sds_request_set_status( 1692 this_request, 1693 SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 1694 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 1695 ); 1696 1697 sci_base_state_machine_change_state( 1698 &this_request->parent.state_machine, 1699 SCI_BASE_REQUEST_STATE_COMPLETED 1700 ); 1701 break; 1702 } 1703 1704 return status; 1705 } 1706 1707 /** 1708 * This method will handle any link layer events while waiting for the data 1709 * frame. 1710 * 1711 * @param[in] request This is the request which is receiving the event. 1712 * @param[in] event_code This is the event code that the request on which the 1713 * request is expected to take action. 1714 * 1715 * @return SCI_STATUS 1716 * @retval SCI_SUCCESS 1717 * @retval SCI_FAILURE 1718 */ 1719 static 1720 SCI_STATUS scic_sds_stp_request_pio_data_in_await_data_event_handler( 1721 SCIC_SDS_REQUEST_T * request, 1722 U32 event_code 1723 ) 1724 { 1725 SCI_STATUS status; 1726 1727 switch (scu_get_event_specifier(event_code)) 1728 { 1729 case SCU_TASK_DONE_CRC_ERR << SCU_EVENT_SPECIFIC_CODE_SHIFT: 1730 // We are waiting for data and the SCU has R_ERR the data frame. 1731 // Go back to waiting for the D2H Register FIS 1732 sci_base_state_machine_change_state( 1733 &request->started_substate_machine, 1734 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE 1735 ); 1736 1737 status = SCI_SUCCESS; 1738 break; 1739 1740 default: 1741 SCIC_LOG_ERROR(( 1742 sci_base_object_get_logger(request), 1743 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1744 "SCIC PIO Request 0x%x received unexpected event 0x%08x\n", 1745 request, event_code 1746 )); 1747 1748 /// @todo Should we fail the PIO request when we get an unexpected event? 1749 status = SCI_FAILURE; 1750 break; 1751 } 1752 1753 return status; 1754 } 1755 1756 // --------------------------------------------------------------------------- 1757 1758 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T 1759 scic_sds_stp_request_started_pio_substate_handler_table 1760 [SCIC_SDS_STP_REQUEST_STARTED_PIO_MAX_SUBSTATES] = 1761 { 1762 // SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE 1763 { 1764 { 1765 scic_sds_request_default_start_handler, 1766 scic_sds_request_started_state_abort_handler, 1767 scic_sds_request_default_complete_handler, 1768 scic_sds_request_default_destruct_handler 1769 }, 1770 scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler, 1771 scic_sds_request_default_event_handler, 1772 scic_sds_request_default_frame_handler 1773 }, 1774 // SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE 1775 { 1776 { 1777 scic_sds_request_default_start_handler, 1778 //scic_sds_stp_pio_request_data_in_await_frame_abort_handler, 1779 scic_sds_request_started_state_abort_handler, 1780 scic_sds_request_default_complete_handler, 1781 scic_sds_request_default_destruct_handler 1782 }, 1783 scic_sds_request_default_tc_completion_handler, 1784 scic_sds_request_default_event_handler, 1785 scic_sds_stp_request_pio_await_frame_frame_handler 1786 }, 1787 // SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE 1788 { 1789 { 1790 scic_sds_request_default_start_handler, 1791 //scic_sds_stp_pio_request_data_in_await_data_abort_handler, 1792 scic_sds_request_started_state_abort_handler, 1793 scic_sds_request_default_complete_handler, 1794 scic_sds_request_default_destruct_handler 1795 }, 1796 scic_sds_request_default_tc_completion_handler, 1797 scic_sds_stp_request_pio_data_in_await_data_event_handler, 1798 scic_sds_stp_request_pio_data_in_await_data_frame_handler 1799 }, 1800 //SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE 1801 { 1802 { 1803 scic_sds_request_default_start_handler, 1804 scic_sds_request_started_state_abort_handler, 1805 scic_sds_request_default_complete_handler, 1806 scic_sds_request_default_destruct_handler 1807 }, 1808 scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler, 1809 scic_sds_request_default_event_handler, 1810 scic_sds_request_default_frame_handler 1811 } 1812 }; 1813 1814 static 1815 void scic_sds_stp_request_started_pio_await_h2d_completion_enter( 1816 SCI_BASE_OBJECT_T *object 1817 ) 1818 { 1819 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 1820 1821 SET_STATE_HANDLER( 1822 this_request, 1823 scic_sds_stp_request_started_pio_substate_handler_table, 1824 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE 1825 ); 1826 1827 scic_sds_remote_device_set_working_request( 1828 this_request->target_device, this_request); 1829 } 1830 1831 static 1832 void scic_sds_stp_request_started_pio_await_frame_enter( 1833 SCI_BASE_OBJECT_T *object 1834 ) 1835 { 1836 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 1837 1838 SET_STATE_HANDLER( 1839 this_request, 1840 scic_sds_stp_request_started_pio_substate_handler_table, 1841 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE 1842 ); 1843 } 1844 1845 static 1846 void scic_sds_stp_request_started_pio_data_in_await_data_enter( 1847 SCI_BASE_OBJECT_T *object 1848 ) 1849 { 1850 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 1851 1852 SET_STATE_HANDLER( 1853 this_request, 1854 scic_sds_stp_request_started_pio_substate_handler_table, 1855 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE 1856 ); 1857 } 1858 1859 static 1860 void scic_sds_stp_request_started_pio_data_out_transmit_data_enter( 1861 SCI_BASE_OBJECT_T *object 1862 ) 1863 { 1864 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 1865 1866 SET_STATE_HANDLER( 1867 this_request, 1868 scic_sds_stp_request_started_pio_substate_handler_table, 1869 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE 1870 ); 1871 } 1872 1873 // --------------------------------------------------------------------------- 1874 1875 SCI_BASE_STATE_T 1876 scic_sds_stp_request_started_pio_substate_table 1877 [SCIC_SDS_STP_REQUEST_STARTED_PIO_MAX_SUBSTATES] = 1878 { 1879 { 1880 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE, 1881 scic_sds_stp_request_started_pio_await_h2d_completion_enter, 1882 NULL 1883 }, 1884 { 1885 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE, 1886 scic_sds_stp_request_started_pio_await_frame_enter, 1887 NULL 1888 }, 1889 { 1890 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE, 1891 scic_sds_stp_request_started_pio_data_in_await_data_enter, 1892 NULL 1893 }, 1894 { 1895 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE, 1896 scic_sds_stp_request_started_pio_data_out_transmit_data_enter, 1897 NULL 1898 } 1899 }; 1900 1901 //****************************************************************************** 1902 //* UDMA REQUEST STATE MACHINE 1903 //****************************************************************************** 1904 1905 static 1906 void scic_sds_stp_request_udma_complete_request( 1907 SCIC_SDS_REQUEST_T * this_request, 1908 U32 scu_status, 1909 SCI_STATUS sci_status 1910 ) 1911 { 1912 scic_sds_request_set_status( 1913 this_request, scu_status, sci_status 1914 ); 1915 1916 sci_base_state_machine_change_state( 1917 &this_request->parent.state_machine, 1918 SCI_BASE_REQUEST_STATE_COMPLETED 1919 ); 1920 } 1921 1922 /** 1923 * 1924 * 1925 * @param[in] this_request 1926 * @param[in] frame_index 1927 * 1928 * @return SCI_STATUS 1929 */ 1930 static 1931 SCI_STATUS scic_sds_stp_request_udma_general_frame_handler( 1932 SCIC_SDS_REQUEST_T * this_request, 1933 U32 frame_index 1934 ) 1935 { 1936 SCI_STATUS status; 1937 SATA_FIS_HEADER_T * frame_header; 1938 U32 * frame_buffer; 1939 1940 SCIC_LOG_TRACE(( 1941 sci_base_object_get_logger(this_request), 1942 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1943 "scic_sds_stp_pio_request_data_in_await_frame_frame_handler(0x%x, 0x%x) enter\n", 1944 this_request, frame_index 1945 )); 1946 1947 status = scic_sds_unsolicited_frame_control_get_header( 1948 &this_request->owning_controller->uf_control, 1949 frame_index, 1950 (void**) &frame_header 1951 ); 1952 1953 if ( 1954 (status == SCI_SUCCESS) 1955 && (frame_header->fis_type == SATA_FIS_TYPE_REGD2H) 1956 ) 1957 { 1958 scic_sds_unsolicited_frame_control_get_buffer( 1959 &this_request->owning_controller->uf_control, 1960 frame_index, 1961 (void**) &frame_buffer 1962 ); 1963 1964 scic_sds_controller_copy_sata_response( 1965 &((SCIC_SDS_STP_REQUEST_T *)this_request)->d2h_reg_fis, 1966 (U32 *)frame_header, 1967 frame_buffer 1968 ); 1969 } 1970 1971 scic_sds_controller_release_frame( 1972 this_request->owning_controller, frame_index); 1973 1974 return status; 1975 } 1976 1977 /** 1978 * @brief This method process TC completions while in the state where 1979 * we are waiting for TC completions. 1980 * 1981 * @param[in] this_request 1982 * @param[in] completion_code 1983 * 1984 * @return SCI_STATUS 1985 */ 1986 static 1987 SCI_STATUS scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler( 1988 SCIC_SDS_REQUEST_T * request, 1989 U32 completion_code 1990 ) 1991 { 1992 SCI_STATUS status = SCI_SUCCESS; 1993 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request; 1994 1995 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 1996 { 1997 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 1998 scic_sds_stp_request_udma_complete_request( 1999 &this_request->parent, SCU_TASK_DONE_GOOD, SCI_SUCCESS 2000 ); 2001 break; 2002 2003 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_FIS): 2004 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR): 2005 // We must check ther response buffer to see if the D2H Register FIS was 2006 // received before we got the TC completion. 2007 if (this_request->d2h_reg_fis.fis_type == SATA_FIS_TYPE_REGD2H) 2008 { 2009 scic_sds_remote_device_suspend( 2010 this_request->parent.target_device, 2011 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code)) 2012 ); 2013 2014 scic_sds_stp_request_udma_complete_request( 2015 &this_request->parent, 2016 SCU_TASK_DONE_CHECK_RESPONSE, 2017 SCI_FAILURE_IO_RESPONSE_VALID 2018 ); 2019 } 2020 else 2021 { 2022 // If we have an error completion status for the TC then we can expect a 2023 // D2H register FIS from the device so we must change state to wait for it 2024 sci_base_state_machine_change_state( 2025 &this_request->parent.started_substate_machine, 2026 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE 2027 ); 2028 } 2029 break; 2030 2031 /// @todo Check to see if any of these completion status need to wait for 2032 /// the device to host register fis. 2033 /// @todo We can retry the command for SCU_TASK_DONE_CMD_LL_R_ERR - this comes only for B0 2034 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_INV_FIS_LEN): 2035 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR): 2036 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_R_ERR): 2037 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CMD_LL_R_ERR): 2038 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CRC_ERR): 2039 scic_sds_remote_device_suspend( 2040 this_request->parent.target_device, 2041 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code)) 2042 ); 2043 // Fall through to the default case 2044 default: 2045 // All other completion status cause the IO to be complete. 2046 SCIC_LOG_ERROR(( 2047 sci_base_object_get_logger(&this_request->parent), 2048 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2049 "SCIC IO Request 0x%x returning CONTROLLER_SPECIFIC_IO_ERR for completion code 0x%x\n", 2050 &this_request->parent, completion_code 2051 )); 2052 scic_sds_stp_request_udma_complete_request( 2053 &this_request->parent, 2054 SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 2055 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 2056 ); 2057 break; 2058 } 2059 2060 return status; 2061 } 2062 2063 static 2064 SCI_STATUS scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler( 2065 SCIC_SDS_REQUEST_T * this_request, 2066 U32 frame_index 2067 ) 2068 { 2069 SCI_STATUS status; 2070 2071 // Use the general frame handler to copy the resposne data 2072 status = scic_sds_stp_request_udma_general_frame_handler(this_request, frame_index); 2073 2074 if (status == SCI_SUCCESS) 2075 { 2076 scic_sds_stp_request_udma_complete_request( 2077 this_request, 2078 SCU_TASK_DONE_CHECK_RESPONSE, 2079 SCI_FAILURE_IO_RESPONSE_VALID 2080 ); 2081 } 2082 2083 return status; 2084 } 2085 2086 // --------------------------------------------------------------------------- 2087 2088 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T 2089 scic_sds_stp_request_started_udma_substate_handler_table 2090 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_MAX_SUBSTATES] = 2091 { 2092 // SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE 2093 { 2094 { 2095 scic_sds_request_default_start_handler, 2096 scic_sds_request_started_state_abort_handler, 2097 scic_sds_request_default_complete_handler, 2098 scic_sds_request_default_destruct_handler 2099 }, 2100 scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler, 2101 scic_sds_request_default_event_handler, 2102 scic_sds_stp_request_udma_general_frame_handler 2103 }, 2104 // SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE 2105 { 2106 { 2107 scic_sds_request_default_start_handler, 2108 scic_sds_request_started_state_abort_handler, 2109 scic_sds_request_default_complete_handler, 2110 scic_sds_request_default_destruct_handler 2111 }, 2112 scic_sds_request_default_tc_completion_handler, 2113 scic_sds_request_default_event_handler, 2114 scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler 2115 } 2116 }; 2117 2118 /** 2119 * 2120 * 2121 * @param[in] object 2122 */ 2123 static 2124 void scic_sds_stp_request_started_udma_await_tc_completion_enter( 2125 SCI_BASE_OBJECT_T *object 2126 ) 2127 { 2128 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2129 2130 SET_STATE_HANDLER( 2131 this_request, 2132 scic_sds_stp_request_started_udma_substate_handler_table, 2133 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE 2134 ); 2135 } 2136 2137 /** 2138 * This state is entered when there is an TC completion failure. The hardware 2139 * received an unexpected condition while processing the IO request and now 2140 * will UF the D2H register FIS to complete the IO. 2141 * 2142 * @param[in] object 2143 */ 2144 static 2145 void scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter( 2146 SCI_BASE_OBJECT_T *object 2147 ) 2148 { 2149 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2150 2151 SET_STATE_HANDLER( 2152 this_request, 2153 scic_sds_stp_request_started_udma_substate_handler_table, 2154 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE 2155 ); 2156 } 2157 2158 // --------------------------------------------------------------------------- 2159 2160 SCI_BASE_STATE_T 2161 scic_sds_stp_request_started_udma_substate_table 2162 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_MAX_SUBSTATES] = 2163 { 2164 { 2165 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE, 2166 scic_sds_stp_request_started_udma_await_tc_completion_enter, 2167 NULL 2168 }, 2169 { 2170 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE, 2171 scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter, 2172 NULL 2173 } 2174 }; 2175 2176 //****************************************************************************** 2177 //* STP SOFT RESET STATE MACHINE 2178 //****************************************************************************** 2179 2180 /** 2181 * This method processes a TC completion. The expected TC completion is 2182 * for the transmission of the H2D register FIS containing the SATA/STP 2183 * non-data request. 2184 * 2185 * @param[in] this_request 2186 * @param[in] completion_code 2187 * 2188 * @return This method always successfully processes the TC completion. 2189 * @retval SCI_SUCCESS This value is always returned. 2190 */ 2191 static 2192 SCI_STATUS scic_sds_stp_request_soft_reset_await_h2d_asserted_tc_completion_handler( 2193 SCIC_SDS_REQUEST_T * this_request, 2194 U32 completion_code 2195 ) 2196 { 2197 SCIC_LOG_TRACE(( 2198 sci_base_object_get_logger(this_request), 2199 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2200 "scic_sds_stp_request_soft_reset_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n", 2201 this_request, completion_code 2202 )); 2203 2204 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 2205 { 2206 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 2207 scic_sds_request_set_status( 2208 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 2209 ); 2210 2211 sci_base_state_machine_change_state( 2212 &this_request->started_substate_machine, 2213 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE 2214 ); 2215 break; 2216 2217 default: 2218 // All other completion status cause the IO to be complete. If a NAK 2219 // was received, then it is up to the user to retry the request. 2220 scic_sds_request_set_status( 2221 this_request, 2222 SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 2223 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 2224 ); 2225 2226 sci_base_state_machine_change_state( 2227 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED 2228 ); 2229 break; 2230 } 2231 2232 return SCI_SUCCESS; 2233 } 2234 2235 /** 2236 * This method processes a TC completion. The expected TC completion is 2237 * for the transmission of the H2D register FIS containing the SATA/STP 2238 * non-data request. 2239 * 2240 * @param[in] this_request 2241 * @param[in] completion_code 2242 * 2243 * @return This method always successfully processes the TC completion. 2244 * @retval SCI_SUCCESS This value is always returned. 2245 */ 2246 static 2247 SCI_STATUS scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler( 2248 SCIC_SDS_REQUEST_T * this_request, 2249 U32 completion_code 2250 ) 2251 { 2252 SCIC_LOG_TRACE(( 2253 sci_base_object_get_logger(this_request), 2254 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2255 "scic_sds_stp_request_soft_reset_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n", 2256 this_request, completion_code 2257 )); 2258 2259 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 2260 { 2261 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 2262 scic_sds_request_set_status( 2263 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 2264 ); 2265 2266 sci_base_state_machine_change_state( 2267 &this_request->started_substate_machine, 2268 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE 2269 ); 2270 break; 2271 2272 default: 2273 // All other completion status cause the IO to be complete. If a NAK 2274 // was received, then it is up to the user to retry the request. 2275 scic_sds_request_set_status( 2276 this_request, 2277 SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 2278 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 2279 ); 2280 2281 sci_base_state_machine_change_state( 2282 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED 2283 ); 2284 break; 2285 } 2286 2287 return SCI_SUCCESS; 2288 } 2289 2290 /** 2291 * This method processes frames received from the target while waiting 2292 * for a device to host register FIS. If a non-register FIS is received 2293 * during this time, it is treated as a protocol violation from an 2294 * IO perspective. 2295 * 2296 * @param[in] request This parameter specifies the request for which a 2297 * frame has been received. 2298 * @param[in] frame_index This parameter specifies the index of the frame 2299 * that has been received. 2300 * 2301 * @return Indicate if the received frame was processed successfully. 2302 */ 2303 static 2304 SCI_STATUS scic_sds_stp_request_soft_reset_await_d2h_frame_handler( 2305 SCIC_SDS_REQUEST_T * request, 2306 U32 frame_index 2307 ) 2308 { 2309 SCI_STATUS status; 2310 SATA_FIS_HEADER_T * frame_header; 2311 U32 * frame_buffer; 2312 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request; 2313 2314 // Save off the controller, so that we do not touch the request after it 2315 // is completed. 2316 SCIC_SDS_CONTROLLER_T * owning_controller = this_request->parent.owning_controller; 2317 2318 SCIC_LOG_TRACE(( 2319 sci_base_object_get_logger(this_request), 2320 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2321 "scic_sds_stp_request_soft_reset_await_d2h_frame_handler(0x%x, 0x%x) enter\n", 2322 this_request, frame_index 2323 )); 2324 2325 status = scic_sds_unsolicited_frame_control_get_header( 2326 &(owning_controller->uf_control), 2327 frame_index, 2328 (void**) &frame_header 2329 ); 2330 2331 if (status == SCI_SUCCESS) 2332 { 2333 switch (frame_header->fis_type) 2334 { 2335 case SATA_FIS_TYPE_REGD2H: 2336 scic_sds_unsolicited_frame_control_get_buffer( 2337 &(owning_controller->uf_control), 2338 frame_index, 2339 (void**) &frame_buffer 2340 ); 2341 2342 scic_sds_controller_copy_sata_response( 2343 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer 2344 ); 2345 2346 // The command has completed with error 2347 scic_sds_request_set_status( 2348 &this_request->parent, 2349 SCU_TASK_DONE_CHECK_RESPONSE, 2350 SCI_FAILURE_IO_RESPONSE_VALID 2351 ); 2352 break; 2353 2354 default: 2355 SCIC_LOG_WARNING(( 2356 sci_base_object_get_logger(this_request), 2357 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2358 "IO Request:0x%x Frame Id:%d protocol violation occurred\n", 2359 this_request, frame_index 2360 )); 2361 2362 scic_sds_request_set_status( 2363 &this_request->parent, 2364 SCU_TASK_DONE_UNEXP_FIS, 2365 SCI_FAILURE_PROTOCOL_VIOLATION 2366 ); 2367 break; 2368 } 2369 2370 sci_base_state_machine_change_state( 2371 &this_request->parent.parent.state_machine, 2372 SCI_BASE_REQUEST_STATE_COMPLETED 2373 ); 2374 2375 // Frame has been decoded return it to the controller 2376 scic_sds_controller_release_frame( 2377 owning_controller, frame_index 2378 ); 2379 } 2380 else 2381 { 2382 SCIC_LOG_ERROR(( 2383 sci_base_object_get_logger(this_request), 2384 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2385 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n", 2386 this_request, frame_index, status 2387 )); 2388 } 2389 2390 return status; 2391 } 2392 2393 // --------------------------------------------------------------------------- 2394 2395 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T 2396 scic_sds_stp_request_started_soft_reset_substate_handler_table 2397 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_MAX_SUBSTATES] = 2398 { 2399 // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE 2400 { 2401 { 2402 scic_sds_request_default_start_handler, 2403 scic_sds_request_started_state_abort_handler, 2404 scic_sds_request_default_complete_handler, 2405 scic_sds_request_default_destruct_handler 2406 }, 2407 scic_sds_stp_request_soft_reset_await_h2d_asserted_tc_completion_handler, 2408 scic_sds_request_default_event_handler, 2409 scic_sds_request_default_frame_handler 2410 }, 2411 // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE 2412 { 2413 { 2414 scic_sds_request_default_start_handler, 2415 scic_sds_request_started_state_abort_handler, 2416 scic_sds_request_default_complete_handler, 2417 scic_sds_request_default_destruct_handler 2418 }, 2419 scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler, 2420 scic_sds_request_default_event_handler, 2421 scic_sds_request_default_frame_handler 2422 }, 2423 // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE 2424 { 2425 { 2426 scic_sds_request_default_start_handler, 2427 scic_sds_request_started_state_abort_handler, 2428 scic_sds_request_default_complete_handler, 2429 scic_sds_request_default_destruct_handler 2430 }, 2431 scic_sds_request_default_tc_completion_handler, 2432 scic_sds_request_default_event_handler, 2433 scic_sds_stp_request_soft_reset_await_d2h_frame_handler 2434 } 2435 }; 2436 2437 static 2438 void scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter( 2439 SCI_BASE_OBJECT_T *object 2440 ) 2441 { 2442 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2443 2444 SET_STATE_HANDLER( 2445 this_request, 2446 scic_sds_stp_request_started_soft_reset_substate_handler_table, 2447 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE 2448 ); 2449 2450 scic_sds_remote_device_set_working_request( 2451 this_request->target_device, this_request 2452 ); 2453 } 2454 2455 static 2456 void scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter( 2457 SCI_BASE_OBJECT_T *object 2458 ) 2459 { 2460 SCI_STATUS status; 2461 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2462 SATA_FIS_REG_H2D_T *h2d_fis; 2463 SCU_TASK_CONTEXT_T *task_context; 2464 2465 // Clear the SRST bit 2466 h2d_fis = scic_stp_io_request_get_h2d_reg_address(this_request); 2467 h2d_fis->control = 0; 2468 2469 // Clear the TC control bit 2470 task_context = scic_sds_controller_get_task_context_buffer( 2471 this_request->owning_controller, this_request->io_tag); 2472 task_context->control_frame = 0; 2473 2474 status = this_request->owning_controller->state_handlers->parent.continue_io_handler( 2475 &this_request->owning_controller->parent, 2476 &this_request->target_device->parent, 2477 &this_request->parent 2478 ); 2479 2480 if (status == SCI_SUCCESS) 2481 { 2482 SET_STATE_HANDLER( 2483 this_request, 2484 scic_sds_stp_request_started_soft_reset_substate_handler_table, 2485 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE 2486 ); 2487 } 2488 } 2489 2490 static 2491 void scic_sds_stp_request_started_soft_reset_await_d2h_response_enter( 2492 SCI_BASE_OBJECT_T *object 2493 ) 2494 { 2495 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2496 2497 SET_STATE_HANDLER( 2498 this_request, 2499 scic_sds_stp_request_started_soft_reset_substate_handler_table, 2500 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE 2501 ); 2502 } 2503 2504 // --------------------------------------------------------------------------- 2505 2506 SCI_BASE_STATE_T 2507 scic_sds_stp_request_started_soft_reset_substate_table 2508 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_MAX_SUBSTATES] = 2509 { 2510 { 2511 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE, 2512 scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter, 2513 NULL 2514 }, 2515 { 2516 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE, 2517 scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter, 2518 NULL 2519 }, 2520 { 2521 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE, 2522 scic_sds_stp_request_started_soft_reset_await_d2h_response_enter, 2523 NULL 2524 } 2525 }; 2526 2527 // --------------------------------------------------------------------------- 2528 2529 SCI_STATUS scic_io_request_construct_basic_sata( 2530 SCI_IO_REQUEST_HANDLE_T scic_io_request 2531 ) 2532 { 2533 SCI_STATUS status; 2534 SCIC_SDS_REQUEST_T * request = (SCIC_SDS_REQUEST_T *)scic_io_request; 2535 2536 SCIC_LOG_TRACE(( 2537 sci_base_object_get_logger(scic_io_request), 2538 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2539 "scic_io_request_construct_basic_sata(0x%x) enter\n", 2540 scic_io_request 2541 )); 2542 2543 status = scic_sds_io_request_construct_sata( 2544 request, 2545 scic_cb_request_get_sat_protocol(request->user_request), 2546 scic_cb_io_request_get_transfer_length(request->user_request), 2547 scic_cb_io_request_get_data_direction(request->user_request), 2548 scic_cb_io_request_do_copy_rx_frames(request->user_request), 2549 TRUE 2550 ); 2551 2552 return status; 2553 } 2554 2555 // --------------------------------------------------------------------------- 2556 2557 SCI_STATUS scic_io_request_construct_advanced_sata( 2558 SCI_IO_REQUEST_HANDLE_T scic_io_request, 2559 SCIC_IO_SATA_PARAMETERS_T * io_parameters 2560 ) 2561 { 2562 SCI_STATUS status; 2563 SCIC_SDS_REQUEST_T * request = (SCIC_SDS_REQUEST_T *)scic_io_request; 2564 2565 SCIC_LOG_TRACE(( 2566 sci_base_object_get_logger(scic_io_request), 2567 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2568 "scic_io_request_construct_basic_sata(0x%x) enter\n", 2569 scic_io_request 2570 )); 2571 2572 status = scic_sds_io_request_construct_sata( 2573 request, 2574 scic_cb_request_get_sat_protocol(request->user_request), 2575 scic_sds_request_get_sgl_element_pair(request, 0)->A.length, 2576 scic_cb_io_request_get_data_direction(request->user_request), 2577 scic_cb_io_request_do_copy_rx_frames(request->user_request), 2578 io_parameters->do_translate_sgl 2579 ); 2580 2581 return status; 2582 } 2583 2584