The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/isci/scil/scic_sds_stp_request.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 62394d093715f9ce675fb2e400ae39bd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.