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

Cache object: 9a2a797e265c76b5d0e19d225b1ae74c


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