tw_cl_intr.c revision 172496
1144966Svkashyap/* 2169400Sscottl * Copyright (c) 2004-07 Applied Micro Circuits Corporation. 3144966Svkashyap * Copyright (c) 2004-05 Vinod Kashyap 4144966Svkashyap * All rights reserved. 5144966Svkashyap * 6144966Svkashyap * Redistribution and use in source and binary forms, with or without 7144966Svkashyap * modification, are permitted provided that the following conditions 8144966Svkashyap * are met: 9144966Svkashyap * 1. Redistributions of source code must retain the above copyright 10144966Svkashyap * notice, this list of conditions and the following disclaimer. 11144966Svkashyap * 2. Redistributions in binary form must reproduce the above copyright 12144966Svkashyap * notice, this list of conditions and the following disclaimer in the 13144966Svkashyap * documentation and/or other materials provided with the distribution. 14144966Svkashyap * 15144966Svkashyap * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16144966Svkashyap * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17144966Svkashyap * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18144966Svkashyap * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19144966Svkashyap * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20144966Svkashyap * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21144966Svkashyap * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22144966Svkashyap * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23144966Svkashyap * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24144966Svkashyap * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25144966Svkashyap * SUCH DAMAGE. 26144966Svkashyap * 27144966Svkashyap * $FreeBSD: head/sys/dev/twa/tw_cl_intr.c 172496 2007-10-09 17:43:57Z scottl $ 28144966Svkashyap */ 29144966Svkashyap 30144966Svkashyap/* 31144966Svkashyap * AMCC'S 3ware driver for 9000 series storage controllers. 32144966Svkashyap * 33144966Svkashyap * Author: Vinod Kashyap 34169400Sscottl * Modifications by: Adam Radford 35172496Sscottl * Modifications by: Manjunath Ranganathaiah 36144966Svkashyap */ 37144966Svkashyap 38144966Svkashyap 39144966Svkashyap/* 40144966Svkashyap * Common Layer interrupt handling functions. 41144966Svkashyap */ 42144966Svkashyap 43144966Svkashyap 44144966Svkashyap#include "tw_osl_share.h" 45144966Svkashyap#include "tw_cl_share.h" 46144966Svkashyap#include "tw_cl_fwif.h" 47144966Svkashyap#include "tw_cl_ioctl.h" 48144966Svkashyap#include "tw_cl.h" 49144966Svkashyap#include "tw_cl_externs.h" 50144966Svkashyap#include "tw_osl_ioctl.h" 51144966Svkashyap 52144966Svkashyap 53144966Svkashyap 54144966Svkashyap/* 55144966Svkashyap * Function name: twa_interrupt 56144966Svkashyap * Description: Interrupt handler. Determines the kind of interrupt, 57144966Svkashyap * and returns TW_CL_TRUE if it recognizes the interrupt. 58144966Svkashyap * 59144966Svkashyap * Input: ctlr_handle -- controller handle 60144966Svkashyap * Output: None 61144966Svkashyap * Return value: TW_CL_TRUE -- interrupt recognized 62144966Svkashyap * TW_CL_FALSE-- interrupt not recognized 63144966Svkashyap */ 64144966SvkashyapTW_INT32 65144966Svkashyaptw_cl_interrupt(struct tw_cl_ctlr_handle *ctlr_handle) 66144966Svkashyap{ 67144966Svkashyap struct tw_cli_ctlr_context *ctlr = 68144966Svkashyap (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt); 69144966Svkashyap TW_UINT32 status_reg; 70144966Svkashyap TW_INT32 rc = TW_CL_FALSE; 71144966Svkashyap 72144966Svkashyap tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(), "entered"); 73144966Svkashyap 74169400Sscottl /* If we don't have controller context, bail */ 75169400Sscottl if (ctlr == NULL) 76169400Sscottl goto out; 77169400Sscottl 78172496Sscottl /* If we get an interrupt while resetting, it is a shared 79172496Sscottl one for another device, so just bail */ 80172496Sscottl if (ctlr->state & TW_CLI_CTLR_STATE_RESET_IN_PROGRESS) 81172496Sscottl goto out; 82172496Sscottl 83144966Svkashyap /* 84152213Svkashyap * Synchronize access between writes to command and control registers 85152213Svkashyap * in 64-bit environments, on G66. 86144966Svkashyap */ 87152213Svkashyap if (ctlr->state & TW_CLI_CTLR_STATE_G66_WORKAROUND_NEEDED) 88152213Svkashyap tw_osl_get_lock(ctlr_handle, ctlr->io_lock); 89144966Svkashyap 90144966Svkashyap /* Read the status register to determine the type of interrupt. */ 91144966Svkashyap status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr_handle); 92144966Svkashyap if (tw_cli_check_ctlr_state(ctlr, status_reg)) 93169400Sscottl goto out_unlock; 94144966Svkashyap 95144966Svkashyap /* Clear the interrupt. */ 96144966Svkashyap if (status_reg & TWA_STATUS_HOST_INTERRUPT) { 97144966Svkashyap tw_cli_dbg_printf(6, ctlr_handle, tw_osl_cur_func(), 98144966Svkashyap "Host interrupt"); 99144966Svkashyap TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle, 100144966Svkashyap TWA_CONTROL_CLEAR_HOST_INTERRUPT); 101144966Svkashyap ctlr->host_intr_pending = 0; /* we don't use this */ 102144966Svkashyap rc |= TW_CL_FALSE; /* don't request for a deferred isr call */ 103144966Svkashyap } 104144966Svkashyap if (status_reg & TWA_STATUS_ATTENTION_INTERRUPT) { 105144966Svkashyap tw_cli_dbg_printf(6, ctlr_handle, tw_osl_cur_func(), 106144966Svkashyap "Attention interrupt"); 107144966Svkashyap TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle, 108144966Svkashyap TWA_CONTROL_CLEAR_ATTENTION_INTERRUPT); 109144966Svkashyap ctlr->attn_intr_pending = 1; 110144966Svkashyap rc |= TW_CL_TRUE; /* request for a deferred isr call */ 111144966Svkashyap } 112144966Svkashyap if (status_reg & TWA_STATUS_COMMAND_INTERRUPT) { 113144966Svkashyap tw_cli_dbg_printf(6, ctlr_handle, tw_osl_cur_func(), 114144966Svkashyap "Command interrupt"); 115144966Svkashyap TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle, 116144966Svkashyap TWA_CONTROL_MASK_COMMAND_INTERRUPT); 117144966Svkashyap ctlr->cmd_intr_pending = 1; 118144966Svkashyap rc |= TW_CL_TRUE; /* request for a deferred isr call */ 119144966Svkashyap } 120144966Svkashyap if (status_reg & TWA_STATUS_RESPONSE_INTERRUPT) { 121144966Svkashyap tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(), 122144966Svkashyap "Response interrupt"); 123144966Svkashyap TW_CLI_WRITE_CONTROL_REGISTER(ctlr_handle, 124144966Svkashyap TWA_CONTROL_MASK_RESPONSE_INTERRUPT); 125144966Svkashyap ctlr->resp_intr_pending = 1; 126144966Svkashyap rc |= TW_CL_TRUE; /* request for a deferred isr call */ 127144966Svkashyap } 128169400Sscottlout_unlock: 129152213Svkashyap if (ctlr->state & TW_CLI_CTLR_STATE_G66_WORKAROUND_NEEDED) 130152213Svkashyap tw_osl_free_lock(ctlr_handle, ctlr->io_lock); 131169400Sscottlout: 132144966Svkashyap return(rc); 133144966Svkashyap} 134144966Svkashyap 135144966Svkashyap 136144966Svkashyap 137144966Svkashyap/* 138144966Svkashyap * Function name: tw_cl_deferred_interrupt 139144966Svkashyap * Description: Deferred interrupt handler. Does most of the processing 140144966Svkashyap * related to an interrupt. 141144966Svkashyap * 142144966Svkashyap * Input: ctlr_handle -- controller handle 143144966Svkashyap * Output: None 144144966Svkashyap * Return value: None 145144966Svkashyap */ 146144966SvkashyapTW_VOID 147144966Svkashyaptw_cl_deferred_interrupt(struct tw_cl_ctlr_handle *ctlr_handle) 148144966Svkashyap{ 149144966Svkashyap struct tw_cli_ctlr_context *ctlr = 150144966Svkashyap (struct tw_cli_ctlr_context *)(ctlr_handle->cl_ctlr_ctxt); 151144966Svkashyap 152144966Svkashyap tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(), "entered"); 153144966Svkashyap 154144966Svkashyap /* Dispatch based on the kind of interrupt. */ 155144966Svkashyap if (ctlr->host_intr_pending) { 156144966Svkashyap tw_cli_dbg_printf(6, ctlr_handle, tw_osl_cur_func(), 157144966Svkashyap "Processing Host interrupt"); 158144966Svkashyap ctlr->host_intr_pending = 0; 159144966Svkashyap tw_cli_process_host_intr(ctlr); 160144966Svkashyap } 161144966Svkashyap if (ctlr->attn_intr_pending) { 162144966Svkashyap tw_cli_dbg_printf(6, ctlr_handle, tw_osl_cur_func(), 163144966Svkashyap "Processing Attention interrupt"); 164144966Svkashyap ctlr->attn_intr_pending = 0; 165144966Svkashyap tw_cli_process_attn_intr(ctlr); 166144966Svkashyap } 167144966Svkashyap if (ctlr->cmd_intr_pending) { 168144966Svkashyap tw_cli_dbg_printf(6, ctlr_handle, tw_osl_cur_func(), 169144966Svkashyap "Processing Command interrupt"); 170144966Svkashyap ctlr->cmd_intr_pending = 0; 171144966Svkashyap tw_cli_process_cmd_intr(ctlr); 172144966Svkashyap } 173144966Svkashyap if (ctlr->resp_intr_pending) { 174144966Svkashyap tw_cli_dbg_printf(10, ctlr_handle, tw_osl_cur_func(), 175144966Svkashyap "Processing Response interrupt"); 176144966Svkashyap ctlr->resp_intr_pending = 0; 177144966Svkashyap tw_cli_process_resp_intr(ctlr); 178144966Svkashyap } 179144966Svkashyap} 180144966Svkashyap 181144966Svkashyap 182144966Svkashyap 183144966Svkashyap/* 184144966Svkashyap * Function name: tw_cli_process_host_intr 185144966Svkashyap * Description: This function gets called if we triggered an interrupt. 186144966Svkashyap * We don't use it as of now. 187144966Svkashyap * 188144966Svkashyap * Input: ctlr -- ptr to CL internal ctlr context 189144966Svkashyap * Output: None 190144966Svkashyap * Return value: None 191144966Svkashyap */ 192144966SvkashyapTW_VOID 193144966Svkashyaptw_cli_process_host_intr(struct tw_cli_ctlr_context *ctlr) 194144966Svkashyap{ 195144966Svkashyap tw_cli_dbg_printf(6, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 196144966Svkashyap} 197144966Svkashyap 198144966Svkashyap 199144966Svkashyap 200144966Svkashyap/* 201144966Svkashyap * Function name: tw_cli_process_attn_intr 202144966Svkashyap * Description: This function gets called if the fw posted an AEN 203144966Svkashyap * (Asynchronous Event Notification). It fetches 204144966Svkashyap * all the AEN's that the fw might have posted. 205144966Svkashyap * 206144966Svkashyap * Input: ctlr -- ptr to CL internal ctlr context 207144966Svkashyap * Output: None 208144966Svkashyap * Return value: None 209144966Svkashyap */ 210144966SvkashyapTW_VOID 211144966Svkashyaptw_cli_process_attn_intr(struct tw_cli_ctlr_context *ctlr) 212144966Svkashyap{ 213144966Svkashyap TW_INT32 error; 214144966Svkashyap 215144966Svkashyap tw_cli_dbg_printf(6, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 216144966Svkashyap 217144966Svkashyap if ((error = tw_cli_get_aen(ctlr))) { 218144966Svkashyap /* 219144966Svkashyap * If the driver is already in the process of retrieveing AEN's, 220144966Svkashyap * we will be returned TW_OSL_EBUSY. In this case, 221144966Svkashyap * tw_cli_param_callback or tw_cli_aen_callback will eventually 222144966Svkashyap * retrieve the AEN this attention interrupt is for. So, we 223144966Svkashyap * don't need to print the failure. 224144966Svkashyap */ 225144966Svkashyap if (error != TW_OSL_EBUSY) 226144966Svkashyap tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 227144966Svkashyap TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 228144966Svkashyap 0x1200, 0x1, TW_CL_SEVERITY_ERROR_STRING, 229144966Svkashyap "Failed to fetch AEN", 230144966Svkashyap "error = %d", error); 231144966Svkashyap } 232144966Svkashyap} 233144966Svkashyap 234144966Svkashyap 235144966Svkashyap 236144966Svkashyap/* 237144966Svkashyap * Function name: tw_cli_process_cmd_intr 238144966Svkashyap * Description: This function gets called if we hit a queue full 239144966Svkashyap * condition earlier, and the fw is now ready for 240144966Svkashyap * new cmds. Submits any pending requests. 241144966Svkashyap * 242144966Svkashyap * Input: ctlr -- ptr to CL internal ctlr context 243144966Svkashyap * Output: None 244144966Svkashyap * Return value: None 245144966Svkashyap */ 246144966SvkashyapTW_VOID 247144966Svkashyaptw_cli_process_cmd_intr(struct tw_cli_ctlr_context *ctlr) 248144966Svkashyap{ 249144966Svkashyap tw_cli_dbg_printf(6, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 250144966Svkashyap 251144966Svkashyap /* 252144966Svkashyap * Let the OS Layer submit any requests in its pending queue, 253144966Svkashyap * if it has one. 254144966Svkashyap */ 255144966Svkashyap tw_osl_ctlr_ready(ctlr->ctlr_handle); 256144966Svkashyap 257144966Svkashyap /* Start any requests that might be in the pending queue. */ 258144966Svkashyap tw_cli_submit_pending_queue(ctlr); 259144966Svkashyap 260144966Svkashyap /* 261144966Svkashyap * If tw_cli_submit_pending_queue was unsuccessful due to a "cmd queue 262144966Svkashyap * full" condition, cmd_intr will already have been unmasked by 263144966Svkashyap * tw_cli_submit_cmd. We don't need to do it again... simply return. 264144966Svkashyap */ 265144966Svkashyap} 266144966Svkashyap 267144966Svkashyap 268144966Svkashyap 269144966Svkashyap/* 270144966Svkashyap * Function name: tw_cli_process_resp_intr 271144966Svkashyap * Description: Looks for cmd completions from fw; queues cmds completed 272144966Svkashyap * by fw into complete queue. 273144966Svkashyap * 274144966Svkashyap * Input: ctlr -- ptr to CL internal ctlr context 275144966Svkashyap * Output: None 276144966Svkashyap * Return value: 0 -- no ctlr error 277144966Svkashyap * non-zero-- ctlr error 278144966Svkashyap */ 279144966SvkashyapTW_INT32 280144966Svkashyaptw_cli_process_resp_intr(struct tw_cli_ctlr_context *ctlr) 281144966Svkashyap{ 282144966Svkashyap TW_UINT32 resp; 283144966Svkashyap struct tw_cli_req_context *req; 284144966Svkashyap TW_INT32 error; 285144966Svkashyap TW_UINT32 status_reg; 286144966Svkashyap 287144966Svkashyap tw_cli_dbg_printf(10, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 288144966Svkashyap 289144966Svkashyap /* Serialize access to the controller response queue. */ 290144966Svkashyap tw_osl_get_lock(ctlr->ctlr_handle, ctlr->intr_lock); 291144966Svkashyap 292144966Svkashyap for (;;) { 293144966Svkashyap status_reg = TW_CLI_READ_STATUS_REGISTER(ctlr->ctlr_handle); 294144966Svkashyap if ((error = tw_cli_check_ctlr_state(ctlr, status_reg))) 295144966Svkashyap break; 296144966Svkashyap if (status_reg & TWA_STATUS_RESPONSE_QUEUE_EMPTY) { 297144966Svkashyap tw_cli_dbg_printf(7, ctlr->ctlr_handle, 298144966Svkashyap tw_osl_cur_func(), "Response queue empty"); 299144966Svkashyap break; 300144966Svkashyap } 301144966Svkashyap 302144966Svkashyap /* Response queue is not empty. */ 303144966Svkashyap resp = TW_CLI_READ_RESPONSE_QUEUE(ctlr->ctlr_handle); 304144966Svkashyap { 305144966Svkashyap req = &(ctlr->req_ctxt_buf[GET_RESP_ID(resp)]); 306144966Svkashyap } 307144966Svkashyap 308144966Svkashyap if (req->state != TW_CLI_REQ_STATE_BUSY) { 309144966Svkashyap tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 310144966Svkashyap TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 311144966Svkashyap 0x1201, 0x1, TW_CL_SEVERITY_ERROR_STRING, 312144966Svkashyap "Unposted command completed!!", 313144966Svkashyap "request = %p, status = %d", 314144966Svkashyap req, req->state); 315144966Svkashyap#ifdef TW_OSL_DEBUG 316144966Svkashyap tw_cl_print_ctlr_stats(ctlr->ctlr_handle); 317144966Svkashyap#endif /* TW_OSL_DEBUG */ 318144966Svkashyap tw_osl_free_lock(ctlr->ctlr_handle, ctlr->intr_lock); 319144966Svkashyap tw_cl_reset_ctlr(ctlr->ctlr_handle); 320144966Svkashyap return(TW_OSL_EIO); 321144966Svkashyap } 322144966Svkashyap 323144966Svkashyap /* 324144966Svkashyap * Remove the request from the busy queue, mark it as complete, 325144966Svkashyap * and enqueue it in the complete queue. 326144966Svkashyap */ 327144966Svkashyap tw_cli_req_q_remove_item(req, TW_CLI_BUSY_Q); 328144966Svkashyap req->state = TW_CLI_REQ_STATE_COMPLETE; 329144966Svkashyap tw_cli_req_q_insert_tail(req, TW_CLI_COMPLETE_Q); 330152213Svkashyap 331144966Svkashyap } 332144966Svkashyap 333144966Svkashyap /* Unmask the response interrupt. */ 334144966Svkashyap TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle, 335144966Svkashyap TWA_CONTROL_UNMASK_RESPONSE_INTERRUPT); 336144966Svkashyap 337144966Svkashyap tw_osl_free_lock(ctlr->ctlr_handle, ctlr->intr_lock); 338144966Svkashyap 339144966Svkashyap /* Complete this, and other requests in the complete queue. */ 340144966Svkashyap tw_cli_process_complete_queue(ctlr); 341144966Svkashyap 342144966Svkashyap return(error); 343144966Svkashyap} 344144966Svkashyap 345144966Svkashyap 346144966Svkashyap 347144966Svkashyap/* 348144966Svkashyap * Function name: tw_cli_submit_pending_queue 349144966Svkashyap * Description: Kick starts any requests in the pending queue. 350144966Svkashyap * 351144966Svkashyap * Input: ctlr -- ptr to CL internal ctlr context 352144966Svkashyap * Output: None 353144966Svkashyap * Return value: 0 -- all pending requests submitted successfully 354144966Svkashyap * non-zero-- otherwise 355144966Svkashyap */ 356144966SvkashyapTW_INT32 357144966Svkashyaptw_cli_submit_pending_queue(struct tw_cli_ctlr_context *ctlr) 358144966Svkashyap{ 359144966Svkashyap struct tw_cli_req_context *req; 360144966Svkashyap TW_INT32 error = TW_OSL_ESUCCESS; 361144966Svkashyap 362144966Svkashyap tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 363144966Svkashyap 364144966Svkashyap /* 365144966Svkashyap * Pull requests off the pending queue, and submit them. 366144966Svkashyap */ 367144966Svkashyap while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_PENDING_Q)) != 368144966Svkashyap TW_CL_NULL) { 369144966Svkashyap if ((error = tw_cli_submit_cmd(req))) { 370144966Svkashyap if (error == TW_OSL_EBUSY) { 371144966Svkashyap tw_cli_dbg_printf(2, ctlr->ctlr_handle, 372144966Svkashyap tw_osl_cur_func(), 373144966Svkashyap "Requeueing pending request"); 374144966Svkashyap req->state = TW_CLI_REQ_STATE_PENDING; 375144966Svkashyap /* 376144966Svkashyap * Queue the request at the head of the pending 377144966Svkashyap * queue, and break away, so we don't try to 378144966Svkashyap * submit any more requests. 379144966Svkashyap */ 380144966Svkashyap tw_cli_req_q_insert_head(req, TW_CLI_PENDING_Q); 381144966Svkashyap break; 382144966Svkashyap } else { 383144966Svkashyap tw_cl_create_event(ctlr->ctlr_handle, 384144966Svkashyap TW_CL_FALSE, 385144966Svkashyap TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 386144966Svkashyap 0x1202, 0x1, 387144966Svkashyap TW_CL_SEVERITY_ERROR_STRING, 388144966Svkashyap "Could not start request " 389144966Svkashyap "in pending queue", 390144966Svkashyap "request = %p, opcode = 0x%x, " 391144966Svkashyap "error = %d", req, 392144966Svkashyap GET_OPCODE(req->cmd_pkt-> 393144966Svkashyap command.cmd_pkt_9k.res__opcode), 394144966Svkashyap error); 395144966Svkashyap /* 396144966Svkashyap * Set the appropriate error and call the CL 397144966Svkashyap * internal callback if there's one. If the 398144966Svkashyap * request originator is polling for completion, 399144966Svkashyap * he should be checking req->error to 400144966Svkashyap * determine that the request did not go 401144966Svkashyap * through. The request originators are 402144966Svkashyap * responsible for the clean-up. 403144966Svkashyap */ 404144966Svkashyap req->error_code = error; 405144966Svkashyap req->state = TW_CLI_REQ_STATE_COMPLETE; 406144966Svkashyap if (req->tw_cli_callback) 407144966Svkashyap req->tw_cli_callback(req); 408144966Svkashyap error = TW_OSL_ESUCCESS; 409144966Svkashyap } 410144966Svkashyap } 411144966Svkashyap } 412144966Svkashyap return(error); 413144966Svkashyap} 414144966Svkashyap 415144966Svkashyap 416144966Svkashyap 417144966Svkashyap/* 418144966Svkashyap * Function name: tw_cli_process_complete_queue 419144966Svkashyap * Description: Calls the CL internal callback routine, if any, for 420144966Svkashyap * each request in the complete queue. 421144966Svkashyap * 422144966Svkashyap * Input: ctlr -- ptr to CL internal ctlr context 423144966Svkashyap * Output: None 424144966Svkashyap * Return value: None 425144966Svkashyap */ 426144966SvkashyapTW_VOID 427144966Svkashyaptw_cli_process_complete_queue(struct tw_cli_ctlr_context *ctlr) 428144966Svkashyap{ 429144966Svkashyap struct tw_cli_req_context *req; 430144966Svkashyap 431144966Svkashyap tw_cli_dbg_printf(10, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 432144966Svkashyap 433144966Svkashyap /* 434144966Svkashyap * Pull commands off the completed list, dispatch them appropriately. 435144966Svkashyap */ 436144966Svkashyap while ((req = tw_cli_req_q_remove_head(ctlr, TW_CLI_COMPLETE_Q)) != 437144966Svkashyap TW_CL_NULL) { 438144966Svkashyap /* Call the CL internal callback, if there's one. */ 439144966Svkashyap if (req->tw_cli_callback) 440144966Svkashyap req->tw_cli_callback(req); 441144966Svkashyap } 442144966Svkashyap} 443144966Svkashyap 444144966Svkashyap 445144966Svkashyap 446144966Svkashyap/* 447144966Svkashyap * Function name: tw_cli_complete_io 448144966Svkashyap * Description: CL internal callback for SCSI/fw passthru requests. 449144966Svkashyap * 450144966Svkashyap * Input: req -- ptr to CL internal request context 451144966Svkashyap * Output: None 452144966Svkashyap * Return value: None 453144966Svkashyap */ 454144966SvkashyapTW_VOID 455144966Svkashyaptw_cli_complete_io(struct tw_cli_req_context *req) 456144966Svkashyap{ 457144966Svkashyap struct tw_cli_ctlr_context *ctlr = req->ctlr; 458144966Svkashyap struct tw_cl_req_packet *req_pkt = 459144966Svkashyap (struct tw_cl_req_packet *)(req->orig_req); 460144966Svkashyap 461144966Svkashyap tw_cli_dbg_printf(8, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 462144966Svkashyap 463144966Svkashyap req_pkt->status = TW_CL_ERR_REQ_SUCCESS; 464144966Svkashyap if (req->error_code) { 465144966Svkashyap req_pkt->status = TW_CL_ERR_REQ_UNABLE_TO_SUBMIT_COMMAND; 466144966Svkashyap goto out; 467144966Svkashyap } 468144966Svkashyap 469144966Svkashyap if (req->state != TW_CLI_REQ_STATE_COMPLETE) { 470144966Svkashyap tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 471144966Svkashyap TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 472144966Svkashyap 0x1203, 0x1, TW_CL_SEVERITY_ERROR_STRING, 473144966Svkashyap "I/O completion on incomplete command!!", 474144966Svkashyap "request = %p, status = %d", 475144966Svkashyap req, req->state); 476144966Svkashyap#ifdef TW_OSL_DEBUG 477144966Svkashyap tw_cl_print_ctlr_stats(ctlr->ctlr_handle); 478144966Svkashyap#endif /* TW_OSL_DEBUG */ 479144966Svkashyap tw_cl_reset_ctlr(ctlr->ctlr_handle); 480144966Svkashyap req_pkt->status = TW_CL_ERR_REQ_BUS_RESET; 481144966Svkashyap goto out; 482144966Svkashyap } 483144966Svkashyap 484144966Svkashyap if (req->flags & TW_CLI_REQ_FLAGS_PASSTHRU) { 485144966Svkashyap /* Copy the command packet back into OSL's space. */ 486144966Svkashyap tw_osl_memcpy(req_pkt->gen_req_pkt.pt_req.cmd_pkt, req->cmd_pkt, 487144966Svkashyap sizeof(struct tw_cl_command_packet)); 488144966Svkashyap } else 489144966Svkashyap tw_cli_scsi_complete(req); 490144966Svkashyap 491144966Svkashyapout: 492144966Svkashyap req_pkt->tw_osl_callback(req->req_handle); 493144966Svkashyap tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q); 494144966Svkashyap} 495144966Svkashyap 496144966Svkashyap 497144966Svkashyap 498144966Svkashyap/* 499144966Svkashyap * Function name: tw_cli_scsi_complete 500144966Svkashyap * Description: Completion routine for SCSI requests. 501144966Svkashyap * 502144966Svkashyap * Input: req -- ptr to CL internal request context 503144966Svkashyap * Output: None 504144966Svkashyap * Return value: None 505144966Svkashyap */ 506144966SvkashyapTW_VOID 507144966Svkashyaptw_cli_scsi_complete(struct tw_cli_req_context *req) 508144966Svkashyap{ 509144966Svkashyap struct tw_cl_req_packet *req_pkt = 510144966Svkashyap (struct tw_cl_req_packet *)(req->orig_req); 511144966Svkashyap struct tw_cl_scsi_req_packet *scsi_req = 512144966Svkashyap &(req_pkt->gen_req_pkt.scsi_req); 513144966Svkashyap struct tw_cl_command_9k *cmd = 514144966Svkashyap &(req->cmd_pkt->command.cmd_pkt_9k); 515144966Svkashyap struct tw_cl_command_header *cmd_hdr; 516144966Svkashyap TW_UINT16 error; 517144966Svkashyap TW_UINT8 *cdb; 518144966Svkashyap 519144966Svkashyap tw_cli_dbg_printf(8, req->ctlr->ctlr_handle, tw_osl_cur_func(), 520144966Svkashyap "entered"); 521144966Svkashyap 522144966Svkashyap scsi_req->scsi_status = cmd->status; 523144966Svkashyap if (! cmd->status) 524144966Svkashyap return; 525144966Svkashyap 526144966Svkashyap tw_cli_dbg_printf(1, req->ctlr->ctlr_handle, tw_osl_cur_func(), 527144966Svkashyap "req_id = 0x%x, status = 0x%x", 528144966Svkashyap GET_REQ_ID(cmd->lun_l4__req_id), cmd->status); 529144966Svkashyap 530144966Svkashyap cmd_hdr = &(req->cmd_pkt->cmd_hdr); 531144966Svkashyap error = cmd_hdr->status_block.error; 532144966Svkashyap if ((error == TWA_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) || 533144966Svkashyap (error == TWA_ERROR_UNIT_OFFLINE)) { 534144966Svkashyap if (GET_LUN_L4(cmd->lun_l4__req_id)) 535144966Svkashyap req_pkt->status |= TW_CL_ERR_REQ_INVALID_LUN; 536144966Svkashyap else 537144966Svkashyap req_pkt->status |= TW_CL_ERR_REQ_INVALID_TARGET; 538144966Svkashyap } else { 539144966Svkashyap tw_cli_dbg_printf(2, req->ctlr->ctlr_handle, 540144966Svkashyap tw_osl_cur_func(), 541144966Svkashyap "cmd = %x %x %x %x %x %x %x", 542144966Svkashyap GET_OPCODE(cmd->res__opcode), 543144966Svkashyap GET_SGL_OFF(cmd->res__opcode), 544144966Svkashyap cmd->unit, 545144966Svkashyap cmd->lun_l4__req_id, 546144966Svkashyap cmd->status, 547144966Svkashyap cmd->sgl_offset, 548144966Svkashyap cmd->lun_h4__sgl_entries); 549144966Svkashyap 550144966Svkashyap cdb = (TW_UINT8 *)(cmd->cdb); 551144966Svkashyap tw_cli_dbg_printf(2, req->ctlr->ctlr_handle, 552144966Svkashyap tw_osl_cur_func(), 553144966Svkashyap "cdb = %x %x %x %x %x %x %x %x " 554144966Svkashyap "%x %x %x %x %x %x %x %x", 555144966Svkashyap cdb[0], cdb[1], cdb[2], cdb[3], 556144966Svkashyap cdb[4], cdb[5], cdb[6], cdb[7], 557144966Svkashyap cdb[8], cdb[9], cdb[10], cdb[11], 558144966Svkashyap cdb[12], cdb[13], cdb[14], cdb[15]); 559144966Svkashyap 560144966Svkashyap /* 561144966Svkashyap * Print the error. Firmware doesn't yet support 562144966Svkashyap * the 'Mode Sense' cmd. Don't print if the cmd 563144966Svkashyap * is 'Mode Sense', and the error is 'Invalid field 564144966Svkashyap * in CDB'. 565144966Svkashyap */ 566144966Svkashyap if (! ((cdb[0] == 0x1A) && (error == 0x10D))) 567144966Svkashyap tw_cli_create_ctlr_event(req->ctlr, 568144966Svkashyap TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR, 569144966Svkashyap cmd_hdr); 570144966Svkashyap } 571144966Svkashyap 572144966Svkashyap if (scsi_req->sense_data) { 573144966Svkashyap tw_osl_memcpy(scsi_req->sense_data, cmd_hdr->sense_data, 574144966Svkashyap TWA_SENSE_DATA_LENGTH); 575144966Svkashyap scsi_req->sense_len = TWA_SENSE_DATA_LENGTH; 576144966Svkashyap req_pkt->status |= TW_CL_ERR_REQ_AUTO_SENSE_VALID; 577144966Svkashyap } 578144966Svkashyap req_pkt->status |= TW_CL_ERR_REQ_SCSI_ERROR; 579144966Svkashyap} 580144966Svkashyap 581144966Svkashyap 582144966Svkashyap 583144966Svkashyap/* 584144966Svkashyap * Function name: tw_cli_param_callback 585144966Svkashyap * Description: Callback for get/set_param requests. 586144966Svkashyap * 587144966Svkashyap * Input: req -- ptr to completed request pkt 588144966Svkashyap * Output: None 589144966Svkashyap * Return value: None 590144966Svkashyap */ 591144966SvkashyapTW_VOID 592144966Svkashyaptw_cli_param_callback(struct tw_cli_req_context *req) 593144966Svkashyap{ 594144966Svkashyap struct tw_cli_ctlr_context *ctlr = req->ctlr; 595144966Svkashyap union tw_cl_command_7k *cmd = 596144966Svkashyap &(req->cmd_pkt->command.cmd_pkt_7k); 597144966Svkashyap TW_INT32 error; 598144966Svkashyap 599144966Svkashyap tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 600144966Svkashyap 601144966Svkashyap /* 602144966Svkashyap * If the request was never submitted to the controller, the function 603144966Svkashyap * that sets req->error is responsible for calling tw_cl_create_event. 604144966Svkashyap */ 605144966Svkashyap if (! req->error_code) 606144966Svkashyap if (cmd->param.status) { 607144966Svkashyap tw_cli_create_ctlr_event(ctlr, 608144966Svkashyap TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR, 609144966Svkashyap &(req->cmd_pkt->cmd_hdr)); 610144966Svkashyap tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 611144966Svkashyap TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 612144966Svkashyap 0x1204, 0x1, TW_CL_SEVERITY_ERROR_STRING, 613144966Svkashyap "get/set_param failed", 614144966Svkashyap "status = %d", cmd->param.status); 615144966Svkashyap } 616144966Svkashyap 617144966Svkashyap ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY; 618144966Svkashyap tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q); 619144966Svkashyap 620144966Svkashyap if ((ctlr->state & TW_CLI_CTLR_STATE_GET_MORE_AENS) && 621144966Svkashyap (!(ctlr->state & TW_CLI_CTLR_STATE_RESET_IN_PROGRESS))) { 622144966Svkashyap ctlr->state &= ~TW_CLI_CTLR_STATE_GET_MORE_AENS; 623144966Svkashyap tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), 624144966Svkashyap "Fetching more AEN's"); 625144966Svkashyap if ((error = tw_cli_get_aen(ctlr))) 626144966Svkashyap tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 627144966Svkashyap TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 628144966Svkashyap 0x1205, 0x1, TW_CL_SEVERITY_ERROR_STRING, 629144966Svkashyap "Failed to fetch all AEN's from param_callback", 630144966Svkashyap "error = %d", error); 631144966Svkashyap } 632144966Svkashyap} 633144966Svkashyap 634144966Svkashyap 635144966Svkashyap 636144966Svkashyap/* 637144966Svkashyap * Function name: tw_cli_aen_callback 638144966Svkashyap * Description: Callback for requests to fetch AEN's. 639144966Svkashyap * 640144966Svkashyap * Input: req -- ptr to completed request pkt 641144966Svkashyap * Output: None 642144966Svkashyap * Return value: None 643144966Svkashyap */ 644144966SvkashyapTW_VOID 645144966Svkashyaptw_cli_aen_callback(struct tw_cli_req_context *req) 646144966Svkashyap{ 647144966Svkashyap struct tw_cli_ctlr_context *ctlr = req->ctlr; 648144966Svkashyap struct tw_cl_command_header *cmd_hdr; 649144966Svkashyap struct tw_cl_command_9k *cmd = 650144966Svkashyap &(req->cmd_pkt->command.cmd_pkt_9k); 651144966Svkashyap TW_UINT16 aen_code = TWA_AEN_QUEUE_EMPTY; 652144966Svkashyap TW_INT32 error; 653144966Svkashyap 654144966Svkashyap tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 655144966Svkashyap 656144966Svkashyap tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), 657144966Svkashyap "req_id = 0x%x, req error = %d, status = 0x%x", 658144966Svkashyap GET_REQ_ID(cmd->lun_l4__req_id), req->error_code, cmd->status); 659144966Svkashyap 660144966Svkashyap /* 661144966Svkashyap * If the request was never submitted to the controller, the function 662144966Svkashyap * that sets error is responsible for calling tw_cl_create_event. 663144966Svkashyap */ 664144966Svkashyap if (!(error = req->error_code)) 665144966Svkashyap if ((error = cmd->status)) { 666144966Svkashyap cmd_hdr = (struct tw_cl_command_header *) 667144966Svkashyap (&(req->cmd_pkt->cmd_hdr)); 668144966Svkashyap tw_cli_create_ctlr_event(ctlr, 669144966Svkashyap TW_CL_MESSAGE_SOURCE_CONTROLLER_ERROR, 670144966Svkashyap cmd_hdr); 671144966Svkashyap tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 672144966Svkashyap TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 673144966Svkashyap 0x1206, 0x1, TW_CL_SEVERITY_ERROR_STRING, 674144966Svkashyap "Request Sense failed", 675144966Svkashyap "opcode = 0x%x, status = %d", 676144966Svkashyap GET_OPCODE(cmd->res__opcode), cmd->status); 677144966Svkashyap } 678144966Svkashyap 679144966Svkashyap if (error) { 680144966Svkashyap ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY; 681144966Svkashyap tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q); 682144966Svkashyap return; 683144966Svkashyap } 684144966Svkashyap 685144966Svkashyap tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), 686144966Svkashyap "Request Sense command succeeded"); 687144966Svkashyap 688144966Svkashyap aen_code = tw_cli_manage_aen(ctlr, req); 689144966Svkashyap 690144966Svkashyap if (aen_code != TWA_AEN_SYNC_TIME_WITH_HOST) { 691144966Svkashyap ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY; 692144966Svkashyap tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q); 693144966Svkashyap if (aen_code != TWA_AEN_QUEUE_EMPTY) 694144966Svkashyap if ((error = tw_cli_get_aen(ctlr))) 695144966Svkashyap tw_cl_create_event(ctlr->ctlr_handle, 696144966Svkashyap TW_CL_FALSE, 697144966Svkashyap TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 698144966Svkashyap 0x1207, 0x1, 699144966Svkashyap TW_CL_SEVERITY_ERROR_STRING, 700144966Svkashyap "Failed to fetch all AEN's", 701144966Svkashyap "error = %d", error); 702144966Svkashyap } 703144966Svkashyap} 704144966Svkashyap 705144966Svkashyap 706144966Svkashyap 707144966Svkashyap/* 708144966Svkashyap * Function name: tw_cli_manage_aen 709144966Svkashyap * Description: Handles AEN's. 710144966Svkashyap * 711144966Svkashyap * Input: ctlr -- ptr to CL internal ctlr context 712144966Svkashyap * req -- ptr to CL internal request context 713144966Svkashyap * Output: None 714144966Svkashyap * Return value: None 715144966Svkashyap */ 716144966SvkashyapTW_UINT16 717144966Svkashyaptw_cli_manage_aen(struct tw_cli_ctlr_context *ctlr, 718144966Svkashyap struct tw_cli_req_context *req) 719144966Svkashyap{ 720144966Svkashyap struct tw_cl_command_header *cmd_hdr; 721144966Svkashyap TW_UINT16 aen_code; 722144966Svkashyap TW_TIME local_time; 723144966Svkashyap TW_TIME sync_time; 724144966Svkashyap TW_UINT32 error; 725144966Svkashyap 726144966Svkashyap tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 727144966Svkashyap 728144966Svkashyap cmd_hdr = (struct tw_cl_command_header *)(req->data); 729144966Svkashyap aen_code = cmd_hdr->status_block.error; 730144966Svkashyap 731144966Svkashyap switch (aen_code) { 732144966Svkashyap case TWA_AEN_SYNC_TIME_WITH_HOST: 733144966Svkashyap tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), 734144966Svkashyap "Received AEN_SYNC_TIME"); 735144966Svkashyap /* 736144966Svkashyap * Free the internal req pkt right here, since 737144966Svkashyap * tw_cli_set_param will need it. 738144966Svkashyap */ 739144966Svkashyap ctlr->state &= ~TW_CLI_CTLR_STATE_INTERNAL_REQ_BUSY; 740144966Svkashyap tw_cli_req_q_insert_tail(req, TW_CLI_FREE_Q); 741144966Svkashyap 742144966Svkashyap /* 743144966Svkashyap * We will use a callback in tw_cli_set_param only when 744144966Svkashyap * interrupts are enabled and we can expect our callback 745144966Svkashyap * to get called. Setting the TW_CLI_CTLR_STATE_GET_MORE_AENS 746144966Svkashyap * flag will make the callback continue to try to retrieve 747144966Svkashyap * more AEN's. 748144966Svkashyap */ 749144966Svkashyap if (ctlr->state & TW_CLI_CTLR_STATE_INTR_ENABLED) 750144966Svkashyap ctlr->state |= TW_CLI_CTLR_STATE_GET_MORE_AENS; 751144966Svkashyap /* Calculate time (in seconds) since last Sunday 12.00 AM. */ 752144966Svkashyap local_time = tw_osl_get_local_time(); 753144966Svkashyap sync_time = (local_time - (3 * 86400)) % 604800; 754144966Svkashyap if ((error = tw_cli_set_param(ctlr, TWA_PARAM_TIME_TABLE, 755144966Svkashyap TWA_PARAM_TIME_SCHED_TIME, 4, 756144966Svkashyap &sync_time, 757144966Svkashyap (ctlr->state & TW_CLI_CTLR_STATE_INTR_ENABLED) 758144966Svkashyap ? tw_cli_param_callback : TW_CL_NULL))) 759144966Svkashyap tw_cl_create_event(ctlr->ctlr_handle, TW_CL_FALSE, 760144966Svkashyap TW_CL_MESSAGE_SOURCE_COMMON_LAYER_ERROR, 761144966Svkashyap 0x1208, 0x1, TW_CL_SEVERITY_ERROR_STRING, 762144966Svkashyap "Unable to sync time with ctlr", 763144966Svkashyap "error = %d", error); 764144966Svkashyap 765144966Svkashyap break; 766144966Svkashyap 767144966Svkashyap 768144966Svkashyap case TWA_AEN_QUEUE_EMPTY: 769144966Svkashyap tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), 770144966Svkashyap "AEN queue empty"); 771144966Svkashyap break; 772144966Svkashyap 773144966Svkashyap 774144966Svkashyap default: 775144966Svkashyap /* Queue the event. */ 776144966Svkashyap 777144966Svkashyap tw_cli_dbg_printf(4, ctlr->ctlr_handle, tw_osl_cur_func(), 778144966Svkashyap "Queueing AEN"); 779144966Svkashyap tw_cli_create_ctlr_event(ctlr, 780144966Svkashyap TW_CL_MESSAGE_SOURCE_CONTROLLER_EVENT, 781144966Svkashyap cmd_hdr); 782144966Svkashyap break; 783144966Svkashyap } /* switch */ 784144966Svkashyap return(aen_code); 785144966Svkashyap} 786144966Svkashyap 787144966Svkashyap 788144966Svkashyap 789144966Svkashyap/* 790144966Svkashyap * Function name: tw_cli_enable_interrupts 791144966Svkashyap * Description: Enables interrupts on the controller 792144966Svkashyap * 793144966Svkashyap * Input: ctlr -- ptr to CL internal ctlr context 794144966Svkashyap * Output: None 795144966Svkashyap * Return value: None 796144966Svkashyap */ 797144966SvkashyapTW_VOID 798144966Svkashyaptw_cli_enable_interrupts(struct tw_cli_ctlr_context *ctlr) 799144966Svkashyap{ 800144966Svkashyap tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 801144966Svkashyap 802144966Svkashyap ctlr->state |= TW_CLI_CTLR_STATE_INTR_ENABLED; 803144966Svkashyap TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle, 804144966Svkashyap TWA_CONTROL_CLEAR_ATTENTION_INTERRUPT | 805144966Svkashyap TWA_CONTROL_UNMASK_RESPONSE_INTERRUPT | 806144966Svkashyap TWA_CONTROL_ENABLE_INTERRUPTS); 807144966Svkashyap} 808144966Svkashyap 809144966Svkashyap 810144966Svkashyap 811144966Svkashyap/* 812144966Svkashyap * Function name: twa_setup 813144966Svkashyap * Description: Disables interrupts on the controller 814144966Svkashyap * 815144966Svkashyap * Input: ctlr -- ptr to CL internal ctlr context 816144966Svkashyap * Output: None 817144966Svkashyap * Return value: None 818144966Svkashyap */ 819144966SvkashyapTW_VOID 820144966Svkashyaptw_cli_disable_interrupts(struct tw_cli_ctlr_context *ctlr) 821144966Svkashyap{ 822144966Svkashyap tw_cli_dbg_printf(3, ctlr->ctlr_handle, tw_osl_cur_func(), "entered"); 823144966Svkashyap 824144966Svkashyap TW_CLI_WRITE_CONTROL_REGISTER(ctlr->ctlr_handle, 825144966Svkashyap TWA_CONTROL_DISABLE_INTERRUPTS); 826144966Svkashyap ctlr->state &= ~TW_CLI_CTLR_STATE_INTR_ENABLED; 827144966Svkashyap} 828144966Svkashyap 829