1 /*- 2 * This file is provided under a dual BSD/GPLv2 license. When using or 3 * redistributing this file, you may do so under either license. 4 * 5 * GPL LICENSE SUMMARY 6 * 7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of version 2 of the GNU General Public License as 11 * published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21 * The full GNU General Public License is included in this distribution 22 * in the file called LICENSE.GPL. 23 * 24 * BSD LICENSE 25 * 26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27 * All rights reserved. 28 * 29 * Redistribution and use in source and binary forms, with or without 30 * modification, are permitted provided that the following conditions 31 * are met: 32 * 33 * * Redistributions of source code must retain the above copyright 34 * notice, this list of conditions and the following disclaimer. 35 * * Redistributions in binary form must reproduce the above copyright 36 * notice, this list of conditions and the following disclaimer in 37 * the documentation and/or other materials provided with the 38 * distribution. 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51 */ 52 53 #include <sys/cdefs.h> 54 __FBSDID("$FreeBSD$"); 55 56 #include <dev/isci/scil/intel_sat.h> 57 #include <dev/isci/scil/intel_sata.h> 58 #include <dev/isci/scil/sci_types.h> 59 #include <dev/isci/scil/scic_remote_device.h> 60 #include <dev/isci/scil/scic_user_callback.h> 61 #include <dev/isci/scil/scic_sds_controller.h> 62 #include <dev/isci/scil/scic_sds_remote_device.h> 63 #include <dev/isci/scil/scic_sds_stp_request.h> 64 #include <dev/isci/scil/scic_sds_stp_pio_request.h> 65 #include <dev/isci/scil/scic_sds_logger.h> 66 #include <dev/isci/sci_environment.h> 67 #include <dev/isci/scil/sci_base_state_machine.h> 68 #include <dev/isci/scil/scu_task_context.h> 69 #include <dev/isci/scil/intel_ata.h> 70 #include <dev/isci/scil/sci_util.h> 71 #include <dev/isci/scil/scic_sds_logger.h> 72 #include <dev/isci/scil/scic_sds_request.h> 73 #include <dev/isci/scil/scic_sds_stp_request.h> 74 #include <dev/isci/scil/scu_completion_codes.h> 75 #include <dev/isci/scil/scu_event_codes.h> 76 #include <dev/isci/scil/sci_base_state.h> 77 #include <dev/isci/scil/scic_sds_unsolicited_frame_control.h> 78 #include <dev/isci/scil/scic_io_request.h> 79 80 #if !defined(DISABLE_ATAPI) 81 #include <dev/isci/scil/scic_sds_stp_packet_request.h> 82 #endif 83 84 /** 85 * This macro returns the address of the stp h2d reg fis buffer in the io 86 * request memory 87 */ 88 #define scic_sds_stp_request_get_h2d_reg_buffer_unaligned(memory) \ 89 ((SATA_FIS_REG_H2D_T *)( \ 90 ((char *)(memory)) + sizeof(SCIC_SDS_STP_REQUEST_T) \ 91 )) 92 93 /** 94 * This macro aligns the stp command buffer in DWORD alignment 95 */ 96 #define scic_sds_stp_request_align_h2d_reg_buffer(address) \ 97 ((SATA_FIS_REG_H2D_T *)( \ 98 (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \ 99 & ~(sizeof(U32)- 1) \ 100 )) 101 102 /** 103 * This macro returns the DWORD-aligned stp command buffer 104 */ 105 #define scic_sds_stp_request_get_h2d_reg_buffer(memory) \ 106 ((SATA_FIS_REG_H2D_T *) \ 107 ((char *)scic_sds_stp_request_align_h2d_reg_buffer( \ 108 (char *) scic_sds_stp_request_get_h2d_reg_buffer_unaligned(memory) \ 109 ))) 110 111 /** 112 * This macro returns the address of the stp response buffer in the io 113 * request memory 114 */ 115 #define scic_sds_stp_request_get_response_buffer_unaligned(memory) \ 116 ((SATA_FIS_REG_D2H_T *)( \ 117 ((char *)(scic_sds_stp_request_get_h2d_reg_buffer(memory))) \ 118 + sizeof(SATA_FIS_REG_H2D_T) \ 119 )) 120 121 122 /** 123 * This macro aligns the stp response buffer in DWORD alignment 124 */ 125 #define scic_sds_stp_request_align_response_buffer(address) \ 126 ((SATA_FIS_REG_D2H_T *)( \ 127 (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \ 128 & ~(sizeof(U32)- 1) \ 129 )) 130 131 /** 132 * This macro returns the DWORD-aligned stp response buffer 133 */ 134 #define scic_sds_stp_request_get_response_buffer(memory) \ 135 ((SATA_FIS_REG_D2H_T *) \ 136 ((char *)scic_sds_stp_request_align_response_buffer( \ 137 (char *)scic_sds_stp_request_get_response_buffer_unaligned(memory) \ 138 ))) 139 140 141 /** 142 * This macro returns the address of the task context buffer in the io 143 * request memory 144 */ 145 #define scic_sds_stp_request_get_task_context_buffer_unaligned(memory) \ 146 ((SCU_TASK_CONTEXT_T *)( \ 147 ((char *)(scic_sds_stp_request_get_response_buffer(memory))) \ 148 + sizeof(SCI_SSP_RESPONSE_IU_T) \ 149 )) 150 151 /** 152 * This macro returns the aligned task context buffer 153 */ 154 #define scic_sds_stp_request_get_task_context_buffer(memory) \ 155 ((SCU_TASK_CONTEXT_T *)( \ 156 ((char *)scic_sds_request_align_task_context_buffer( \ 157 (char *)scic_sds_stp_request_get_task_context_buffer_unaligned(memory)) \ 158 ))) 159 160 /** 161 * This macro returns the address of the sgl elment pairs in the io request 162 * memory buffer 163 */ 164 #define scic_sds_stp_request_get_sgl_element_buffer(memory) \ 165 ((SCU_SGL_ELEMENT_PAIR_T *)( \ 166 ((char *)(scic_sds_stp_request_get_task_context_buffer(memory))) \ 167 + sizeof(SCU_TASK_CONTEXT_T) \ 168 )) 169 170 171 /** 172 * This method return the memory space commonly required for STP IO and 173 * task requests. 174 * 175 * @return U32 176 */ 177 static 178 U32 scic_sds_stp_common_request_get_object_size(void) 179 { 180 return sizeof(SCIC_SDS_STP_REQUEST_T) 181 + sizeof(SATA_FIS_REG_H2D_T) 182 + sizeof(U32) 183 + sizeof(SATA_FIS_REG_D2H_T) 184 + sizeof(U32) 185 + sizeof(SCU_TASK_CONTEXT_T) 186 + CACHE_LINE_SIZE; 187 } 188 189 190 /** 191 * This method return the memory space required for STP PIO requests. 192 * 193 * @return U32 194 */ 195 U32 scic_sds_stp_request_get_object_size(void) 196 { 197 return scic_sds_stp_common_request_get_object_size() 198 + sizeof(SCU_SGL_ELEMENT_PAIR_T) * SCU_MAX_SGL_ELEMENT_PAIRS; 199 } 200 201 202 /** 203 * This method return the memory space required for STP task requests. 204 * 205 * @return U32 206 */ 207 U32 scic_sds_stp_task_request_get_object_size(void) 208 { 209 return scic_sds_stp_common_request_get_object_size(); 210 } 211 212 213 /** 214 * 215 * 216 * @param[in] this_request 217 */ 218 void scic_sds_stp_request_assign_buffers( 219 SCIC_SDS_REQUEST_T * request 220 ) 221 { 222 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request; 223 224 this_request->parent.command_buffer = 225 scic_sds_stp_request_get_h2d_reg_buffer(this_request); 226 this_request->parent.response_buffer = 227 scic_sds_stp_request_get_response_buffer(this_request); 228 this_request->parent.sgl_element_pair_buffer = 229 scic_sds_stp_request_get_sgl_element_buffer(this_request); 230 this_request->parent.sgl_element_pair_buffer = 231 scic_sds_request_align_sgl_element_buffer(this_request->parent.sgl_element_pair_buffer); 232 233 if (this_request->parent.was_tag_assigned_by_user == FALSE) 234 { 235 this_request->parent.task_context_buffer = 236 scic_sds_stp_request_get_task_context_buffer(this_request); 237 } 238 } 239 240 /** 241 * @brief This method is will fill in the SCU Task Context for any type of 242 * SATA request. This is called from the various SATA constructors. 243 * 244 * @pre The general io request construction is complete. 245 * @pre The buffer assignment for the command buffer is complete. 246 * 247 * @param[in] this_request The general IO request object which is to be used 248 * in constructing the SCU task context. 249 * @param[in] task_context The buffer pointer for the SCU task context which 250 * is being constructed. 251 * 252 * @return none 253 * 254 * @todo Revisit task context construction to determine what is common for 255 * SSP/SMP/STP task context structures. 256 */ 257 void scu_sata_reqeust_construct_task_context( 258 SCIC_SDS_REQUEST_T * this_request, 259 SCU_TASK_CONTEXT_T * task_context 260 ) 261 { 262 SCI_PHYSICAL_ADDRESS physical_address; 263 SCIC_SDS_CONTROLLER_T *owning_controller; 264 SCIC_SDS_REMOTE_DEVICE_T *target_device; 265 SCIC_SDS_PORT_T *target_port; 266 267 owning_controller = scic_sds_request_get_controller(this_request); 268 target_device = scic_sds_request_get_device(this_request); 269 target_port = scic_sds_request_get_port(this_request); 270 271 // Fill in the TC with the its required data 272 task_context->abort = 0; 273 task_context->priority = SCU_TASK_PRIORITY_NORMAL; 274 task_context->initiator_request = 1; 275 task_context->connection_rate = 276 scic_remote_device_get_connection_rate(target_device); 277 task_context->protocol_engine_index = 278 scic_sds_controller_get_protocol_engine_group(owning_controller); 279 task_context->logical_port_index = 280 scic_sds_port_get_index(target_port); 281 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_STP; 282 task_context->valid = SCU_TASK_CONTEXT_VALID; 283 task_context->context_type = SCU_TASK_CONTEXT_TYPE; 284 285 task_context->remote_node_index = 286 scic_sds_remote_device_get_index(this_request->target_device); 287 task_context->command_code = 0; 288 289 task_context->link_layer_control = 0; 290 task_context->do_not_dma_ssp_good_response = 1; 291 task_context->strict_ordering = 0; 292 task_context->control_frame = 0; 293 task_context->timeout_enable = 0; 294 task_context->block_guard_enable = 0; 295 296 task_context->address_modifier = 0; 297 task_context->task_phase = 0x01; 298 299 task_context->ssp_command_iu_length = 300 (sizeof(SATA_FIS_REG_H2D_T) - sizeof(U32)) / sizeof(U32); 301 302 // Set the first word of the H2D REG FIS 303 task_context->type.words[0] = *(U32 *)this_request->command_buffer; 304 305 if (this_request->was_tag_assigned_by_user) 306 { 307 // Build the task context now since we have already read the data 308 this_request->post_context = ( 309 SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC 310 | ( 311 scic_sds_controller_get_protocol_engine_group(owning_controller) 312 << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT 313 ) 314 | ( 315 scic_sds_port_get_index(target_port) 316 << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT 317 ) 318 | scic_sds_io_tag_get_index(this_request->io_tag) 319 ); 320 } 321 else 322 { 323 // Build the task context now since we have already read the data 324 this_request->post_context = ( 325 SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC 326 | ( 327 scic_sds_controller_get_protocol_engine_group(owning_controller) 328 << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT 329 ) 330 | ( 331 scic_sds_port_get_index(target_port) 332 << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT 333 ) 334 // This is not assigned because we have to wait until we get a TCi 335 ); 336 } 337 338 // Copy the physical address for the command buffer to the SCU Task Context 339 // We must offset the command buffer by 4 bytes because the first 4 bytes are 340 // transfered in the body of the TC 341 scic_cb_io_request_get_physical_address( 342 scic_sds_request_get_controller(this_request), 343 this_request, 344 ((char *)this_request->command_buffer) + sizeof(U32), 345 &physical_address 346 ); 347 348 task_context->command_iu_upper = 349 sci_cb_physical_address_upper(physical_address); 350 task_context->command_iu_lower = 351 sci_cb_physical_address_lower(physical_address); 352 353 // SATA Requests do not have a response buffer 354 task_context->response_iu_upper = 0; 355 task_context->response_iu_lower = 0; 356 } 357 358 /** 359 * This method will perform any general sata request construction. 360 * 361 * @todo What part of SATA IO request construction is general? 362 * 363 * @param[in] this_request 364 * 365 * @return none 366 */ 367 void scic_sds_stp_non_ncq_request_construct( 368 SCIC_SDS_REQUEST_T * this_request 369 ) 370 { 371 this_request->has_started_substate_machine = TRUE; 372 } 373 374 /** 375 * This method will perform request construction common to all types of 376 * STP requests that are optimized by the silicon (i.e. UDMA, NCQ). 377 * 378 * @param[in,out] this_request This parameter specifies the request to be 379 * constructed as an optimized request. 380 * @param[in] optimized_task_type This parameter specifies whether the 381 * request is to be an UDMA request or a NCQ request. 382 * - A value of 0 indicates UDMA. 383 * - A value of 1 indicates NCQ. 384 * 385 * @return This method returns an indication as to whether the construction 386 * was successful. 387 */ 388 static 389 void scic_sds_stp_optimized_request_construct( 390 SCIC_SDS_REQUEST_T * this_request, 391 U8 optimized_task_type, 392 U32 transfer_length, 393 SCI_IO_REQUEST_DATA_DIRECTION data_direction 394 ) 395 { 396 SCU_TASK_CONTEXT_T * task_context = this_request->task_context_buffer; 397 398 // Build the STP task context structure 399 scu_sata_reqeust_construct_task_context(this_request, task_context); 400 401 // Copy over the number of bytes to be transfered 402 task_context->transfer_length_bytes = transfer_length; 403 404 if ( data_direction == SCI_IO_REQUEST_DATA_OUT ) 405 { 406 // The difference between the DMA IN and DMA OUT request task type 407 // values are consistent with the difference between FPDMA READ 408 // and FPDMA WRITE values. Add the supplied task type parameter 409 // to this difference to set the task type properly for this 410 // DATA OUT (WRITE) case. 411 task_context->task_type = optimized_task_type + (SCU_TASK_TYPE_DMA_OUT 412 - SCU_TASK_TYPE_DMA_IN); 413 } 414 else 415 { 416 // For the DATA IN (READ) case, simply save the supplied 417 // optimized task type. 418 task_context->task_type = optimized_task_type; 419 } 420 } 421 422 /** 423 * This method performs the operations common to all SATA/STP requests 424 * utilizing the raw frame method. 425 * 426 * @param[in] this_request This parameter specifies the STP request object 427 * for which to construct a RAW command frame task context. 428 * @param[in] task_context This parameter specifies the SCU specific 429 * task context buffer to construct. 430 * 431 * @return none 432 */ 433 void scu_stp_raw_request_construct_task_context( 434 SCIC_SDS_STP_REQUEST_T * this_request, 435 SCU_TASK_CONTEXT_T * task_context 436 ) 437 { 438 scu_sata_reqeust_construct_task_context(&this_request->parent, task_context); 439 440 task_context->control_frame = 0; 441 task_context->priority = SCU_TASK_PRIORITY_NORMAL; 442 task_context->task_type = SCU_TASK_TYPE_SATA_RAW_FRAME; 443 task_context->type.stp.fis_type = SATA_FIS_TYPE_REGH2D; 444 task_context->transfer_length_bytes = sizeof(SATA_FIS_REG_H2D_T) - sizeof(U32); 445 } 446 447 /** 448 * This method will construct the STP Non-data request and its associated 449 * TC data. A non-data request essentially behaves like a 0 length read 450 * request in the SCU. 451 * 452 * @param[in] this_request This parameter specifies the core request 453 * object to construction into an STP/SATA non-data request. 454 * 455 * @return This method currently always returns SCI_SUCCESS 456 */ 457 SCI_STATUS scic_sds_stp_non_data_request_construct( 458 SCIC_SDS_REQUEST_T * this_request 459 ) 460 { 461 scic_sds_stp_non_ncq_request_construct(this_request); 462 463 // Build the STP task context structure 464 scu_stp_raw_request_construct_task_context( 465 (SCIC_SDS_STP_REQUEST_T*) this_request, 466 this_request->task_context_buffer 467 ); 468 469 sci_base_state_machine_construct( 470 &this_request->started_substate_machine, 471 &this_request->parent.parent, 472 scic_sds_stp_request_started_non_data_substate_table, 473 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE 474 ); 475 476 return SCI_SUCCESS; 477 } 478 479 480 SCI_STATUS scic_sds_stp_soft_reset_request_construct( 481 SCIC_SDS_REQUEST_T * this_request 482 ) 483 { 484 scic_sds_stp_non_ncq_request_construct(this_request); 485 486 // Build the STP task context structure 487 scu_stp_raw_request_construct_task_context( 488 (SCIC_SDS_STP_REQUEST_T*) this_request, 489 this_request->task_context_buffer 490 ); 491 492 sci_base_state_machine_construct( 493 &this_request->started_substate_machine, 494 &this_request->parent.parent, 495 scic_sds_stp_request_started_soft_reset_substate_table, 496 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE 497 ); 498 499 return SCI_SUCCESS; 500 } 501 502 /** 503 * @brief This method constructs the SATA request object. 504 * 505 * @param[in] this_request 506 * @param[in] sat_protocol 507 * @param[in] transfer_length 508 * @param[in] data_direction 509 * @param[in] copy_rx_frame 510 * @param[in] do_translate_sgl This parameter specifies whether SGL 511 * translation should be performed or if the user is handling 512 * it. 513 * 514 * @return SCI_STATUS 515 */ 516 SCI_STATUS scic_sds_io_request_construct_sata( 517 SCIC_SDS_REQUEST_T * this_request, 518 U8 sat_protocol, 519 U32 transfer_length, 520 SCI_IO_REQUEST_DATA_DIRECTION data_direction, 521 BOOL copy_rx_frame, 522 BOOL do_translate_sgl 523 ) 524 { 525 SCI_STATUS status = SCI_SUCCESS; 526 527 this_request->protocol = SCIC_STP_PROTOCOL; 528 529 this_request->sat_protocol = sat_protocol; 530 531 switch (sat_protocol) 532 { 533 case SAT_PROTOCOL_FPDMA: 534 scic_sds_stp_optimized_request_construct( 535 this_request, 536 SCU_TASK_TYPE_FPDMAQ_READ, 537 transfer_length, 538 data_direction 539 ); 540 541 // Copy over the SGL elements 542 if (do_translate_sgl == TRUE) 543 scic_sds_request_build_sgl(this_request); 544 break; 545 546 case SAT_PROTOCOL_UDMA_DATA_IN: 547 case SAT_PROTOCOL_UDMA_DATA_OUT: 548 scic_sds_stp_non_ncq_request_construct(this_request); 549 550 scic_sds_stp_optimized_request_construct( 551 this_request, SCU_TASK_TYPE_DMA_IN, transfer_length, data_direction 552 ); 553 554 // Copy over the SGL elements 555 if (do_translate_sgl == TRUE) 556 scic_sds_request_build_sgl(this_request); 557 558 sci_base_state_machine_construct( 559 &this_request->started_substate_machine, 560 &this_request->parent.parent, 561 scic_sds_stp_request_started_udma_substate_table, 562 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE 563 ); 564 break; 565 566 case SAT_PROTOCOL_PIO_DATA_IN: 567 case SAT_PROTOCOL_PIO_DATA_OUT: 568 status = scic_sds_stp_pio_request_construct( 569 this_request, sat_protocol, copy_rx_frame); 570 break; 571 572 case SAT_PROTOCOL_ATA_HARD_RESET: 573 case SAT_PROTOCOL_SOFT_RESET: 574 status = scic_sds_stp_soft_reset_request_construct(this_request); 575 break; 576 577 case SAT_PROTOCOL_NON_DATA: 578 status = scic_sds_stp_non_data_request_construct(this_request); 579 break; 580 581 #if !defined(DISABLE_ATAPI) 582 case SAT_PROTOCOL_PACKET_NON_DATA: 583 case SAT_PROTOCOL_PACKET_DMA_DATA_IN: 584 case SAT_PROTOCOL_PACKET_DMA_DATA_OUT: 585 case SAT_PROTOCOL_PACKET_PIO_DATA_IN: 586 case SAT_PROTOCOL_PACKET_PIO_DATA_OUT: 587 status = scic_sds_stp_packet_request_construct(this_request); 588 if (do_translate_sgl == TRUE) 589 scic_sds_request_build_sgl(this_request); 590 break; 591 #endif 592 593 case SAT_PROTOCOL_DMA_QUEUED: 594 case SAT_PROTOCOL_DMA: 595 case SAT_PROTOCOL_DEVICE_DIAGNOSTIC: 596 case SAT_PROTOCOL_DEVICE_RESET: 597 case SAT_PROTOCOL_RETURN_RESPONSE_INFO: 598 default: 599 SCIC_LOG_ERROR(( 600 sci_base_object_get_logger(this_request), 601 SCIC_LOG_OBJECT_STP_IO_REQUEST, 602 "SCIC IO Request 0x%x received un-handled SAT Protocol %d.\n", 603 this_request, sat_protocol 604 )); 605 606 status = SCI_FAILURE; 607 break; 608 } 609 610 if (status == SCI_SUCCESS) 611 { 612 scic_sds_request_initialize_state_logging(this_request); 613 614 sci_base_state_machine_change_state( 615 &this_request->parent.state_machine, 616 SCI_BASE_REQUEST_STATE_CONSTRUCTED 617 ); 618 } 619 620 return status; 621 } 622 623 //**************************************************************************** 624 //* SCIC Interface Implementation 625 //**************************************************************************** 626 627 void scic_stp_io_request_set_ncq_tag( 628 SCI_IO_REQUEST_HANDLE_T scic_io_request, 629 U16 ncq_tag 630 ) 631 { 632 /** 633 * @note This could be made to return an error to the user if the user 634 * attempts to set the NCQ tag in the wrong state. 635 */ 636 SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request; 637 this_request->task_context_buffer->type.stp.ncq_tag = ncq_tag; 638 } 639 640 // --------------------------------------------------------------------------- 641 642 void * scic_stp_io_request_get_h2d_reg_address( 643 SCI_IO_REQUEST_HANDLE_T scic_io_request 644 ) 645 { 646 SCIC_SDS_REQUEST_T * this_request = (SCIC_SDS_REQUEST_T *)scic_io_request; 647 648 return this_request->command_buffer; 649 } 650 651 // --------------------------------------------------------------------------- 652 653 void * scic_stp_io_request_get_d2h_reg_address( 654 SCI_IO_REQUEST_HANDLE_T scic_io_request 655 ) 656 { 657 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)scic_io_request; 658 659 return &this_request->d2h_reg_fis; 660 } 661 662 /** 663 * Get the next SGL element from the request. 664 * - Check on which SGL element pair we are working 665 * - if working on SLG pair element A 666 * - advance to element B 667 * - else 668 * - check to see if there are more SGL element pairs 669 * for this IO request 670 * - if there are more SGL element pairs 671 * - advance to the next pair and return element A 672 * 673 * @param[in] this_request 674 * 675 * @return SCU_SGL_ELEMENT_T* 676 */ 677 SCU_SGL_ELEMENT_T * scic_sds_stp_request_pio_get_next_sgl( 678 SCIC_SDS_STP_REQUEST_T * this_request 679 ) 680 { 681 SCU_SGL_ELEMENT_T * current_sgl; 682 683 if (this_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) 684 { 685 if ( 686 (this_request->type.pio.request_current.sgl_pair->B.address_lower == 0) 687 && (this_request->type.pio.request_current.sgl_pair->B.address_upper == 0) 688 ) 689 { 690 current_sgl = NULL; 691 } 692 else 693 { 694 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_B; 695 current_sgl = &(this_request->type.pio.request_current.sgl_pair->B); 696 } 697 } 698 else 699 { 700 if ( 701 (this_request->type.pio.request_current.sgl_pair->next_pair_lower == 0) 702 && (this_request->type.pio.request_current.sgl_pair->next_pair_upper == 0) 703 ) 704 { 705 current_sgl = NULL; 706 } 707 else 708 { 709 this_request->type.pio.request_current.sgl_pair = 710 scic_sds_request_get_sgl_element_pair( 711 &(this_request->parent), 712 ++this_request->type.pio.sgl_pair_index 713 ); 714 715 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A; 716 717 current_sgl = &(this_request->type.pio.request_current.sgl_pair->A); 718 } 719 } 720 721 return current_sgl; 722 } 723 724 /** 725 * This method will construct the SATA PIO request. 726 * 727 * @param[in] scic_io_request The core request object which is cast to a SATA 728 * PIO request object. 729 * 730 * @return This method returns an indication as to whether the construction 731 * was successful. 732 * @retval SCI_SUCCESS Currently this method always returns this value. 733 */ 734 SCI_STATUS scic_sds_stp_pio_request_construct( 735 SCIC_SDS_REQUEST_T * scic_io_request, 736 U8 sat_protocol, 737 BOOL copy_rx_frame 738 ) 739 { 740 SCIC_SDS_STP_REQUEST_T * this_request; 741 742 this_request = (SCIC_SDS_STP_REQUEST_T *)scic_io_request; 743 744 scic_sds_stp_non_ncq_request_construct(&this_request->parent); 745 746 scu_stp_raw_request_construct_task_context( 747 this_request, this_request->parent.task_context_buffer 748 ); 749 750 this_request->type.pio.current_transfer_bytes = 0; 751 this_request->type.pio.ending_error = 0; 752 this_request->type.pio.ending_status = 0; 753 754 this_request->type.pio.request_current.sgl_offset = 0; 755 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A; 756 this_request->type.pio.sat_protocol = sat_protocol; 757 this_request->type.pio.sgl_pair_index = 0; 758 759 if ((copy_rx_frame) || (sat_protocol == SAT_PROTOCOL_PIO_DATA_OUT)) 760 { 761 scic_sds_request_build_sgl(&this_request->parent); 762 // Since the IO request copy of the TC contains the same data as 763 // the actual TC this pointer is vaild for either. 764 this_request->type.pio.request_current.sgl_pair = 765 &this_request->parent.task_context_buffer->sgl_pair_ab; 766 } 767 else 768 { 769 // The user does not want the data copied to the SGL buffer location 770 this_request->type.pio.request_current.sgl_pair = NULL; 771 } 772 773 sci_base_state_machine_construct( 774 &this_request->parent.started_substate_machine, 775 &this_request->parent.parent.parent, 776 scic_sds_stp_request_started_pio_substate_table, 777 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE 778 ); 779 780 return SCI_SUCCESS; 781 } 782 783 //****************************************************************************** 784 //* STP NON-DATA STATE MACHINE 785 //****************************************************************************** 786 787 /** 788 * This method processes a TC completion. The expected TC completion is 789 * for the transmission of the H2D register FIS containing the SATA/STP 790 * non-data request. 791 * 792 * @param[in] this_request 793 * @param[in] completion_code 794 * 795 * @return This method always successfully processes the TC completion. 796 * @retval SCI_SUCCESS This value is always returned. 797 */ 798 static 799 SCI_STATUS scic_sds_stp_request_non_data_await_h2d_tc_completion_handler( 800 SCIC_SDS_REQUEST_T * this_request, 801 U32 completion_code 802 ) 803 { 804 SCIC_LOG_TRACE(( 805 sci_base_object_get_logger(this_request), 806 SCIC_LOG_OBJECT_STP_IO_REQUEST, 807 "scic_sds_stp_request_non_data_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n", 808 this_request, completion_code 809 )); 810 811 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 812 { 813 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 814 scic_sds_request_set_status( 815 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 816 ); 817 818 sci_base_state_machine_change_state( 819 &this_request->started_substate_machine, 820 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE 821 ); 822 break; 823 824 default: 825 // All other completion status cause the IO to be complete. If a NAK 826 // was received, then it is up to the user to retry the request. 827 scic_sds_request_set_status( 828 this_request, 829 SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 830 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 831 ); 832 833 sci_base_state_machine_change_state( 834 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED 835 ); 836 break; 837 } 838 839 return SCI_SUCCESS; 840 } 841 842 /** 843 * This method processes frames received from the target while waiting 844 * for a device to host register FIS. If a non-register FIS is received 845 * during this time, it is treated as a protocol violation from an 846 * IO perspective. 847 * 848 * @param[in] request This parameter specifies the request for which a 849 * frame has been received. 850 * @param[in] frame_index This parameter specifies the index of the frame 851 * that has been received. 852 * 853 * @return Indicate if the received frame was processed successfully. 854 */ 855 static 856 SCI_STATUS scic_sds_stp_request_non_data_await_d2h_frame_handler( 857 SCIC_SDS_REQUEST_T * request, 858 U32 frame_index 859 ) 860 { 861 SCI_STATUS status; 862 SATA_FIS_HEADER_T * frame_header; 863 U32 * frame_buffer; 864 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request; 865 866 // Save off the controller, so that we do not touch the request after it 867 // is completed. 868 SCIC_SDS_CONTROLLER_T * owning_controller = this_request->parent.owning_controller; 869 870 SCIC_LOG_TRACE(( 871 sci_base_object_get_logger(this_request), 872 SCIC_LOG_OBJECT_STP_IO_REQUEST, 873 "scic_sds_stp_request_non_data_await_d2h_frame_handler(0x%x, 0x%x) enter\n", 874 this_request, frame_index 875 )); 876 877 status = scic_sds_unsolicited_frame_control_get_header( 878 &(owning_controller->uf_control), 879 frame_index, 880 (void**) &frame_header 881 ); 882 883 if (status == SCI_SUCCESS) 884 { 885 switch (frame_header->fis_type) 886 { 887 case SATA_FIS_TYPE_REGD2H: 888 scic_sds_unsolicited_frame_control_get_buffer( 889 &(owning_controller->uf_control), 890 frame_index, 891 (void**) &frame_buffer 892 ); 893 894 scic_sds_controller_copy_sata_response( 895 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer 896 ); 897 898 // The command has completed with error 899 scic_sds_request_set_status( 900 &this_request->parent, 901 SCU_TASK_DONE_CHECK_RESPONSE, 902 SCI_FAILURE_IO_RESPONSE_VALID 903 ); 904 break; 905 906 default: 907 SCIC_LOG_WARNING(( 908 sci_base_object_get_logger(this_request), 909 SCIC_LOG_OBJECT_STP_IO_REQUEST, 910 "IO Request:0x%x Frame Id:%d protocol violation occurred\n", 911 this_request, frame_index 912 )); 913 914 scic_sds_request_set_status( 915 &this_request->parent, 916 SCU_TASK_DONE_UNEXP_FIS, 917 SCI_FAILURE_PROTOCOL_VIOLATION 918 ); 919 break; 920 } 921 922 sci_base_state_machine_change_state( 923 &this_request->parent.parent.state_machine, 924 SCI_BASE_REQUEST_STATE_COMPLETED 925 ); 926 927 // Frame has been decoded return it to the controller 928 scic_sds_controller_release_frame( 929 owning_controller, frame_index 930 ); 931 } 932 else 933 { 934 SCIC_LOG_ERROR(( 935 sci_base_object_get_logger(this_request), 936 SCIC_LOG_OBJECT_STP_IO_REQUEST, 937 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n", 938 this_request, frame_index, status 939 )); 940 } 941 942 return status; 943 } 944 945 // --------------------------------------------------------------------------- 946 947 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T 948 scic_sds_stp_request_started_non_data_substate_handler_table 949 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_MAX_SUBSTATES] = 950 { 951 // SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE 952 { 953 { 954 scic_sds_request_default_start_handler, 955 scic_sds_request_started_state_abort_handler, 956 scic_sds_request_default_complete_handler, 957 scic_sds_request_default_destruct_handler 958 }, 959 scic_sds_stp_request_non_data_await_h2d_tc_completion_handler, 960 scic_sds_request_default_event_handler, 961 scic_sds_request_default_frame_handler 962 }, 963 // SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE 964 { 965 { 966 scic_sds_request_default_start_handler, 967 scic_sds_request_started_state_abort_handler, 968 scic_sds_request_default_complete_handler, 969 scic_sds_request_default_destruct_handler 970 }, 971 scic_sds_request_default_tc_completion_handler, 972 scic_sds_request_default_event_handler, 973 scic_sds_stp_request_non_data_await_d2h_frame_handler 974 } 975 }; 976 977 static 978 void scic_sds_stp_request_started_non_data_await_h2d_completion_enter( 979 SCI_BASE_OBJECT_T *object 980 ) 981 { 982 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 983 984 SET_STATE_HANDLER( 985 this_request, 986 scic_sds_stp_request_started_non_data_substate_handler_table, 987 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE 988 ); 989 990 scic_sds_remote_device_set_working_request( 991 this_request->target_device, this_request 992 ); 993 } 994 995 static 996 void scic_sds_stp_request_started_non_data_await_d2h_enter( 997 SCI_BASE_OBJECT_T *object 998 ) 999 { 1000 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 1001 1002 SET_STATE_HANDLER( 1003 this_request, 1004 scic_sds_stp_request_started_non_data_substate_handler_table, 1005 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE 1006 ); 1007 } 1008 1009 // --------------------------------------------------------------------------- 1010 1011 SCI_BASE_STATE_T scic_sds_stp_request_started_non_data_substate_table 1012 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_MAX_SUBSTATES] = 1013 { 1014 { 1015 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE, 1016 scic_sds_stp_request_started_non_data_await_h2d_completion_enter, 1017 NULL 1018 }, 1019 { 1020 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE, 1021 scic_sds_stp_request_started_non_data_await_d2h_enter, 1022 NULL 1023 } 1024 }; 1025 1026 //****************************************************************************** 1027 //* STP PIO STATE MACHINE 1028 //****************************************************************************** 1029 1030 #define SCU_MAX_FRAME_BUFFER_SIZE 0x400 // 1K is the maximum SCU frame data payload 1031 1032 /** 1033 * This function will transmit DATA_FIS from (current sgl + offset) for input parameter length. 1034 * current sgl and offset is alreay stored in the IO request 1035 * 1036 * @param[in] this_request 1037 * @param[in] length 1038 * 1039 * @return SCI_STATUS 1040 */ 1041 static 1042 SCI_STATUS scic_sds_stp_request_pio_data_out_trasmit_data_frame ( 1043 SCIC_SDS_REQUEST_T * this_request, 1044 U32 length 1045 ) 1046 { 1047 SCI_STATUS status = SCI_SUCCESS; 1048 SCU_SGL_ELEMENT_T * current_sgl; 1049 SCIC_SDS_STP_REQUEST_T * this_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *)this_request; 1050 1051 // Recycle the TC and reconstruct it for sending out DATA FIS containing 1052 // for the data from current_sgl+offset for the input length 1053 SCU_TASK_CONTEXT_T * task_context = scic_sds_controller_get_task_context_buffer( 1054 this_request->owning_controller, 1055 this_request->io_tag 1056 ); 1057 1058 if (this_sds_stp_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) 1059 { 1060 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->A); 1061 } 1062 else 1063 { 1064 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->B); 1065 } 1066 1067 //update the TC 1068 task_context->command_iu_upper = current_sgl->address_upper; 1069 task_context->command_iu_lower = current_sgl->address_lower; 1070 task_context->transfer_length_bytes = length; 1071 task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA; 1072 1073 // send the new TC out. 1074 status = this_request->owning_controller->state_handlers->parent.continue_io_handler( 1075 &this_request->owning_controller->parent, 1076 &this_request->target_device->parent, 1077 &this_request->parent 1078 ); 1079 1080 return status; 1081 1082 } 1083 1084 /** 1085 * 1086 * 1087 * @param[in] this_request 1088 * 1089 * @return SCI_STATUS 1090 */ 1091 static 1092 SCI_STATUS scic_sds_stp_request_pio_data_out_transmit_data( 1093 SCIC_SDS_REQUEST_T * this_sds_request 1094 ) 1095 { 1096 1097 SCU_SGL_ELEMENT_T * current_sgl; 1098 U32 sgl_offset; 1099 U32 remaining_bytes_in_current_sgl = 0; 1100 SCI_STATUS status = SCI_SUCCESS; 1101 1102 SCIC_SDS_STP_REQUEST_T * this_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *)this_sds_request; 1103 1104 sgl_offset = this_sds_stp_request->type.pio.request_current.sgl_offset; 1105 1106 if (this_sds_stp_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) 1107 { 1108 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->A); 1109 remaining_bytes_in_current_sgl = this_sds_stp_request->type.pio.request_current.sgl_pair->A.length - sgl_offset; 1110 } 1111 else 1112 { 1113 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->B); 1114 remaining_bytes_in_current_sgl = this_sds_stp_request->type.pio.request_current.sgl_pair->B.length - sgl_offset; 1115 } 1116 1117 1118 if (this_sds_stp_request->type.pio.pio_transfer_bytes > 0) 1119 { 1120 if (this_sds_stp_request->type.pio.pio_transfer_bytes >= remaining_bytes_in_current_sgl ) 1121 { 1122 //recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = remaining_bytes_in_current_sgl 1123 status = scic_sds_stp_request_pio_data_out_trasmit_data_frame (this_sds_request, remaining_bytes_in_current_sgl); 1124 if (status == SCI_SUCCESS) 1125 { 1126 this_sds_stp_request->type.pio.pio_transfer_bytes -= remaining_bytes_in_current_sgl; 1127 1128 //update the current sgl, sgl_offset and save for future 1129 current_sgl = scic_sds_stp_request_pio_get_next_sgl(this_sds_stp_request); 1130 sgl_offset = 0; 1131 } 1132 } 1133 else if (this_sds_stp_request->type.pio.pio_transfer_bytes < remaining_bytes_in_current_sgl ) 1134 { 1135 //recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = type.pio.pio_transfer_bytes 1136 scic_sds_stp_request_pio_data_out_trasmit_data_frame (this_sds_request, this_sds_stp_request->type.pio.pio_transfer_bytes); 1137 1138 if (status == SCI_SUCCESS) 1139 { 1140 //Sgl offset will be adjusted and saved for future 1141 sgl_offset += this_sds_stp_request->type.pio.pio_transfer_bytes; 1142 current_sgl->address_lower += this_sds_stp_request->type.pio.pio_transfer_bytes; 1143 this_sds_stp_request->type.pio.pio_transfer_bytes = 0; 1144 } 1145 } 1146 } 1147 1148 if (status == SCI_SUCCESS) 1149 { 1150 this_sds_stp_request->type.pio.request_current.sgl_offset = sgl_offset; 1151 } 1152 1153 return status; 1154 } 1155 1156 /** 1157 * Copy the data from the buffer for the length specified to the IO reqeust 1158 * SGL specified data region. 1159 * 1160 * @param[in] this_request The request that is used for the SGL processing. 1161 * @param[in] data_buffer The buffer of data to be copied. 1162 * @param[in] length The length of the data transfer. 1163 * 1164 * @return SCI_STATUS 1165 */ 1166 static 1167 SCI_STATUS scic_sds_stp_request_pio_data_in_copy_data_buffer( 1168 SCIC_SDS_STP_REQUEST_T * this_request, 1169 U8 * data_buffer, 1170 U32 length 1171 ) 1172 { 1173 SCI_STATUS status; 1174 SCU_SGL_ELEMENT_T * current_sgl; 1175 U32 sgl_offset; 1176 U32 data_offset; 1177 U8 * source_address; 1178 1179 // Initial setup to get the current working SGL and the offset within the buffer 1180 current_sgl = 1181 (this_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) ? 1182 &(this_request->type.pio.request_current.sgl_pair->A) : 1183 &(this_request->type.pio.request_current.sgl_pair->B) ; 1184 1185 sgl_offset = this_request->type.pio.request_current.sgl_offset; 1186 1187 source_address = data_buffer; 1188 data_offset = this_request->type.pio.current_transfer_bytes; 1189 status = SCI_SUCCESS; 1190 1191 // While we are still doing Ok and there is more data to transfer 1192 while ( 1193 (length > 0) 1194 && (status == SCI_SUCCESS) 1195 ) 1196 { 1197 if (current_sgl->length == sgl_offset) 1198 { 1199 // This SGL has been exauhasted so we need to get the next SGL 1200 current_sgl = scic_sds_stp_request_pio_get_next_sgl(this_request); 1201 1202 if (current_sgl == NULL) 1203 status = SCI_FAILURE; 1204 else 1205 sgl_offset = 0; 1206 } 1207 else 1208 { 1209 #ifdef ENABLE_OSSL_COPY_BUFFER 1210 scic_cb_io_request_copy_buffer(this_request, data_buffer, data_offset, length); 1211 length = 0; 1212 #else 1213 U8 * destination_address; 1214 U32 copy_length; 1215 1216 destination_address = (U8 *)scic_cb_io_request_get_virtual_address_from_sgl( 1217 this_request, 1218 data_offset 1219 ); 1220 1221 copy_length = MIN(length, current_sgl->length - sgl_offset); 1222 1223 memcpy(destination_address, source_address, copy_length); 1224 1225 length -= copy_length; 1226 sgl_offset += copy_length; 1227 data_offset += 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 transfering 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 recieved 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