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