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

Cache object: 94b72bd0a499ce66e6ad025f03159c88


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