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

Cache object: e9224127b4621b555c6eb7e16c0c8e7f


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