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_domain.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  * BSD LICENSE
    3  *
    4  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  *
   11  *   * Redistributions of source code must retain the above copyright
   12  *     notice, this list of conditions and the following disclaimer.
   13  *   * Redistributions in binary form must reproduce the above copyright
   14  *     notice, this list of conditions and the following disclaimer in
   15  *     the documentation and/or other materials provided with the
   16  *     distribution.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD: releng/8.4/sys/dev/isci/isci_domain.c 233785 2012-04-02 16:31:53Z jimharris $");
   33 
   34 #include <dev/isci/isci.h>
   35 
   36 #include <cam/cam_periph.h>
   37 #include <cam/cam_xpt_periph.h>
   38 
   39 #include <dev/isci/scil/scif_domain.h>
   40 #include <dev/isci/scil/scif_remote_device.h>
   41 #include <dev/isci/scil/scif_controller.h>
   42 #include <dev/isci/scil/scif_user_callback.h>
   43 
   44 /**
   45  * @brief This callback method informs the framework user that something
   46  *        in the supplied domain has changed (e.g. a device was added or
   47  *        removed).
   48  *
   49  * This callback is called by the framework outside of discovery or
   50  * target reset processes.  Specifically, domain changes occurring
   51  * during these processes are handled by the framework.  For example,
   52  * in the case of Serial Attached SCSI, reception of a BROADCAST (CHANGE)
   53  * during discovery will cause discovery to restart.  Thus, discovery
   54  * does not complete until all BCNs are processed. Note, during controller
   55  * stopping/reset process, the framework user should not expect this call
   56  * back.
   57  *
   58  * @param[in]  controller This parameter specifies the controller object
   59  *             with which this callback is associated.
   60  * @param[in]  domain This parameter specifies the domain object with
   61  *             which this callback is associated.
   62  *
   63  * @return none
   64  */
   65 void
   66 scif_cb_domain_change_notification(SCI_CONTROLLER_HANDLE_T controller,
   67     SCI_DOMAIN_HANDLE_T domain)
   68 {
   69         struct ISCI_CONTROLLER *isci_controller =
   70             (struct ISCI_CONTROLLER *)sci_object_get_association(controller);
   71 
   72         /* When the controller start is complete, we will explicitly discover
   73          *  all of the domains then.  This is because SCIF will not allow
   74          *  any I/O to start until the controller is ready, meaning internal SMP
   75          *  requests triggered by domain discovery won't work until the controller
   76          *  is ready.
   77          */
   78         if (isci_controller->is_started == TRUE)
   79             scif_domain_discover(domain,
   80                 scif_domain_get_suggested_discover_timeout(domain),
   81                 DEVICE_TIMEOUT);
   82 }
   83 
   84 /**
   85  * @brief This callback method informs the framework user that a previously
   86  *        requested discovery operation on the domain has completed.
   87  *
   88  * @param[in]  controller This parameter specifies the controller object
   89  *             with which this callback is associated.
   90  * @param[in]  domain This parameter specifies the domain object with
   91  *             which this callback is associated.
   92  * @param[in]  completion_status This parameter indicates the results of the
   93  *             discovery operation.
   94  *
   95  * @return none
   96  */
   97 void
   98 scif_cb_domain_discovery_complete(SCI_CONTROLLER_HANDLE_T controller,
   99     SCI_DOMAIN_HANDLE_T domain, SCI_STATUS completion_status)
  100 {
  101 
  102         if(completion_status != SCI_SUCCESS)
  103                 isci_log_message(0, "ISCI",
  104                     "scif_cb_domain_discovery_complete status = 0x%x\n",
  105                     completion_status);
  106 
  107         isci_controller_domain_discovery_complete(
  108             (struct ISCI_CONTROLLER *)sci_object_get_association(controller),
  109             (struct ISCI_DOMAIN *) sci_object_get_association(domain));
  110 }
  111 
  112 /**
  113  * @brief This callback method informs the framework user that a previously
  114  *        requested reset operation on the domain has completed.
  115  *
  116  * @param[in]  controller This parameter specifies the controller object
  117  *             with which this callback is associated.
  118  * @param[in]  domain This parameter specifies the domain object with
  119  *             which this callback is associated.
  120  * @param[in]  completion_status This parameter indicates the results of the
  121  *             reset operation.
  122  *
  123  * @return none
  124  */
  125 void
  126 scif_cb_domain_reset_complete(SCI_CONTROLLER_HANDLE_T controller,
  127     SCI_DOMAIN_HANDLE_T domain, SCI_STATUS completion_status)
  128 {
  129 
  130 }
  131 
  132 /**
  133  * @brief This callback method informs the framework user that the domain
  134  *        is ready and capable of processing IO requests for devices found
  135  *        inside it.
  136  *
  137  * @param[in]  controller This parameter specifies the controller object
  138  *             with which this callback is associated.
  139  * @param[in]  domain This parameter specifies the domain object with
  140  *             which this callback is associated.
  141  *
  142  * @return none
  143  */
  144 void
  145 scif_cb_domain_ready(SCI_CONTROLLER_HANDLE_T controller,
  146     SCI_DOMAIN_HANDLE_T domain)
  147 {
  148         uint32_t i;
  149         struct ISCI_DOMAIN *isci_domain = sci_object_get_association(domain);
  150         struct ISCI_CONTROLLER *isci_controller =
  151             sci_object_get_association(controller);
  152 
  153         for (i = 0; i < SCI_MAX_REMOTE_DEVICES; i++) {
  154                 struct ISCI_REMOTE_DEVICE *remote_device =
  155                     isci_controller->remote_device[i];
  156 
  157                 if (remote_device != NULL &&
  158                     remote_device->domain == isci_domain)
  159                         isci_remote_device_release_device_queue(remote_device);
  160         }
  161 }
  162 
  163 /**
  164  * @brief This callback method informs the framework user that the domain
  165  *        is no longer ready. Thus, it is incapable of processing IO
  166  *        requests for devices found inside it.
  167  *
  168  * @param[in]  controller This parameter specifies the controller object
  169  *             with which this callback is associated.
  170  * @param[in]  domain This parameter specifies the domain object with
  171  *             which this callback is associated.
  172  *
  173  * @return none
  174  */
  175 void
  176 scif_cb_domain_not_ready(SCI_CONTROLLER_HANDLE_T controller,
  177     SCI_DOMAIN_HANDLE_T domain)
  178 {
  179 
  180 }
  181 
  182 /**
  183  * @brief This callback method informs the framework user that a new
  184  *        direct attached device was found in the domain.
  185  *
  186  * @param[in]  controller This parameter specifies the controller object
  187  *             with which this callback is associated.
  188  * @param[in]  domain This parameter specifies the domain object with
  189  *             which this callback is associated.
  190  * @param[in]  sas_address This parameter specifies the SAS address of
  191  *             the new device.
  192  * @param[in]  protocols This parameter specifies the protocols
  193  *             supported by the newly discovered device.
  194  *
  195  * @return none
  196  */
  197 void
  198 scif_cb_domain_da_device_added(SCI_CONTROLLER_HANDLE_T controller,
  199     SCI_DOMAIN_HANDLE_T domain, SCI_SAS_ADDRESS_T *sas_address,
  200     SCI_SAS_IDENTIFY_ADDRESS_FRAME_PROTOCOLS_T *protocols)
  201 {
  202         struct ISCI_REMOTE_DEVICE *remote_device;
  203         struct ISCI_DOMAIN *isci_domain =
  204             (struct ISCI_DOMAIN *)sci_object_get_association(domain);
  205 
  206         /*
  207          * For direct-attached devices, do not pull the device object from
  208          *  the pool.  Rather, use the one stored in the domain object which
  209          *  will ensure that we always get consistent target ids for direct
  210          *  attached devices.
  211          */
  212         remote_device = isci_domain->da_remote_device;
  213 
  214         scif_remote_device_construct(domain,
  215             (uint8_t*)remote_device + sizeof(struct ISCI_REMOTE_DEVICE),
  216             &(remote_device->sci_object));
  217 
  218         sci_object_set_association(remote_device->sci_object, remote_device);
  219 
  220         scif_remote_device_da_construct(remote_device->sci_object, sas_address,
  221             protocols);
  222 
  223         /* We do not put the device in the ISCI_CONTROLLER's device array yet.
  224          *  That will happen once the device becomes ready (see
  225          *  scif_cb_remote_device_ready).
  226          */
  227 
  228         remote_device->domain = isci_domain;
  229 }
  230 
  231 /**
  232  * @brief This callback method informs the framework user that a new
  233  *        expander attached device was found in the domain.
  234  *
  235  * @param[in]  controller This parameter specifies the controller object
  236  *             with which this callback is associated.
  237  * @param[in]  domain This parameter specifies the domain object with
  238  *             which this callback is associated.
  239  * @param[in]  containing_device This parameter specifies the remote
  240  *             device that contains the device that was added.
  241  * @param[in]  smp_response This parameter specifies the SMP response
  242  *             data associated with the newly discovered device.
  243  *
  244  * @return none
  245  */
  246 void
  247 scif_cb_domain_ea_device_added(SCI_CONTROLLER_HANDLE_T controller,
  248     SCI_DOMAIN_HANDLE_T domain, SCI_REMOTE_DEVICE_HANDLE_T containing_device,
  249     SMP_RESPONSE_DISCOVER_T *smp_response)
  250 {
  251         struct ISCI_REMOTE_DEVICE *remote_device;
  252         struct ISCI_DOMAIN *isci_domain =
  253                 (struct ISCI_DOMAIN *)sci_object_get_association(domain);
  254         struct ISCI_CONTROLLER *isci_controller =
  255                 (struct ISCI_CONTROLLER *)sci_object_get_association(controller);
  256 
  257         sci_pool_get(isci_controller->remote_device_pool, remote_device);
  258 
  259         scif_remote_device_construct( domain,
  260             (uint8_t*)remote_device + sizeof(struct ISCI_REMOTE_DEVICE),
  261             &(remote_device->sci_object));
  262 
  263         sci_object_set_association(remote_device->sci_object, remote_device);
  264 
  265         scif_remote_device_ea_construct(remote_device->sci_object,
  266             containing_device, smp_response);
  267 
  268         /* We do not put the device in the ISCI_CONTROLLER's device array yet.
  269          *  That will happen once the device becomes ready (see
  270          *  scif_cb_remote_device_ready).
  271          */
  272         remote_device->domain = isci_domain;
  273 }
  274 
  275 /**
  276  * @brief This callback method informs the framework user that a device
  277  *        has been removed from the domain.
  278  *
  279  * @param[in]  controller This parameter specifies the controller object
  280  *             with which this callback is associated.
  281  * @param[in]  domain This parameter specifies the domain object with
  282  *             which this callback is associated.
  283  * @param[in]  remote_device This parameter specifies the device object with
  284  *             which this callback is associated.
  285  *
  286  * @return none
  287  */
  288 void
  289 scif_cb_domain_device_removed(SCI_CONTROLLER_HANDLE_T controller,
  290     SCI_DOMAIN_HANDLE_T domain, SCI_REMOTE_DEVICE_HANDLE_T remote_device)
  291 {
  292         struct ISCI_REMOTE_DEVICE *isci_remote_device =
  293             (struct ISCI_REMOTE_DEVICE *)sci_object_get_association(remote_device);
  294         struct ISCI_DOMAIN *isci_domain =
  295             (struct ISCI_DOMAIN *)sci_object_get_association(domain);
  296         struct ISCI_CONTROLLER *isci_controller =
  297             (struct ISCI_CONTROLLER *)sci_object_get_association(controller);
  298         uint32_t path = cam_sim_path(isci_controller->sim);
  299         union ccb *ccb = xpt_alloc_ccb_nowait();
  300 
  301         isci_controller->remote_device[isci_remote_device->index] = NULL;
  302 
  303         xpt_create_path(&ccb->ccb_h.path, xpt_periph, path,
  304             isci_remote_device->index, CAM_LUN_WILDCARD);
  305 
  306         xpt_rescan(ccb);
  307 
  308         scif_remote_device_destruct(remote_device);
  309 
  310         /*
  311          * Only put the remote device back into the pool if it was an
  312          *  expander-attached device.
  313          */
  314         if (isci_remote_device != isci_domain->da_remote_device)
  315                 sci_pool_put(isci_controller->remote_device_pool,
  316                     isci_remote_device);
  317 }
  318 
  319 void
  320 isci_domain_construct(struct ISCI_DOMAIN *domain, uint32_t domain_index,
  321     struct ISCI_CONTROLLER *controller)
  322 {
  323 
  324         scif_controller_get_domain_handle( controller->scif_controller_handle,
  325             domain_index, &domain->sci_object);
  326 
  327         domain->index = domain_index;
  328         domain->controller = controller;
  329         sci_object_set_association(domain->sci_object, (void *)domain);
  330 }

Cache object: d23f8016205d94e7ee91d0426f50a6f7


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