xref: /dflybsd-src/sys/dev/raid/twa/tw_cl.h (revision 1e0dd9dd32a69a1d3bbe6a9e41c3a63aae59fb4d)
1df54c2f9SSascha Wildner /*
2df54c2f9SSascha Wildner  * Copyright (c) 2004-07 Applied Micro Circuits Corporation.
3df54c2f9SSascha Wildner  * Copyright (c) 2004-05 Vinod Kashyap
4df54c2f9SSascha Wildner  * All rights reserved.
5df54c2f9SSascha Wildner  *
6df54c2f9SSascha Wildner  * Redistribution and use in source and binary forms, with or without
7df54c2f9SSascha Wildner  * modification, are permitted provided that the following conditions
8df54c2f9SSascha Wildner  * are met:
9df54c2f9SSascha Wildner  * 1. Redistributions of source code must retain the above copyright
10df54c2f9SSascha Wildner  *    notice, this list of conditions and the following disclaimer.
11df54c2f9SSascha Wildner  * 2. Redistributions in binary form must reproduce the above copyright
12df54c2f9SSascha Wildner  *    notice, this list of conditions and the following disclaimer in the
13df54c2f9SSascha Wildner  *    documentation and/or other materials provided with the distribution.
14df54c2f9SSascha Wildner  *
15df54c2f9SSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16df54c2f9SSascha Wildner  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17df54c2f9SSascha Wildner  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18df54c2f9SSascha Wildner  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19df54c2f9SSascha Wildner  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20df54c2f9SSascha Wildner  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21df54c2f9SSascha Wildner  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22df54c2f9SSascha Wildner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23df54c2f9SSascha Wildner  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24df54c2f9SSascha Wildner  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25df54c2f9SSascha Wildner  * SUCH DAMAGE.
26df54c2f9SSascha Wildner  *
27*1e0dd9ddSSascha Wildner  *	$FreeBSD: head/sys/dev/twa/tw_cl.h 212008 2010-08-30 19:15:04Z delphij $
28df54c2f9SSascha Wildner  */
29df54c2f9SSascha Wildner 
30df54c2f9SSascha Wildner /*
31df54c2f9SSascha Wildner  * AMCC'S 3ware driver for 9000 series storage controllers.
32df54c2f9SSascha Wildner  *
33df54c2f9SSascha Wildner  * Author: Vinod Kashyap
34df54c2f9SSascha Wildner  * Modifications by: Adam Radford
35df54c2f9SSascha Wildner  */
36df54c2f9SSascha Wildner 
37df54c2f9SSascha Wildner 
38df54c2f9SSascha Wildner 
39df54c2f9SSascha Wildner #ifndef TW_CL_H
40df54c2f9SSascha Wildner 
41df54c2f9SSascha Wildner #define TW_CL_H
42df54c2f9SSascha Wildner 
43df54c2f9SSascha Wildner 
44df54c2f9SSascha Wildner /*
45df54c2f9SSascha Wildner  * Common Layer internal macros, structures and functions.
46df54c2f9SSascha Wildner  */
47df54c2f9SSascha Wildner 
48df54c2f9SSascha Wildner 
49df54c2f9SSascha Wildner #define TW_CLI_SECTOR_SIZE		0x200
50df54c2f9SSascha Wildner #define TW_CLI_REQUEST_TIMEOUT_PERIOD	60 /* seconds */
51df54c2f9SSascha Wildner #define TW_CLI_RESET_TIMEOUT_PERIOD	60 /* seconds */
52df54c2f9SSascha Wildner #define TW_CLI_MAX_RESET_ATTEMPTS	2
53df54c2f9SSascha Wildner 
54df54c2f9SSascha Wildner /* Possible values of ctlr->ioctl_lock.lock. */
55df54c2f9SSascha Wildner #define TW_CLI_LOCK_FREE		0x0	/* lock is free */
56df54c2f9SSascha Wildner #define TW_CLI_LOCK_HELD		0x1	/* lock is held */
57df54c2f9SSascha Wildner 
58df54c2f9SSascha Wildner /* Possible values of req->state. */
59df54c2f9SSascha Wildner #define TW_CLI_REQ_STATE_INIT		0x0	/* being initialized */
60df54c2f9SSascha Wildner #define TW_CLI_REQ_STATE_BUSY		0x1	/* submitted to controller */
61df54c2f9SSascha Wildner #define TW_CLI_REQ_STATE_PENDING	0x2	/* in pending queue */
62df54c2f9SSascha Wildner #define TW_CLI_REQ_STATE_COMPLETE	0x3	/* completed by controller */
63df54c2f9SSascha Wildner 
64df54c2f9SSascha Wildner /* Possible values of req->flags. */
65df54c2f9SSascha Wildner #define TW_CLI_REQ_FLAGS_7K		(1<<0)	/* 7000 cmd pkt */
66df54c2f9SSascha Wildner #define TW_CLI_REQ_FLAGS_9K		(1<<1)	/* 9000 cmd pkt */
67df54c2f9SSascha Wildner #define TW_CLI_REQ_FLAGS_INTERNAL	(1<<2)	/* internal request */
68df54c2f9SSascha Wildner #define TW_CLI_REQ_FLAGS_PASSTHRU	(1<<3)	/* passthru request */
69df54c2f9SSascha Wildner #define TW_CLI_REQ_FLAGS_EXTERNAL	(1<<4)	/* external request */
70df54c2f9SSascha Wildner 
71df54c2f9SSascha Wildner #ifdef TW_OSL_PCI_CONFIG_ACCESSIBLE
72df54c2f9SSascha Wildner /* Register offsets in PCI config space. */
73df54c2f9SSascha Wildner #define TW_CLI_PCI_CONFIG_COMMAND_OFFSET	0x4 /* cmd register offset */
74df54c2f9SSascha Wildner #define TW_CLI_PCI_CONFIG_STATUS_OFFSET		0x6 /* status register offset */
75df54c2f9SSascha Wildner #endif /* TW_OSL_PCI_CONFIG_ACCESSIBLE */
76df54c2f9SSascha Wildner 
77df54c2f9SSascha Wildner 
78df54c2f9SSascha Wildner #ifdef TW_OSL_DEBUG
79df54c2f9SSascha Wildner struct tw_cli_q_stats {
80df54c2f9SSascha Wildner 	TW_UINT32	cur_len;/* current # of entries in q */
81df54c2f9SSascha Wildner 	TW_UINT32	max_len;	 /* max # of entries in q, ever reached */
82df54c2f9SSascha Wildner };
83df54c2f9SSascha Wildner #endif /* TW_OSL_DEBUG */
84df54c2f9SSascha Wildner 
85df54c2f9SSascha Wildner 
86df54c2f9SSascha Wildner /* Queues of CL internal request context packets. */
87df54c2f9SSascha Wildner #define TW_CLI_FREE_Q		0	/* free q */
88df54c2f9SSascha Wildner #define TW_CLI_BUSY_Q		1	/* q of reqs submitted to fw */
89df54c2f9SSascha Wildner #define TW_CLI_PENDING_Q	2	/* q of reqs deferred due to 'q full' */
90df54c2f9SSascha Wildner #define TW_CLI_COMPLETE_Q	3	/* q of reqs completed by fw */
914fbf05f9SSascha Wildner #define TW_CLI_RESET_Q		4	/* q of reqs reset by timeout */
924fbf05f9SSascha Wildner #define TW_CLI_Q_COUNT		5	/* total number of queues */
93df54c2f9SSascha Wildner 
94df54c2f9SSascha Wildner 
95df54c2f9SSascha Wildner /* CL's internal request context. */
96df54c2f9SSascha Wildner struct tw_cli_req_context {
97df54c2f9SSascha Wildner 	struct tw_cl_req_handle	*req_handle;/* handle to track requests between
98df54c2f9SSascha Wildner 						OSL & CL */
99df54c2f9SSascha Wildner 	struct tw_cli_ctlr_context  *ctlr; /* ptr to CL's controller context */
100df54c2f9SSascha Wildner 	struct tw_cl_command_packet *cmd_pkt;/* ptr to ctlr cmd pkt */
101df54c2f9SSascha Wildner 	TW_UINT64	cmd_pkt_phys;	/* cmd pkt physical address */
102df54c2f9SSascha Wildner 	TW_VOID		*data;		/* ptr to data being passed to fw */
103df54c2f9SSascha Wildner 	TW_UINT32	length;		/* length of data being passed to fw */
104df54c2f9SSascha Wildner 	TW_UINT64	data_phys;	/* physical address of data */
105df54c2f9SSascha Wildner 
106df54c2f9SSascha Wildner 	TW_UINT32	state;		/* request state */
107df54c2f9SSascha Wildner 	TW_UINT32	flags;		/* request flags */
108df54c2f9SSascha Wildner 
109df54c2f9SSascha Wildner 	TW_UINT32	error_code;	/* error encountered before submission
110df54c2f9SSascha Wildner 					of request to fw, if any */
111df54c2f9SSascha Wildner 
112df54c2f9SSascha Wildner 	TW_VOID		*orig_req;	/* ptr to original request for use
113df54c2f9SSascha Wildner 					during callback */
114df54c2f9SSascha Wildner 	TW_VOID		(*tw_cli_callback)(struct tw_cli_req_context *req);
115df54c2f9SSascha Wildner 					/* CL internal callback */
116df54c2f9SSascha Wildner 	TW_UINT32	request_id;	/* request id for tracking with fw */
117df54c2f9SSascha Wildner 	struct tw_cl_link link;		/* to link this request in a list */
118df54c2f9SSascha Wildner };
119df54c2f9SSascha Wildner 
120df54c2f9SSascha Wildner 
121df54c2f9SSascha Wildner /* CL's internal controller context. */
122df54c2f9SSascha Wildner struct tw_cli_ctlr_context {
123df54c2f9SSascha Wildner 	struct tw_cl_ctlr_handle *ctlr_handle;	/* handle to track ctlr between
124df54c2f9SSascha Wildner 							OSL & CL. */
125df54c2f9SSascha Wildner 	struct tw_cli_req_context *req_ctxt_buf;/* pointer to the array of CL's
126df54c2f9SSascha Wildner 						internal request context pkts */
127df54c2f9SSascha Wildner 	struct tw_cl_command_packet *cmd_pkt_buf;/* ptr to array of cmd pkts */
128df54c2f9SSascha Wildner 
129df54c2f9SSascha Wildner 	TW_UINT64		cmd_pkt_phys;	/* phys addr of cmd_pkt_buf */
130df54c2f9SSascha Wildner 
131df54c2f9SSascha Wildner 	TW_UINT32		device_id;	/* controller device id */
132df54c2f9SSascha Wildner 	TW_UINT32		arch_id;	/* controller architecture id */
133df54c2f9SSascha Wildner 	TW_UINT8 		active;			  /* Initialization done, and controller is active. */
134df54c2f9SSascha Wildner 	TW_UINT8 		interrupts_enabled;	  /* Interrupts on controller enabled. */
135df54c2f9SSascha Wildner 	TW_UINT8 		internal_req_busy;	  /* Data buffer for internal requests in use. */
136df54c2f9SSascha Wildner 	TW_UINT8 		get_more_aens;		  /* More AEN's need to be retrieved. */
1374fbf05f9SSascha Wildner 	TW_UINT8 		reset_needed;		  /* Controller needs a soft reset. */
138df54c2f9SSascha Wildner 	TW_UINT8 		reset_in_progress;	  /* Controller is being reset. */
139df54c2f9SSascha Wildner 	TW_UINT8 		reset_phase1_in_progress; /* In 'phase 1' of reset. */
140df54c2f9SSascha Wildner 	TW_UINT32		flags;		/* controller settings */
141df54c2f9SSascha Wildner 	TW_UINT32		sg_size_factor;	/* SG element size should be a
142df54c2f9SSascha Wildner 							multiple of this */
143df54c2f9SSascha Wildner 
144df54c2f9SSascha Wildner 	/* Request queues and arrays. */
145df54c2f9SSascha Wildner 	struct tw_cl_link	req_q_head[TW_CLI_Q_COUNT];
146df54c2f9SSascha Wildner 
147df54c2f9SSascha Wildner 	TW_UINT8		*internal_req_data;/* internal req data buf */
148df54c2f9SSascha Wildner 	TW_UINT64		internal_req_data_phys;/* phys addr of internal
149df54c2f9SSascha Wildner 							req data buf */
150df54c2f9SSascha Wildner 	TW_UINT32		max_simult_reqs; /* max simultaneous requests
151df54c2f9SSascha Wildner 							supported */
152df54c2f9SSascha Wildner 	TW_UINT32		max_aens_supported;/* max AEN's supported */
153df54c2f9SSascha Wildner 	/* AEN handler fields. */
154df54c2f9SSascha Wildner 	struct tw_cl_event_packet *aen_queue;	/* circular queue of AENs from
155df54c2f9SSascha Wildner 							firmware/CL/OSL */
156df54c2f9SSascha Wildner 	TW_UINT32		aen_head;	/* AEN queue head */
157df54c2f9SSascha Wildner 	TW_UINT32		aen_tail;	/* AEN queue tail */
158df54c2f9SSascha Wildner 	TW_UINT32		aen_cur_seq_id;	/* index of the last event+1 */
159df54c2f9SSascha Wildner 	TW_UINT32		aen_q_overflow;	/* indicates if unretrieved
160df54c2f9SSascha Wildner 						events were overwritten */
161df54c2f9SSascha Wildner 	TW_UINT32		aen_q_wrapped;	/* indicates if AEN queue ever
162df54c2f9SSascha Wildner 							wrapped */
163df54c2f9SSascha Wildner 
164df54c2f9SSascha Wildner 	TW_UINT16		working_srl;	/* driver & firmware negotiated
165df54c2f9SSascha Wildner 							srl */
166df54c2f9SSascha Wildner 	TW_UINT16		working_branch;	/* branch # of the firmware
167df54c2f9SSascha Wildner 					that the driver is compatible with */
168df54c2f9SSascha Wildner 	TW_UINT16		working_build;	/* build # of the firmware
169df54c2f9SSascha Wildner 					that the driver is compatible with */
170df54c2f9SSascha Wildner 	TW_UINT16		fw_on_ctlr_srl;	/* srl of running firmware */
171df54c2f9SSascha Wildner 	TW_UINT16		fw_on_ctlr_branch;/* branch # of running
172df54c2f9SSascha Wildner 							firmware */
173df54c2f9SSascha Wildner 	TW_UINT16		fw_on_ctlr_build;/* build # of running
174df54c2f9SSascha Wildner 							firmware */
175df54c2f9SSascha Wildner 	TW_UINT32		operating_mode; /* base mode/current mode */
176df54c2f9SSascha Wildner 
177df54c2f9SSascha Wildner 	TW_INT32		host_intr_pending;/* host intr processing
178df54c2f9SSascha Wildner 							needed */
179df54c2f9SSascha Wildner 	TW_INT32		attn_intr_pending;/* attn intr processing
180df54c2f9SSascha Wildner 							needed */
181df54c2f9SSascha Wildner 	TW_INT32		cmd_intr_pending;/* cmd intr processing
182df54c2f9SSascha Wildner 							needed */
183df54c2f9SSascha Wildner 	TW_INT32		resp_intr_pending;/* resp intr processing
184df54c2f9SSascha Wildner 							needed */
185df54c2f9SSascha Wildner 
186df54c2f9SSascha Wildner 	TW_LOCK_HANDLE		gen_lock_handle;/* general purpose lock */
187df54c2f9SSascha Wildner 	TW_LOCK_HANDLE		*gen_lock;/* ptr to general purpose lock */
188df54c2f9SSascha Wildner 	TW_LOCK_HANDLE		io_lock_handle;	/* lock held during cmd
189df54c2f9SSascha Wildner 						submission */
190df54c2f9SSascha Wildner 	TW_LOCK_HANDLE		*io_lock;/* ptr to lock held during cmd
191df54c2f9SSascha Wildner 						submission */
192df54c2f9SSascha Wildner 
193df54c2f9SSascha Wildner #ifdef TW_OSL_CAN_SLEEP
194df54c2f9SSascha Wildner 	TW_SLEEP_HANDLE		sleep_handle;	/* handle to co-ordinate sleeps
195df54c2f9SSascha Wildner 						& wakeups */
196df54c2f9SSascha Wildner #endif /* TW_OSL_CAN_SLEEP */
197df54c2f9SSascha Wildner 
198df54c2f9SSascha Wildner 	struct {
199df54c2f9SSascha Wildner 		TW_UINT32	lock;		/* lock state */
200df54c2f9SSascha Wildner 		TW_TIME		timeout;	/* time at which the lock will
201df54c2f9SSascha Wildner 						become available, even if not
202df54c2f9SSascha Wildner 						explicitly released */
203df54c2f9SSascha Wildner 	} ioctl_lock;		/* lock for use by user applications, for
204df54c2f9SSascha Wildner 				synchronization between ioctl calls */
205df54c2f9SSascha Wildner #ifdef TW_OSL_DEBUG
206df54c2f9SSascha Wildner 	struct tw_cli_q_stats	q_stats[TW_CLI_Q_COUNT];/* queue statistics */
207df54c2f9SSascha Wildner #endif /* TW_OSL_DEBUG */
208df54c2f9SSascha Wildner };
209df54c2f9SSascha Wildner 
210df54c2f9SSascha Wildner 
211df54c2f9SSascha Wildner 
212df54c2f9SSascha Wildner /*
213df54c2f9SSascha Wildner  * Queue primitives
214df54c2f9SSascha Wildner  */
215df54c2f9SSascha Wildner 
216df54c2f9SSascha Wildner #ifdef TW_OSL_DEBUG
217df54c2f9SSascha Wildner 
218df54c2f9SSascha Wildner #define TW_CLI_Q_INIT(ctlr, q_type)	do {				\
219df54c2f9SSascha Wildner 	(ctlr)->q_stats[q_type].cur_len = 0;				\
220df54c2f9SSascha Wildner 	(ctlr)->q_stats[q_type].max_len = 0;				\
221df54c2f9SSascha Wildner } while (0)
222df54c2f9SSascha Wildner 
223df54c2f9SSascha Wildner 
224df54c2f9SSascha Wildner #define TW_CLI_Q_INSERT(ctlr, q_type)	do {				\
225df54c2f9SSascha Wildner 	struct tw_cli_q_stats *q_stats = &((ctlr)->q_stats[q_type]);	\
226df54c2f9SSascha Wildner 									\
227df54c2f9SSascha Wildner 	if (++(q_stats->cur_len) > q_stats->max_len)			\
228df54c2f9SSascha Wildner 		q_stats->max_len = q_stats->cur_len;			\
229df54c2f9SSascha Wildner } while (0)
230df54c2f9SSascha Wildner 
231df54c2f9SSascha Wildner 
232df54c2f9SSascha Wildner #define TW_CLI_Q_REMOVE(ctlr, q_type)					\
233df54c2f9SSascha Wildner 	(ctlr)->q_stats[q_type].cur_len--
234df54c2f9SSascha Wildner 
235df54c2f9SSascha Wildner #else /* TW_OSL_DEBUG */
236df54c2f9SSascha Wildner 
237df54c2f9SSascha Wildner #define TW_CLI_Q_INIT(ctlr, q_index)
238df54c2f9SSascha Wildner #define TW_CLI_Q_INSERT(ctlr, q_index)
239df54c2f9SSascha Wildner #define TW_CLI_Q_REMOVE(ctlr, q_index)
240df54c2f9SSascha Wildner 
241df54c2f9SSascha Wildner #endif /* TW_OSL_DEBUG */
242df54c2f9SSascha Wildner 
243df54c2f9SSascha Wildner 
244df54c2f9SSascha Wildner /* Initialize a queue of requests. */
245df54c2f9SSascha Wildner static __inline TW_VOID
tw_cli_req_q_init(struct tw_cli_ctlr_context * ctlr,TW_UINT8 q_type)246df54c2f9SSascha Wildner tw_cli_req_q_init(struct tw_cli_ctlr_context *ctlr, TW_UINT8 q_type)
247df54c2f9SSascha Wildner {
248df54c2f9SSascha Wildner 	TW_CL_Q_INIT(&(ctlr->req_q_head[q_type]));
249df54c2f9SSascha Wildner 	TW_CLI_Q_INIT(ctlr, q_type);
250df54c2f9SSascha Wildner }
251df54c2f9SSascha Wildner 
252df54c2f9SSascha Wildner 
253df54c2f9SSascha Wildner 
254df54c2f9SSascha Wildner /* Insert the given request at the head of the given queue (q_type). */
255df54c2f9SSascha Wildner static __inline TW_VOID
tw_cli_req_q_insert_head(struct tw_cli_req_context * req,TW_UINT8 q_type)256df54c2f9SSascha Wildner tw_cli_req_q_insert_head(struct tw_cli_req_context *req, TW_UINT8 q_type)
257df54c2f9SSascha Wildner {
258df54c2f9SSascha Wildner 	struct tw_cli_ctlr_context	*ctlr = req->ctlr;
259df54c2f9SSascha Wildner 
260df54c2f9SSascha Wildner 	tw_osl_get_lock(ctlr->ctlr_handle, ctlr->gen_lock);
261df54c2f9SSascha Wildner 	TW_CL_Q_INSERT_HEAD(&(ctlr->req_q_head[q_type]), &(req->link));
262df54c2f9SSascha Wildner 	TW_CLI_Q_INSERT(ctlr, q_type);
263df54c2f9SSascha Wildner 	tw_osl_free_lock(ctlr->ctlr_handle, ctlr->gen_lock);
264df54c2f9SSascha Wildner }
265df54c2f9SSascha Wildner 
266df54c2f9SSascha Wildner 
267df54c2f9SSascha Wildner 
268df54c2f9SSascha Wildner /* Insert the given request at the tail of the given queue (q_type). */
269df54c2f9SSascha Wildner static __inline TW_VOID
tw_cli_req_q_insert_tail(struct tw_cli_req_context * req,TW_UINT8 q_type)270df54c2f9SSascha Wildner tw_cli_req_q_insert_tail(struct tw_cli_req_context *req, TW_UINT8 q_type)
271df54c2f9SSascha Wildner {
272df54c2f9SSascha Wildner 	struct tw_cli_ctlr_context	*ctlr = req->ctlr;
273df54c2f9SSascha Wildner 
274df54c2f9SSascha Wildner 	tw_osl_get_lock(ctlr->ctlr_handle, ctlr->gen_lock);
275df54c2f9SSascha Wildner 	TW_CL_Q_INSERT_TAIL(&(ctlr->req_q_head[q_type]), &(req->link));
276df54c2f9SSascha Wildner 	TW_CLI_Q_INSERT(ctlr, q_type);
277df54c2f9SSascha Wildner 	tw_osl_free_lock(ctlr->ctlr_handle, ctlr->gen_lock);
278df54c2f9SSascha Wildner }
279df54c2f9SSascha Wildner 
280df54c2f9SSascha Wildner 
281df54c2f9SSascha Wildner 
282df54c2f9SSascha Wildner /* Remove and return the request at the head of the given queue (q_type). */
283df54c2f9SSascha Wildner static __inline struct tw_cli_req_context *
tw_cli_req_q_remove_head(struct tw_cli_ctlr_context * ctlr,TW_UINT8 q_type)284df54c2f9SSascha Wildner tw_cli_req_q_remove_head(struct tw_cli_ctlr_context *ctlr, TW_UINT8 q_type)
285df54c2f9SSascha Wildner {
286df54c2f9SSascha Wildner 	struct tw_cli_req_context	*req = TW_CL_NULL;
287df54c2f9SSascha Wildner 	struct tw_cl_link		*link;
288df54c2f9SSascha Wildner 
289df54c2f9SSascha Wildner 	tw_osl_get_lock(ctlr->ctlr_handle, ctlr->gen_lock);
290df54c2f9SSascha Wildner 	if ((link = TW_CL_Q_FIRST_ITEM(&(ctlr->req_q_head[q_type]))) !=
291df54c2f9SSascha Wildner 		TW_CL_NULL) {
292df54c2f9SSascha Wildner 		req = TW_CL_STRUCT_HEAD(link,
293df54c2f9SSascha Wildner 			struct tw_cli_req_context, link);
294df54c2f9SSascha Wildner 		TW_CL_Q_REMOVE_ITEM(&(ctlr->req_q_head[q_type]), &(req->link));
295df54c2f9SSascha Wildner 		TW_CLI_Q_REMOVE(ctlr, q_type);
296df54c2f9SSascha Wildner 	}
297df54c2f9SSascha Wildner 	tw_osl_free_lock(ctlr->ctlr_handle, ctlr->gen_lock);
298df54c2f9SSascha Wildner 	return(req);
299df54c2f9SSascha Wildner }
300df54c2f9SSascha Wildner 
301df54c2f9SSascha Wildner 
302df54c2f9SSascha Wildner 
303df54c2f9SSascha Wildner /* Remove the given request from the given queue (q_type). */
304df54c2f9SSascha Wildner static __inline TW_VOID
tw_cli_req_q_remove_item(struct tw_cli_req_context * req,TW_UINT8 q_type)305df54c2f9SSascha Wildner tw_cli_req_q_remove_item(struct tw_cli_req_context *req, TW_UINT8 q_type)
306df54c2f9SSascha Wildner {
307df54c2f9SSascha Wildner 	struct tw_cli_ctlr_context	*ctlr = req->ctlr;
308df54c2f9SSascha Wildner 
309df54c2f9SSascha Wildner 	tw_osl_get_lock(ctlr->ctlr_handle, ctlr->gen_lock);
310df54c2f9SSascha Wildner 	TW_CL_Q_REMOVE_ITEM(&(ctlr->req_q_head[q_type]), &(req->link));
311df54c2f9SSascha Wildner 	TW_CLI_Q_REMOVE(ctlr, q_type);
312df54c2f9SSascha Wildner 	tw_osl_free_lock(ctlr->ctlr_handle, ctlr->gen_lock);
313df54c2f9SSascha Wildner }
314df54c2f9SSascha Wildner 
315df54c2f9SSascha Wildner 
316df54c2f9SSascha Wildner 
317df54c2f9SSascha Wildner /* Create an event packet for an event/error posted by the controller. */
318df54c2f9SSascha Wildner #define tw_cli_create_ctlr_event(ctlr, event_src, cmd_hdr)	do {	\
319df54c2f9SSascha Wildner 	TW_UINT8 severity =						\
320df54c2f9SSascha Wildner 		GET_SEVERITY((cmd_hdr)->status_block.res__severity);	\
321df54c2f9SSascha Wildner 									\
322df54c2f9SSascha Wildner 	tw_cl_create_event(ctlr->ctlr_handle, TW_CL_TRUE, event_src,	\
323df54c2f9SSascha Wildner 		(cmd_hdr)->status_block.error,				\
324df54c2f9SSascha Wildner 		severity,						\
325df54c2f9SSascha Wildner 		tw_cli_severity_string_table[severity],			\
326df54c2f9SSascha Wildner 		(cmd_hdr)->err_specific_desc +				\
327df54c2f9SSascha Wildner 		tw_osl_strlen((cmd_hdr)->err_specific_desc) + 1,	\
328df54c2f9SSascha Wildner 		(cmd_hdr)->err_specific_desc);				\
329df54c2f9SSascha Wildner 	/* Print 18 bytes of sense information. */			\
330df54c2f9SSascha Wildner 	tw_cli_dbg_printf(2, ctlr->ctlr_handle,				\
331df54c2f9SSascha Wildner 		tw_osl_cur_func(),					\
332df54c2f9SSascha Wildner 		"sense info: %x %x %x %x %x %x %x %x %x "		\
333df54c2f9SSascha Wildner 		"%x %x %x %x %x %x %x %x %x",				\
334df54c2f9SSascha Wildner 		(cmd_hdr)->sense_data[0], (cmd_hdr)->sense_data[1],	\
335df54c2f9SSascha Wildner 		(cmd_hdr)->sense_data[2], (cmd_hdr)->sense_data[3],	\
336df54c2f9SSascha Wildner 		(cmd_hdr)->sense_data[4], (cmd_hdr)->sense_data[5],	\
337df54c2f9SSascha Wildner 		(cmd_hdr)->sense_data[6], (cmd_hdr)->sense_data[7],	\
338df54c2f9SSascha Wildner 		(cmd_hdr)->sense_data[8], (cmd_hdr)->sense_data[9],	\
339df54c2f9SSascha Wildner 		(cmd_hdr)->sense_data[10], (cmd_hdr)->sense_data[11],	\
340df54c2f9SSascha Wildner 		(cmd_hdr)->sense_data[12], (cmd_hdr)->sense_data[13],	\
341df54c2f9SSascha Wildner 		(cmd_hdr)->sense_data[14], (cmd_hdr)->sense_data[15],	\
342df54c2f9SSascha Wildner 		(cmd_hdr)->sense_data[16], (cmd_hdr)->sense_data[17]);	\
343df54c2f9SSascha Wildner } while (0)
344df54c2f9SSascha Wildner 
345df54c2f9SSascha Wildner 
346df54c2f9SSascha Wildner 
347df54c2f9SSascha Wildner #endif /* TW_CL_H */
348