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_remote_device.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 /**
   59  * @file
   60  *
   61  * @brief This file contains the methods and state machines for SATA/STP
   62  *        remote devices.
   63  */
   64 
   65 #include <dev/isci/scil/intel_sat.h>
   66 #include <dev/isci/scil/intel_ata.h>
   67 #include <dev/isci/scil/intel_sata.h>
   68 #include <dev/isci/scil/scic_remote_device.h>
   69 #include <dev/isci/scil/scic_user_callback.h>
   70 #include <dev/isci/scil/scic_sds_logger.h>
   71 #include <dev/isci/scil/scic_sds_controller.h>
   72 #include <dev/isci/scil/scic_sds_port.h>
   73 #include <dev/isci/scil/scic_sds_remote_device.h>
   74 #include <dev/isci/scil/scic_sds_request.h>
   75 #include <dev/isci/scil/scu_event_codes.h>
   76 #include <dev/isci/scil/scu_completion_codes.h>
   77 #include <dev/isci/scil/sci_base_state.h>
   78 
   79 /**
   80  * This method will perform the STP request completion processing common
   81  * to IO requests and task requests of all types
   82  *
   83  * @param[in] device This parameter specifies the device for which the
   84  *            request is being completed.
   85  * @param[in] request This parameter specifies the request being completed.
   86  *
   87  * @return This method returns an indication as to whether the request
   88  *         processing completed successfully.
   89  */
   90 static
   91 SCI_STATUS scic_sds_stp_remote_device_complete_request(
   92    SCI_BASE_REMOTE_DEVICE_T * device,
   93    SCI_BASE_REQUEST_T       * request
   94 )
   95 {
   96    SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
   97    SCIC_SDS_REQUEST_T       * the_request = (SCIC_SDS_REQUEST_T *)request;
   98    SCI_STATUS                 status;
   99 
  100    status = scic_sds_io_request_complete(the_request);
  101 
  102    if (status == SCI_SUCCESS)
  103    {
  104       status = scic_sds_port_complete_io(
  105                   this_device->owning_port, this_device, the_request
  106                );
  107 
  108       if (status == SCI_SUCCESS)
  109       {
  110          scic_sds_remote_device_decrement_request_count(this_device);
  111          if (the_request->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED)
  112          {
  113             //This request causes hardware error, device needs to be Lun Reset.
  114             //So here we force the state machine to IDLE state so the rest IOs
  115             //can reach RNC state handler, these IOs will be completed by RNC with
  116             //status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE".
  117             sci_base_state_machine_change_state(
  118                &this_device->ready_substate_machine,
  119                SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
  120             );
  121          }
  122          else if (scic_sds_remote_device_get_request_count(this_device) == 0)
  123          {
  124             sci_base_state_machine_change_state(
  125                &this_device->ready_substate_machine,
  126                SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
  127             );
  128          }
  129       }
  130    }
  131 
  132    if (status != SCI_SUCCESS)
  133    {
  134       SCIC_LOG_ERROR((
  135          sci_base_object_get_logger(this_device),
  136          SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
  137          "Port:0x%x Device:0x%x Request:0x%x Status:0x%x could not complete\n",
  138          this_device->owning_port, this_device, the_request, status
  139       ));
  140    }
  141 
  142    return status;
  143 }
  144 
  145 //*****************************************************************************
  146 //*  STP REMOTE DEVICE READY COMMON SUBSTATE HANDLERS
  147 //*****************************************************************************
  148 
  149 /**
  150  * This is the READY NCQ substate handler to start task management request. In this
  151  * routine, we suspend and resume the RNC.
  152  *
  153  * @param[in] device The target device a task management request towards to.
  154  * @param[in] request The task request.
  155  *
  156  * @return SCI_STATUS Always return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS status
  157  *     to let controller_start_task_handler know that the controller can't post TC for
  158  *     task request yet, instead, when RNC gets resumed, a controller_continue_task
  159  *     callback will be called.
  160  */
  161 static
  162 SCI_STATUS scic_sds_stp_remote_device_ready_substate_start_request_handler(
  163    SCI_BASE_REMOTE_DEVICE_T * device,
  164    SCI_BASE_REQUEST_T       * request
  165 )
  166 {
  167    SCI_STATUS status;
  168    SCIC_SDS_REMOTE_DEVICE_T * this_device  = (SCIC_SDS_REMOTE_DEVICE_T *)device;
  169    SCIC_SDS_REQUEST_T       * this_request = (SCIC_SDS_REQUEST_T       *)request;
  170 
  171    // Will the port allow the io request to start?
  172    status = this_device->owning_port->state_handlers->start_io_handler(
  173       this_device->owning_port,
  174       this_device,
  175       this_request
  176    );
  177 
  178    if (SCI_SUCCESS == status)
  179    {
  180       status =
  181          scic_sds_remote_node_context_start_task(this_device->rnc, this_request);
  182 
  183       if (SCI_SUCCESS == status)
  184       {
  185          status = this_request->state_handlers->parent.start_handler(request);
  186       }
  187 
  188       if (status == SCI_SUCCESS)
  189       {
  190          /// @note If the remote device state is not IDLE this will replace
  191          ///       the request that probably resulted in the task management
  192          ///       request.
  193          this_device->working_request = this_request;
  194 
  195          sci_base_state_machine_change_state(
  196             &this_device->ready_substate_machine,
  197             SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
  198          );
  199 
  200          //The remote node context must cleanup the TCi to NCQ mapping table.
  201          //The only way to do this correctly is to either write to the TLCR
  202          //register or to invalidate and repost the RNC. In either case the
  203          //remote node context state machine will take the correct action when
  204          //the remote node context is suspended and later resumed.
  205          scic_sds_remote_node_context_suspend(
  206             this_device->rnc, SCI_SOFTWARE_SUSPENSION, NULL, NULL);
  207 
  208          scic_sds_remote_node_context_resume(
  209             this_device->rnc,
  210             (SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK)
  211                 scic_sds_remote_device_continue_request,
  212             this_device);
  213       }
  214 
  215       scic_sds_remote_device_start_request(this_device,this_request,status);
  216 
  217       //We need to let the controller start request handler know that it can't
  218       //post TC yet. We will provide a callback function to post TC when RNC gets
  219       //resumed.
  220       return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS;
  221    }
  222 
  223    return status;
  224 }
  225 
  226 //*****************************************************************************
  227 //*  STP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS
  228 //*****************************************************************************
  229 
  230 /**
  231  * This method will handle the start io operation for a sata device that is in
  232  * the command idle state.
  233  *    - Evalute the type of IO request to be started
  234  *    - If its an NCQ request change to NCQ substate
  235  *    - If its any other command change to the CMD substate
  236  *
  237  * @note If this is a softreset we may want to have a different substate.
  238  *
  239  * @param [in] device
  240  * @param [in] request
  241  *
  242  * @return SCI_STATUS
  243  */
  244 static
  245 SCI_STATUS scic_sds_stp_remote_device_ready_idle_substate_start_io_handler(
  246    SCI_BASE_REMOTE_DEVICE_T * device,
  247    SCI_BASE_REQUEST_T       * request
  248 )
  249 {
  250    SCI_STATUS status;
  251    SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
  252    SCIC_SDS_REQUEST_T       * io_request  = (SCIC_SDS_REQUEST_T       *)request;
  253 
  254 
  255    // Will the port allow the io request to start?
  256    status = this_device->owning_port->state_handlers->start_io_handler(
  257       this_device->owning_port,
  258       this_device,
  259       io_request
  260    );
  261 
  262    if (status == SCI_SUCCESS)
  263    {
  264       status =
  265          scic_sds_remote_node_context_start_io(this_device->rnc, io_request);
  266 
  267       if (status == SCI_SUCCESS)
  268       {
  269          status = io_request->state_handlers->parent.start_handler(request);
  270       }
  271 
  272       if (status == SCI_SUCCESS)
  273       {
  274          if (io_request->sat_protocol == SAT_PROTOCOL_FPDMA)
  275          {
  276             sci_base_state_machine_change_state(
  277                &this_device->ready_substate_machine,
  278                SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
  279             );
  280          }
  281          else
  282          {
  283             this_device->working_request = io_request;
  284 
  285             sci_base_state_machine_change_state(
  286                &this_device->ready_substate_machine,
  287                SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
  288             );
  289          }
  290       }
  291 
  292       scic_sds_remote_device_start_request(this_device, io_request, status);
  293    }
  294 
  295    return status;
  296 }
  297 
  298 
  299 /**
  300  * This method will handle the event for a sata device that is in
  301  * the idle state. We pick up suspension events to handle specifically
  302  * to this state. We resume the RNC right away.
  303  *
  304  * @param [in] device The device received event.
  305  * @param [in] event_code The event code.
  306  *
  307  * @return SCI_STATUS
  308  */
  309 static
  310 SCI_STATUS scic_sds_stp_remote_device_ready_idle_substate_event_handler(
  311    SCIC_SDS_REMOTE_DEVICE_T * this_device,
  312    U32                        event_code
  313 )
  314 {
  315    SCI_STATUS status;
  316 
  317    status = scic_sds_remote_device_general_event_handler(this_device, event_code);
  318 
  319    if (status == SCI_SUCCESS)
  320    {
  321       if ((scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
  322           || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX)
  323           && (this_device->rnc->destination_state != SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY))
  324       {
  325          status = scic_sds_remote_node_context_resume(
  326                   this_device->rnc, NULL, NULL);
  327       }
  328    }
  329 
  330    return status;
  331 }
  332 
  333 
  334 //*****************************************************************************
  335 //*  STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
  336 //*****************************************************************************
  337 
  338 /**
  339  *
  340  */
  341 static
  342 SCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler(
  343    SCI_BASE_REMOTE_DEVICE_T * device,
  344    SCI_BASE_REQUEST_T       * request
  345 )
  346 {
  347    SCI_STATUS status;
  348    SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
  349    SCIC_SDS_REQUEST_T       * io_request  = (SCIC_SDS_REQUEST_T       *)request;
  350 
  351    if (io_request->sat_protocol == SAT_PROTOCOL_FPDMA)
  352    {
  353       status = this_device->owning_port->state_handlers->start_io_handler(
  354          this_device->owning_port,
  355          this_device,
  356          io_request
  357       );
  358 
  359       if (status == SCI_SUCCESS)
  360       {
  361          status = scic_sds_remote_node_context_start_io(this_device->rnc, io_request);
  362 
  363          if (status == SCI_SUCCESS)
  364          {
  365             status = io_request->state_handlers->parent.start_handler(request);
  366          }
  367 
  368          scic_sds_remote_device_start_request(this_device, io_request, status);
  369       }
  370    }
  371    else
  372    {
  373       status = SCI_FAILURE_INVALID_STATE;
  374    }
  375 
  376    return status;
  377 }
  378 
  379 /**
  380  *  This method will handle events received while the STP device is in the
  381  *  ready command substate.
  382  *
  383  *  @param [in] this_device This is the device object that is receiving the
  384  *         event.
  385  *  @param [in] event_code The event code to process.
  386  *
  387  *  @return SCI_STATUS
  388  */
  389 static
  390 SCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_event_handler(
  391    SCIC_SDS_REMOTE_DEVICE_T * this_device,
  392    U32                        event_code
  393 )
  394 {
  395    SCI_STATUS status;
  396 
  397    status = scic_sds_remote_device_general_event_handler(this_device, event_code);
  398 
  399    switch (scu_get_event_code(event_code))
  400    {
  401    case SCU_EVENT_TL_RNC_SUSPEND_TX:
  402    case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
  403       /// @todo We need to decode and understand why the hardware suspended the device.
  404       ///       The suspension reason was probably due to an SDB error FIS received.
  405       break;
  406 
  407    case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_DATA_LEN_ERR:
  408    case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_OFFSET_ERR:
  409    case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_DMASETUP_DIERR:
  410    case SCU_EVENT_TL_RNC_SUSPEND_TX_DONE_XFERCNT_ERR:
  411    case SCU_EVENT_TL_RNC_SUSPEND_TX_RX_DONE_PLD_LEN_ERR:
  412       this_device->not_ready_reason =
  413          SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
  414 
  415       sci_base_state_machine_change_state(
  416          &this_device->ready_substate_machine,
  417          SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
  418       );
  419 
  420       // We have a notification that the driver requested a suspend operation
  421       // this should not happen.
  422       SCIC_LOG_WARNING((
  423          sci_base_object_get_logger(this_device),
  424          SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
  425          "SCIC Remote device 0x%x received driver suspend event %x while in ncq ready substate %d\n",
  426          this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine)
  427       ));
  428 
  429       // Since we didn't expect to get here start the device again.
  430       status = scic_sds_remote_device_resume(this_device);
  431       break;
  432 
  433    case SCU_EVENT_POST_RCN_RELEASE:
  434       /// @todo Do we need to store the suspend state on the device?
  435       SCIC_LOG_INFO((
  436          sci_base_object_get_logger(this_device),
  437          SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
  438          "SCIC Remote device 0x%x received driver release event %x while in the ready substate %d\n",
  439          this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine)
  440       ));
  441       break;
  442 
  443    default:
  444       // Some other event just log it and continue
  445       SCIC_LOG_WARNING((
  446          sci_base_object_get_logger(this_device),
  447          SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
  448          "SCIC Remote device 0x%x received driver unexpected event %x while in the ready substate %d\n",
  449          this_device, event_code, sci_base_state_machine_get_state(&this_device->ready_substate_machine)
  450       ));
  451 
  452       status = SCI_FAILURE_INVALID_STATE;
  453       break;
  454    }
  455 
  456    return status;
  457 }
  458 
  459 /**
  460  *
  461  *
  462  * @param[in] this_device
  463  * @param[in] frame_index
  464  *
  465  * @return SCI_STATUS
  466  */
  467 static
  468 SCI_STATUS scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(
  469    SCIC_SDS_REMOTE_DEVICE_T * this_device,
  470    U32                        frame_index
  471 )
  472 {
  473    SCI_STATUS           status;
  474    SATA_FIS_HEADER_T  * frame_header;
  475 
  476    status = scic_sds_unsolicited_frame_control_get_header(
  477       &(scic_sds_remote_device_get_controller(this_device)->uf_control),
  478       frame_index,
  479       (void **)&frame_header
  480    );
  481 
  482    if (status == SCI_SUCCESS)
  483    {
  484       if (
  485             (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS)
  486          && (frame_header->status & ATA_STATUS_REG_ERROR_BIT)
  487          )
  488       {
  489          this_device->not_ready_reason =
  490             SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
  491 
  492          /** @todo Check sactive and complete associated IO if any. */
  493 
  494          sci_base_state_machine_change_state(
  495             &this_device->ready_substate_machine,
  496             SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
  497          );
  498       }
  499       else if (
  500             (frame_header->fis_type == SATA_FIS_TYPE_REGD2H)
  501          && (frame_header->status & ATA_STATUS_REG_ERROR_BIT)
  502          )
  503       {
  504          // Some devices return D2H FIS when an NCQ error is detected.
  505          // Treat this like an SDB error FIS ready reason.
  506          this_device->not_ready_reason =
  507             SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
  508 
  509          sci_base_state_machine_change_state(
  510             &this_device->ready_substate_machine,
  511             SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
  512          );
  513       }
  514       else
  515       {
  516          status = SCI_FAILURE;
  517       }
  518 
  519       scic_sds_controller_release_frame(
  520          scic_sds_remote_device_get_controller(this_device), frame_index
  521       );
  522    }
  523 
  524    return status;
  525 }
  526 
  527 //*****************************************************************************
  528 //*  STP REMOTE DEVICE READY CMD SUBSTATE HANDLERS
  529 //*****************************************************************************
  530 
  531 /**
  532  * This device is already handling a command it can not accept new commands
  533  * until this one is complete.
  534  *
  535  * @param[in] device
  536  * @param[in] request
  537  *
  538  * @return SCI_STATUS
  539  */
  540 static
  541 SCI_STATUS scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler(
  542    SCI_BASE_REMOTE_DEVICE_T * device,
  543    SCI_BASE_REQUEST_T       * request
  544 )
  545 {
  546    return SCI_FAILURE_INVALID_STATE;
  547 }
  548 
  549 static
  550 SCI_STATUS scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler(
  551    SCIC_SDS_REMOTE_DEVICE_T * this_device,
  552    U32                        suspend_type
  553 )
  554 {
  555    SCI_STATUS status;
  556 
  557    status = scic_sds_remote_node_context_suspend(
  558       this_device->rnc, suspend_type, NULL, NULL
  559    );
  560 
  561    return status;
  562 }
  563 
  564 /**
  565  *
  566  *
  567  * @param[in] this_device
  568  * @param[in] frame_index
  569  *
  570  * @return SCI_STATUS
  571  */
  572 static
  573 SCI_STATUS scic_sds_stp_remote_device_ready_cmd_substate_frame_handler(
  574    SCIC_SDS_REMOTE_DEVICE_T * this_device,
  575    U32                        frame_index
  576 )
  577 {
  578    SCI_STATUS status;
  579 
  580    /// The device doe not process any UF received from the hardware while
  581    /// in this state.  All unsolicited frames are forwarded to the io request
  582    /// object.
  583    status = scic_sds_io_request_frame_handler(
  584       this_device->working_request,
  585       frame_index
  586    );
  587 
  588    return status;
  589 }
  590 
  591 
  592 //*****************************************************************************
  593 //*  STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
  594 //*****************************************************************************
  595 
  596 
  597 //*****************************************************************************
  598 //*  STP REMOTE DEVICE READY AWAIT RESET SUBSTATE HANDLERS
  599 //*****************************************************************************
  600 static
  601 SCI_STATUS scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler(
  602    SCI_BASE_REMOTE_DEVICE_T * device,
  603    SCI_BASE_REQUEST_T       * request
  604 )
  605 {
  606    return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
  607 }
  608 
  609 
  610 
  611 /**
  612  * This method will perform the STP request (both io or task) completion
  613  * processing for await reset state.
  614  *
  615  * @param[in] device This parameter specifies the device for which the
  616  *            request is being completed.
  617  * @param[in] request This parameter specifies the request being completed.
  618  *
  619  * @return This method returns an indication as to whether the request
  620  *         processing completed successfully.
  621  */
  622 static
  623 SCI_STATUS scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler(
  624    SCI_BASE_REMOTE_DEVICE_T * device,
  625    SCI_BASE_REQUEST_T       * request
  626 )
  627 {
  628    SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
  629    SCIC_SDS_REQUEST_T       * the_request = (SCIC_SDS_REQUEST_T *)request;
  630    SCI_STATUS                 status;
  631 
  632    status = scic_sds_io_request_complete(the_request);
  633 
  634    if (status == SCI_SUCCESS)
  635    {
  636       status = scic_sds_port_complete_io(
  637                   this_device->owning_port, this_device, the_request
  638                );
  639 
  640       if (status == SCI_SUCCESS)
  641          scic_sds_remote_device_decrement_request_count(this_device);
  642    }
  643 
  644    if (status != SCI_SUCCESS)
  645    {
  646       SCIC_LOG_ERROR((
  647          sci_base_object_get_logger(this_device),
  648          SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
  649          "Port:0x%x Device:0x%x Request:0x%x Status:0x%x could not complete\n",
  650          this_device->owning_port, this_device, the_request, status
  651       ));
  652    }
  653 
  654    return status;
  655 }
  656 
  657 #if !defined(DISABLE_ATAPI)
  658 //*****************************************************************************
  659 //*  STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE HANDLERS
  660 //*****************************************************************************
  661 
  662 /**
  663  * This method will handle the event for a ATAPI device that is in
  664  * the ATAPI ERROR state. We pick up suspension events to handle specifically
  665  * to this state. We resume the RNC right away. We then complete the outstanding
  666  * IO to this device.
  667  *
  668  * @param [in] device The device received event.
  669  * @param [in] event_code The event code.
  670  *
  671  * @return SCI_STATUS
  672  */
  673 static
  674 SCI_STATUS scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler(
  675    SCIC_SDS_REMOTE_DEVICE_T * this_device,
  676    U32                        event_code
  677 )
  678 {
  679    SCI_STATUS status;
  680 
  681    status = scic_sds_remote_device_general_event_handler(this_device, event_code);
  682 
  683    if (status == SCI_SUCCESS)
  684    {
  685       if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
  686           || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX)
  687       {
  688          status = scic_sds_remote_node_context_resume(
  689                      this_device->rnc,
  690                      (SCIC_SDS_REMOTE_NODE_CONTEXT_CALLBACK)
  691                         this_device->working_request->state_handlers->parent.complete_handler,
  692                      (void *)this_device->working_request
  693                   );
  694       }
  695    }
  696 
  697    return status;
  698 }
  699 #endif // !defined(DISABLE_ATAPI)
  700 
  701 // ---------------------------------------------------------------------------
  702 
  703 SCIC_SDS_REMOTE_DEVICE_STATE_HANDLER_T
  704    scic_sds_stp_remote_device_ready_substate_handler_table[
  705                               SCIC_SDS_STP_REMOTE_DEVICE_READY_MAX_SUBSTATES] =
  706 {
  707    // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
  708    {
  709       {
  710          scic_sds_remote_device_default_start_handler,
  711          scic_sds_remote_device_ready_state_stop_handler,
  712          scic_sds_remote_device_default_fail_handler,
  713          scic_sds_remote_device_default_destruct_handler,
  714          scic_sds_remote_device_ready_state_reset_handler,
  715          scic_sds_remote_device_default_reset_complete_handler,
  716          scic_sds_stp_remote_device_ready_idle_substate_start_io_handler,
  717          scic_sds_remote_device_default_complete_request_handler,
  718          scic_sds_remote_device_default_continue_request_handler,
  719          scic_sds_stp_remote_device_ready_substate_start_request_handler,
  720          scic_sds_remote_device_default_complete_request_handler
  721       },
  722       scic_sds_remote_device_default_suspend_handler,
  723       scic_sds_remote_device_default_resume_handler,
  724       scic_sds_stp_remote_device_ready_idle_substate_event_handler,
  725       scic_sds_remote_device_default_frame_handler
  726    },
  727    // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
  728    {
  729       {
  730          scic_sds_remote_device_default_start_handler,
  731          scic_sds_remote_device_ready_state_stop_handler,
  732          scic_sds_remote_device_default_fail_handler,
  733          scic_sds_remote_device_default_destruct_handler,
  734          scic_sds_remote_device_ready_state_reset_handler,
  735          scic_sds_remote_device_default_reset_complete_handler,
  736          scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler,
  737          scic_sds_stp_remote_device_complete_request,
  738          scic_sds_remote_device_default_continue_request_handler,
  739          scic_sds_stp_remote_device_ready_substate_start_request_handler,
  740          scic_sds_stp_remote_device_complete_request,
  741       },
  742       scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler,
  743       scic_sds_remote_device_default_resume_handler,
  744       scic_sds_remote_device_general_event_handler,
  745       scic_sds_stp_remote_device_ready_cmd_substate_frame_handler
  746    },
  747    // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
  748    {
  749       {
  750          scic_sds_remote_device_default_start_handler,
  751          scic_sds_remote_device_ready_state_stop_handler,
  752          scic_sds_remote_device_default_fail_handler,
  753          scic_sds_remote_device_default_destruct_handler,
  754          scic_sds_remote_device_ready_state_reset_handler,
  755          scic_sds_remote_device_default_reset_complete_handler,
  756          scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler,
  757          scic_sds_stp_remote_device_complete_request,
  758          scic_sds_remote_device_default_continue_request_handler,
  759          scic_sds_stp_remote_device_ready_substate_start_request_handler,
  760          scic_sds_stp_remote_device_complete_request
  761       },
  762       scic_sds_remote_device_default_suspend_handler,
  763       scic_sds_remote_device_default_resume_handler,
  764       scic_sds_stp_remote_device_ready_ncq_substate_event_handler,
  765       scic_sds_stp_remote_device_ready_ncq_substate_frame_handler
  766    },
  767    // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
  768    {
  769       {
  770          scic_sds_remote_device_default_start_handler,
  771          scic_sds_remote_device_ready_state_stop_handler,
  772          scic_sds_remote_device_default_fail_handler,
  773          scic_sds_remote_device_default_destruct_handler,
  774          scic_sds_remote_device_ready_state_reset_handler,
  775          scic_sds_remote_device_default_reset_complete_handler,
  776          scic_sds_remote_device_default_start_request_handler,
  777          scic_sds_stp_remote_device_complete_request,
  778          scic_sds_remote_device_default_continue_request_handler,
  779          scic_sds_stp_remote_device_ready_substate_start_request_handler,
  780          scic_sds_stp_remote_device_complete_request
  781       },
  782       scic_sds_remote_device_default_suspend_handler,
  783       scic_sds_remote_device_default_resume_handler,
  784       scic_sds_remote_device_general_event_handler,
  785       scic_sds_remote_device_general_frame_handler
  786    },
  787 #if !defined(DISABLE_ATAPI)
  788    // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
  789    {
  790       {
  791          scic_sds_remote_device_default_start_handler,
  792          scic_sds_remote_device_ready_state_stop_handler,
  793          scic_sds_remote_device_default_fail_handler,
  794          scic_sds_remote_device_default_destruct_handler,
  795          scic_sds_remote_device_ready_state_reset_handler,
  796          scic_sds_remote_device_default_reset_complete_handler,
  797          scic_sds_remote_device_default_start_request_handler,
  798          scic_sds_stp_remote_device_complete_request,
  799          scic_sds_remote_device_default_continue_request_handler,
  800          scic_sds_stp_remote_device_ready_substate_start_request_handler,
  801          scic_sds_stp_remote_device_complete_request
  802       },
  803       scic_sds_remote_device_default_suspend_handler,
  804       scic_sds_remote_device_default_resume_handler,
  805       scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler,
  806       scic_sds_remote_device_general_frame_handler
  807    },
  808 #endif
  809    // SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
  810    {
  811       {
  812          scic_sds_remote_device_default_start_handler,
  813          scic_sds_remote_device_ready_state_stop_handler,
  814          scic_sds_remote_device_default_fail_handler,
  815          scic_sds_remote_device_default_destruct_handler,
  816          scic_sds_remote_device_ready_state_reset_handler,
  817          scic_sds_remote_device_default_reset_complete_handler,
  818          scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler,
  819          scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler,
  820          scic_sds_remote_device_default_continue_request_handler,
  821          scic_sds_stp_remote_device_ready_substate_start_request_handler,
  822          scic_sds_stp_remote_device_complete_request
  823       },
  824       scic_sds_remote_device_default_suspend_handler,
  825       scic_sds_remote_device_default_resume_handler,
  826       scic_sds_remote_device_general_event_handler,
  827       scic_sds_remote_device_general_frame_handler
  828    }
  829 };
  830 
  831 //*****************************************************************************
  832 //*  STP REMOTE DEVICE READY SUBSTATE PRIVATE METHODS
  833 //*****************************************************************************
  834 
  835 static
  836 void scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
  837    void * user_cookie
  838 )
  839 {
  840    SCIC_SDS_REMOTE_DEVICE_T * this_device;
  841    this_device = (SCIC_SDS_REMOTE_DEVICE_T *)user_cookie;
  842 
  843    // For NCQ operation we do not issue a
  844    // scic_cb_remote_device_not_ready().  As a result, avoid sending
  845    // the ready notification.
  846    if (this_device->ready_substate_machine.previous_state_id
  847        != SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ)
  848    {
  849       scic_cb_remote_device_ready(
  850          scic_sds_remote_device_get_controller(this_device), this_device
  851       );
  852    }
  853 }
  854 
  855 //*****************************************************************************
  856 //*  STP REMOTE DEVICE READY IDLE SUBSTATE
  857 //*****************************************************************************
  858 
  859 /**
  860  *
  861  * @param[in] device This is the SCI base object which is cast into a
  862  *       SCIC_SDS_REMOTE_DEVICE object.
  863  *
  864  * @return none
  865  */
  866 static
  867 void scic_sds_stp_remote_device_ready_idle_substate_enter(
  868    SCI_BASE_OBJECT_T * device
  869 )
  870 {
  871    SCIC_SDS_REMOTE_DEVICE_T * this_device;
  872 
  873    this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
  874 
  875    SET_STATE_HANDLER(
  876       this_device,
  877       scic_sds_stp_remote_device_ready_substate_handler_table,
  878       SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
  879    );
  880 
  881    this_device->working_request = NULL;
  882 
  883    if (scic_sds_remote_node_context_is_ready(this_device->rnc))
  884    {
  885       // Since the RNC is ready, it's alright to finish completion
  886       // processing (e.g. signal the remote device is ready).
  887       scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
  888          this_device
  889       );
  890    }
  891    else
  892    {
  893       scic_sds_remote_node_context_resume(
  894          this_device->rnc,
  895          scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler,
  896          this_device
  897       );
  898    }
  899 }
  900 
  901 //*****************************************************************************
  902 //*  STP REMOTE DEVICE READY CMD SUBSTATE
  903 //*****************************************************************************
  904 
  905 /**
  906  *
  907  *
  908  * @param[in] device This is the SCI base object which is cast into a
  909  *       SCIC_SDS_REMOTE_DEVICE object.
  910  *
  911  * @return none
  912  */
  913 static
  914 void scic_sds_stp_remote_device_ready_cmd_substate_enter(
  915    SCI_BASE_OBJECT_T * device
  916 )
  917 {
  918    SCIC_SDS_REMOTE_DEVICE_T * this_device;
  919 
  920    this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
  921 
  922    ASSERT(this_device->working_request != NULL);
  923 
  924    SET_STATE_HANDLER(
  925       this_device,
  926       scic_sds_stp_remote_device_ready_substate_handler_table,
  927       SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
  928    );
  929 
  930    scic_cb_remote_device_not_ready(
  931       scic_sds_remote_device_get_controller(this_device),
  932       this_device,
  933       SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED
  934    );
  935 }
  936 
  937 //*****************************************************************************
  938 //*  STP REMOTE DEVICE READY NCQ SUBSTATE
  939 //*****************************************************************************
  940 
  941 /**
  942  *
  943  *
  944  * @param[in] device This is the SCI base object which is cast into a
  945  *       SCIC_SDS_REMOTE_DEVICE object.
  946  *
  947  * @return none
  948  */
  949 static
  950 void scic_sds_stp_remote_device_ready_ncq_substate_enter(
  951    SCI_BASE_OBJECT_T * device
  952 )
  953 {
  954    SCIC_SDS_REMOTE_DEVICE_T * this_device;
  955 
  956    this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
  957 
  958    SET_STATE_HANDLER(
  959       this_device,
  960       scic_sds_stp_remote_device_ready_substate_handler_table,
  961       SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
  962    );
  963 }
  964 
  965 //*****************************************************************************
  966 //*  STP REMOTE DEVICE READY NCQ ERROR SUBSTATE
  967 //*****************************************************************************
  968 
  969 /**
  970  *
  971  *
  972  * @param[in] device This is the SCI base object which is cast into a
  973  *       SCIC_SDS_REMOTE_DEVICE object.
  974  *
  975  * @return none
  976  */
  977 static
  978 void scic_sds_stp_remote_device_ready_ncq_error_substate_enter(
  979    SCI_BASE_OBJECT_T * device
  980 )
  981 {
  982    SCIC_SDS_REMOTE_DEVICE_T * this_device;
  983 
  984    this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
  985 
  986    SET_STATE_HANDLER(
  987       this_device,
  988       scic_sds_stp_remote_device_ready_substate_handler_table,
  989       SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
  990    );
  991 
  992    if(this_device->not_ready_reason ==
  993          SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED)
  994    {
  995       scic_cb_remote_device_not_ready(
  996          scic_sds_remote_device_get_controller(this_device),
  997          this_device,
  998          this_device->not_ready_reason
  999       );
 1000    }
 1001 }
 1002 
 1003 //*****************************************************************************
 1004 //*  STP REMOTE DEVICE READY AWAIT RESET SUBSTATE
 1005 //*****************************************************************************
 1006 
 1007 /**
 1008  * @brief The enter routine to READY AWAIT RESET substate.
 1009  *
 1010  * @param[in] device This is the SCI base object which is cast into a
 1011  *       SCIC_SDS_REMOTE_DEVICE object.
 1012  *
 1013  * @return none
 1014  */
 1015 static
 1016 void scic_sds_stp_remote_device_ready_await_reset_substate_enter(
 1017    SCI_BASE_OBJECT_T * device
 1018 )
 1019 {
 1020    SCIC_SDS_REMOTE_DEVICE_T * this_device;
 1021 
 1022    this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
 1023 
 1024    SET_STATE_HANDLER(
 1025       this_device,
 1026       scic_sds_stp_remote_device_ready_substate_handler_table,
 1027       SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
 1028    );
 1029 }
 1030 
 1031 #if !defined(DISABLE_ATAPI)
 1032 //*****************************************************************************
 1033 //*  STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE
 1034 //*****************************************************************************
 1035 
 1036 /**
 1037  * @brief The enter routine to READY ATAPI ERROR substate.
 1038  *
 1039  * @param[in] device This is the SCI base object which is cast into a
 1040  *       SCIC_SDS_REMOTE_DEVICE object.
 1041  *
 1042  * @return none
 1043  */
 1044 static
 1045 void scic_sds_stp_remote_device_ready_atapi_error_substate_enter(
 1046    SCI_BASE_OBJECT_T * device
 1047 )
 1048 {
 1049    SCIC_SDS_REMOTE_DEVICE_T * this_device;
 1050 
 1051    this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device;
 1052 
 1053    SET_STATE_HANDLER(
 1054       this_device,
 1055       scic_sds_stp_remote_device_ready_substate_handler_table,
 1056       SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
 1057    );
 1058 }
 1059 #endif // !defined(DISABLE_ATAPI)
 1060 
 1061 // ---------------------------------------------------------------------------
 1062 
 1063 SCI_BASE_STATE_T
 1064    scic_sds_stp_remote_device_ready_substate_table[
 1065       SCIC_SDS_STP_REMOTE_DEVICE_READY_MAX_SUBSTATES] =
 1066 {
 1067    {
 1068       SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE,
 1069       scic_sds_stp_remote_device_ready_idle_substate_enter,
 1070       NULL
 1071    },
 1072    {
 1073       SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD,
 1074       scic_sds_stp_remote_device_ready_cmd_substate_enter,
 1075       NULL
 1076    },
 1077    {
 1078       SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ,
 1079       scic_sds_stp_remote_device_ready_ncq_substate_enter,
 1080       NULL
 1081    },
 1082    {
 1083       SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR,
 1084       scic_sds_stp_remote_device_ready_ncq_error_substate_enter,
 1085       NULL
 1086    },
 1087 #if !defined(DISABLE_ATAPI)
 1088    {
 1089       SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR,
 1090       scic_sds_stp_remote_device_ready_atapi_error_substate_enter,
 1091       NULL
 1092    },
 1093 #endif
 1094    {
 1095       SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET,
 1096       scic_sds_stp_remote_device_ready_await_reset_substate_enter,
 1097       NULL
 1098    }
 1099 };
 1100 

Cache object: ce0f4af754da1ee4dd2a519b67382f67


[ 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.