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_task_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 /**
   59  * @file
   60  *
   61  * @brief This file contains the task management request object
   62  *        (SCIF_SAS_TASK_REQUEST) method implementations.
   63  */
   64 
   65 
   66 #include <dev/isci/scil/intel_sas.h>
   67 
   68 #include <dev/isci/scil/scic_task_request.h>
   69 #include <dev/isci/scil/scic_remote_device.h>
   70 #include <dev/isci/scil/scic_user_callback.h>
   71 #include <dev/isci/scil/scic_controller.h>
   72 #include <dev/isci/scil/scif_user_callback.h>
   73 
   74 #include <dev/isci/scil/scif_sas_request.h>
   75 #include <dev/isci/scil/scif_sas_task_request.h>
   76 #include <dev/isci/scil/scif_sas_stp_task_request.h>
   77 #include <dev/isci/scil/scif_sas_logger.h>
   78 #include <dev/isci/scil/scif_sas_controller.h>
   79 #include <dev/isci/scil/scif_sas_domain.h>
   80 #include <dev/isci/scil/scif_sas_remote_device.h>
   81 #include <dev/isci/scil/scif_sas_smp_io_request.h>
   82 
   83 //******************************************************************************
   84 //* P U B L I C   M E T H O D S
   85 //******************************************************************************
   86 
   87 U32 scif_task_request_get_object_size(
   88    void
   89 )
   90 {
   91    return (sizeof(SCIF_SAS_TASK_REQUEST_T) + scic_task_request_get_object_size());
   92 }
   93 
   94 // ---------------------------------------------------------------------------
   95 
   96 U8 scif_sas_task_request_get_function(
   97    SCIF_SAS_TASK_REQUEST_T *fw_task
   98 )
   99 {
  100    return fw_task->function;
  101 }
  102 
  103 // ---------------------------------------------------------------------------
  104 
  105 static
  106 SCI_STATUS scif_sas_task_request_generic_construct(
  107    SCI_CONTROLLER_HANDLE_T      scif_controller,
  108    SCI_REMOTE_DEVICE_HANDLE_T   scif_remote_device,
  109    U16                          io_tag,
  110    void                       * user_task_request_object,
  111    void                       * task_request_memory,
  112    SCI_TASK_REQUEST_HANDLE_T  * scif_task_request,
  113    U8                           task_function
  114 )
  115 {
  116    SCI_STATUS                 status;
  117    SCIF_SAS_CONTROLLER_T    * fw_controller   = (SCIF_SAS_CONTROLLER_T*)
  118                                                 scif_controller;
  119    SCIF_SAS_TASK_REQUEST_T  * fw_task         = (SCIF_SAS_TASK_REQUEST_T*)
  120                                                 task_request_memory;
  121    SCIF_SAS_REMOTE_DEVICE_T * fw_device       = (SCIF_SAS_REMOTE_DEVICE_T*)
  122                                                 scif_remote_device;
  123    U8                       * core_request_memory;
  124 
  125    SCIF_LOG_TRACE((
  126       sci_base_object_get_logger(fw_controller),
  127       SCIF_LOG_OBJECT_TASK_MANAGEMENT,
  128       "scif_task_request_construct(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) enter\n",
  129       scif_controller, scif_remote_device, io_tag, user_task_request_object,
  130       task_request_memory, scif_task_request
  131    ));
  132 
  133    // Initialize the user's handle to the framework task request.
  134    *scif_task_request = fw_task;
  135 
  136    // initialize affected request count
  137    fw_task->affected_request_count = 0;
  138    fw_task->io_tag_to_manage = SCI_CONTROLLER_INVALID_IO_TAG;
  139    fw_task->function = task_function;
  140 
  141    if (task_function == SCI_SAS_HARD_RESET )
  142    {
  143       if (fw_device->containing_device != NULL )
  144       {// Target Reset is for an expander attached device,
  145        // go down to construct smp Phy Control request.
  146          scif_sas_smp_request_construct_phy_control(
  147             fw_controller,
  148             fw_device->containing_device,
  149             PHY_OPERATION_HARD_RESET,
  150             fw_device->expander_phy_identifier,
  151             user_task_request_object,
  152             task_request_memory
  153          );
  154       }
  155       else
  156       {
  157          scif_sas_request_construct(
  158             &fw_task->parent,
  159             fw_device,
  160             sci_base_object_get_logger(fw_controller),
  161             scif_sas_task_request_state_table
  162          );
  163 
  164          // If target reset is for a DA device, don't build task at all.
  165          // Just set object association.
  166          sci_object_set_association(fw_task, user_task_request_object);
  167       }
  168 
  169       return SCI_SUCCESS;
  170    }
  171 
  172    // Construct the parent object first in order to ensure logging can
  173    // function.
  174    scif_sas_request_construct(
  175       &fw_task->parent,
  176       fw_device,
  177       sci_base_object_get_logger(fw_controller),
  178       scif_sas_task_request_state_table
  179    );
  180 
  181    core_request_memory = (U8 *)task_request_memory + sizeof(SCIF_SAS_TASK_REQUEST_T);
  182 
  183    status = scic_task_request_construct(
  184                fw_controller->core_object,
  185                fw_device->core_object,
  186                io_tag,
  187                fw_task,
  188                core_request_memory,
  189                &fw_task->parent.core_object
  190             );
  191 
  192    if (status == SCI_SUCCESS)
  193    {
  194       SMP_DISCOVER_RESPONSE_PROTOCOLS_T  dev_protocols;
  195 
  196       // These associations must be set early for the core io request
  197       // object construction to complete correctly as there will be
  198       // callbacks into the user driver framework during core construction
  199       sci_object_set_association(fw_task, user_task_request_object);
  200       sci_object_set_association(fw_task->parent.core_object, fw_task);
  201 
  202       // Perform protocol specific core IO request construction.
  203       scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols);
  204       if (dev_protocols.u.bits.attached_ssp_target)
  205          status = scic_task_request_construct_ssp(fw_task->parent.core_object);
  206       else if (dev_protocols.u.bits.attached_stp_target)
  207          status = scif_sas_stp_task_request_construct(fw_task);
  208       else
  209          status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
  210 
  211       if (status == SCI_SUCCESS)
  212       {
  213          sci_base_state_machine_logger_initialize(
  214             &fw_task->parent.parent.state_machine_logger,
  215             &fw_task->parent.parent.state_machine,
  216             &fw_task->parent.parent.parent,
  217             scif_cb_logger_log_states,
  218             "SCIF_SAS_TASK_REQUEST_T", "base_state_machine",
  219             SCIF_LOG_OBJECT_TASK_MANAGEMENT
  220          );
  221       }
  222       else
  223       {
  224          SCIF_LOG_WARNING((
  225             sci_base_object_get_logger(fw_task),
  226             SCIF_LOG_OBJECT_TASK_MANAGEMENT,
  227             "Device:0x%x TaskRequest:0x%x Function:0x%x construct failed\n",
  228             fw_device, fw_task, scif_sas_task_request_get_function(fw_task)
  229          ));
  230       }
  231    }
  232 
  233    return status;
  234 }
  235 
  236 // ---------------------------------------------------------------------------
  237 
  238 SCI_STATUS scif_sas_internal_task_request_construct(
  239    SCI_CONTROLLER_HANDLE_T      scif_controller,
  240    SCI_REMOTE_DEVICE_HANDLE_T   scif_remote_device,
  241    U16                          io_tag,
  242    void                       * task_request_memory,
  243    SCI_TASK_REQUEST_HANDLE_T  * scif_task_request,
  244    U8                           task_function
  245 )
  246 {
  247    SCI_STATUS                 status;
  248    SCIF_SAS_TASK_REQUEST_T *  fw_task;
  249 
  250    status = scif_sas_task_request_generic_construct(
  251                scif_controller,
  252                scif_remote_device,
  253                io_tag,
  254                NULL,
  255                task_request_memory,
  256                scif_task_request,
  257                task_function
  258             );
  259 
  260    fw_task = (SCIF_SAS_TASK_REQUEST_T *)task_request_memory;
  261 
  262    fw_task->parent.is_internal = TRUE;
  263 
  264    return status;
  265 }
  266 
  267 // ---------------------------------------------------------------------------
  268 
  269 SCI_STATUS scif_task_request_construct(
  270    SCI_CONTROLLER_HANDLE_T      scif_controller,
  271    SCI_REMOTE_DEVICE_HANDLE_T   scif_remote_device,
  272    U16                          io_tag,
  273    void                       * user_task_request_object,
  274    void                       * task_request_memory,
  275    SCI_TASK_REQUEST_HANDLE_T  * scif_task_request
  276 )
  277 {
  278    SCI_STATUS  status;
  279    U8          task_function =
  280                 scif_cb_task_request_get_function(user_task_request_object);
  281 
  282    status = scif_sas_task_request_generic_construct(
  283                scif_controller,
  284                scif_remote_device,
  285                io_tag,
  286                user_task_request_object,
  287                task_request_memory,
  288                scif_task_request,
  289                task_function
  290             );
  291 
  292    return status;
  293 }
  294 
  295 // ---------------------------------------------------------------------------
  296 
  297 void scif_sas_internal_task_request_destruct(
  298    SCIF_SAS_TASK_REQUEST_T * fw_internal_task
  299 )
  300 {
  301    SCIF_SAS_CONTROLLER_T * fw_controller =
  302       fw_internal_task->parent.device->domain->controller;
  303    scif_sas_controller_free_internal_request(fw_controller, fw_internal_task);
  304 }
  305 
  306 // ---------------------------------------------------------------------------
  307 
  308 void scic_cb_task_request_complete(
  309    SCI_CONTROLLER_HANDLE_T     controller,
  310    SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
  311    SCI_TASK_REQUEST_HANDLE_T   task_request,
  312    SCI_TASK_STATUS             completion_status
  313 )
  314 {
  315    SCIF_SAS_CONTROLLER_T    * fw_controller = (SCIF_SAS_CONTROLLER_T*)
  316                                          sci_object_get_association(controller);
  317    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
  318                                       sci_object_get_association(remote_device);
  319    SCIF_SAS_TASK_REQUEST_T  * fw_task = (SCIF_SAS_TASK_REQUEST_T*)
  320                                        sci_object_get_association(task_request);
  321    SCI_STATUS                 status;
  322 
  323    SCIF_LOG_TRACE((
  324       sci_base_object_get_logger(fw_controller),
  325       SCIF_LOG_OBJECT_TASK_MANAGEMENT,
  326       "scic_cb_task_request_complete(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
  327       controller, remote_device, task_request, completion_status
  328    ));
  329 
  330    status = fw_task->parent.state_handlers->complete_handler(
  331                &fw_task->parent.parent
  332             );
  333 
  334    if (status == SCI_SUCCESS)
  335    {
  336       if (fw_task->parent.protocol_complete_handler != NULL)
  337       {
  338          status = fw_task->parent.protocol_complete_handler(
  339             fw_controller, fw_device, &fw_task->parent, (SCI_STATUS *)&completion_status
  340          );
  341       }
  342 
  343       if (status == SCI_SUCCESS)
  344       {
  345          SCIF_LOG_WARNING((
  346             sci_base_object_get_logger(fw_task),
  347             SCIF_LOG_OBJECT_TASK_MANAGEMENT,
  348             "RemoteDevice:0x%x TaskRequest:0x%x Function:0x%x CompletionStatus:0x%x "
  349             "completed\n",
  350             fw_device, fw_task,
  351             scif_sas_task_request_get_function(fw_task),
  352             completion_status
  353          ));
  354 
  355          // If this isn't an internal framework IO request, then simply pass the
  356          // notification up to the SCIF user.  Otherwise, immediately complete the
  357          // task since there is no SCIF user to notify.
  358          if (fw_task->parent.is_internal == FALSE)
  359          {
  360             scif_cb_task_request_complete(
  361                fw_controller, fw_device, fw_task, completion_status
  362             );
  363          }
  364          else
  365          {
  366             scif_controller_complete_task(
  367                fw_controller,
  368                fw_device,
  369                fw_task
  370             );
  371          }
  372       }
  373    }
  374 }
  375 
  376 // ---------------------------------------------------------------------------
  377 
  378 U32 scic_cb_ssp_task_request_get_lun(
  379    void * scic_user_task_request
  380 )
  381 {
  382    SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T*)
  383                                        scic_user_task_request;
  384 
  385    fw_task->parent.lun = scif_cb_task_request_get_lun(
  386                             fw_task->parent.parent.parent.associated_object
  387                          );
  388 
  389    return fw_task->parent.lun;
  390 }
  391 
  392 // ---------------------------------------------------------------------------
  393 
  394 U8 scic_cb_ssp_task_request_get_function(
  395    void * scic_user_task_request
  396 )
  397 {
  398    SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T*)
  399                                        scic_user_task_request;
  400 
  401    return scif_sas_task_request_get_function(fw_task);
  402 }
  403 
  404 // ---------------------------------------------------------------------------
  405 
  406 U16 scic_cb_ssp_task_request_get_io_tag_to_manage(
  407    void * scic_user_task_request
  408 )
  409 {
  410    SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T*)
  411                                        scic_user_task_request;
  412 
  413    fw_task->io_tag_to_manage
  414       = scif_cb_task_request_get_io_tag_to_manage(
  415            fw_task->parent.parent.parent.associated_object
  416         );
  417 
  418    return fw_task->io_tag_to_manage;
  419 }
  420 
  421 // ---------------------------------------------------------------------------
  422 
  423 void * scic_cb_ssp_task_request_get_response_data_address(
  424    void * scic_user_task_request
  425 )
  426 {
  427    SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T*)
  428                                        scic_user_task_request;
  429 
  430    return scif_cb_task_request_get_response_data_address(
  431                 fw_task->parent.parent.parent.associated_object
  432           );
  433 }
  434 
  435 // ---------------------------------------------------------------------------
  436 
  437 U32 scic_cb_ssp_task_request_get_response_data_length(
  438    void * scic_user_task_request
  439 )
  440 {
  441    SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T*)
  442                                        scic_user_task_request;
  443 
  444    return scif_cb_task_request_get_response_data_length(
  445              fw_task->parent.parent.parent.associated_object
  446           );
  447 }
  448 
  449 //******************************************************************************
  450 //* P R O T E C T E D   M E T H O D S
  451 //******************************************************************************
  452 
  453 /**
  454  * @brief This method performs functionality required after a task management
  455  *        operation (either a task management request or a silicon task
  456  *        termination) has finished.
  457  *
  458  * @param[in]  fw_task This parameter specifies the request that has
  459  *             the operation completing.
  460  *
  461  * @return none
  462  */
  463 void scif_sas_task_request_operation_complete(
  464    SCIF_SAS_TASK_REQUEST_T * fw_task
  465 )
  466 {
  467    SCIF_LOG_TRACE((
  468       sci_base_object_get_logger(fw_task),
  469       SCIF_LOG_OBJECT_TASK_MANAGEMENT,
  470       "scif_sas_task_request_operation_complete(0x%x) enter\n",
  471       fw_task
  472    ));
  473 
  474    fw_task->affected_request_count--;
  475 
  476    SCIF_LOG_INFO((
  477       sci_base_object_get_logger(fw_task),
  478       SCIF_LOG_OBJECT_TASK_MANAGEMENT,
  479       "TaskRequest:0x%x current affected request count:0x%x\n",
  480       fw_task, fw_task->affected_request_count
  481    ));
  482 }
  483 

Cache object: 285084a4b1041247d7157bac631b805a


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