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

Cache object: 0fb65518180a3b1e4d1bef210d6a6bcd


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