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/isci_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
    3  *
    4  * BSD LICENSE
    5  *
    6  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  *
   13  *   * Redistributions of source code must retain the above copyright
   14  *     notice, this list of conditions and the following disclaimer.
   15  *   * Redistributions in binary form must reproduce the above copyright
   16  *     notice, this list of conditions and the following disclaimer in
   17  *     the documentation and/or other materials provided with the
   18  *     distribution.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD$");
   35 
   36 #include <dev/isci/isci.h>
   37 
   38 #include <dev/isci/scil/scif_controller.h>
   39 #include <dev/isci/scil/scif_user_callback.h>
   40 
   41 /**
   42  * @brief This user callback will inform the user that a task management
   43  *        request completed.
   44  *
   45  * @param[in]  controller This parameter specifies the controller on
   46  *             which the task management request is completing.
   47  * @param[in]  remote_device This parameter specifies the remote device on
   48  *             which this task management request is completing.
   49  * @param[in]  task_request This parameter specifies the task management
   50  *             request that has completed.
   51  * @param[in]  completion_status This parameter specifies the results of
   52  *             the IO request operation.  SCI_TASK_SUCCESS indicates
   53  *             successful completion.
   54  *
   55  * @return none
   56  */
   57 void
   58 scif_cb_task_request_complete(SCI_CONTROLLER_HANDLE_T controller,
   59     SCI_REMOTE_DEVICE_HANDLE_T remote_device,
   60     SCI_TASK_REQUEST_HANDLE_T task_request, SCI_TASK_STATUS completion_status)
   61 {
   62 
   63         scif_controller_complete_task(controller, remote_device, task_request);
   64         isci_task_request_complete(controller, remote_device, task_request,
   65             completion_status);
   66 }
   67 
   68 /**
   69  * @brief This method returns the Logical Unit to be utilized for this
   70  *        task management request.
   71  *
   72  * @note The contents of the value returned from this callback are defined
   73  *       by the protocol standard (e.g. T10 SAS specification).  Please
   74  *       refer to the transport task information unit description
   75  *       in the associated standard.
   76  *
   77  * @param[in] scif_user_task_request This parameter points to the user's
   78  *            task request object.  It is a cookie that allows the user to
   79  *            provide the necessary information for this callback.
   80  *
   81  * @return This method returns the LUN associated with this request.
   82  * @todo This should be U64?
   83  */
   84 uint32_t
   85 scif_cb_task_request_get_lun(void * scif_user_task_request)
   86 {
   87 
   88         /* Currently we are only doing hard resets, not LUN resets.  So
   89          *  always returning 0 is OK here, since LUN doesn't matter for
   90          *  a hard device reset.
   91          */
   92         return (0);
   93 }
   94 
   95 /**
   96  * @brief This method returns the task management function to be utilized
   97  *        for this task request.
   98  *
   99  * @note The contents of the value returned from this callback are defined
  100  *       by the protocol standard (e.g. T10 SAS specification).  Please
  101  *       refer to the transport task information unit description
  102  *       in the associated standard.
  103  *
  104  * @param[in] scif_user_task_request This parameter points to the user's
  105  *            task request object.  It is a cookie that allows the user to
  106  *            provide the necessary information for this callback.
  107  *
  108  * @return This method returns an unsigned byte representing the task
  109  *         management function to be performed.
  110  */
  111 uint8_t scif_cb_task_request_get_function(void * scif_user_task_request)
  112 {
  113         /* SCIL supports many types of task management functions, but this
  114          *  driver only uses HARD_RESET.
  115          */
  116         return (SCI_SAS_HARD_RESET);
  117 }
  118 
  119 /**
  120  * @brief This method returns the task management IO tag to be managed.
  121  *        Depending upon the task management function the value returned
  122  *        from this method may be ignored.
  123  *
  124  * @param[in] scif_user_task_request This parameter points to the user's
  125  *            task request object.  It is a cookie that allows the user to
  126  *            provide the necessary information for this callback.
  127  *
  128  * @return This method returns an unsigned 16-bit word depicting the IO
  129  *         tag to be managed.
  130  */
  131 uint16_t
  132 scif_cb_task_request_get_io_tag_to_manage(void * scif_user_task_request)
  133 {
  134 
  135         return (0);
  136 }
  137 
  138 /**
  139  * @brief This callback method asks the user to provide the virtual
  140  *        address of the response data buffer for the supplied IO request.
  141  *
  142  * @param[in] scif_user_task_request This parameter points to the user's
  143  *            task request object.  It is a cookie that allows the user to
  144  *            provide the necessary information for this callback.
  145  *
  146  * @return This method returns the virtual address for the response data buffer
  147  *         associated with this IO request.
  148  */
  149 void *
  150 scif_cb_task_request_get_response_data_address(void * scif_user_task_request)
  151 {
  152         struct ISCI_TASK_REQUEST *task_request =
  153             (struct ISCI_TASK_REQUEST *)scif_user_task_request;
  154 
  155         return (&task_request->sense_data);
  156 }
  157 
  158 /**
  159  * @brief This callback method asks the user to provide the length of the
  160  *        response data buffer for the supplied IO request.
  161  *
  162  * @param[in] scif_user_task_request This parameter points to the user's
  163  *            task request object.  It is a cookie that allows the user to
  164  *            provide the necessary information for this callback.
  165  *
  166  * @return This method returns the length of the response buffer data
  167  *         associated with this IO request.
  168  */
  169 uint32_t
  170 scif_cb_task_request_get_response_data_length(void * scif_user_task_request)
  171 {
  172 
  173         return (sizeof(struct scsi_sense_data));
  174 }
  175 
  176 void
  177 isci_task_request_complete(SCI_CONTROLLER_HANDLE_T scif_controller,
  178     SCI_REMOTE_DEVICE_HANDLE_T remote_device,
  179     SCI_TASK_REQUEST_HANDLE_T task_request, SCI_TASK_STATUS completion_status)
  180 {
  181         struct ISCI_TASK_REQUEST *isci_task_request =
  182                 (struct ISCI_TASK_REQUEST *)sci_object_get_association(task_request);
  183         struct ISCI_CONTROLLER *isci_controller =
  184                 (struct ISCI_CONTROLLER *)sci_object_get_association(scif_controller);
  185         struct ISCI_REMOTE_DEVICE *isci_remote_device =
  186                 (struct ISCI_REMOTE_DEVICE *)sci_object_get_association(remote_device);
  187         struct ISCI_REMOTE_DEVICE *pending_remote_device;
  188         BOOL retry_task = FALSE;
  189         union ccb *ccb = isci_task_request->ccb;
  190 
  191         isci_remote_device->is_resetting = FALSE;
  192 
  193         switch ((int)completion_status) {
  194         case SCI_TASK_SUCCESS:
  195         case SCI_TASK_FAILURE_RESPONSE_VALID:
  196                 break;
  197 
  198         case SCI_TASK_FAILURE_INVALID_STATE:
  199                 retry_task = TRUE;
  200                 isci_log_message(0, "ISCI",
  201                     "task failure (invalid state) - retrying\n");
  202                 break;
  203 
  204         case SCI_TASK_FAILURE_INSUFFICIENT_RESOURCES:
  205                 retry_task = TRUE;
  206                 isci_log_message(0, "ISCI",
  207                     "task failure (insufficient resources) - retrying\n");
  208                 break;
  209 
  210         case SCI_FAILURE_TIMEOUT:
  211                 if (isci_controller->fail_on_task_timeout) {
  212                         retry_task = FALSE;
  213                         isci_log_message(0, "ISCI",
  214                             "task timeout - not retrying\n");
  215                         scif_cb_domain_device_removed(scif_controller,
  216                             isci_remote_device->domain->sci_object,
  217                             remote_device);
  218                 } else {
  219                         retry_task = TRUE;
  220                         isci_log_message(0, "ISCI",
  221                             "task timeout - retrying\n");
  222                 }
  223                 break;
  224 
  225         case SCI_TASK_FAILURE:
  226         case SCI_TASK_FAILURE_UNSUPPORTED_PROTOCOL:
  227         case SCI_TASK_FAILURE_INVALID_TAG:
  228         case SCI_TASK_FAILURE_CONTROLLER_SPECIFIC_ERR:
  229         case SCI_TASK_FAILURE_TERMINATED:
  230         case SCI_TASK_FAILURE_INVALID_PARAMETER_VALUE:
  231                 isci_log_message(0, "ISCI",
  232                     "unhandled task completion code 0x%x\n", completion_status);
  233                 break;
  234 
  235         default:
  236                 isci_log_message(0, "ISCI",
  237                     "unhandled task completion code 0x%x\n", completion_status);
  238                 break;
  239         }
  240 
  241         if (isci_controller->is_frozen == TRUE) {
  242                 isci_controller->is_frozen = FALSE;
  243                 xpt_release_simq(isci_controller->sim, TRUE);
  244         }
  245 
  246         sci_pool_put(isci_controller->request_pool,
  247             (struct ISCI_REQUEST *)isci_task_request);
  248 
  249         /* Make sure we release the device queue, since it may have been frozen
  250          *  if someone tried to start an I/O while the task was in progress.
  251          */
  252         isci_remote_device_release_device_queue(isci_remote_device);
  253 
  254         if (retry_task == TRUE)
  255                 isci_remote_device_reset(isci_remote_device, ccb);
  256         else {
  257                 pending_remote_device = sci_fast_list_remove_head(
  258                     &isci_controller->pending_device_reset_list);
  259 
  260                 if (pending_remote_device != NULL) {
  261                         /* Any resets that were triggered from an XPT_RESET_DEV
  262                          *  CCB are never put in the pending list if the request
  263                          *  pool is empty - they are given back to CAM to be
  264                          *  requeued.  So we will alawys pass NULL here,
  265                          *  denoting that there is no CCB associated with the
  266                          *  device reset.
  267                          */
  268                         isci_remote_device_reset(pending_remote_device, NULL);
  269                 } else if (ccb != NULL) {
  270                         /* There was a CCB associated with this reset, so mark
  271                          *  it complete and return it to CAM.
  272                          */
  273                         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
  274                         ccb->ccb_h.status |= CAM_REQ_CMP;
  275                         xpt_done(ccb);
  276                 }
  277         }
  278 }
  279 

Cache object: bdf5cfcbdbf6a64a81fe416957f75774


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