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