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