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

Cache object: ec2ffdb9c441cd460014d597e3547631


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