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_misc.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-05 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.0/sys/dev/twa/tw_cl_misc.c 144966 2005-04-12 22:07:11Z vkashyap $
   28  */
   29 
   30 /*
   31  * AMCC'S 3ware driver for 9000 series storage controllers.
   32  *
   33  * Author: Vinod Kashyap
   34  */
   35 
   36 
   37 /*
   38  * Common Layer miscellaneous functions.
   39  */
   40 
   41 
   42 #include "tw_osl_share.h"
   43 #include "tw_cl_share.h"
   44 #include "tw_cl_fwif.h"
   45 #include "tw_cl_ioctl.h"
   46 #include "tw_cl.h"
   47 #include "tw_cl_externs.h"
   48 #include "tw_osl_ioctl.h"
   49 
   50 
   51 
   52 /* AEN severity table. */
   53 TW_INT8 *tw_cli_severity_string_table[] = {
   54         "None",
   55         TW_CL_SEVERITY_ERROR_STRING,
   56         TW_CL_SEVERITY_WARNING_STRING,
   57         TW_CL_SEVERITY_INFO_STRING,
   58         TW_CL_SEVERITY_DEBUG_STRING,
   59         ""
   60 };
   61 
   62 
   63 
   64 /*
   65  * Function name:       tw_cli_drain_complete_queue
   66  * Description:         This function gets called during a controller reset.
   67  *                      It errors back to CAM, all those requests that are
   68  *                      in the complete queue, at the time of the reset.  Any
   69  *                      CL internal requests will be simply freed.
   70  *
   71  * Input:               ctlr    -- ptr to CL internal ctlr context
   72  * Output:              None
   73  * Return value:        None
   74  */
   75 TW_VOID
   76 tw_cli_drain_complete_queue(struct tw_cli_ctlr_context *ctlr)
   77 {
   78         struct tw_cli_req_context       *req;
   79         struct tw_cl_req_packet         *req_pkt;
   80 
   81         tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
   82 
   83         /* Walk the busy queue. */
   84         while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_COMPLETE_Q))) {
   85                 if (req->flags & TW_CLI_REQ_FLAGS_INTERNAL) {
   86                         /*
   87                          * It's an internal request.  Set the appropriate
   88                          * error and call the CL internal callback if there's
   89                          * one.  If the request originator is polling for
   90                          * completion, he should be checking req->error to
   91                          * determine that the request did not go through.
   92                          * The request originators are responsible for the
   93                          * clean-up.
   94                          */
   95                         req->error_code = TW_CL_ERR_REQ_BUS_RESET;
   96                         if (req->tw_cli_callback)
   97                                 req->tw_cli_callback(req);
   98                 } else {
   99                         if ((req_pkt = req->orig_req)) {
  100                                 /* It's a SCSI request.  Complete it. */
  101                                 tw_cli_dbg_printf(2, ctlr->ctlr_handle,
  102                                         tw_osl_cur_func(),
  103                                         "Completing complete request %p "
  104                                         "on reset",
  105                                         req);
  106                                 req_pkt->status = TW_CL_ERR_REQ_BUS_RESET;
  107                                 req_pkt->tw_osl_callback(req->req_handle);
  108                         }
  109                         tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
  110                 }
  111         }
  112 }
  113 
  114 
  115 
  116 /*
  117  * Function name:       tw_cli_drain_busy_queue
  118  * Description:         This function gets called during a controller reset.
  119  *                      It errors back to CAM, all those requests that were
  120  *                      pending with the firmware, at the time of the reset.
  121  *
  122  * Input:               ctlr    -- ptr to CL internal ctlr context
  123  * Output:              None
  124  * Return value:        None
  125  */
  126 TW_VOID
  127 tw_cli_drain_busy_queue(struct tw_cli_ctlr_context *ctlr)
  128 {
  129         struct tw_cli_req_context       *req;
  130         struct tw_cl_req_packet         *req_pkt;
  131 
  132         tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
  133 
  134         /* Walk the busy queue. */
  135         while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_BUSY_Q))) {
  136                 if (req->flags & TW_CLI_REQ_FLAGS_INTERNAL) {
  137                         /*
  138                          * It's an internal request.  Set the appropriate
  139                          * error and call the CL internal callback if there's
  140                          * one.  If the request originator is polling for
  141                          * completion, he should be checking req->error to
  142                          * determine that the request did not go through.
  143                          * The request originators are responsible for the
  144                          * clean-up.
  145                          */
  146                         req->error_code = TW_CL_ERR_REQ_BUS_RESET;
  147                         if (req->tw_cli_callback)
  148                                 req->tw_cli_callback(req);
  149                 } else {
  150                         if ((req_pkt = req->orig_req)) {
  151                                 /* It's a SCSI request.  Complete it. */
  152                                 tw_cli_dbg_printf(2, ctlr->ctlr_handle,
  153                                         tw_osl_cur_func(),
  154                                         "Completing busy request %p on reset",
  155                                         req);
  156                                 req_pkt->status = TW_CL_ERR_REQ_BUS_RESET;
  157                                 req_pkt->tw_osl_callback(req->req_handle);
  158                         }
  159                         tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
  160                 }
  161         }
  162 }
  163 
  164 
  165 
  166 /*
  167  * Function name:       tw_cli_drain_pending_queue
  168  * Description:         This function gets called during a controller reset.
  169  *                      It errors back to CAM, all those requests that were
  170  *                      in the pending queue, at the time of the reset.
  171  *
  172  * Input:               ctlr    -- ptr to CL internal ctlr context
  173  * Output:              None
  174  * Return value:        None
  175  */
  176 
  177 TW_VOID
  178 tw_cli_drain_pending_queue(struct tw_cli_ctlr_context *ctlr)
  179 {
  180         struct tw_cli_req_context       *req;
  181         struct tw_cl_req_packet         *req_pkt;
  182     
  183         tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
  184         
  185         /*
  186          * Pull requests off the pending queue, and complete them.
  187          */
  188         while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_PENDING_Q))) {
  189                 if (req->flags & TW_CLI_REQ_FLAGS_INTERNAL) {
  190                         /*
  191                          * It's an internal request.  Set the appropriate
  192                          * error and call the CL internal callback if there's
  193                          * one.  If the request originator is polling for
  194                          * completion, he should be checking req->error to
  195                          * determine that the request did not go through.
  196                          * The request originators are responsible for the
  197                          * clean-up.
  198                          */
  199                         req->error_code = TW_CL_ERR_REQ_BUS_RESET;
  200                         if (req->tw_cli_callback)
  201                                 req->tw_cli_callback(req);
  202                 } else {
  203                         if ((req_pkt = req->orig_req)) {
  204                                 /* It's an external request.  Complete it. */
  205                                 tw_cli_dbg_printf(2, ctlr->ctlr_handle,
  206                                         tw_osl_cur_func(),
  207                                         "Completing pending request %p "
  208                                         "on reset", req);
  209                                 req_pkt->status = TW_CL_ERR_REQ_BUS_RESET;
  210                                 req_pkt->tw_osl_callback(req->req_handle);
  211                         }
  212                         tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
  213                 }
  214         }
  215 }
  216 
  217 
  218 
  219 /*
  220  * Function name:       tw_cli_drain_response_queue
  221  * Description:         Drain the controller response queue.
  222  *
  223  * Input:               ctlr    -- ptr to per ctlr structure
  224  * Output:              None
  225  * Return value:        0       -- success
  226  *                      non-zero-- failure
  227  */
  228 TW_INT32
  229 tw_cli_drain_response_queue(struct tw_cli_ctlr_context *ctlr)
  230 {
  231         TW_UINT32       resp;
  232         TW_UINT32       status_reg;
  233 
  234         tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
  235 
  236         for (;;) {
  237                 status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr->ctlr_handle);
  238 
  239                 if (tw_cli_check_ctlr_state(ctlr, status_reg))
  240                         return(TW_OSL_EGENFAILURE);
  241 
  242                 if (status_reg & TWA_STATUS_RESPONSE_QUEUE_EMPTY)
  243                         return(TW_OSL_ESUCCESS); /* no more response queue entries */
  244 
  245                 resp = TW_CLI_READ_RESPONSE_QUEUE(ctlr->ctlr_handle);
  246         }
  247 }
  248 
  249 
  250 
  251 /*
  252  * Function name:       tw_cli_drain_aen_queue
  253  * Description:         Fetches all un-retrieved AEN's posted by fw.
  254  *
  255  * Input:               ctlr    -- ptr to CL internal ctlr context
  256  * Output:              None
  257  * Return value:        0       -- success
  258  *                      non-zero-- failure
  259  */
  260 TW_INT32
  261 tw_cli_drain_aen_queue(struct tw_cli_ctlr_context *ctlr)
  262 {
  263         struct tw_cli_req_context       *req;
  264         struct tw_cl_command_header     *cmd_hdr;
  265         TW_TIME                         end_time;
  266         TW_UINT16                       aen_code;
  267         TW_INT32                        error;
  268 
  269         tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
  270 
  271         for (;;) {
  272                 if ((req = tw_cli_get_request(ctlr
  273 #ifdef TW_OSL_NON_DMA_MEM_ALLOC_PER_REQUEST
  274                         , TW_CL_NULL
  275 #endif /* TW_OSL_NON_DMA_MEM_ALLOC_PER_REQUEST */
  276                         )) == TW_CL_NULL) {
  277                         error = TW_OSL_EBUSY;
  278                         break;
  279                 }
  280 
  281 #ifdef TW_OSL_DMA_MEM_ALLOC_PER_REQUEST
  282 
  283                 req->cmd_pkt = ctlr->cmd_pkt_buf;
  284                 req->cmd_pkt_phys = ctlr->cmd_pkt_phys;
  285                 tw_osl_memzero(req->cmd_pkt,
  286                         sizeof(struct tw_cl_command_header) +
  287                         28 /* max bytes before sglist */);
  288 
  289 #endif /* TW_OSL_DMA_MEM_ALLOC_PER_REQUEST */
  290 
  291                 req->flags |= TW_CLI_REQ_FLAGS_INTERNAL;
  292                 req->tw_cli_callback = TW_CL_NULL;
  293                 if ((error = tw_cli_send_scsi_cmd(req,
  294                                 0x03 /* REQUEST_SENSE */))) {
  295                         tw_cli_dbg_printf(1, ctlr->ctlr_handle,
  296                                 tw_osl_cur_func(),
  297                                 "Cannot send command to fetch aen");
  298                         break;
  299                 }
  300 
  301                 end_time = tw_osl_get_local_time() +
  302                         TW_CLI_REQUEST_TIMEOUT_PERIOD;
  303                 do {
  304                         if ((error = req->error_code))
  305                                 /*
  306                                  * This will take care of completion due to
  307                                  * a reset, or a failure in
  308                                  * tw_cli_submit_pending_queue.
  309                                  */
  310                                 goto out;
  311 
  312                         tw_cli_process_resp_intr(req->ctlr);
  313 
  314                         if ((req->state != TW_CLI_REQ_STATE_BUSY) &&
  315                                 (req->state != TW_CLI_REQ_STATE_PENDING))
  316                                 break;
  317                 } while (tw_osl_get_local_time() <= end_time);
  318 
  319                 if (req->state != TW_CLI_REQ_STATE_COMPLETE) {
  320                         error = TW_OSL_ETIMEDOUT;
  321                         break;
  322                 }
  323 
  324                 if ((error = req->cmd_pkt->command.cmd_pkt_9k.status)) {
  325                         cmd_hdr = &req->cmd_pkt->cmd_hdr;
  326                         tw_cli_create_ctlr_event(ctlr,
  327                                 TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR,
  328                                 cmd_hdr);
  329                         break;
  330                 }
  331 
  332                 aen_code = tw_cli_manage_aen(ctlr, req);
  333                 if (aen_code == TWA_AEN_QUEUE_EMPTY)
  334                         break;
  335                 if (aen_code == TWA_AEN_SYNC_TIME_WITH_HOST)
  336                         continue;
  337 
  338                 ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
  339                 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
  340         }
  341 
  342 out:
  343         if (req) {
  344                 if (req->data)
  345                         ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY;
  346                 tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q);
  347         }
  348         return(error);
  349 }
  350 
  351 
  352 
  353 /*
  354  * Function name:       tw_cli_find_aen
  355  * Description:         Reports whether a given AEN ever occurred.
  356  *
  357  * Input:               ctlr    -- ptr to CL internal ctlr context
  358  *                      aen_code-- AEN to look for
  359  * Output:              None
  360  * Return value:        0       -- success
  361  *                      non-zero-- failure
  362  */
  363 TW_INT32
  364 tw_cli_find_aen(struct tw_cli_ctlr_context *ctlr, TW_UINT16 aen_code)
  365 {
  366         TW_UINT32       last_index;
  367         TW_INT32        i;
  368 
  369         tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
  370 
  371         if (ctlr->aen_q_wrapped)
  372                 last_index = ctlr->aen_head;
  373         else
  374                 last_index = 0;
  375 
  376         i = ctlr->aen_head;
  377         do {
  378                 i = (i + ctlr->max_aens_supported - 1) %
  379                         ctlr->max_aens_supported;
  380                 if (ctlr->aen_queue[i].aen_code == aen_code)
  381                         return(TW_OSL_ESUCCESS);
  382         } while (i != last_index);
  383 
  384         return(TW_OSL_EGENFAILURE);
  385 }
  386 
  387 
  388 
  389 /*
  390  * Function name:       tw_cli_poll_status
  391  * Description:         Poll for a given status to show up in the firmware
  392  *                      status register.
  393  *
  394  * Input:               ctlr    -- ptr to CL internal ctlr context
  395  *                      status  -- status to look for
  396  *                      timeout -- max # of seconds to wait before giving up
  397  * Output:              None
  398  * Return value:        0       -- success
  399  *                      non-zero-- failure
  400  */
  401 TW_INT32
  402 tw_cli_poll_status(struct tw_cli_ctlr_context *ctlr, TW_UINT32 status,
  403         TW_UINT32 timeout)
  404 {
  405         TW_TIME         end_time;
  406         TW_UINT32       status_reg;
  407 
  408         tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
  409 
  410         end_time = tw_osl_get_local_time() + timeout;
  411         do {
  412                 status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr->ctlr_handle);
  413                 if ((status_reg & status) == status)
  414                         /* got the required bit(s) */
  415                         return(TW_OSL_ESUCCESS);
  416 
  417                 /*
  418                  * The OSL should not define TW_OSL_CAN_SLEEP if it calls
  419                  * tw_cl_deferred_interrupt from within the ISR and not a
  420                  * lower interrupt level, since, in that case, we might end
  421                  * up here, and try to sleep (within an ISR).
  422                  */
  423 #ifndef TW_OSL_CAN_SLEEP
  424                 /* OSL doesn't support sleeping; will spin. */
  425                 tw_osl_delay(1000);
  426 #else /* TW_OSL_CAN_SLEEP */
  427 #if 0
  428                 /* Will spin if initializing, sleep otherwise. */
  429                 if (!(ctlr->state & TW_CLI_CTLR_STATE_ACTIVE))
  430                         tw_osl_delay(1000);
  431                 else
  432                         tw_osl_sleep(ctlr->ctlr_handle,
  433                                 &(ctlr->sleep_handle), 1 /* ms */);
  434 #else /* #if 0 */
  435                 /*
  436                  * Will always spin for now (since reset holds a spin lock).
  437                  * We could free io_lock after the call to TW_CLI_SOFT_RESET,
  438                  * so we could sleep here.  To block new requests (since
  439                  * the lock will have been released) we could use the
  440                  * ...RESET_IN_PROGRESS flag.  Need to revisit.
  441                  */
  442                 tw_osl_delay(1000);
  443 #endif /* #if 0 */
  444 #endif /* TW_OSL_CAN_SLEEP */
  445         } while (tw_osl_get_local_time() <= end_time);
  446 
  447         return(TW_OSL_ETIMEDOUT);
  448 }
  449 
  450 
  451 
  452 /*
  453  * Function name:       tw_cl_create_event
  454  * Description:         Creates and queues ctlr/CL/OSL AEN's to be
  455  *                      supplied to user-space tools on request.
  456  *                      Also notifies OS Layer.
  457  * Input:               ctlr    -- ptr to CL internal ctlr context
  458  *                      queue_event-- TW_CL_TRUE --> queue event;
  459  *                                    TW_CL_FALSE--> don't queue event
  460  *                                                      (simply notify OSL)
  461  *                      event_src  -- source of event
  462  *                      event_code -- AEN/error code
  463  *                      severity -- severity of event
  464  *                      severity_str--Text description of severity
  465  *                      event_desc -- standard string related to the event/error
  466  *                      event_specific_desc -- format string for additional
  467  *                                              info about the event
  468  *                      ... -- additional arguments conforming to the format
  469  *                              specified by event_specific_desc
  470  * Output:              None
  471  * Return value:        None
  472  */
  473 TW_VOID
  474 tw_cl_create_event(struct tw_cl_ctlr_handle *ctlr_handle,
  475         TW_UINT8 queue_event, TW_UINT8 event_src, TW_UINT16 event_code,
  476         TW_UINT8 severity, TW_UINT8 *severity_str, TW_UINT8 *event_desc,
  477         TW_UINT8 *event_specific_desc, ...)
  478 {
  479         struct tw_cli_ctlr_context      *ctlr = ctlr_handle->cl_ctlr_ctxt;
  480         struct tw_cl_event_packet       event_pkt;
  481         struct tw_cl_event_packet       *event;
  482         va_list                         ap;
  483 
  484         tw_cli_dbg_printf(8, ctlr_handle, tw_osl_cur_func(), "entered");
  485 
  486         if ((ctlr) && (queue_event)) {
  487                 /* Protect access to ctlr->aen_head. */
  488                 tw_osl_get_lock(ctlr_handle, ctlr->gen_lock);
  489 
  490                 /* Queue the event. */
  491                 event = &(ctlr->aen_queue[ctlr->aen_head]);
  492                 tw_osl_memzero(event->parameter_data,
  493                         sizeof(event->parameter_data));
  494 
  495                 if (event->retrieved == TW_CL_AEN_NOT_RETRIEVED)
  496                         ctlr->aen_q_overflow = TW_CL_TRUE;
  497                 event->sequence_id = ++(ctlr->aen_cur_seq_id);
  498                 if ((ctlr->aen_head + 1) == ctlr->max_aens_supported) {
  499                         tw_cli_dbg_printf(4, ctlr->ctlr_handle,
  500                                 tw_osl_cur_func(), "AEN queue wrapped");
  501                         ctlr->aen_q_wrapped = TW_CL_TRUE;
  502                 }
  503         } else {
  504                 event = &event_pkt;
  505                 tw_osl_memzero(event, sizeof(struct tw_cl_event_packet));
  506         }
  507 
  508         event->event_src = event_src;
  509         event->time_stamp_sec = (TW_UINT32)tw_osl_get_local_time();
  510         event->aen_code = event_code;
  511         event->severity = severity;
  512         tw_osl_strcpy(event->severity_str, severity_str);
  513         event->retrieved = TW_CL_AEN_NOT_RETRIEVED;
  514 
  515         va_start(ap, event_specific_desc);
  516         tw_osl_vsprintf(event->parameter_data, event_specific_desc, ap);
  517         va_end(ap);
  518 
  519         event->parameter_len =
  520                 (TW_UINT8)(tw_osl_strlen(event->parameter_data));
  521         tw_osl_strcpy(event->parameter_data + event->parameter_len + 1,
  522                 event_desc);
  523         event->parameter_len += (1 + tw_osl_strlen(event_desc));
  524 
  525         tw_cli_dbg_printf(4, ctlr_handle, tw_osl_cur_func(),
  526                 "event = %x %x %x %x %x %x %x\n %s",
  527                 event->sequence_id,
  528                 event->time_stamp_sec,
  529                 event->aen_code,
  530                 event->severity,
  531                 event->retrieved,
  532                 event->repeat_count,
  533                 event->parameter_len,
  534                 event->parameter_data);
  535 
  536         if ((ctlr) && (queue_event)) {
  537                 ctlr->aen_head =
  538                         (ctlr->aen_head + 1) % ctlr->max_aens_supported;
  539                 /* Free access to ctlr->aen_head. */
  540                 tw_osl_free_lock(ctlr_handle, ctlr->gen_lock);
  541         }
  542         tw_osl_notify_event(ctlr_handle, event);
  543 }
  544 
  545 
  546 
  547 /*
  548  * Function name:       tw_cli_get_request
  549  * Description:         Gets a request pkt from the free queue.
  550  *
  551  * Input:               ctlr    -- ptr to CL internal ctlr context
  552  *                      req_pkt -- ptr to OSL built req_pkt, if there's one
  553  * Output:              None
  554  * Return value:        ptr to request pkt      -- success
  555  *                      TW_CL_NULL              -- failure
  556  */
  557 struct tw_cli_req_context *
  558 tw_cli_get_request(struct tw_cli_ctlr_context *ctlr
  559 #ifdef TW_OSL_NON_DMA_MEM_ALLOC_PER_REQUEST
  560         , struct tw_cl_req_packet *req_pkt
  561 #endif /* TW_OSL_NON_DMA_MEM_ALLOC_PER_REQUEST */
  562         )
  563 {
  564         struct tw_cli_req_context       *req;
  565 
  566         tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
  567 
  568 #ifdef TW_OSL_NON_DMA_MEM_ALLOC_PER_REQUEST
  569 
  570         if (req_pkt) {
  571                 if (ctlr->num_free_req_ids == 0) {
  572                         DbgPrint("Out of req_ids!!\n");
  573                         return(TW_CL_NULL);
  574                 }
  575                 ctlr->num_free_req_ids--;
  576                 req = (struct tw_cli_req_context *)(req_pkt->non_dma_mem);
  577                 req->ctlr = ctlr;
  578                 req->request_id = ctlr->free_req_ids[ctlr->free_req_head];
  579                 ctlr->busy_reqs[req->request_id] = req;
  580                 ctlr->free_req_head = (ctlr->free_req_head + 1) %
  581                         (ctlr->max_simult_reqs - 1);
  582         } else
  583 
  584 #endif /* TW_OSL_NON_DMA_MEM_ALLOC_PER_REQUEST */
  585         {
  586                 /* Get a free request packet. */
  587                 req = tw_cli_req_q_remove_head(ctlr, TW_CLI_FREE_Q);
  588         }
  589 
  590         /* Initialize some fields to their defaults. */
  591         if (req) {
  592                 req->req_handle = TW_CL_NULL;
  593                 req->data = TW_CL_NULL;
  594                 req->length = 0;
  595                 req->data_phys = 0;
  596                 req->state = TW_CLI_REQ_STATE_INIT; /* req being initialized */
  597                 req->flags = 0;
  598                 req->error_code = 0;
  599                 req->orig_req = TW_CL_NULL;
  600                 req->tw_cli_callback = TW_CL_NULL;
  601 
  602 #ifndef TW_OSL_DMA_MEM_ALLOC_PER_REQUEST
  603 
  604                 /*
  605                  * Look at the status field in the command packet to see how
  606                  * it completed the last time it was used, and zero out only
  607                  * the portions that might have changed.  Note that we don't
  608                  * care to zero out the sglist.
  609                  */
  610                 if (req->cmd_pkt->command.cmd_pkt_9k.status)
  611                         tw_osl_memzero(req->cmd_pkt,
  612                                 sizeof(struct tw_cl_command_header) +
  613                                 28 /* max bytes before sglist */);
  614                 else
  615                         tw_osl_memzero(&(req->cmd_pkt->command),
  616                                 28 /* max bytes before sglist */);
  617 
  618 #endif /* TW_OSL_DMA_MEM_ALLOC_PER_REQUEST */
  619         }
  620         return(req);
  621 }
  622 
  623 
  624 
  625 /*
  626  * Function name:       tw_cli_dbg_printf
  627  * Description:         Calls OSL print function if dbg_level is appropriate
  628  *
  629  * Input:               dbg_level -- Determines whether or not to print
  630  *                      ctlr_handle -- controller handle
  631  *                      cur_func -- text name of calling function
  632  *                      fmt -- format string for the arguments to follow
  633  *                      ... -- variable number of arguments, to be printed
  634  *                              based on the fmt string
  635  * Output:              None
  636  * Return value:        None
  637  */
  638 TW_VOID
  639 tw_cli_dbg_printf(TW_UINT8 dbg_level,
  640         struct tw_cl_ctlr_handle *ctlr_handle, const TW_INT8 *cur_func,
  641         TW_INT8 *fmt, ...)
  642 {
  643 #ifdef TW_OSL_DEBUG
  644         TW_INT8 print_str[256];
  645         va_list ap;
  646 
  647         tw_osl_memzero(print_str, 256);
  648         if (dbg_level <= TW_OSL_DEBUG_LEVEL_FOR_CL) {
  649                 tw_osl_sprintf(print_str, "%s: ", cur_func);
  650 
  651                 va_start(ap, fmt);
  652                 tw_osl_vsprintf(print_str + tw_osl_strlen(print_str), fmt, ap);
  653                 va_end(ap);
  654 
  655                 tw_osl_strcpy(print_str + tw_osl_strlen(print_str), "\n");
  656                 tw_osl_dbg_printf(ctlr_handle, print_str);
  657         }
  658 #endif /* TW_OSL_DEBUG */
  659 }
  660 
  661 
  662 
  663 /*
  664  * Function name:       tw_cli_notify_ctlr_info
  665  * Description:         Notify OSL of controller info (fw/BIOS versions, etc.).
  666  *
  667  * Input:               ctlr    -- ptr to CL internal ctlr context
  668  * Output:              None
  669  * Return value:        None
  670  */
  671 TW_VOID
  672 tw_cli_notify_ctlr_info(struct tw_cli_ctlr_context *ctlr)
  673 {
  674         TW_INT8         fw_ver[16];
  675         TW_INT8         bios_ver[16];
  676         TW_INT32        error[2];
  677         TW_UINT8        num_ports = 0;
  678 
  679         tw_cli_dbg_printf(5, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
  680 
  681         /* Get the port count. */
  682         error[0] = tw_cli_get_param(ctlr, TWA_PARAM_CONTROLLER_TABLE,
  683                         TWA_PARAM_CONTROLLER_PORT_COUNT, &num_ports,
  684                         1, TW_CL_NULL);
  685 
  686         /* Get the firmware and BIOS versions. */
  687         error[0] = tw_cli_get_param(ctlr, TWA_PARAM_VERSION_TABLE,
  688                         TWA_PARAM_VERSION_FW, fw_ver, 16, TW_CL_NULL);
  689         error[1] = tw_cli_get_param(ctlr, TWA_PARAM_VERSION_TABLE,
  690                         TWA_PARAM_VERSION_BIOS, bios_ver, 16, TW_CL_NULL);
  691 
  692         tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE,
  693                 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR,
  694                 0x1300, 0x3, TW_CL_SEVERITY_INFO_STRING,
  695                 "Controller details:",
  696                 "%d ports, Firmware %.16s, BIOS %.16s",
  697                 num_ports,
  698                 error[0]?(TW_INT8 *)TW_CL_NULL:fw_ver,
  699                 error[1]?(TW_INT8 *)TW_CL_NULL:bios_ver);
  700 }
  701 
  702 
  703 
  704 /*
  705  * Function name:       tw_cli_check_ctlr_state
  706  * Description:         Makes sure that the fw status register reports a
  707  *                      proper status.
  708  *
  709  * Input:               ctlr    -- ptr to CL internal ctlr context
  710  *                      status_reg-- value in the status register
  711  * Output:              None
  712  * Return value:        0       -- no errors
  713  *                      non-zero-- errors
  714  */
  715 TW_INT32
  716 tw_cli_check_ctlr_state(struct tw_cli_ctlr_context *ctlr, TW_UINT32 status_reg)
  717 {
  718         struct tw_cl_ctlr_handle        *ctlr_handle = ctlr->ctlr_handle;
  719         TW_INT32                        error = TW_OSL_ESUCCESS;
  720 
  721         tw_cli_dbg_printf(8, ctlr->ctlr_handle, tw_osl_cur_func(), "entered");
  722 
  723         /* Check if the 'micro-controller ready' bit is not set. */
  724         if ((status_reg & TWA_STATUS_EXPECTED_BITS) !=
  725                                 TWA_STATUS_EXPECTED_BITS) {
  726                 TW_INT8 desc[200];
  727 
  728                 tw_osl_memzero(desc, 200);
  729                 tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
  730                         TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
  731                         0x1301, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  732                         "Missing expected status bit(s)",
  733                         "status reg = 0x%x; Missing bits: %s",
  734                         status_reg,
  735                         tw_cli_describe_bits (~status_reg &
  736                                 TWA_STATUS_EXPECTED_BITS, desc));
  737                 error = TW_OSL_EGENFAILURE;
  738         }
  739 
  740         /* Check if any error bits are set. */
  741         if ((status_reg & TWA_STATUS_UNEXPECTED_BITS) != 0) {
  742                 TW_INT8 desc[200];
  743 
  744                 tw_osl_memzero(desc, 200);
  745                 tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
  746                         TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
  747                         0x1302, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  748                         "Unexpected status bit(s)",
  749                         "status reg = 0x%x Unexpected bits: %s",
  750                         status_reg & TWA_STATUS_UNEXPECTED_BITS,
  751                         tw_cli_describe_bits(status_reg &
  752                                 TWA_STATUS_UNEXPECTED_BITS, desc));
  753 
  754                 if (status_reg & TWA_STATUS_PCI_PARITY_ERROR_INTERRUPT) {
  755                         tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
  756                                 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
  757                                 0x1303, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  758                                 "PCI parity error: clearing... "
  759                                 "Re-seat/move/replace card",
  760                                 "status reg = 0x%x %s",
  761                                 status_reg,
  762                                 tw_cli_describe_bits(status_reg, desc));
  763                         TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle,
  764                                 TWA_CONTROL_CLEAR_PARITY_ERROR);
  765 
  766 #ifdef TW_OSL_PCI_CONFIG_ACCESSIBLE
  767                         tw_osl_write_pci_config(ctlr->ctlr_handle,
  768                                 TW_CLI_PCI_CONFIG_STATUS_OFFSET,
  769                                 TWA_PCI_CONFIG_CLEAR_PARITY_ERROR, 2);
  770 #endif /* TW_OSL_PCI_CONFIG_ACCESSIBLE */
  771                 
  772                 }
  773 
  774                 if (status_reg & TWA_STATUS_PCI_ABORT_INTERRUPT) {
  775                         tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
  776                                 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
  777                                 0x1304, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  778                                 "PCI abort: clearing... ",
  779                                 "status reg = 0x%x %s",
  780                                 status_reg,
  781                                 tw_cli_describe_bits(status_reg, desc));
  782                         TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle,
  783                                 TWA_CONTROL_CLEAR_PCI_ABORT);
  784 
  785 #ifdef TW_OSL_PCI_CONFIG_ACCESSIBLE
  786                         tw_osl_write_pci_config(ctlr->ctlr_handle,
  787                                 TW_CLI_PCI_CONFIG_STATUS_OFFSET,
  788                                 TWA_PCI_CONFIG_CLEAR_PCI_ABORT, 2);
  789 #endif /* TW_OSL_PCI_CONFIG_ACCESSIBLE */
  790 
  791                 }
  792 
  793                 if (status_reg & TWA_STATUS_QUEUE_ERROR_INTERRUPT) {
  794                         tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
  795                                 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
  796                                 0x1305, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  797                                 "Controller queue error: clearing... ",
  798                                 "status reg = 0x%x %s",
  799                                 status_reg,
  800                                 tw_cli_describe_bits(status_reg, desc));
  801                         TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle,
  802                                 TWA_CONTROL_CLEAR_QUEUE_ERROR);
  803                 }
  804 
  805                 if (status_reg & TWA_STATUS_SBUF_WRITE_ERROR) {
  806                         tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
  807                                 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
  808                                 0x1306, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  809                                 "SBUF write error: clearing... ",
  810                                 "status reg = 0x%x %s",
  811                                 status_reg,
  812                                 tw_cli_describe_bits(status_reg, desc));
  813                         TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle,
  814                                 TWA_CONTROL_CLEAR_SBUF_WRITE_ERROR);
  815                 }
  816 
  817                 if (status_reg & TWA_STATUS_MICROCONTROLLER_ERROR) {
  818                         tw_cl_create_event(ctlr_handle, TW_CL_TRUE,
  819                                 TW_CL_MESSAGE_SOURCE_COMMON_LAYER_EVENT,
  820                                 0x1307, 0x1, TW_CL_SEVERITY_ERROR_STRING,
  821                                 "Micro-controller error! ",
  822                                 "status reg = 0x%x %s",
  823                                 status_reg,
  824                                 tw_cli_describe_bits(status_reg, desc));
  825                         error = TW_OSL_EGENFAILURE;
  826                 }
  827         }
  828         return(error);
  829 }       
  830 
  831 
  832 
  833 /*
  834  * Function name:       tw_cli_describe_bits
  835  * Description:         Given the value of the status register, returns a
  836  *                      string describing the meaning of each set bit.
  837  *
  838  * Input:               reg -- status register value
  839  * Output:              Pointer to a string describing each set bit
  840  * Return value:        Pointer to the string describing each set bit
  841  */
  842 TW_INT8 *
  843 tw_cli_describe_bits(TW_UINT32 reg, TW_INT8 *str)
  844 {
  845         tw_osl_strcpy(str, "[");
  846 
  847         if (reg & TWA_STATUS_SBUF_WRITE_ERROR)
  848                 tw_osl_strcpy(str, "SBUF_WR_ERR,");
  849         if (reg & TWA_STATUS_COMMAND_QUEUE_EMPTY)
  850                 tw_osl_strcpy(&str[tw_osl_strlen(str)], "CMD_Q_EMPTY,");
  851         if (reg & TWA_STATUS_MICROCONTROLLER_READY)
  852                 tw_osl_strcpy(&str[tw_osl_strlen(str)], "MC_RDY,");
  853         if (reg & TWA_STATUS_RESPONSE_QUEUE_EMPTY)
  854                 tw_osl_strcpy(&str[tw_osl_strlen(str)], "RESP_Q_EMPTY,");
  855         if (reg & TWA_STATUS_COMMAND_QUEUE_FULL)
  856                 tw_osl_strcpy(&str[tw_osl_strlen(str)], "CMD_Q_FULL,");
  857         if (reg & TWA_STATUS_RESPONSE_INTERRUPT)
  858                 tw_osl_strcpy(&str[tw_osl_strlen(str)], "RESP_INTR,");
  859         if (reg & TWA_STATUS_COMMAND_INTERRUPT)
  860                 tw_osl_strcpy(&str[tw_osl_strlen(str)], "CMD_INTR,");
  861         if (reg & TWA_STATUS_ATTENTION_INTERRUPT)
  862                 tw_osl_strcpy(&str[tw_osl_strlen(str)], "ATTN_INTR,");
  863         if (reg & TWA_STATUS_HOST_INTERRUPT)
  864                 tw_osl_strcpy(&str[tw_osl_strlen(str)], "HOST_INTR,");
  865         if (reg & TWA_STATUS_PCI_ABORT_INTERRUPT)
  866                 tw_osl_strcpy(&str[tw_osl_strlen(str)], "PCI_ABRT,");
  867         if (reg & TWA_STATUS_MICROCONTROLLER_ERROR)
  868                 tw_osl_strcpy(&str[tw_osl_strlen(str)], "MC_ERR,");
  869         if (reg & TWA_STATUS_QUEUE_ERROR_INTERRUPT)
  870                 tw_osl_strcpy(&str[tw_osl_strlen(str)], "Q_ERR,");
  871         if (reg & TWA_STATUS_PCI_PARITY_ERROR_INTERRUPT)
  872                 tw_osl_strcpy(&str[tw_osl_strlen(str)], "PCI_PERR");
  873 
  874         tw_osl_strcpy(&str[tw_osl_strlen(str)], "]");
  875         return(str);
  876 }
  877 
  878 
  879 
  880 #ifdef TW_OSL_DEBUG
  881 
  882 /*
  883  * Function name:       tw_cl_print_ctlr_stats
  884  * Description:         Prints the current status of the controller.
  885  *
  886  * Input:               ctlr_handle-- controller handle
  887  * Output:              None
  888  * Return value:        None
  889  */
  890 TW_VOID
  891 tw_cl_print_ctlr_stats(struct tw_cl_ctlr_handle *ctlr_handle)
  892 {
  893         struct tw_cli_ctlr_context      *ctlr =
  894                 (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
  895         TW_UINT32                       status_reg;
  896         TW_INT8                         desc[200];
  897 
  898         tw_cli_dbg_printf(7, ctlr->ctlr_handle, "", "entered");
  899 
  900         /* Print current controller details. */
  901         tw_cli_dbg_printf(0, ctlr_handle, "", "cl_ctlr_ctxt = %p", ctlr);
  902 
  903         tw_osl_memzero(desc, 200);
  904         status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr_handle);
  905         tw_cli_dbg_printf(0, ctlr_handle, "", "status reg = 0x%x %s",
  906                 status_reg, tw_cli_describe_bits(status_reg, desc));
  907 
  908         tw_cli_dbg_printf(0, ctlr_handle, "", "CLq type  current  max");
  909         tw_cli_dbg_printf(0, ctlr_handle, "", "free      %04d     %04d",
  910                 ctlr->q_stats[TW_CLI_FREE_Q].cur_len,
  911                 ctlr->q_stats[TW_CLI_FREE_Q].max_len);
  912         tw_cli_dbg_printf(0, ctlr_handle, "", "busy      %04d     %04d",
  913                 ctlr->q_stats[TW_CLI_BUSY_Q].cur_len,
  914                 ctlr->q_stats[TW_CLI_BUSY_Q].max_len);
  915         tw_cli_dbg_printf(0, ctlr_handle, "", "pending   %04d     %04d",
  916                 ctlr->q_stats[TW_CLI_PENDING_Q].cur_len,
  917                 ctlr->q_stats[TW_CLI_PENDING_Q].max_len);
  918         tw_cli_dbg_printf(0, ctlr_handle, "", "complete  %04d     %04d",
  919                 ctlr->q_stats[TW_CLI_COMPLETE_Q].cur_len,
  920                 ctlr->q_stats[TW_CLI_COMPLETE_Q].max_len);
  921         tw_cli_dbg_printf(0, ctlr_handle, "", "AEN queue head %d  tail %d",
  922                         ctlr->aen_head, ctlr->aen_tail);
  923 }       
  924 
  925 
  926 
  927 /*
  928  * Function name:       tw_cl_reset_stats
  929  * Description:         Resets CL maintained statistics for the controller.
  930  *
  931  * Input:               ctlr_handle-- controller handle
  932  * Output:              None
  933  * Return value:        None
  934  */
  935 TW_VOID
  936 tw_cl_reset_stats(struct tw_cl_ctlr_handle *ctlr_handle)
  937 {
  938         struct tw_cli_ctlr_context      *ctlr =
  939                 (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt);
  940 
  941         tw_cli_dbg_printf(7, ctlr_handle, tw_osl_cur_func(), "entered");
  942         ctlr->q_stats[TW_CLI_FREE_Q].max_len = 0;
  943         ctlr->q_stats[TW_CLI_BUSY_Q].max_len = 0;
  944         ctlr->q_stats[TW_CLI_PENDING_Q].max_len = 0;
  945         ctlr->q_stats[TW_CLI_COMPLETE_Q].max_len = 0;
  946 }
  947 
  948 
  949 
  950 /*
  951  * Function name:       tw_cli_print_req_info
  952  * Description:         Prints CL internal details of a given request.
  953  *
  954  * Input:               req     -- ptr to CL internal request context
  955  * Output:              None
  956  * Return value:        None
  957  */
  958 TW_VOID
  959 tw_cl_print_req_info(struct tw_cl_req_handle *req_handle)
  960 {
  961         struct tw_cli_req_context       *req = req_handle->cl_req_ctxt;
  962         struct tw_cli_ctlr_context      *ctlr = req->ctlr;
  963         struct tw_cl_ctlr_handle        *ctlr_handle = ctlr->ctlr_handle;
  964         struct tw_cl_command_packet     *cmd_pkt = req->cmd_pkt;
  965         struct tw_cl_command_9k         *cmd9k;
  966         union tw_cl_command_7k          *cmd7k;
  967         TW_UINT8                        *cdb;
  968         TW_VOID                         *sgl;
  969         TW_UINT32                       sgl_entries;
  970         TW_UINT32                       i;
  971 
  972         tw_cli_dbg_printf(0, ctlr_handle, tw_osl_cur_func(),
  973                 "CL details for request:");
  974         tw_cli_dbg_printf(0, ctlr_handle, tw_osl_cur_func(),
  975                 "req_handle = %p, ctlr = %p,\n"
  976                 "cmd_pkt = %p, cmd_pkt_phys = 0x%llx,\n"
  977                 "data = %p, length = 0x%x, data_phys = 0x%llx,\n"
  978                 "state = 0x%x, flags = 0x%x, error = 0x%x,\n"
  979                 "orig_req = %p, callback = %p, req_id = 0x%x,\n"
  980                 "next_req = %p, prev_req = %p",
  981                 req_handle, ctlr,
  982                 cmd_pkt, req->cmd_pkt_phys,
  983                 req->data, req->length, req->data_phys,
  984                 req->state, req->flags, req->error_code,
  985                 req->orig_req, req->tw_cli_callback, req->request_id,
  986                 req->link.next, req->link.prev);
  987 
  988         if (req->flags & TW_CLI_REQ_FLAGS_9K) {
  989                 cmd9k = &(cmd_pkt->command.cmd_pkt_9k);
  990                 sgl = cmd9k->sg_list;
  991                 sgl_entries = TW_CL_SWAP16(
  992                         GET_SGL_ENTRIES(cmd9k->lun_h4__sgl_entries));
  993                 tw_cli_dbg_printf(0, ctlr_handle, tw_osl_cur_func(),
  994                         "9K cmd: opcode = 0x%x, unit = 0x%x, req_id = 0x%x,\n"
  995                         "status = 0x%x, sgl_offset = 0x%x, sgl_entries = 0x%x",
  996                         GET_OPCODE(cmd9k->res__opcode),
  997                         cmd9k->unit,
  998                         TW_CL_SWAP16(GET_REQ_ID(cmd9k->lun_l4__req_id)),
  999                         cmd9k->status,
 1000                         cmd9k->sgl_offset,
 1001                         sgl_entries);
 1002 
 1003                 cdb = (TW_UINT8 *)(cmd9k->cdb);
 1004                 tw_cli_dbg_printf(0, ctlr_handle, tw_osl_cur_func(),
 1005                         "CDB: %x %x %x %x %x %x %x %x"
 1006                         "%x %x %x %x %x %x %x %x",
 1007                         cdb[0], cdb[1], cdb[2], cdb[3],
 1008                         cdb[4], cdb[5], cdb[6], cdb[7],
 1009                         cdb[8], cdb[9], cdb[10], cdb[11],
 1010                         cdb[12], cdb[13], cdb[14], cdb[15]);
 1011         } else {
 1012                 cmd7k = &(cmd_pkt->command.cmd_pkt_7k);
 1013                 sgl = cmd7k->param.sgl;
 1014                 sgl_entries = (cmd7k->generic.size -
 1015                         GET_SGL_OFF(cmd7k->generic.sgl_off__opcode)) /
 1016                         ((ctlr->flags & TW_CL_64BIT_ADDRESSES) ? 3 : 2);
 1017                 tw_cli_dbg_printf(0, ctlr_handle, tw_osl_cur_func(),
 1018                         "7K cmd: opcode = 0x%x, sgl_offset = 0x%x,\n"
 1019                         "size = 0x%x, req_id = 0x%x, unit = 0x%x,\n"
 1020                         "status = 0x%x, flags = 0x%x, count = 0x%x",
 1021                         GET_OPCODE(cmd7k->generic.sgl_off__opcode),
 1022                         GET_SGL_OFF(cmd7k->generic.sgl_off__opcode),
 1023                         cmd7k->generic.size,
 1024                         TW_CL_SWAP16(cmd7k->generic.request_id),
 1025                         GET_UNIT(cmd7k->generic.host_id__unit),
 1026                         cmd7k->generic.status,
 1027                         cmd7k->generic.flags,
 1028                         TW_CL_SWAP16(cmd7k->generic.count));
 1029         }
 1030 
 1031         tw_cli_dbg_printf(0, ctlr_handle, tw_osl_cur_func(), "SG entries:");
 1032 
 1033         if (ctlr->flags & TW_CL_64BIT_ADDRESSES) {
 1034                 struct tw_cl_sg_desc64 *sgl64 = (struct tw_cl_sg_desc64 *)sgl;
 1035 
 1036                 for (i = 0; i < sgl_entries; i++) {
 1037                         tw_cli_dbg_printf(0, ctlr_handle, tw_osl_cur_func(),
 1038                                 "0x%llx  0x%x",
 1039                                 sgl64[i].address, sgl64[i].length);
 1040                 }
 1041         } else {
 1042                 struct tw_cl_sg_desc32 *sgl32 = (struct tw_cl_sg_desc32 *)sgl;
 1043 
 1044                 for (i = 0; i < sgl_entries; i++) {
 1045                         tw_cli_dbg_printf(0, ctlr_handle, tw_osl_cur_func(),
 1046                                 "0x%x  0x%x",
 1047                                 sgl32[i].address, sgl32[i].length);
 1048                 }
 1049         }
 1050 }
 1051 
 1052 #endif /* TW_OSL_DEBUG */
 1053 

Cache object: 0f232ec394c9a7d4bd5f235ef7517c98


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