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 sgl_offset = 0; 1128 } 1129 } 1130 else if (this_sds_stp_request->type.pio.pio_transfer_bytes < remaining_bytes_in_current_sgl ) 1131 { 1132 //recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = type.pio.pio_transfer_bytes 1133 scic_sds_stp_request_pio_data_out_trasmit_data_frame (this_sds_request, this_sds_stp_request->type.pio.pio_transfer_bytes); 1134 1135 if (status == SCI_SUCCESS) 1136 { 1137 //Sgl offset will be adjusted and saved for future 1138 sgl_offset += this_sds_stp_request->type.pio.pio_transfer_bytes; 1139 current_sgl->address_lower += this_sds_stp_request->type.pio.pio_transfer_bytes; 1140 this_sds_stp_request->type.pio.pio_transfer_bytes = 0; 1141 } 1142 } 1143 } 1144 1145 if (status == SCI_SUCCESS) 1146 { 1147 this_sds_stp_request->type.pio.request_current.sgl_offset = sgl_offset; 1148 } 1149 1150 return status; 1151 } 1152 1153 /** 1154 * Copy the data from the buffer for the length specified to the IO reqeust 1155 * SGL specified data region. 1156 * 1157 * @param[in] this_request The request that is used for the SGL processing. 1158 * @param[in] data_buffer The buffer of data to be copied. 1159 * @param[in] length The length of the data transfer. 1160 * 1161 * @return SCI_STATUS 1162 */ 1163 static 1164 SCI_STATUS scic_sds_stp_request_pio_data_in_copy_data_buffer( 1165 SCIC_SDS_STP_REQUEST_T * this_request, 1166 U8 * data_buffer, 1167 U32 length 1168 ) 1169 { 1170 SCI_STATUS status; 1171 SCU_SGL_ELEMENT_T * current_sgl; 1172 U32 sgl_offset; 1173 U32 data_offset; 1174 U8 * source_address; 1175 1176 // Initial setup to get the current working SGL and the offset within the buffer 1177 current_sgl = 1178 (this_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) ? 1179 &(this_request->type.pio.request_current.sgl_pair->A) : 1180 &(this_request->type.pio.request_current.sgl_pair->B) ; 1181 1182 sgl_offset = this_request->type.pio.request_current.sgl_offset; 1183 1184 source_address = data_buffer; 1185 data_offset = this_request->type.pio.current_transfer_bytes; 1186 status = SCI_SUCCESS; 1187 1188 // While we are still doing Ok and there is more data to transfer 1189 while ( 1190 (length > 0) 1191 && (status == SCI_SUCCESS) 1192 ) 1193 { 1194 if (current_sgl->length == sgl_offset) 1195 { 1196 // This SGL has been exauhasted so we need to get the next SGL 1197 current_sgl = scic_sds_stp_request_pio_get_next_sgl(this_request); 1198 1199 if (current_sgl == NULL) 1200 status = SCI_FAILURE; 1201 else 1202 sgl_offset = 0; 1203 } 1204 else 1205 { 1206 #ifdef ENABLE_OSSL_COPY_BUFFER 1207 scic_cb_io_request_copy_buffer(this_request, data_buffer, data_offset, length); 1208 length = 0; 1209 #else 1210 U8 * destination_address; 1211 U32 copy_length; 1212 1213 destination_address = (U8 *)scic_cb_io_request_get_virtual_address_from_sgl( 1214 this_request, 1215 data_offset 1216 ); 1217 1218 copy_length = MIN(length, current_sgl->length - sgl_offset); 1219 1220 memcpy(destination_address, source_address, copy_length); 1221 1222 length -= copy_length; 1223 sgl_offset += copy_length; 1224 data_offset += copy_length; 1225 #endif 1226 } 1227 } 1228 1229 this_request->type.pio.request_current.sgl_offset = sgl_offset; 1230 1231 return status; 1232 } 1233 1234 /** 1235 * Copy the data buffer to the io request data region. 1236 * 1237 * @param[in] this_request The PIO DATA IN request that is to receive the 1238 * data. 1239 * @param[in] data_buffer The buffer to copy from. 1240 * 1241 * @return SCI_STATUS 1242 */ 1243 static 1244 SCI_STATUS scic_sds_stp_request_pio_data_in_copy_data( 1245 SCIC_SDS_STP_REQUEST_T * this_request, 1246 U8 * data_buffer 1247 ) 1248 { 1249 SCI_STATUS status; 1250 1251 // If there is less than 1K remaining in the transfer request 1252 // copy just the data for the transfer 1253 if (this_request->type.pio.pio_transfer_bytes < SCU_MAX_FRAME_BUFFER_SIZE) 1254 { 1255 status = scic_sds_stp_request_pio_data_in_copy_data_buffer( 1256 this_request,data_buffer,this_request->type.pio.pio_transfer_bytes); 1257 1258 if (status == SCI_SUCCESS) 1259 { 1260 // All data for this PIO request has now been copied, so we don't 1261 // technically need to update current_transfer_bytes here - just 1262 // doing it for completeness. 1263 this_request->type.pio.current_transfer_bytes += this_request->type.pio.pio_transfer_bytes; 1264 this_request->type.pio.pio_transfer_bytes = 0; 1265 } 1266 } 1267 else 1268 { 1269 // We are transfering the whole frame so copy 1270 status = scic_sds_stp_request_pio_data_in_copy_data_buffer( 1271 this_request, data_buffer, SCU_MAX_FRAME_BUFFER_SIZE); 1272 1273 if (status == SCI_SUCCESS) 1274 { 1275 this_request->type.pio.pio_transfer_bytes -= SCU_MAX_FRAME_BUFFER_SIZE; 1276 this_request->type.pio.current_transfer_bytes += SCU_MAX_FRAME_BUFFER_SIZE; 1277 } 1278 } 1279 1280 return status; 1281 } 1282 1283 /** 1284 * 1285 * 1286 * @param[in] this_request 1287 * @param[in] completion_code 1288 * 1289 * @return SCI_STATUS 1290 */ 1291 static 1292 SCI_STATUS scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler( 1293 SCIC_SDS_REQUEST_T * this_request, 1294 U32 completion_code 1295 ) 1296 { 1297 SCI_STATUS status = SCI_SUCCESS; 1298 1299 SCIC_LOG_TRACE(( 1300 sci_base_object_get_logger(this_request), 1301 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1302 "scic_sds_stp_request_pio_data_in_await_h2d_completion_tc_completion_handler(0x%x, 0x%x) enter\n", 1303 this_request, completion_code 1304 )); 1305 1306 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 1307 { 1308 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 1309 scic_sds_request_set_status( 1310 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 1311 ); 1312 1313 sci_base_state_machine_change_state( 1314 &this_request->started_substate_machine, 1315 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE 1316 ); 1317 break; 1318 1319 default: 1320 // All other completion status cause the IO to be complete. If a NAK 1321 // was received, then it is up to the user to retry the request. 1322 scic_sds_request_set_status( 1323 this_request, 1324 SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 1325 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 1326 ); 1327 1328 sci_base_state_machine_change_state( 1329 &this_request->parent.state_machine, 1330 SCI_BASE_REQUEST_STATE_COMPLETED 1331 ); 1332 break; 1333 } 1334 1335 return status; 1336 } 1337 1338 /** 1339 * 1340 * 1341 * @param[in] this_request 1342 * @param[in] frame_index 1343 * 1344 * @return SCI_STATUS 1345 */ 1346 static 1347 SCI_STATUS scic_sds_stp_request_pio_await_frame_frame_handler( 1348 SCIC_SDS_REQUEST_T * request, 1349 U32 frame_index 1350 ) 1351 { 1352 SCI_STATUS status; 1353 SATA_FIS_HEADER_T * frame_header; 1354 U32 * frame_buffer; 1355 SCIC_SDS_STP_REQUEST_T * this_request; 1356 SCIC_SDS_CONTROLLER_T * owning_controller; 1357 1358 this_request = (SCIC_SDS_STP_REQUEST_T *)request; 1359 1360 // Save off the controller, so that we do not touch the request after it 1361 // is completed. 1362 owning_controller = this_request->parent.owning_controller; 1363 1364 SCIC_LOG_TRACE(( 1365 sci_base_object_get_logger(this_request), 1366 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1367 "scic_sds_stp_request_pio_data_in_await_frame_frame_handler(0x%x, 0x%x) enter\n", 1368 this_request, frame_index 1369 )); 1370 1371 status = scic_sds_unsolicited_frame_control_get_header( 1372 &(owning_controller->uf_control), 1373 frame_index, 1374 (void**) &frame_header 1375 ); 1376 1377 if (status == SCI_SUCCESS) 1378 { 1379 switch (frame_header->fis_type) 1380 { 1381 case SATA_FIS_TYPE_PIO_SETUP: 1382 // Get from the frame buffer the PIO Setup Data 1383 scic_sds_unsolicited_frame_control_get_buffer( 1384 &(owning_controller->uf_control), 1385 frame_index, 1386 (void**) &frame_buffer 1387 ); 1388 1389 // Get the data from the PIO Setup 1390 // The SCU Hardware returns first word in the frame_header and the rest 1391 // of the data is in the frame buffer so we need to back up one dword 1392 this_request->type.pio.pio_transfer_bytes = 1393 (U16)((SATA_FIS_PIO_SETUP_T *)(&frame_buffer[-1]))->transfter_count; 1394 this_request->type.pio.ending_status = 1395 (U8)((SATA_FIS_PIO_SETUP_T *)(&frame_buffer[-1]))->ending_status; 1396 1397 scic_sds_controller_copy_sata_response( 1398 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer 1399 ); 1400 1401 this_request->d2h_reg_fis.status = 1402 this_request->type.pio.ending_status; 1403 1404 //The next state is dependent on whether the request was PIO Data-in or Data out 1405 if (this_request->type.pio.sat_protocol == SAT_PROTOCOL_PIO_DATA_IN) 1406 { 1407 sci_base_state_machine_change_state( 1408 &this_request->parent.started_substate_machine, 1409 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE 1410 ); 1411 } 1412 else if (this_request->type.pio.sat_protocol == SAT_PROTOCOL_PIO_DATA_OUT) 1413 { 1414 //Transmit data 1415 status = scic_sds_stp_request_pio_data_out_transmit_data ( request); 1416 if (status == SCI_SUCCESS) 1417 { 1418 sci_base_state_machine_change_state( 1419 &this_request->parent.started_substate_machine, 1420 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE 1421 ); 1422 } 1423 } 1424 break; 1425 1426 case SATA_FIS_TYPE_SETDEVBITS: 1427 sci_base_state_machine_change_state( 1428 &this_request->parent.started_substate_machine, 1429 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE 1430 ); 1431 break; 1432 1433 case SATA_FIS_TYPE_REGD2H: 1434 if ( (frame_header->status & ATA_STATUS_REG_BSY_BIT) == 0) 1435 { 1436 scic_sds_unsolicited_frame_control_get_buffer( 1437 &(owning_controller->uf_control), 1438 frame_index, 1439 (void**) &frame_buffer 1440 ); 1441 1442 scic_sds_controller_copy_sata_response( 1443 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer); 1444 1445 scic_sds_request_set_status( 1446 &this_request->parent, 1447 SCU_TASK_DONE_CHECK_RESPONSE, 1448 SCI_FAILURE_IO_RESPONSE_VALID 1449 ); 1450 1451 sci_base_state_machine_change_state( 1452 &this_request->parent.parent.state_machine, 1453 SCI_BASE_REQUEST_STATE_COMPLETED 1454 ); 1455 } 1456 else 1457 { 1458 // Now why is the drive sending a D2H Register FIS when it is still busy? 1459 // Do nothing since we are still in the right state. 1460 SCIC_LOG_INFO(( 1461 sci_base_object_get_logger(this_request), 1462 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1463 "SCIC PIO Request 0x%x received D2H Register FIS with BSY status 0x%x\n", 1464 this_request, frame_header->status 1465 )); 1466 } 1467 break; 1468 1469 default: 1470 break; 1471 } 1472 1473 // Frame is decoded return it to the controller 1474 scic_sds_controller_release_frame( 1475 owning_controller, 1476 frame_index 1477 ); 1478 } 1479 else 1480 { 1481 SCIC_LOG_ERROR(( 1482 sci_base_object_get_logger(this_request), 1483 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1484 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n", 1485 this_request, frame_index, status 1486 )); 1487 } 1488 1489 return status; 1490 } 1491 1492 /** 1493 * 1494 * 1495 * @param[in] this_request 1496 * @param[in] frame_index 1497 * 1498 * @return SCI_STATUS 1499 */ 1500 static 1501 SCI_STATUS scic_sds_stp_request_pio_data_in_await_data_frame_handler( 1502 SCIC_SDS_REQUEST_T * request, 1503 U32 frame_index 1504 ) 1505 { 1506 SCI_STATUS status; 1507 SATA_FIS_HEADER_T * frame_header; 1508 SATA_FIS_DATA_T * frame_buffer; 1509 SCIC_SDS_STP_REQUEST_T * this_request; 1510 SCIC_SDS_CONTROLLER_T * owning_controller; 1511 1512 this_request = (SCIC_SDS_STP_REQUEST_T *)request; 1513 1514 // Save off the controller, so that we do not touch the request after it 1515 // is completed. 1516 owning_controller = this_request->parent.owning_controller; 1517 1518 SCIC_LOG_TRACE(( 1519 sci_base_object_get_logger(this_request), 1520 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1521 "scic_sds_stp_request_pio_data_in_await_data_frame_handler(0x%x, 0x%x) enter\n", 1522 this_request, frame_index 1523 )); 1524 1525 status = scic_sds_unsolicited_frame_control_get_header( 1526 &(owning_controller->uf_control), 1527 frame_index, 1528 (void**) &frame_header 1529 ); 1530 1531 if (status == SCI_SUCCESS) 1532 { 1533 if (frame_header->fis_type == SATA_FIS_TYPE_DATA) 1534 { 1535 if (this_request->type.pio.request_current.sgl_pair == NULL) 1536 { 1537 this_request->parent.saved_rx_frame_index = frame_index; 1538 this_request->type.pio.pio_transfer_bytes = 0; 1539 } 1540 else 1541 { 1542 status = scic_sds_unsolicited_frame_control_get_buffer( 1543 &(owning_controller->uf_control), 1544 frame_index, 1545 (void**) &frame_buffer 1546 ); 1547 1548 status = scic_sds_stp_request_pio_data_in_copy_data(this_request, (U8 *)frame_buffer); 1549 1550 // Frame is decoded return it to the controller 1551 scic_sds_controller_release_frame( 1552 owning_controller, 1553 frame_index 1554 ); 1555 } 1556 1557 // Check for the end of the transfer, are there more bytes remaining 1558 // for this data transfer 1559 if ( 1560 (status == SCI_SUCCESS) 1561 && (this_request->type.pio.pio_transfer_bytes == 0) 1562 ) 1563 { 1564 if ((this_request->type.pio.ending_status & ATA_STATUS_REG_BSY_BIT) == 0) 1565 { 1566 scic_sds_request_set_status( 1567 &this_request->parent, 1568 SCU_TASK_DONE_CHECK_RESPONSE, 1569 SCI_FAILURE_IO_RESPONSE_VALID 1570 ); 1571 1572 sci_base_state_machine_change_state( 1573 &this_request->parent.parent.state_machine, 1574 SCI_BASE_REQUEST_STATE_COMPLETED 1575 ); 1576 } 1577 else 1578 { 1579 sci_base_state_machine_change_state( 1580 &this_request->parent.started_substate_machine, 1581 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE 1582 ); 1583 } 1584 } 1585 } 1586 else 1587 { 1588 SCIC_LOG_ERROR(( 1589 sci_base_object_get_logger(this_request), 1590 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1591 "SCIC PIO Request 0x%x received frame %d with fis type 0x%02x when expecting a data fis.\n", 1592 this_request, frame_index, frame_header->fis_type 1593 )); 1594 1595 scic_sds_request_set_status( 1596 &this_request->parent, 1597 SCU_TASK_DONE_GOOD, 1598 SCI_FAILURE_IO_REQUIRES_SCSI_ABORT 1599 ); 1600 1601 sci_base_state_machine_change_state( 1602 &this_request->parent.parent.state_machine, 1603 SCI_BASE_REQUEST_STATE_COMPLETED 1604 ); 1605 1606 // Frame is decoded return it to the controller 1607 scic_sds_controller_release_frame( 1608 owning_controller, 1609 frame_index 1610 ); 1611 } 1612 } 1613 else 1614 { 1615 SCIC_LOG_ERROR(( 1616 sci_base_object_get_logger(this_request), 1617 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1618 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n", 1619 this_request, frame_index, status 1620 )); 1621 } 1622 1623 return status; 1624 } 1625 1626 1627 /** 1628 * 1629 * 1630 * @param[in] this_request 1631 * @param[in] completion_code 1632 * 1633 * @return SCI_STATUS 1634 */ 1635 static 1636 SCI_STATUS scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler( 1637 1638 SCIC_SDS_REQUEST_T * this_request, 1639 U32 completion_code 1640 ) 1641 { 1642 SCI_STATUS status = SCI_SUCCESS; 1643 BOOL all_frames_transferred = FALSE; 1644 1645 SCIC_SDS_STP_REQUEST_T *this_scic_sds_stp_request = (SCIC_SDS_STP_REQUEST_T *) this_request; 1646 1647 SCIC_LOG_TRACE(( 1648 sci_base_object_get_logger(this_request), 1649 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1650 "scic_sds_stp_request_pio_data_in_await_h2d_completion_tc_completion_handler(0x%x, 0x%x) enter\n", 1651 this_request, completion_code 1652 )); 1653 1654 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 1655 { 1656 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 1657 //Transmit data 1658 if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes != 0) 1659 { 1660 status = scic_sds_stp_request_pio_data_out_transmit_data ( this_request); 1661 if (status == SCI_SUCCESS) 1662 { 1663 if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes == 0) 1664 all_frames_transferred = TRUE; 1665 } 1666 } 1667 else if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes == 0) 1668 { 1669 //this will happen if the all data is written at the first time after the pio setup fis is recieved 1670 all_frames_transferred = TRUE; 1671 } 1672 1673 //all data transferred. 1674 if (all_frames_transferred) 1675 { 1676 //Change the state to SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_FRAME_SUBSTATE 1677 //and wait for PIO_SETUP fis / or D2H REg fis. 1678 sci_base_state_machine_change_state( 1679 &this_request->started_substate_machine, 1680 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE 1681 ); 1682 } 1683 break; 1684 1685 default: 1686 // All other completion status cause the IO to be complete. If a NAK 1687 // was received, then it is up to the user to retry the request. 1688 scic_sds_request_set_status( 1689 this_request, 1690 SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 1691 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 1692 ); 1693 1694 sci_base_state_machine_change_state( 1695 &this_request->parent.state_machine, 1696 SCI_BASE_REQUEST_STATE_COMPLETED 1697 ); 1698 break; 1699 } 1700 1701 return status; 1702 } 1703 1704 /** 1705 * This method will handle any link layer events while waiting for the data 1706 * frame. 1707 * 1708 * @param[in] request This is the request which is receiving the event. 1709 * @param[in] event_code This is the event code that the request on which the 1710 * request is expected to take action. 1711 * 1712 * @return SCI_STATUS 1713 * @retval SCI_SUCCESS 1714 * @retval SCI_FAILURE 1715 */ 1716 static 1717 SCI_STATUS scic_sds_stp_request_pio_data_in_await_data_event_handler( 1718 SCIC_SDS_REQUEST_T * request, 1719 U32 event_code 1720 ) 1721 { 1722 SCI_STATUS status; 1723 1724 switch (scu_get_event_specifier(event_code)) 1725 { 1726 case SCU_TASK_DONE_CRC_ERR << SCU_EVENT_SPECIFIC_CODE_SHIFT: 1727 // We are waiting for data and the SCU has R_ERR the data frame. 1728 // Go back to waiting for the D2H Register FIS 1729 sci_base_state_machine_change_state( 1730 &request->started_substate_machine, 1731 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE 1732 ); 1733 1734 status = SCI_SUCCESS; 1735 break; 1736 1737 default: 1738 SCIC_LOG_ERROR(( 1739 sci_base_object_get_logger(request), 1740 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1741 "SCIC PIO Request 0x%x received unexpected event 0x%08x\n", 1742 request, event_code 1743 )); 1744 1745 /// @todo Should we fail the PIO request when we get an unexpected event? 1746 status = SCI_FAILURE; 1747 break; 1748 } 1749 1750 return status; 1751 } 1752 1753 // --------------------------------------------------------------------------- 1754 1755 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T 1756 scic_sds_stp_request_started_pio_substate_handler_table 1757 [SCIC_SDS_STP_REQUEST_STARTED_PIO_MAX_SUBSTATES] = 1758 { 1759 // SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE 1760 { 1761 { 1762 scic_sds_request_default_start_handler, 1763 scic_sds_request_started_state_abort_handler, 1764 scic_sds_request_default_complete_handler, 1765 scic_sds_request_default_destruct_handler 1766 }, 1767 scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler, 1768 scic_sds_request_default_event_handler, 1769 scic_sds_request_default_frame_handler 1770 }, 1771 // SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE 1772 { 1773 { 1774 scic_sds_request_default_start_handler, 1775 //scic_sds_stp_pio_request_data_in_await_frame_abort_handler, 1776 scic_sds_request_started_state_abort_handler, 1777 scic_sds_request_default_complete_handler, 1778 scic_sds_request_default_destruct_handler 1779 }, 1780 scic_sds_request_default_tc_completion_handler, 1781 scic_sds_request_default_event_handler, 1782 scic_sds_stp_request_pio_await_frame_frame_handler 1783 }, 1784 // SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE 1785 { 1786 { 1787 scic_sds_request_default_start_handler, 1788 //scic_sds_stp_pio_request_data_in_await_data_abort_handler, 1789 scic_sds_request_started_state_abort_handler, 1790 scic_sds_request_default_complete_handler, 1791 scic_sds_request_default_destruct_handler 1792 }, 1793 scic_sds_request_default_tc_completion_handler, 1794 scic_sds_stp_request_pio_data_in_await_data_event_handler, 1795 scic_sds_stp_request_pio_data_in_await_data_frame_handler 1796 }, 1797 //SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE 1798 { 1799 { 1800 scic_sds_request_default_start_handler, 1801 scic_sds_request_started_state_abort_handler, 1802 scic_sds_request_default_complete_handler, 1803 scic_sds_request_default_destruct_handler 1804 }, 1805 scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler, 1806 scic_sds_request_default_event_handler, 1807 scic_sds_request_default_frame_handler 1808 } 1809 }; 1810 1811 static 1812 void scic_sds_stp_request_started_pio_await_h2d_completion_enter( 1813 SCI_BASE_OBJECT_T *object 1814 ) 1815 { 1816 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 1817 1818 SET_STATE_HANDLER( 1819 this_request, 1820 scic_sds_stp_request_started_pio_substate_handler_table, 1821 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE 1822 ); 1823 1824 scic_sds_remote_device_set_working_request( 1825 this_request->target_device, this_request); 1826 } 1827 1828 static 1829 void scic_sds_stp_request_started_pio_await_frame_enter( 1830 SCI_BASE_OBJECT_T *object 1831 ) 1832 { 1833 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 1834 1835 SET_STATE_HANDLER( 1836 this_request, 1837 scic_sds_stp_request_started_pio_substate_handler_table, 1838 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE 1839 ); 1840 } 1841 1842 static 1843 void scic_sds_stp_request_started_pio_data_in_await_data_enter( 1844 SCI_BASE_OBJECT_T *object 1845 ) 1846 { 1847 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 1848 1849 SET_STATE_HANDLER( 1850 this_request, 1851 scic_sds_stp_request_started_pio_substate_handler_table, 1852 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE 1853 ); 1854 } 1855 1856 static 1857 void scic_sds_stp_request_started_pio_data_out_transmit_data_enter( 1858 SCI_BASE_OBJECT_T *object 1859 ) 1860 { 1861 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 1862 1863 SET_STATE_HANDLER( 1864 this_request, 1865 scic_sds_stp_request_started_pio_substate_handler_table, 1866 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE 1867 ); 1868 } 1869 1870 // --------------------------------------------------------------------------- 1871 1872 SCI_BASE_STATE_T 1873 scic_sds_stp_request_started_pio_substate_table 1874 [SCIC_SDS_STP_REQUEST_STARTED_PIO_MAX_SUBSTATES] = 1875 { 1876 { 1877 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE, 1878 scic_sds_stp_request_started_pio_await_h2d_completion_enter, 1879 NULL 1880 }, 1881 { 1882 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE, 1883 scic_sds_stp_request_started_pio_await_frame_enter, 1884 NULL 1885 }, 1886 { 1887 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE, 1888 scic_sds_stp_request_started_pio_data_in_await_data_enter, 1889 NULL 1890 }, 1891 { 1892 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE, 1893 scic_sds_stp_request_started_pio_data_out_transmit_data_enter, 1894 NULL 1895 } 1896 }; 1897 1898 //****************************************************************************** 1899 //* UDMA REQUEST STATE MACHINE 1900 //****************************************************************************** 1901 1902 static 1903 void scic_sds_stp_request_udma_complete_request( 1904 SCIC_SDS_REQUEST_T * this_request, 1905 U32 scu_status, 1906 SCI_STATUS sci_status 1907 ) 1908 { 1909 scic_sds_request_set_status( 1910 this_request, scu_status, sci_status 1911 ); 1912 1913 sci_base_state_machine_change_state( 1914 &this_request->parent.state_machine, 1915 SCI_BASE_REQUEST_STATE_COMPLETED 1916 ); 1917 } 1918 1919 /** 1920 * 1921 * 1922 * @param[in] this_request 1923 * @param[in] frame_index 1924 * 1925 * @return SCI_STATUS 1926 */ 1927 static 1928 SCI_STATUS scic_sds_stp_request_udma_general_frame_handler( 1929 SCIC_SDS_REQUEST_T * this_request, 1930 U32 frame_index 1931 ) 1932 { 1933 SCI_STATUS status; 1934 SATA_FIS_HEADER_T * frame_header; 1935 U32 * frame_buffer; 1936 1937 SCIC_LOG_TRACE(( 1938 sci_base_object_get_logger(this_request), 1939 SCIC_LOG_OBJECT_STP_IO_REQUEST, 1940 "scic_sds_stp_pio_request_data_in_await_frame_frame_handler(0x%x, 0x%x) enter\n", 1941 this_request, frame_index 1942 )); 1943 1944 status = scic_sds_unsolicited_frame_control_get_header( 1945 &this_request->owning_controller->uf_control, 1946 frame_index, 1947 (void**) &frame_header 1948 ); 1949 1950 if ( 1951 (status == SCI_SUCCESS) 1952 && (frame_header->fis_type == SATA_FIS_TYPE_REGD2H) 1953 ) 1954 { 1955 scic_sds_unsolicited_frame_control_get_buffer( 1956 &this_request->owning_controller->uf_control, 1957 frame_index, 1958 (void**) &frame_buffer 1959 ); 1960 1961 scic_sds_controller_copy_sata_response( 1962 &((SCIC_SDS_STP_REQUEST_T *)this_request)->d2h_reg_fis, 1963 (U32 *)frame_header, 1964 frame_buffer 1965 ); 1966 } 1967 1968 scic_sds_controller_release_frame( 1969 this_request->owning_controller, frame_index); 1970 1971 return status; 1972 } 1973 1974 /** 1975 * @brief This method process TC completions while in the state where 1976 * we are waiting for TC completions. 1977 * 1978 * @param[in] this_request 1979 * @param[in] completion_code 1980 * 1981 * @return SCI_STATUS 1982 */ 1983 static 1984 SCI_STATUS scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler( 1985 SCIC_SDS_REQUEST_T * request, 1986 U32 completion_code 1987 ) 1988 { 1989 SCI_STATUS status = SCI_SUCCESS; 1990 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request; 1991 1992 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 1993 { 1994 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 1995 scic_sds_stp_request_udma_complete_request( 1996 &this_request->parent, SCU_TASK_DONE_GOOD, SCI_SUCCESS 1997 ); 1998 break; 1999 2000 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_FIS): 2001 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR): 2002 // We must check ther response buffer to see if the D2H Register FIS was 2003 // received before we got the TC completion. 2004 if (this_request->d2h_reg_fis.fis_type == SATA_FIS_TYPE_REGD2H) 2005 { 2006 scic_sds_remote_device_suspend( 2007 this_request->parent.target_device, 2008 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code)) 2009 ); 2010 2011 scic_sds_stp_request_udma_complete_request( 2012 &this_request->parent, 2013 SCU_TASK_DONE_CHECK_RESPONSE, 2014 SCI_FAILURE_IO_RESPONSE_VALID 2015 ); 2016 } 2017 else 2018 { 2019 // If we have an error completion status for the TC then we can expect a 2020 // D2H register FIS from the device so we must change state to wait for it 2021 sci_base_state_machine_change_state( 2022 &this_request->parent.started_substate_machine, 2023 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE 2024 ); 2025 } 2026 break; 2027 2028 /// @todo Check to see if any of these completion status need to wait for 2029 /// the device to host register fis. 2030 /// @todo We can retry the command for SCU_TASK_DONE_CMD_LL_R_ERR - this comes only for B0 2031 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_INV_FIS_LEN): 2032 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR): 2033 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_R_ERR): 2034 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CMD_LL_R_ERR): 2035 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CRC_ERR): 2036 scic_sds_remote_device_suspend( 2037 this_request->parent.target_device, 2038 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code)) 2039 ); 2040 // Fall through to the default case 2041 default: 2042 // All other completion status cause the IO to be complete. 2043 SCIC_LOG_ERROR(( 2044 sci_base_object_get_logger(&this_request->parent), 2045 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2046 "SCIC IO Request 0x%x returning CONTROLLER_SPECIFIC_IO_ERR for completion code 0x%x\n", 2047 &this_request->parent, completion_code 2048 )); 2049 scic_sds_stp_request_udma_complete_request( 2050 &this_request->parent, 2051 SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 2052 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 2053 ); 2054 break; 2055 } 2056 2057 return status; 2058 } 2059 2060 static 2061 SCI_STATUS scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler( 2062 SCIC_SDS_REQUEST_T * this_request, 2063 U32 frame_index 2064 ) 2065 { 2066 SCI_STATUS status; 2067 2068 // Use the general frame handler to copy the resposne data 2069 status = scic_sds_stp_request_udma_general_frame_handler(this_request, frame_index); 2070 2071 if (status == SCI_SUCCESS) 2072 { 2073 scic_sds_stp_request_udma_complete_request( 2074 this_request, 2075 SCU_TASK_DONE_CHECK_RESPONSE, 2076 SCI_FAILURE_IO_RESPONSE_VALID 2077 ); 2078 } 2079 2080 return status; 2081 } 2082 2083 // --------------------------------------------------------------------------- 2084 2085 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T 2086 scic_sds_stp_request_started_udma_substate_handler_table 2087 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_MAX_SUBSTATES] = 2088 { 2089 // SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE 2090 { 2091 { 2092 scic_sds_request_default_start_handler, 2093 scic_sds_request_started_state_abort_handler, 2094 scic_sds_request_default_complete_handler, 2095 scic_sds_request_default_destruct_handler 2096 }, 2097 scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler, 2098 scic_sds_request_default_event_handler, 2099 scic_sds_stp_request_udma_general_frame_handler 2100 }, 2101 // SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE 2102 { 2103 { 2104 scic_sds_request_default_start_handler, 2105 scic_sds_request_started_state_abort_handler, 2106 scic_sds_request_default_complete_handler, 2107 scic_sds_request_default_destruct_handler 2108 }, 2109 scic_sds_request_default_tc_completion_handler, 2110 scic_sds_request_default_event_handler, 2111 scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler 2112 } 2113 }; 2114 2115 /** 2116 * 2117 * 2118 * @param[in] object 2119 */ 2120 static 2121 void scic_sds_stp_request_started_udma_await_tc_completion_enter( 2122 SCI_BASE_OBJECT_T *object 2123 ) 2124 { 2125 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2126 2127 SET_STATE_HANDLER( 2128 this_request, 2129 scic_sds_stp_request_started_udma_substate_handler_table, 2130 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE 2131 ); 2132 } 2133 2134 /** 2135 * This state is entered when there is an TC completion failure. The hardware 2136 * received an unexpected condition while processing the IO request and now 2137 * will UF the D2H register FIS to complete the IO. 2138 * 2139 * @param[in] object 2140 */ 2141 static 2142 void scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter( 2143 SCI_BASE_OBJECT_T *object 2144 ) 2145 { 2146 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2147 2148 SET_STATE_HANDLER( 2149 this_request, 2150 scic_sds_stp_request_started_udma_substate_handler_table, 2151 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE 2152 ); 2153 } 2154 2155 // --------------------------------------------------------------------------- 2156 2157 SCI_BASE_STATE_T 2158 scic_sds_stp_request_started_udma_substate_table 2159 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_MAX_SUBSTATES] = 2160 { 2161 { 2162 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE, 2163 scic_sds_stp_request_started_udma_await_tc_completion_enter, 2164 NULL 2165 }, 2166 { 2167 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE, 2168 scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter, 2169 NULL 2170 } 2171 }; 2172 2173 //****************************************************************************** 2174 //* STP SOFT RESET STATE MACHINE 2175 //****************************************************************************** 2176 2177 /** 2178 * This method processes a TC completion. The expected TC completion is 2179 * for the transmission of the H2D register FIS containing the SATA/STP 2180 * non-data request. 2181 * 2182 * @param[in] this_request 2183 * @param[in] completion_code 2184 * 2185 * @return This method always successfully processes the TC completion. 2186 * @retval SCI_SUCCESS This value is always returned. 2187 */ 2188 static 2189 SCI_STATUS scic_sds_stp_request_soft_reset_await_h2d_asserted_tc_completion_handler( 2190 SCIC_SDS_REQUEST_T * this_request, 2191 U32 completion_code 2192 ) 2193 { 2194 SCIC_LOG_TRACE(( 2195 sci_base_object_get_logger(this_request), 2196 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2197 "scic_sds_stp_request_soft_reset_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n", 2198 this_request, completion_code 2199 )); 2200 2201 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 2202 { 2203 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 2204 scic_sds_request_set_status( 2205 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 2206 ); 2207 2208 sci_base_state_machine_change_state( 2209 &this_request->started_substate_machine, 2210 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE 2211 ); 2212 break; 2213 2214 default: 2215 // All other completion status cause the IO to be complete. If a NAK 2216 // was received, then it is up to the user to retry the request. 2217 scic_sds_request_set_status( 2218 this_request, 2219 SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 2220 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 2221 ); 2222 2223 sci_base_state_machine_change_state( 2224 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED 2225 ); 2226 break; 2227 } 2228 2229 return SCI_SUCCESS; 2230 } 2231 2232 /** 2233 * This method processes a TC completion. The expected TC completion is 2234 * for the transmission of the H2D register FIS containing the SATA/STP 2235 * non-data request. 2236 * 2237 * @param[in] this_request 2238 * @param[in] completion_code 2239 * 2240 * @return This method always successfully processes the TC completion. 2241 * @retval SCI_SUCCESS This value is always returned. 2242 */ 2243 static 2244 SCI_STATUS scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler( 2245 SCIC_SDS_REQUEST_T * this_request, 2246 U32 completion_code 2247 ) 2248 { 2249 SCIC_LOG_TRACE(( 2250 sci_base_object_get_logger(this_request), 2251 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2252 "scic_sds_stp_request_soft_reset_await_h2d_tc_completion_handler(0x%x, 0x%x) enter\n", 2253 this_request, completion_code 2254 )); 2255 2256 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) 2257 { 2258 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD): 2259 scic_sds_request_set_status( 2260 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS 2261 ); 2262 2263 sci_base_state_machine_change_state( 2264 &this_request->started_substate_machine, 2265 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE 2266 ); 2267 break; 2268 2269 default: 2270 // All other completion status cause the IO to be complete. If a NAK 2271 // was received, then it is up to the user to retry the request. 2272 scic_sds_request_set_status( 2273 this_request, 2274 SCU_NORMALIZE_COMPLETION_STATUS(completion_code), 2275 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR 2276 ); 2277 2278 sci_base_state_machine_change_state( 2279 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED 2280 ); 2281 break; 2282 } 2283 2284 return SCI_SUCCESS; 2285 } 2286 2287 /** 2288 * This method processes frames received from the target while waiting 2289 * for a device to host register FIS. If a non-register FIS is received 2290 * during this time, it is treated as a protocol violation from an 2291 * IO perspective. 2292 * 2293 * @param[in] request This parameter specifies the request for which a 2294 * frame has been received. 2295 * @param[in] frame_index This parameter specifies the index of the frame 2296 * that has been received. 2297 * 2298 * @return Indicate if the received frame was processed successfully. 2299 */ 2300 static 2301 SCI_STATUS scic_sds_stp_request_soft_reset_await_d2h_frame_handler( 2302 SCIC_SDS_REQUEST_T * request, 2303 U32 frame_index 2304 ) 2305 { 2306 SCI_STATUS status; 2307 SATA_FIS_HEADER_T * frame_header; 2308 U32 * frame_buffer; 2309 SCIC_SDS_STP_REQUEST_T * this_request = (SCIC_SDS_STP_REQUEST_T *)request; 2310 2311 // Save off the controller, so that we do not touch the request after it 2312 // is completed. 2313 SCIC_SDS_CONTROLLER_T * owning_controller = this_request->parent.owning_controller; 2314 2315 SCIC_LOG_TRACE(( 2316 sci_base_object_get_logger(this_request), 2317 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2318 "scic_sds_stp_request_soft_reset_await_d2h_frame_handler(0x%x, 0x%x) enter\n", 2319 this_request, frame_index 2320 )); 2321 2322 status = scic_sds_unsolicited_frame_control_get_header( 2323 &(owning_controller->uf_control), 2324 frame_index, 2325 (void**) &frame_header 2326 ); 2327 2328 if (status == SCI_SUCCESS) 2329 { 2330 switch (frame_header->fis_type) 2331 { 2332 case SATA_FIS_TYPE_REGD2H: 2333 scic_sds_unsolicited_frame_control_get_buffer( 2334 &(owning_controller->uf_control), 2335 frame_index, 2336 (void**) &frame_buffer 2337 ); 2338 2339 scic_sds_controller_copy_sata_response( 2340 &this_request->d2h_reg_fis, (U32 *)frame_header, frame_buffer 2341 ); 2342 2343 // The command has completed with error 2344 scic_sds_request_set_status( 2345 &this_request->parent, 2346 SCU_TASK_DONE_CHECK_RESPONSE, 2347 SCI_FAILURE_IO_RESPONSE_VALID 2348 ); 2349 break; 2350 2351 default: 2352 SCIC_LOG_WARNING(( 2353 sci_base_object_get_logger(this_request), 2354 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2355 "IO Request:0x%x Frame Id:%d protocol violation occurred\n", 2356 this_request, frame_index 2357 )); 2358 2359 scic_sds_request_set_status( 2360 &this_request->parent, 2361 SCU_TASK_DONE_UNEXP_FIS, 2362 SCI_FAILURE_PROTOCOL_VIOLATION 2363 ); 2364 break; 2365 } 2366 2367 sci_base_state_machine_change_state( 2368 &this_request->parent.parent.state_machine, 2369 SCI_BASE_REQUEST_STATE_COMPLETED 2370 ); 2371 2372 // Frame has been decoded return it to the controller 2373 scic_sds_controller_release_frame( 2374 owning_controller, frame_index 2375 ); 2376 } 2377 else 2378 { 2379 SCIC_LOG_ERROR(( 2380 sci_base_object_get_logger(this_request), 2381 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2382 "SCIC IO Request 0x%x could not get frame header for frame index %d, status %x\n", 2383 this_request, frame_index, status 2384 )); 2385 } 2386 2387 return status; 2388 } 2389 2390 // --------------------------------------------------------------------------- 2391 2392 SCIC_SDS_IO_REQUEST_STATE_HANDLER_T 2393 scic_sds_stp_request_started_soft_reset_substate_handler_table 2394 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_MAX_SUBSTATES] = 2395 { 2396 // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE 2397 { 2398 { 2399 scic_sds_request_default_start_handler, 2400 scic_sds_request_started_state_abort_handler, 2401 scic_sds_request_default_complete_handler, 2402 scic_sds_request_default_destruct_handler 2403 }, 2404 scic_sds_stp_request_soft_reset_await_h2d_asserted_tc_completion_handler, 2405 scic_sds_request_default_event_handler, 2406 scic_sds_request_default_frame_handler 2407 }, 2408 // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE 2409 { 2410 { 2411 scic_sds_request_default_start_handler, 2412 scic_sds_request_started_state_abort_handler, 2413 scic_sds_request_default_complete_handler, 2414 scic_sds_request_default_destruct_handler 2415 }, 2416 scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler, 2417 scic_sds_request_default_event_handler, 2418 scic_sds_request_default_frame_handler 2419 }, 2420 // SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE 2421 { 2422 { 2423 scic_sds_request_default_start_handler, 2424 scic_sds_request_started_state_abort_handler, 2425 scic_sds_request_default_complete_handler, 2426 scic_sds_request_default_destruct_handler 2427 }, 2428 scic_sds_request_default_tc_completion_handler, 2429 scic_sds_request_default_event_handler, 2430 scic_sds_stp_request_soft_reset_await_d2h_frame_handler 2431 } 2432 }; 2433 2434 static 2435 void scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter( 2436 SCI_BASE_OBJECT_T *object 2437 ) 2438 { 2439 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2440 2441 SET_STATE_HANDLER( 2442 this_request, 2443 scic_sds_stp_request_started_soft_reset_substate_handler_table, 2444 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE 2445 ); 2446 2447 scic_sds_remote_device_set_working_request( 2448 this_request->target_device, this_request 2449 ); 2450 } 2451 2452 static 2453 void scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter( 2454 SCI_BASE_OBJECT_T *object 2455 ) 2456 { 2457 SCI_STATUS status; 2458 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2459 SATA_FIS_REG_H2D_T *h2d_fis; 2460 SCU_TASK_CONTEXT_T *task_context; 2461 2462 // Clear the SRST bit 2463 h2d_fis = scic_stp_io_request_get_h2d_reg_address(this_request); 2464 h2d_fis->control = 0; 2465 2466 // Clear the TC control bit 2467 task_context = scic_sds_controller_get_task_context_buffer( 2468 this_request->owning_controller, this_request->io_tag); 2469 task_context->control_frame = 0; 2470 2471 status = this_request->owning_controller->state_handlers->parent.continue_io_handler( 2472 &this_request->owning_controller->parent, 2473 &this_request->target_device->parent, 2474 &this_request->parent 2475 ); 2476 2477 if (status == SCI_SUCCESS) 2478 { 2479 SET_STATE_HANDLER( 2480 this_request, 2481 scic_sds_stp_request_started_soft_reset_substate_handler_table, 2482 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE 2483 ); 2484 } 2485 } 2486 2487 static 2488 void scic_sds_stp_request_started_soft_reset_await_d2h_response_enter( 2489 SCI_BASE_OBJECT_T *object 2490 ) 2491 { 2492 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object; 2493 2494 SET_STATE_HANDLER( 2495 this_request, 2496 scic_sds_stp_request_started_soft_reset_substate_handler_table, 2497 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE 2498 ); 2499 } 2500 2501 // --------------------------------------------------------------------------- 2502 2503 SCI_BASE_STATE_T 2504 scic_sds_stp_request_started_soft_reset_substate_table 2505 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_MAX_SUBSTATES] = 2506 { 2507 { 2508 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE, 2509 scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter, 2510 NULL 2511 }, 2512 { 2513 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE, 2514 scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter, 2515 NULL 2516 }, 2517 { 2518 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE, 2519 scic_sds_stp_request_started_soft_reset_await_d2h_response_enter, 2520 NULL 2521 } 2522 }; 2523 2524 // --------------------------------------------------------------------------- 2525 2526 SCI_STATUS scic_io_request_construct_basic_sata( 2527 SCI_IO_REQUEST_HANDLE_T scic_io_request 2528 ) 2529 { 2530 SCI_STATUS status; 2531 SCIC_SDS_REQUEST_T * request = (SCIC_SDS_REQUEST_T *)scic_io_request; 2532 2533 SCIC_LOG_TRACE(( 2534 sci_base_object_get_logger(scic_io_request), 2535 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2536 "scic_io_request_construct_basic_sata(0x%x) enter\n", 2537 scic_io_request 2538 )); 2539 2540 status = scic_sds_io_request_construct_sata( 2541 request, 2542 scic_cb_request_get_sat_protocol(request->user_request), 2543 scic_cb_io_request_get_transfer_length(request->user_request), 2544 scic_cb_io_request_get_data_direction(request->user_request), 2545 scic_cb_io_request_do_copy_rx_frames(request->user_request), 2546 TRUE 2547 ); 2548 2549 return status; 2550 } 2551 2552 // --------------------------------------------------------------------------- 2553 2554 SCI_STATUS scic_io_request_construct_advanced_sata( 2555 SCI_IO_REQUEST_HANDLE_T scic_io_request, 2556 SCIC_IO_SATA_PARAMETERS_T * io_parameters 2557 ) 2558 { 2559 SCI_STATUS status; 2560 SCIC_SDS_REQUEST_T * request = (SCIC_SDS_REQUEST_T *)scic_io_request; 2561 2562 SCIC_LOG_TRACE(( 2563 sci_base_object_get_logger(scic_io_request), 2564 SCIC_LOG_OBJECT_STP_IO_REQUEST, 2565 "scic_io_request_construct_basic_sata(0x%x) enter\n", 2566 scic_io_request 2567 )); 2568 2569 status = scic_sds_io_request_construct_sata( 2570 request, 2571 scic_cb_request_get_sat_protocol(request->user_request), 2572 scic_sds_request_get_sgl_element_pair(request, 0)->A.length, 2573 scic_cb_io_request_get_data_direction(request->user_request), 2574 scic_cb_io_request_do_copy_rx_frames(request->user_request), 2575 io_parameters->do_translate_sgl 2576 ); 2577 2578 return status; 2579 } 2580 2581