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

Cache object: 03f74c7964a9d0c2e2184c22c730f82e


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