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/twa/tw_cl_init.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-FreeBSD
    3  *
    4  * Copyright (c) 2004-07 Applied Micro Circuits Corporation.
    5  * Copyright (c) 2004-05 Vinod Kashyap
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  *      $FreeBSD$
   30  */
   31 
   32 /*
   33  * AMCC'S 3ware driver for 9000 series storage controllers.
   34  *
   35  * Author: Vinod Kashyap
   36  * Modifications by: Adam Radford
   37  * Modifications by: Manjunath Ranganathaiah
   38  */
   39 
   40 /*
   41  * Common Layer initialization functions.
   42  */
   43 
   44 #include "tw_osl_share.h"
   45 #include "tw_cl_share.h"
   46 #include "tw_cl_fwif.h"
   47 #include "tw_cl_ioctl.h"
   48 #include "tw_cl.h"
   49 #include "tw_cl_externs.h"
   50 #include "tw_osl_ioctl.h"
   51 
   52 /*
   53  * Function name:       tw_cl_ctlr_supported
   54  * Description:         Determines if a controller is supported.
   55  *
   56  * Input:               vendor_id -- vendor id of the controller
   57  *                      device_id -- device id of the controller
   58  * Output:              None
   59  * Return value:        TW_CL_TRUE-- controller supported
   60  *                      TW_CL_FALSE-- controller not supported
   61  */
   62 TW_INT32
   63 tw_cl_ctlr_supported(TW_INT32 vendor_id, TW_INT32 device_id)
   64 {
   65         if ((vendor_id == TW_CL_VENDOR_ID) &&
   66                 ((device_id == TW_CL_DEVICE_ID_9K) ||
   67                  (device_id == TW_CL_DEVICE_ID_9K_X) ||
   68                  (device_id == TW_CL_DEVICE_ID_9K_E) ||
   69                  (device_id == TW_CL_DEVICE_ID_9K_SA)))
   70                 return(TW_CL_TRUE);
   71         return(TW_CL_FALSE);
   72 }
   73 
   74 /*
   75  * Function name:       tw_cl_get_pci_bar_info
   76  * Description:         Returns PCI BAR info.
   77  *
   78  * Input:               device_id -- device id of the controller
   79  *                      bar_type -- type of PCI BAR in question
   80  * Output:              bar_num -- PCI BAR number corresponding to bar_type
   81  *                      bar0_offset -- byte offset from BAR 0 (0x10 in
   82  *                                      PCI config space)
   83  *                      bar_size -- size, in bytes, of the BAR in question
   84  * Return value:        0 -- success
   85  *                      non-zero -- failure
   86  */
   87 TW_INT32
   88 tw_cl_get_pci_bar_info(TW_INT32 device_id, TW_INT32 bar_type,
   89         TW_INT32 *bar_num, TW_INT32 *bar0_offset, TW_INT32 *bar_size)
   90 {
   91         TW_INT32        error = TW_OSL_ESUCCESS;
   92 
   93         switch(device_id) {
   94         case TW_CL_DEVICE_ID_9K:
   95                 switch(bar_type) {
   96                 case TW_CL_BAR_TYPE_IO:
   97                         *bar_num = 0;
   98                         *bar0_offset = 0;
   99                         *bar_size = 4;
  100                         break;
  101 
  102                 case TW_CL_BAR_TYPE_MEM:
  103                         *bar_num = 1;
  104                         *bar0_offset = 0x4;
  105                         *bar_size = 8;
  106                         break;
  107 
  108                 case TW_CL_BAR_TYPE_SBUF:
  109                         *bar_num = 2;
  110                         *bar0_offset = 0xC;
  111                         *bar_size = 8;
  112                         break;
  113                 }
  114                 break;
  115 
  116         case TW_CL_DEVICE_ID_9K_X:
  117         case TW_CL_DEVICE_ID_9K_E:
  118         case TW_CL_DEVICE_ID_9K_SA:
  119                 switch(bar_type) {
  120                 case TW_CL_BAR_TYPE_IO:
  121                         *bar_num = 2;
  122                         *bar0_offset = 0x10;
  123                         *bar_size = 4;
  124                         break;
  125 
  126                 case TW_CL_BAR_TYPE_MEM:
  127                         *bar_num = 1;
  128                         *bar0_offset = 0x8;
  129                         *bar_size = 8;
  130                         break;
  131 
  132                 case TW_CL_BAR_TYPE_SBUF:
  133                         *bar_num = 0;
  134                         *bar0_offset = 0;
  135                         *bar_size = 8;
  136                         break;
  137                 }
  138                 break;
  139 
  140         default:
  141                 error = TW_OSL_ENOTTY;
  142                 break;
  143         }
  144 
  145         return(error);
  146 }
  147 
  148 /*
  149  * Function name:       tw_cl_get_mem_requirements
  150  * Description:         Provides info about Common Layer requirements for a
  151  *                      controller, given the controller type (in 'flags').
  152  * Input:               ctlr_handle -- controller handle
  153  *                      flags -- more info passed by the OS Layer
  154  *                      device_id -- device id of the controller
  155  *                      max_simult_reqs -- maximum # of simultaneous
  156  *                                      requests that the OS Layer expects
  157  *                                      the Common Layer to support
  158  *                      max_aens -- maximun # of AEN's needed to be supported
  159  * Output:              alignment -- alignment needed for all DMA'able
  160  *                                      buffers
  161  *                      sg_size_factor -- every SG element should have a size
  162  *                                      that's a multiple of this number
  163  *                      non_dma_mem_size -- # of bytes of memory needed for
  164  *                                      non-DMA purposes
  165  *                      dma_mem_size -- # of bytes of DMA'able memory needed
  166  *                      per_req_dma_mem_size -- # of bytes of DMA'able memory
  167  *                                      needed per request, if applicable
  168  *                      per_req_non_dma_mem_size -- # of bytes of memory needed
  169  *                                      per request for non-DMA purposes,
  170  *                                      if applicable
  171  * Output:              None
  172  * Return value:        0       -- success
  173  *                      non-zero-- failure
  174  */
  175 TW_INT32
  176 tw_cl_get_mem_requirements(struct tw_cl_ctlr_handle *ctlr_handle,
  177         TW_UINT32 flags, TW_INT32 device_id, TW_INT32 max_simult_reqs,
  178         TW_INT32 max_aens, TW_UINT32 *alignment, TW_UINT32 *sg_size_factor,
  179         TW_UINT32 *non_dma_mem_size, TW_UINT32 *dma_mem_size
  180         )
  181 {
  182         if (device_id == 0)
  183                 device_id = TW_CL_DEVICE_ID_9K;
  184 
  185         if (max_simult_reqs > TW_CL_MAX_SIMULTANEOUS_REQUESTS) {
  186                 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
  187                         TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  188                         0x1000, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  189                         "Too many simultaneous requests to support!",
  190                         "requested = %d, supported = %d, error = %d\n",
  191                         max_simult_reqs, TW_CL_MAX_SIMULTANEOUS_REQUESTS,
  192                         TW_OSL_EBIG);
  193                 return(TW_OSL_EBIG);
  194         }
  195 
  196         *alignment = TWA_ALIGNMENT(device_id);
  197         *sg_size_factor = TWA_SG_ELEMENT_SIZE_FACTOR(device_id);
  198 
  199         /*
  200          * Total non-DMA memory needed is the sum total of memory needed for
  201          * the controller context, request packets (including the 1 needed for
  202          * CL internal requests), and event packets.
  203          */
  204 
  205         *non_dma_mem_size = sizeof(struct tw_cli_ctlr_context) +
  206                 (sizeof(struct tw_cli_req_context) * max_simult_reqs) +
  207                 (sizeof(struct tw_cl_event_packet) * max_aens);
  208 
  209         /*
  210          * Total DMA'able memory needed is the sum total of memory needed for
  211          * all command packets (including the 1 needed for CL internal
  212          * requests), and memory needed to hold the payload for internal
  213          * requests.
  214          */
  215 
  216         *dma_mem_size = (sizeof(struct tw_cl_command_packet) *
  217                 (max_simult_reqs)) + (TW_CLI_SECTOR_SIZE);
  218 
  219         return(0);
  220 }
  221 
  222 /*
  223  * Function name:       tw_cl_init_ctlr
  224  * Description:         Initializes driver data structures for the controller.
  225  *
  226  * Input:               ctlr_handle -- controller handle
  227  *                      flags -- more info passed by the OS Layer
  228  *                      device_id -- device id of the controller
  229  *                      max_simult_reqs -- maximum # of simultaneous requests
  230  *                                      that the OS Layer expects the Common
  231  *                                      Layer to support
  232  *                      max_aens -- maximun # of AEN's needed to be supported
  233  *                      non_dma_mem -- ptr to allocated non-DMA memory
  234  *                      dma_mem -- ptr to allocated DMA'able memory
  235  *                      dma_mem_phys -- physical address of dma_mem
  236  * Output:              None
  237  * Return value:        0       -- success
  238  *                      non-zero-- failure
  239  */
  240 TW_INT32
  241 tw_cl_init_ctlr(struct tw_cl_ctlr_handle *ctlr_handle, TW_UINT32 flags,
  242         TW_INT32 device_id, TW_INT32 max_simult_reqs, TW_INT32 max_aens,
  243         TW_VOID *non_dma_mem, TW_VOID *dma_mem, TW_UINT64 dma_mem_phys
  244         )
  245 {
  246         struct tw_cli_ctlr_context      *ctlr;
  247         struct tw_cli_req_context       *req;
  248         TW_UINT8                        *free_non_dma_mem;
  249         TW_INT32                        error = TW_OSL_ESUCCESS;
  250         TW_INT32                        i;
  251 
  252         tw_cli_dbg_printf(3, ctlr_handle, tw_osl_cur_func(), "entered");
  253 
  254         if (flags & TW_CL_START_CTLR_ONLY) {
  255                 ctlr = (struct tw_cli_ctlr_context *)
  256                         (ctlr_handle->cl_ctlr_ctxt);
  257                 goto start_ctlr;
  258         }
  259 
  260         if (max_simult_reqs > TW_CL_MAX_SIMULTANEOUS_REQUESTS) {
  261                 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
  262                         TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  263                         0x1000, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  264                         "Too many simultaneous requests to support!",
  265                         "requested = %d, supported = %d, error = %d\n",
  266                         max_simult_reqs, TW_CL_MAX_SIMULTANEOUS_REQUESTS,
  267                         TW_OSL_EBIG);
  268                 return(TW_OSL_EBIG);
  269         }
  270 
  271         if ((non_dma_mem == TW_CL_NULL) || (dma_mem == TW_CL_NULL)
  272                 ) {
  273                 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
  274                         TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  275                         0x1001, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  276                         "Insufficient memory for Common Layer's internal usage",
  277                         "error = %d\n", TW_OSL_ENOMEM);
  278                 return(TW_OSL_ENOMEM);
  279         }
  280 
  281         tw_osl_memzero(non_dma_mem, sizeof(struct tw_cli_ctlr_context) +
  282                 (sizeof(struct tw_cli_req_context) * max_simult_reqs) +
  283                 (sizeof(struct tw_cl_event_packet) * max_aens));
  284 
  285         tw_osl_memzero(dma_mem,
  286                 (sizeof(struct tw_cl_command_packet) *
  287                 max_simult_reqs) +
  288                 TW_CLI_SECTOR_SIZE);
  289 
  290         free_non_dma_mem = (TW_UINT8 *)non_dma_mem;
  291 
  292         ctlr = (struct tw_cli_ctlr_context *)free_non_dma_mem;
  293         free_non_dma_mem += sizeof(struct tw_cli_ctlr_context);
  294 
  295         ctlr_handle->cl_ctlr_ctxt = ctlr;
  296         ctlr->ctlr_handle = ctlr_handle;
  297 
  298         ctlr->device_id = (TW_UINT32)device_id;
  299         ctlr->arch_id = TWA_ARCH_ID(device_id);
  300         ctlr->flags = flags;
  301         ctlr->sg_size_factor = TWA_SG_ELEMENT_SIZE_FACTOR(device_id);
  302         ctlr->max_simult_reqs = max_simult_reqs;
  303         ctlr->max_aens_supported = max_aens;
  304 
  305         /* Initialize queues of CL internal request context packets. */
  306         tw_cli_req_q_init(ctlr, TW_CLI_FREE_Q);
  307         tw_cli_req_q_init(ctlr, TW_CLI_BUSY_Q);
  308         tw_cli_req_q_init(ctlr, TW_CLI_PENDING_Q);
  309         tw_cli_req_q_init(ctlr, TW_CLI_COMPLETE_Q);
  310         tw_cli_req_q_init(ctlr, TW_CLI_RESET_Q);
  311 
  312         /* Initialize all locks used by CL. */
  313         ctlr->gen_lock = &(ctlr->gen_lock_handle);
  314         tw_osl_init_lock(ctlr_handle, "tw_cl_gen_lock", ctlr->gen_lock);
  315         ctlr->io_lock = &(ctlr->io_lock_handle);
  316         tw_osl_init_lock(ctlr_handle, "tw_cl_io_lock", ctlr->io_lock);
  317 
  318         /* Initialize CL internal request context packets. */
  319         ctlr->req_ctxt_buf = (struct tw_cli_req_context *)free_non_dma_mem;
  320         free_non_dma_mem += (sizeof(struct tw_cli_req_context) *
  321                 max_simult_reqs);
  322 
  323         ctlr->cmd_pkt_buf = (struct tw_cl_command_packet *)dma_mem;
  324         ctlr->cmd_pkt_phys = dma_mem_phys;
  325 
  326         ctlr->internal_req_data = (TW_UINT8 *)
  327                 (ctlr->cmd_pkt_buf +
  328                 max_simult_reqs);
  329         ctlr->internal_req_data_phys = ctlr->cmd_pkt_phys +
  330                 (sizeof(struct tw_cl_command_packet) *
  331                 max_simult_reqs);
  332 
  333         for (i = 0; i < max_simult_reqs; i++) {
  334                 req = &(ctlr->req_ctxt_buf[i]);
  335 
  336                 req->cmd_pkt = &(ctlr->cmd_pkt_buf[i]);
  337                 req->cmd_pkt_phys = ctlr->cmd_pkt_phys +
  338                         (i * sizeof(struct tw_cl_command_packet));
  339 
  340                 req->request_id = i;
  341                 req->ctlr = ctlr;
  342 
  343                 /* Insert request into the free queue. */
  344                 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
  345         }
  346 
  347         /* Initialize the AEN queue. */
  348         ctlr->aen_queue = (struct tw_cl_event_packet *)free_non_dma_mem;
  349 
  350 start_ctlr:
  351         /*
  352          * Disable interrupts.  Interrupts will be enabled in tw_cli_start_ctlr
  353          * (only) if initialization succeeded.
  354          */
  355         tw_cli_disable_interrupts(ctlr);
  356 
  357         /* Initialize the controller. */
  358         if ((error = tw_cli_start_ctlr(ctlr))) {
  359                 /* Soft reset the controller, and try one more time. */
  360                 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
  361                         TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  362                         0x1002, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  363                         "Controller initialization failed. Retrying...",
  364                         "error = %d\n", error);
  365                 if ((error = tw_cli_soft_reset(ctlr))) {
  366                         tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
  367                                 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  368                                 0x1003, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  369                                 "Controller soft reset failed",
  370                                 "error = %d\n", error);
  371                         return(error);
  372                 } else if ((error = tw_cli_start_ctlr(ctlr))) {
  373                         tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
  374                                 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  375                                 0x1004, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  376                                 "Controller initialization retry failed",
  377                                 "error = %d\n", error);
  378                         return(error);
  379                 }
  380         }
  381         /* Notify some info about the controller to the OSL. */
  382         tw_cli_notify_ctlr_info(ctlr);
  383 
  384         /* Mark the controller active. */
  385         ctlr->active = TW_CL_TRUE;
  386         return(error);
  387 }
  388 
  389 /*
  390  * Function name:       tw_cli_start_ctlr
  391  * Description:         Establishes a logical connection with the controller.
  392  *                      Determines whether or not the driver is compatible 
  393  *                      with the firmware on the controller, before proceeding
  394  *                      to work with it.
  395  *
  396  * Input:               ctlr    -- ptr to per ctlr structure
  397  * Output:              None
  398  * Return value:        0       -- success
  399  *                      non-zero-- failure
  400  */
  401 TW_INT32
  402 tw_cli_start_ctlr(struct tw_cli_ctlr_context *ctlr)
  403 {
  404         TW_UINT16       fw_on_ctlr_srl = 0;
  405         TW_UINT16       fw_on_ctlr_arch_id = 0;
  406         TW_UINT16       fw_on_ctlr_branch = 0;
  407         TW_UINT16       fw_on_ctlr_build = 0;
  408         TW_UINT32       init_connect_result = 0;
  409         TW_INT32        error = TW_OSL_ESUCCESS;
  410 
  411         tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
  412 
  413         /* Wait for the controller to become ready. */
  414         if ((error = tw_cli_poll_status(ctlr,
  415                         TWA_STATUS_MICROCONTROLLER_READY,
  416                         TW_CLI_REQUEST_TIMEOUT_PERIOD))) {
  417                 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
  418                         TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  419                         0x1009, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  420                         "Microcontroller not ready",
  421                         "error = %d", error);
  422                 return(error);
  423         }
  424         /* Drain the response queue. */
  425         if ((error = tw_cli_drain_response_queue(ctlr))) {
  426                 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
  427                         TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  428                         0x100A, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  429                         "Can't drain response queue",
  430                         "error = %d", error);
  431                 return(error);
  432         }
  433         /* Establish a logical connection with the controller. */
  434         if ((error = tw_cli_init_connection(ctlr,
  435                         (TW_UINT16)(ctlr->max_simult_reqs),
  436                         TWA_EXTENDED_INIT_CONNECT, TWA_CURRENT_FW_SRL,
  437                         (TW_UINT16)(ctlr->arch_id),
  438                         TWA_CURRENT_FW_BRANCH(ctlr->arch_id),
  439                         TWA_CURRENT_FW_BUILD(ctlr->arch_id),
  440                         &fw_on_ctlr_srl, &fw_on_ctlr_arch_id,
  441                         &fw_on_ctlr_branch, &fw_on_ctlr_build,
  442                         &init_connect_result))) {
  443                 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
  444                         TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  445                         0x100B, 0x2, TW_CL_SEVERITY_WARNING_STRING,
  446                         "Can't initialize connection in current mode",
  447                         "error = %d", error);
  448                 return(error);
  449         }
  450         {
  451                  /* See if we can at least work with the firmware on the
  452                  * controller in the current mode.
  453                  */
  454                 if (init_connect_result & TWA_CTLR_FW_COMPATIBLE) {
  455                         /* Yes, we can.  Make note of the operating mode. */
  456                         if (init_connect_result & TWA_CTLR_FW_SAME_OR_NEWER) {
  457                                 ctlr->working_srl = TWA_CURRENT_FW_SRL;
  458                                 ctlr->working_branch =
  459                                         TWA_CURRENT_FW_BRANCH(ctlr->arch_id);
  460                                 ctlr->working_build =
  461                                         TWA_CURRENT_FW_BUILD(ctlr->arch_id);
  462                         } else {
  463                                 ctlr->working_srl = fw_on_ctlr_srl;
  464                                 ctlr->working_branch = fw_on_ctlr_branch;
  465                                 ctlr->working_build = fw_on_ctlr_build;
  466                         }
  467                 } else {
  468                         /*
  469                          * No, we can't.  See if we can at least work with
  470                          * it in the base mode.
  471                          */
  472                         tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
  473                                 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  474                                 0x1010, 0x2, TW_CL_SEVERITY_WARNING_STRING,
  475                                 "Driver/Firmware mismatch. "
  476                                 "Negotiating for base level...",
  477                                 " ");
  478                         if ((error = tw_cli_init_connection(ctlr,
  479                                         (TW_UINT16)(ctlr->max_simult_reqs),
  480                                         TWA_EXTENDED_INIT_CONNECT,
  481                                         TWA_BASE_FW_SRL,
  482                                         (TW_UINT16)(ctlr->arch_id),
  483                                         TWA_BASE_FW_BRANCH, TWA_BASE_FW_BUILD,
  484                                         &fw_on_ctlr_srl, &fw_on_ctlr_arch_id,
  485                                         &fw_on_ctlr_branch, &fw_on_ctlr_build,
  486                                         &init_connect_result))) {
  487                                 tw_cl_create_event(ctlr->ctlr_handle,
  488                                         TW_CL_FALSE,
  489                                         TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  490                                         0x1011, 0x1,
  491                                         TW_CL_SEVERITY_ERROR_STRING,
  492                                         "Can't initialize connection in "
  493                                         "base mode",
  494                                         " ");
  495                                 return(error);
  496                         }
  497                         if (!(init_connect_result & TWA_CTLR_FW_COMPATIBLE)) {
  498                                 /*
  499                                  * The firmware on the controller is not even
  500                                  * compatible with our base mode.  We cannot
  501                                  * work with it.  Bail...
  502                                  */
  503                                 return(1);
  504                         }
  505                         /*
  506                          * We can work with this firmware, but only in
  507                          * base mode.
  508                          */
  509                         ctlr->working_srl = TWA_BASE_FW_SRL;
  510                         ctlr->working_branch = TWA_BASE_FW_BRANCH;
  511                         ctlr->working_build = TWA_BASE_FW_BUILD;
  512                         ctlr->operating_mode = TWA_BASE_MODE;
  513                 }
  514                 ctlr->fw_on_ctlr_srl = fw_on_ctlr_srl;
  515                 ctlr->fw_on_ctlr_branch = fw_on_ctlr_branch;
  516                 ctlr->fw_on_ctlr_build = fw_on_ctlr_build;
  517         }
  518 
  519         /* Drain the AEN queue */
  520         if ((error = tw_cli_drain_aen_queue(ctlr)))
  521                 /* 
  522                  * We will just print that we couldn't drain the AEN queue.
  523                  * There's no need to bail out.
  524                  */
  525                 tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
  526                         TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  527                         0x1014, 0x2, TW_CL_SEVERITY_WARNING_STRING,
  528                         "Can't drain AEN queue",
  529                         "error = %d", error);
  530 
  531         /* Enable interrupts. */
  532         tw_cli_enable_interrupts(ctlr);
  533 
  534         return(TW_OSL_ESUCCESS);
  535 }
  536 
  537 /*
  538  * Function name:       tw_cl_shutdown_ctlr
  539  * Description:         Closes logical connection with the controller.
  540  *
  541  * Input:               ctlr    -- ptr to per ctlr structure
  542  *                      flags   -- more info passed by the OS Layer
  543  * Output:              None
  544  * Return value:        0       -- success
  545  *                      non-zero-- failure
  546  */
  547 TW_INT32
  548 tw_cl_shutdown_ctlr(struct tw_cl_ctlr_handle *ctlr_handle, TW_UINT32 flags)
  549 {
  550         struct tw_cli_ctlr_context      *ctlr =
  551                 (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
  552         TW_INT32                        error;
  553 
  554         tw_cli_dbg_printf(3, ctlr_handle, tw_osl_cur_func(), "entered");
  555         /*
  556          * Mark the controller as inactive, disable any further interrupts,
  557          * and notify the controller that we are going down.
  558          */
  559         ctlr->active = TW_CL_FALSE;
  560 
  561         tw_cli_disable_interrupts(ctlr);
  562 
  563         /* Let the controller know that we are going down. */
  564         if ((error = tw_cli_init_connection(ctlr, TWA_SHUTDOWN_MESSAGE_CREDITS,
  565                         0, 0, 0, 0, 0, TW_CL_NULL, TW_CL_NULL, TW_CL_NULL,
  566                         TW_CL_NULL, TW_CL_NULL)))
  567                 tw_cl_create_event(ctlr_handle, TW_CL_FALSE,
  568                         TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  569                         0x1015, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  570                         "Can't close connection with controller",
  571                         "error = %d", error);
  572 
  573         if (flags & TW_CL_STOP_CTLR_ONLY)
  574                 goto ret;
  575 
  576         /* Destroy all locks used by CL. */
  577         tw_osl_destroy_lock(ctlr_handle, ctlr->gen_lock);
  578         tw_osl_destroy_lock(ctlr_handle, ctlr->io_lock);
  579 
  580 ret:
  581         return(error);
  582 }
  583 
  584 /*
  585  * Function name:       tw_cli_init_connection
  586  * Description:         Sends init_connection cmd to firmware
  587  *
  588  * Input:               ctlr            -- ptr to per ctlr structure
  589  *                      message_credits -- max # of requests that we might send
  590  *                                       down simultaneously.  This will be
  591  *                                       typically set to 256 at init-time or
  592  *                                      after a reset, and to 1 at shutdown-time
  593  *                      set_features    -- indicates if we intend to use 64-bit
  594  *                                      sg, also indicates if we want to do a
  595  *                                      basic or an extended init_connection;
  596  *
  597  * Note: The following input/output parameters are valid, only in case of an
  598  *              extended init_connection:
  599  *
  600  *                      current_fw_srl          -- srl of fw we are bundled
  601  *                                              with, if any; 0 otherwise
  602  *                      current_fw_arch_id      -- arch_id of fw we are bundled
  603  *                                              with, if any; 0 otherwise
  604  *                      current_fw_branch       -- branch # of fw we are bundled
  605  *                                              with, if any; 0 otherwise
  606  *                      current_fw_build        -- build # of fw we are bundled
  607  *                                              with, if any; 0 otherwise
  608  * Output:              fw_on_ctlr_srl          -- srl of fw on ctlr
  609  *                      fw_on_ctlr_arch_id      -- arch_id of fw on ctlr
  610  *                      fw_on_ctlr_branch       -- branch # of fw on ctlr
  611  *                      fw_on_ctlr_build        -- build # of fw on ctlr
  612  *                      init_connect_result     -- result bitmap of fw response
  613  * Return value:        0       -- success
  614  *                      non-zero-- failure
  615  */
  616 TW_INT32
  617 tw_cli_init_connection(struct tw_cli_ctlr_context *ctlr,
  618         TW_UINT16 message_credits, TW_UINT32 set_features,
  619         TW_UINT16 current_fw_srl, TW_UINT16 current_fw_arch_id,
  620         TW_UINT16 current_fw_branch, TW_UINT16 current_fw_build,
  621         TW_UINT16 *fw_on_ctlr_srl, TW_UINT16 *fw_on_ctlr_arch_id,
  622         TW_UINT16 *fw_on_ctlr_branch, TW_UINT16 *fw_on_ctlr_build,
  623         TW_UINT32 *init_connect_result)
  624 {
  625         struct tw_cli_req_context               *req;
  626         struct tw_cl_command_init_connect       *init_connect;
  627         TW_INT32                                error = TW_OSL_EBUSY;
  628     
  629         tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
  630 
  631         /* Get a request packet. */
  632         if ((req = tw_cli_get_request(ctlr
  633                 )) == TW_CL_NULL)
  634                 goto out;
  635 
  636         req->flags |= TW_CLI_REQ_FLAGS_INTERNAL;
  637 
  638         /* Build the cmd pkt. */
  639         init_connect = &(req->cmd_pkt->command.cmd_pkt_7k.init_connect);
  640 
  641         req->cmd_pkt->cmd_hdr.header_desc.size_header = 128;
  642 
  643         init_connect->res1__opcode =
  644                 BUILD_RES__OPCODE(0, TWA_FW_CMD_INIT_CONNECTION);
  645         init_connect->request_id =
  646                 (TW_UINT8)(TW_CL_SWAP16(req->request_id));
  647         init_connect->message_credits = TW_CL_SWAP16(message_credits);
  648         init_connect->features = TW_CL_SWAP32(set_features);
  649         if (ctlr->flags & TW_CL_64BIT_ADDRESSES)
  650                 init_connect->features |= TW_CL_SWAP32(TWA_64BIT_SG_ADDRESSES);
  651         if (set_features & TWA_EXTENDED_INIT_CONNECT) {
  652                 /*
  653                  * Fill in the extra fields needed for an extended
  654                  * init_connect.
  655                  */
  656                 init_connect->size = 6;
  657                 init_connect->fw_srl = TW_CL_SWAP16(current_fw_srl);
  658                 init_connect->fw_arch_id = TW_CL_SWAP16(current_fw_arch_id);
  659                 init_connect->fw_branch = TW_CL_SWAP16(current_fw_branch);
  660                 init_connect->fw_build = TW_CL_SWAP16(current_fw_build);
  661         } else
  662                 init_connect->size = 3;
  663 
  664         /* Submit the command, and wait for it to complete. */
  665         error = tw_cli_submit_and_poll_request(req,
  666                 TW_CLI_REQUEST_TIMEOUT_PERIOD);
  667         if (error)
  668                 goto out;
  669         if ((error = init_connect->status)) {
  670 #if       0
  671                 tw_cli_create_ctlr_event(ctlr,
  672                         TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
  673                         &(req->cmd_pkt->cmd_hdr));
  674 #endif // 0
  675                 goto out;
  676         }
  677         if (set_features & TWA_EXTENDED_INIT_CONNECT) {
  678                 *fw_on_ctlr_srl = TW_CL_SWAP16(init_connect->fw_srl);
  679                 *fw_on_ctlr_arch_id = TW_CL_SWAP16(init_connect->fw_arch_id);
  680                 *fw_on_ctlr_branch = TW_CL_SWAP16(init_connect->fw_branch);
  681                 *fw_on_ctlr_build = TW_CL_SWAP16(init_connect->fw_build);
  682                 *init_connect_result = TW_CL_SWAP32(init_connect->result);
  683         }
  684         tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
  685         return(error);
  686 
  687 out:
  688         tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
  689                 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  690                 0x1016, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  691                 "init_connection failed",
  692                 "error = %d", error);
  693         if (req)
  694                 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
  695         return(error);
  696 }

Cache object: ece4cd9cb613e2f17f44dd0c0c7d0c2f


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