The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/twa/tw_cl_misc.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

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

Cache object: 93dc0c873d2272e7e0ce4be4824ab447


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