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-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

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

Cache object: c55e5aea1c9b9a02c1f25c799d7dff3c


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