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/scif_sas_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 implementation of the SCIF_SAS_REMOTE_DEVICE
   62  *        object.
   63  */
   64 
   65 
   66 #include <dev/isci/scil/scic_remote_device.h>
   67 #include <dev/isci/scil/scic_port.h>
   68 #include <dev/isci/scil/scic_user_callback.h>
   69 
   70 #include <dev/isci/scil/scif_sas_logger.h>
   71 #include <dev/isci/scil/scif_sas_remote_device.h>
   72 #include <dev/isci/scil/scif_sas_stp_remote_device.h>
   73 #include <dev/isci/scil/scif_sas_domain.h>
   74 #include <dev/isci/scil/scif_sas_controller.h>
   75 #include <dev/isci/scil/sci_controller.h>
   76 #include <dev/isci/scil/sci_util.h>
   77 
   78 
   79 //******************************************************************************
   80 //* P U B L I C   M E T H O D S
   81 //******************************************************************************
   82 
   83 U32 scif_remote_device_get_object_size(
   84    void
   85 )
   86 {
   87    return ( sizeof(SCIF_SAS_REMOTE_DEVICE_T)
   88           + scic_remote_device_get_object_size() );
   89 }
   90 
   91 // ---------------------------------------------------------------------------
   92 
   93 void scif_remote_device_construct(
   94    SCI_DOMAIN_HANDLE_T          domain,
   95    void                       * remote_device_memory,
   96    SCI_REMOTE_DEVICE_HANDLE_T * new_scif_remote_device_handle
   97 )
   98 {
   99    SCIF_SAS_DOMAIN_T        * fw_domain = (SCIF_SAS_DOMAIN_T *) domain;
  100    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
  101                                           remote_device_memory;
  102 
  103    SCIF_LOG_TRACE((
  104       sci_base_object_get_logger(fw_domain),
  105       SCIF_LOG_OBJECT_REMOTE_DEVICE,
  106       "scif_remote_device_construct(0x%x, 0x%x, 0x%x) enter\n",
  107       domain, remote_device_memory, new_scif_remote_device_handle
  108    ));
  109 
  110    memset(remote_device_memory, 0, sizeof(SCIF_SAS_REMOTE_DEVICE_T));
  111 
  112    // The user's handle to the remote device evaluates to the memory
  113    // address where the remote device object is stored.
  114    *new_scif_remote_device_handle = remote_device_memory;
  115 
  116    fw_device->domain                = fw_domain;
  117    fw_device->destruct_when_stopped = FALSE;
  118    //fw_device->parent.is_failed      = FALSE;
  119    fw_device->operation_status      = SCI_SUCCESS;
  120    fw_device->request_count         = 0;
  121    fw_device->task_request_count    = 0;
  122    fw_device->is_currently_discovered = TRUE;
  123    fw_device->containing_device       = NULL;
  124    fw_device->device_port_width       = 1;
  125    fw_device->expander_phy_identifier = 0;
  126    fw_device->destination_state       =
  127       SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_UNSPECIFIED;
  128    fw_device->ea_target_reset_request_scheduled = NULL;
  129 
  130    // Construct the base object first in order to ensure logging can
  131    // function.
  132    sci_base_remote_device_construct(
  133       &fw_device->parent,
  134       sci_base_object_get_logger(fw_domain),
  135       scif_sas_remote_device_state_table
  136    );
  137 
  138    sci_base_state_machine_construct(
  139       &fw_device->starting_substate_machine,
  140       &fw_device->parent.parent,
  141       scif_sas_remote_device_starting_substate_table,
  142       SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATE_AWAIT_COMPLETE
  143    );
  144 
  145    sci_base_state_machine_construct(
  146       &fw_device->ready_substate_machine,
  147       &fw_device->parent.parent,
  148       scif_sas_remote_device_ready_substate_table,
  149       SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL
  150    );
  151 
  152    scif_sas_remote_device_initialize_state_logging(fw_device);
  153 
  154    scic_remote_device_construct(
  155       fw_domain->core_object,
  156       ((U8*) remote_device_memory) + sizeof(SCIF_SAS_REMOTE_DEVICE_T),
  157       &fw_device->core_object
  158    );
  159 
  160    // Set the association in the core object, so that we are able to
  161    // determine our framework remote device object from the core remote
  162    // device.
  163    sci_object_set_association(fw_device->core_object, fw_device);
  164 }
  165 
  166 // ---------------------------------------------------------------------------
  167 
  168 SCI_STATUS scif_remote_device_da_construct(
  169    SCI_REMOTE_DEVICE_HANDLE_T                   remote_device,
  170    SCI_SAS_ADDRESS_T                          * sas_address,
  171    SCI_SAS_IDENTIFY_ADDRESS_FRAME_PROTOCOLS_T * protocols
  172 )
  173 {
  174    SCI_STATUS                 status    = SCI_SUCCESS;
  175    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
  176                                           remote_device;
  177 
  178    SCIF_LOG_TRACE((
  179       sci_base_object_get_logger(fw_device),
  180       SCIF_LOG_OBJECT_REMOTE_DEVICE,
  181       "scif_remote_device_da_construct(0x%x, 0x%x, 0x%x) enter\n",
  182       remote_device, sas_address, protocols
  183    ));
  184 
  185    // Make sure the device hasn't already been constructed and added
  186    // to the domain.
  187    if (scif_domain_get_device_by_sas_address(fw_device->domain, sas_address)
  188        == SCI_INVALID_HANDLE)
  189    {
  190       SCIC_PORT_PROPERTIES_T  properties;
  191 
  192       scic_port_get_properties(fw_device->domain->core_object, &properties);
  193 
  194       // Check to see if this is the direct attached device.
  195       if (  (sas_address->low == properties.remote.sas_address.low)
  196          && (sas_address->high == properties.remote.sas_address.high) )
  197       {
  198          //Get accurate port width from port's phy mask for a DA device.
  199          SCI_GET_BITS_SET_COUNT(properties.phy_mask, fw_device->device_port_width);
  200 
  201          status = scic_remote_device_da_construct(fw_device->core_object);
  202       }
  203       else
  204          // Don't allow the user to construct a direct attached device
  205          // if it's not a direct attached device.
  206          status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
  207    }
  208    else
  209       status = SCI_FAILURE_DEVICE_EXISTS;
  210 
  211    if (status == SCI_SUCCESS)
  212    {
  213       // Add the device to the domain list.
  214       sci_abstract_list_pushback(
  215          &fw_device->domain->remote_device_list, fw_device
  216       );
  217 
  218       // If a SATA/STP device is connected, then construct it.
  219       if (protocols->u.bits.stp_target)
  220          scif_sas_stp_remote_device_construct(fw_device);
  221       else if (protocols->u.bits.smp_target)
  222          scif_sas_smp_remote_device_construct(fw_device);
  223 
  224       SCIF_LOG_INFO((
  225          sci_base_object_get_logger(fw_device),
  226          SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
  227          "Domain:0x%x SasAddress:0x%x,0x%x remote device constructed\n",
  228          fw_device->domain, sas_address->low, sas_address->high
  229       ));
  230 
  231       status = fw_device->state_handlers->parent.start_handler(
  232                   &fw_device->parent
  233                );
  234    }
  235    else
  236    {
  237       SCIF_LOG_WARNING((
  238          sci_base_object_get_logger(fw_device),
  239          SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
  240          "Domain:0x%x SasAddress:0x%x,0x%x Status:0x%x remote device construct failure\n",
  241          fw_device->domain, sas_address->low, sas_address->high, status
  242       ));
  243    }
  244 
  245    return status;
  246 }
  247 
  248 // ---------------------------------------------------------------------------
  249 
  250 SCI_STATUS scif_remote_device_ea_construct(
  251    SCI_REMOTE_DEVICE_HANDLE_T   remote_device,
  252    SCI_REMOTE_DEVICE_HANDLE_T   containing_device,
  253    SMP_RESPONSE_DISCOVER_T    * smp_response
  254 )
  255 {
  256    SCI_SAS_ADDRESS_T        * sas_address;
  257    SCI_STATUS                 status        = SCI_SUCCESS;
  258    SCIF_SAS_REMOTE_DEVICE_T * fw_device     = (SCIF_SAS_REMOTE_DEVICE_T *)
  259                                               remote_device;
  260    SCIF_SAS_REMOTE_DEVICE_T * fw_smp_device = (SCIF_SAS_REMOTE_DEVICE_T *)
  261                                               containing_device;
  262 
  263    fw_device->containing_device = fw_smp_device;
  264    fw_device->expander_phy_identifier =
  265       fw_smp_device->protocol_device.smp_device.current_activity_phy_index;
  266 
  267    sas_address = &smp_response->attached_sas_address;
  268 
  269    SCIF_LOG_TRACE((
  270       sci_base_object_get_logger(fw_device),
  271       SCIF_LOG_OBJECT_REMOTE_DEVICE,
  272       "scif_remote_device_ea_construct(0x%x, 0x%x) enter\n",
  273       remote_device, smp_response
  274    ));
  275 
  276    // Make sure the device hasn't already been constructed and added
  277    // to the domain.
  278    if (scif_domain_get_device_by_sas_address(fw_device->domain, sas_address)
  279        == SCI_INVALID_HANDLE)
  280    {
  281       //for sata device, we need another routine. likely
  282       //scif_remote_device_ea_sata_construct.
  283       status = scic_remote_device_ea_construct(fw_device->core_object, smp_response);
  284    }
  285    else
  286       status = SCI_FAILURE_DEVICE_EXISTS;
  287 
  288    if (status == SCI_SUCCESS)
  289    {
  290       // Add the device to the domain list.
  291       sci_abstract_list_pushback(
  292          &fw_device->domain->remote_device_list, fw_device
  293       );
  294 
  295       if (smp_response->protocols.u.bits.attached_smp_target)
  296          scif_sas_smp_remote_device_construct(fw_device);
  297       else if (smp_response->protocols.u.bits.attached_stp_target)
  298          scif_sas_stp_remote_device_construct(fw_device);
  299 
  300       SCIF_LOG_INFO((
  301          sci_base_object_get_logger(fw_device),
  302          SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
  303          "Domain:0x%x SasAddress:0x%x,0x%x remote device constructed\n",
  304          fw_device->domain, sas_address->low, sas_address->high
  305       ));
  306 
  307       //only start the device if the device is not a SATA disk on SPINUP_HOLD state.
  308       if ( scic_remote_device_get_connection_rate(fw_device->core_object) !=
  309               SCI_SATA_SPINUP_HOLD )
  310       {
  311           status = fw_device->state_handlers->parent.start_handler(
  312                       &fw_device->parent
  313                    );
  314       }
  315    }
  316    else
  317    {
  318       SCIF_LOG_WARNING((
  319          sci_base_object_get_logger(fw_device),
  320          SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
  321          "Domain:0x%x SasAddress:0x%x,0x%x Status:0x%x remote device construct failure\n",
  322          fw_device->domain, sas_address->low, sas_address->high, status
  323       ));
  324    }
  325 
  326    return status;
  327 }
  328 
  329 // ---------------------------------------------------------------------------
  330 
  331 SCI_STATUS scif_remote_device_destruct(
  332    SCI_REMOTE_DEVICE_HANDLE_T  remote_device
  333 )
  334 {
  335    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
  336                                           remote_device;
  337 
  338    SCIF_LOG_TRACE((
  339       sci_base_object_get_logger(fw_device),
  340       SCIF_LOG_OBJECT_REMOTE_DEVICE,
  341       "scif_remote_device_destruct(0x%x) enter\n",
  342       remote_device
  343    ));
  344 
  345    //remove the device from domain's remote_device_list
  346    fw_device->domain->state_handlers->device_destruct_handler(
  347       &fw_device->domain->parent, &fw_device->parent
  348    );
  349 
  350    // The destruct process may not complete immediately, since the core
  351    // remote device likely needs to be stopped first.  However, the user
  352    // is not given a callback notification for destruction.
  353    return fw_device->state_handlers->parent.destruct_handler(
  354              &fw_device->parent
  355           );
  356 }
  357 
  358 // ---------------------------------------------------------------------------
  359 
  360 SCI_REMOTE_DEVICE_HANDLE_T scif_remote_device_get_scic_handle(
  361    SCI_REMOTE_DEVICE_HANDLE_T  scif_remote_device
  362 )
  363 {
  364    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
  365                                           scif_remote_device;
  366 
  367    if ( (fw_device == NULL) || (fw_device->core_object == SCI_INVALID_HANDLE) )
  368       return SCI_INVALID_HANDLE;
  369 
  370    SCIF_LOG_WARNING((
  371       sci_base_object_get_logger(fw_device),
  372       SCIF_LOG_OBJECT_REMOTE_DEVICE,
  373       "RemoteDevice:0x%x no associated core device found\n",
  374       fw_device
  375    ));
  376 
  377    return fw_device->core_object;
  378 }
  379 
  380 // ---------------------------------------------------------------------------
  381 
  382 void scic_cb_remote_device_start_complete(
  383    SCI_CONTROLLER_HANDLE_T    controller,
  384    SCI_REMOTE_DEVICE_HANDLE_T remote_device,
  385    SCI_STATUS                 completion_status
  386 )
  387 {
  388    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
  389                                       sci_object_get_association(remote_device);
  390 
  391    SCIF_LOG_TRACE((
  392       sci_base_object_get_logger(fw_device),
  393       SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
  394       "scic_cb_remote_device_start_complete(0x%x, 0x%x, 0x%x) enter\n",
  395       controller, remote_device, completion_status
  396    ));
  397 
  398    fw_device->state_handlers->start_complete_handler(
  399       fw_device, completion_status
  400    );
  401 }
  402 
  403 // ---------------------------------------------------------------------------
  404 
  405 void scic_cb_remote_device_stop_complete(
  406    SCI_CONTROLLER_HANDLE_T    controller,
  407    SCI_REMOTE_DEVICE_HANDLE_T remote_device,
  408    SCI_STATUS                 completion_status
  409 )
  410 {
  411    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
  412                                       sci_object_get_association(remote_device);
  413 
  414    SCIF_LOG_TRACE((
  415       sci_base_object_get_logger(fw_device),
  416       SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
  417       "scic_cb_remote_device_stop_complete(0x%x, 0x%x, 0x%x) enter\n",
  418       controller, remote_device, completion_status
  419    ));
  420 
  421    fw_device->state_handlers->stop_complete_handler(
  422       fw_device, completion_status
  423    );
  424 }
  425 
  426 // ---------------------------------------------------------------------------
  427 
  428 void scic_cb_remote_device_ready(
  429    SCI_CONTROLLER_HANDLE_T     controller,
  430    SCI_REMOTE_DEVICE_HANDLE_T  remote_device
  431 )
  432 {
  433    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
  434                                       sci_object_get_association(remote_device);
  435 
  436    fw_device->state_handlers->ready_handler(fw_device);
  437 }
  438 
  439 // ---------------------------------------------------------------------------
  440 
  441 void scic_cb_remote_device_not_ready(
  442    SCI_CONTROLLER_HANDLE_T     controller,
  443    SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
  444    U32                         reason_code
  445 )
  446 {
  447    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
  448                                       sci_object_get_association(remote_device);
  449 
  450    fw_device->state_handlers->not_ready_handler(fw_device,reason_code);
  451 }
  452 
  453 // ---------------------------------------------------------------------------
  454 
  455 U16 scif_remote_device_get_max_queue_depth(
  456    SCI_REMOTE_DEVICE_HANDLE_T  remote_device
  457 )
  458 {
  459    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
  460                                           remote_device;
  461    SMP_DISCOVER_RESPONSE_PROTOCOLS_T  protocols;
  462 
  463    scic_remote_device_get_protocols(fw_device->core_object, &protocols);
  464 
  465    // If the target is a SATA/STP target, then determine the queue depth
  466    // for either NCQ or for UDMA.
  467    if (protocols.u.bits.attached_stp_target)
  468    {
  469       if (fw_device->protocol_device.stp_device.sati_device.capabilities
  470           & SATI_DEVICE_CAP_NCQ_SUPPORTED_ENABLE)
  471       {
  472          return fw_device->protocol_device.stp_device.sati_device.ncq_depth;
  473       }
  474       else
  475       {
  476          // At the moment, we only allow a single UDMA request to be queued.
  477          return 1;
  478       }
  479    }
  480 
  481    // For SSP devices return a no maximum queue depth supported.
  482    return SCIF_REMOTE_DEVICE_NO_MAX_QUEUE_DEPTH;
  483 }
  484 
  485 // ---------------------------------------------------------------------------
  486 
  487 SCI_STATUS scif_remote_device_get_containing_device(
  488    SCI_REMOTE_DEVICE_HANDLE_T          remote_device,
  489    SCI_REMOTE_DEVICE_HANDLE_T        * containing_device
  490 )
  491 {
  492    SCI_STATUS                 status      = SCI_FAILURE;
  493    SCIF_SAS_REMOTE_DEVICE_T * this_device = (SCIF_SAS_REMOTE_DEVICE_T *)
  494                                             remote_device;
  495 
  496    if ( (this_device != NULL) && (containing_device != NULL) )
  497    {
  498       *containing_device = (SCI_REMOTE_DEVICE_HANDLE_T)(this_device->containing_device);
  499       if (*containing_device != NULL)
  500       {
  501          status = SCI_SUCCESS;
  502       }
  503    }
  504 
  505    return status;
  506 }
  507 
  508 // ---------------------------------------------------------------------------
  509 
  510 U32 scif_remote_device_get_started_io_count(
  511    SCI_REMOTE_DEVICE_HANDLE_T  remote_device
  512 )
  513 {
  514    SCIF_SAS_REMOTE_DEVICE_T * this_device = (SCIF_SAS_REMOTE_DEVICE_T *)
  515                                             remote_device;
  516 
  517    return this_device->request_count - this_device->task_request_count;
  518 }
  519 //******************************************************************************
  520 //* P R O T E C T E D   M E T H O D S
  521 //******************************************************************************
  522 
  523 /*
  524 void scif_sas_remote_device_failure(
  525    SCIF_SAS_REMOTE_DEVICE_T * fw_device
  526 )
  527 {
  528    fw_device->parent.is_failed = TRUE;
  529    sci_base_state_machine_change_state(
  530       &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
  531    );
  532 }
  533 */
  534 
  535 
  536 /**
  537  * @brief This method retrieves info from Report Phy Sata response and
  538  *        save the additional data for a SATA remote device, if necessary.
  539  *
  540  * @param[in] report_phy_sata_response SMP Report Phy Sata response
  541  *
  542  * @return none
  543  */
  544 void scif_sas_remote_device_save_report_phy_sata_information(
  545    SMP_RESPONSE_REPORT_PHY_SATA_T * report_phy_sata_response
  546 )
  547 {
  548    //do nothing currently. Later, if needed, we will search the existed
  549    //remote device by stp_sas_address, then save more information for
  550    //that device off the report_phy_sata_response. This assumes the
  551    //stp_sas_address from report_phy_sata response is the same sas address
  552    //from discover response.
  553 
  554    return;
  555 }
  556 
  557 /**
  558  * @brief This method does target reset for DA or EA remote device.
  559  *
  560  * @param[in] fw_controller, the controller object the target device belongs
  561  *            to.
  562  * @param[in] fw_device, the target device to be hard reset.
  563  * @param[in] fw_request, the scif task request object that asked for this
  564  *            target reset.
  565  */
  566 void scif_sas_remote_device_target_reset(
  567    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
  568    SCIF_SAS_REQUEST_T       * fw_request
  569 )
  570 {
  571    SCIF_LOG_INFO((
  572       sci_base_object_get_logger(fw_device),
  573       SCIF_LOG_OBJECT_REMOTE_DEVICE,
  574       "scif_sas_remote_device_target_reset! fw_device:0x%x fw_request:0x%x\n",
  575       fw_device, fw_request
  576    ));
  577 
  578    if (fw_device->containing_device == NULL)
  579    {
  580       SCI_PORT_HANDLE_T port;
  581 
  582       port = scif_domain_get_scic_port_handle(fw_device->domain);
  583 
  584       //Direct attached device target reset.
  585       //calling core to do port reset. The fw_request will not be used here.
  586       scic_port_hard_reset(
  587          port,
  588          scic_remote_device_get_suggested_reset_timeout(fw_device->core_object)
  589       );
  590    }
  591    else
  592    {  //Expander attached device target reset.
  593 
  594       if ( fw_device->containing_device->protocol_device.smp_device.current_activity
  595               == SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_TARGET_RESET )
  596       {
  597          //The containing expander is in the middle of target resetting other of its
  598          //remote disks. Flag this remote device to be target reset later.
  599          SCIF_LOG_INFO((
  600             sci_base_object_get_logger(fw_device),
  601             SCIF_LOG_OBJECT_REMOTE_DEVICE,
  602             "scif_sas_remote_device_target_reset DELAYED! fw_device:0x%x fw_request:0x%x\n",
  603             fw_device, fw_request
  604          ));
  605 
  606          fw_device->ea_target_reset_request_scheduled = fw_request;
  607          return;
  608       }
  609 
  610       //set current_activity and current_smp_request to expander device.
  611       scif_sas_smp_remote_device_start_target_reset(
  612          fw_device->containing_device, fw_device, fw_request);
  613    }
  614 
  615    scic_remote_device_reset(fw_device->core_object);
  616 }
  617 
  618 
  619 /**
  620  * @brief This method completes target reset for DA or EA remote device.
  621  *
  622  * @param[in] fw_device, the target device to be hard reset.
  623  * @param[in] fw_request, the scif task request object that asked for this
  624  *            target reset.
  625  * @param[in] completion_status
  626  */
  627 void scif_sas_remote_device_target_reset_complete(
  628    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
  629    SCIF_SAS_REQUEST_T       * fw_request,
  630    SCI_STATUS                 completion_status
  631 )
  632 {
  633    SCIF_LOG_INFO((
  634       sci_base_object_get_logger(fw_device),
  635       SCIF_LOG_OBJECT_REMOTE_DEVICE,
  636       "scif_sas_remote_device_target_reset_complete! "
  637       "fw_device:0x%x fw_request:0x%x completion_status 0x%x\n",
  638       fw_device, fw_request, completion_status
  639    ));
  640 
  641    scif_cb_task_request_complete(
  642       fw_device->domain->controller,
  643       fw_device,
  644       fw_request,
  645       (SCI_TASK_STATUS) completion_status
  646    );
  647 
  648    scic_remote_device_reset_complete(fw_device->core_object);
  649 
  650    //For expander attached device done target reset.
  651    if (fw_device->containing_device != NULL)
  652    {
  653       //search for all the devices in the domain to find other remote devices
  654       //needs to be target reset.
  655       SCIF_SAS_REMOTE_DEVICE_T * next_device;
  656 
  657       scif_sas_smp_remote_device_clear(fw_device->containing_device);
  658 
  659       if( (next_device = scif_sas_domain_find_next_ea_target_reset(fw_device->domain))
  660               != NULL )
  661       {
  662          scif_sas_smp_remote_device_start_target_reset(
  663             next_device->containing_device,
  664             next_device,
  665             next_device->ea_target_reset_request_scheduled
  666          );
  667 
  668          next_device->ea_target_reset_request_scheduled = NULL;
  669       }
  670       else
  671       {
  672          //if the domain is in the DISCOVER state, we should resume the DISCOVER.
  673          if (fw_device->domain->parent.state_machine.current_state_id ==
  674                 SCI_BASE_DOMAIN_STATE_DISCOVERING)
  675          {
  676             SCIF_SAS_REMOTE_DEVICE_T * top_expander = fw_device->containing_device;
  677 
  678             while(top_expander->containing_device != NULL)
  679                top_expander = top_expander->containing_device;
  680 
  681             scif_sas_domain_start_smp_discover(fw_device->domain, top_expander);
  682          }
  683          else
  684          {
  685             //Tell driver to kick off Discover process. If the domain is already
  686             //in Discovery state, this discovery request will not be carried on.
  687             scif_cb_domain_change_notification(
  688             fw_device->domain->controller, fw_device->domain );
  689          }
  690       }
  691    }
  692    else
  693    {
  694       //Tell driver to kick off Discover process. If the domain is already
  695       //in Discovery state, this discovery request will not be carried on.
  696       scif_cb_domain_change_notification(
  697          fw_device->domain->controller, fw_device->domain );
  698    }
  699 }
  700 
  701 #if !defined(DISABLE_WIDE_PORTED_TARGETS)
  702 SCI_STATUS scif_sas_remote_device_update_port_width(
  703    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
  704    U8                         new_port_width
  705 )
  706 {
  707    SCIF_LOG_INFO((
  708       sci_base_object_get_logger(fw_device),
  709       SCIF_LOG_OBJECT_REMOTE_DEVICE,
  710       "scif_sas_remote_device_update_port_width (0x%x, 0x%x) enter\n",
  711       fw_device, new_port_width
  712    ));
  713 
  714    fw_device->device_port_width = new_port_width;
  715 
  716    //Don't Start a new update of port width if a device is already in
  717    //UPDATING PORT WIDTH state.
  718    if (fw_device->parent.state_machine.current_state_id == SCI_BASE_REMOTE_DEVICE_STATE_READY)
  719    {
  720       if (fw_device->device_port_width != 0)
  721       {
  722          //Change state to UPDATING_PORT_WIDTH
  723          sci_base_state_machine_change_state(
  724             &fw_device->parent.state_machine,
  725             SCI_BASE_REMOTE_DEVICE_STATE_UPDATING_PORT_WIDTH
  726          );
  727       }
  728 
  729       return SCI_SUCCESS;
  730    }
  731    else if (fw_device->parent.state_machine.current_state_id ==
  732                SCI_BASE_REMOTE_DEVICE_STATE_STARTING)
  733    {
  734       fw_device->destination_state =
  735          SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_UPDATING_PORT_WIDTH;
  736    }
  737 
  738    return SCI_FAILURE_INVALID_STATE;
  739 }
  740 #endif //#if !defined(DISABLE_WIDE_PORTED_TARGETS)
  741 
  742 
  743 #ifdef SCI_LOGGING
  744 void scif_sas_remote_device_initialize_state_logging(
  745    SCIF_SAS_REMOTE_DEVICE_T * remote_device
  746 )
  747 {
  748    sci_base_state_machine_logger_initialize(
  749       &remote_device->parent.state_machine_logger,
  750       &remote_device->parent.state_machine,
  751       &remote_device->parent.parent,
  752       scif_cb_logger_log_states,
  753       "SCIF_SAS_REMOTE_DEVICE_T", "base_state_machine",
  754       SCIF_LOG_OBJECT_REMOTE_DEVICE
  755    );
  756 
  757    sci_base_state_machine_logger_initialize(
  758       &remote_device->starting_substate_machine_logger,
  759       &remote_device->starting_substate_machine,
  760       &remote_device->parent.parent,
  761       scif_cb_logger_log_states,
  762       "SCIF_SAS_REMOTE_DEVICE_T", "starting substate machine",
  763       SCIF_LOG_OBJECT_REMOTE_DEVICE
  764    );
  765 
  766    sci_base_state_machine_logger_initialize(
  767       &remote_device->ready_substate_machine_logger,
  768       &remote_device->ready_substate_machine,
  769       &remote_device->parent.parent,
  770       scif_cb_logger_log_states,
  771       "SCIF_SAS_REMOTE_DEVICE_T", "ready substate machine",
  772       SCIF_LOG_OBJECT_REMOTE_DEVICE
  773    );
  774 }
  775 
  776 void scif_sas_remote_device_deinitialize_state_logging(
  777    SCIF_SAS_REMOTE_DEVICE_T * remote_device
  778 )
  779 {
  780    sci_base_state_machine_logger_deinitialize(
  781       &remote_device->parent.state_machine_logger,
  782       &remote_device->parent.state_machine
  783    );
  784 
  785    sci_base_state_machine_logger_deinitialize(
  786       &remote_device->starting_substate_machine_logger,
  787       &remote_device->starting_substate_machine
  788    );
  789 
  790    sci_base_state_machine_logger_deinitialize(
  791       &remote_device->ready_substate_machine_logger,
  792       &remote_device->ready_substate_machine
  793    );
  794 }
  795 #endif // SCI_LOGGING
  796 

Cache object: adedeea4dd092fcddc68a6c1173eecbf


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