xref: /illumos-gate/usr/src/uts/intel/io/dktp/hba/ghd/ghd.h (revision 2d6eb4a5)
1*507c3241Smlf /*
2*507c3241Smlf  * CDDL HEADER START
3*507c3241Smlf  *
4*507c3241Smlf  * The contents of this file are subject to the terms of the
5*507c3241Smlf  * Common Development and Distribution License (the "License").
6*507c3241Smlf  * You may not use this file except in compliance with the License.
7*507c3241Smlf  *
8*507c3241Smlf  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*507c3241Smlf  * or http://www.opensolaris.org/os/licensing.
10*507c3241Smlf  * See the License for the specific language governing permissions
11*507c3241Smlf  * and limitations under the License.
12*507c3241Smlf  *
13*507c3241Smlf  * When distributing Covered Code, include this CDDL HEADER in each
14*507c3241Smlf  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*507c3241Smlf  * If applicable, add the following below this CDDL HEADER, with the
16*507c3241Smlf  * fields enclosed by brackets "[]" replaced with your own identifying
17*507c3241Smlf  * information: Portions Copyright [yyyy] [name of copyright owner]
18*507c3241Smlf  *
19*507c3241Smlf  * CDDL HEADER END
20*507c3241Smlf  */
21*507c3241Smlf 
22*507c3241Smlf /*
23*507c3241Smlf  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*507c3241Smlf  * Use is subject to license terms.
25*507c3241Smlf  */
26*507c3241Smlf 
27*507c3241Smlf #ifndef _GHD_H
28*507c3241Smlf #define	_GHD_H
29*507c3241Smlf 
30*507c3241Smlf #ifdef __cplusplus
31*507c3241Smlf extern "C" {
32*507c3241Smlf #endif
33*507c3241Smlf 
34*507c3241Smlf #include <sys/types.h>
35*507c3241Smlf #include <sys/conf.h>
36*507c3241Smlf #include <sys/kmem.h>
37*507c3241Smlf #include <sys/ddi.h>
38*507c3241Smlf #include <sys/sunddi.h>
39*507c3241Smlf #include <sys/debug.h>
40*507c3241Smlf #include <sys/scsi/scsi.h>
41*507c3241Smlf 
42*507c3241Smlf #include "ghd_queue.h"		/* linked list structures */
43*507c3241Smlf #include "ghd_scsi.h"
44*507c3241Smlf #include "ghd_waitq.h"
45*507c3241Smlf #include "ghd_debug.h"
46*507c3241Smlf 
47*507c3241Smlf #ifndef	TRUE
48*507c3241Smlf #define	TRUE	1
49*507c3241Smlf #endif
50*507c3241Smlf 
51*507c3241Smlf #ifndef	FALSE
52*507c3241Smlf #define	FALSE	0
53*507c3241Smlf #endif
54*507c3241Smlf 
55*507c3241Smlf /*
56*507c3241Smlf  * values for cmd_state:
57*507c3241Smlf  */
58*507c3241Smlf 
59*507c3241Smlf typedef enum {
60*507c3241Smlf 	GCMD_STATE_IDLE = 0,
61*507c3241Smlf 	GCMD_STATE_WAITQ,
62*507c3241Smlf 	GCMD_STATE_ACTIVE,
63*507c3241Smlf 	GCMD_STATE_DONEQ,
64*507c3241Smlf 	GCMD_STATE_ABORTING_CMD,
65*507c3241Smlf 	GCMD_STATE_ABORTING_DEV,
66*507c3241Smlf 	GCMD_STATE_RESETTING_DEV,
67*507c3241Smlf 	GCMD_STATE_RESETTING_BUS,
68*507c3241Smlf 	GCMD_STATE_HUNG,
69*507c3241Smlf 	GCMD_NSTATES
70*507c3241Smlf } cmdstate_t;
71*507c3241Smlf 
72*507c3241Smlf /*
73*507c3241Smlf  * action codes for the HBA timeout function
74*507c3241Smlf  */
75*507c3241Smlf 
76*507c3241Smlf typedef enum {
77*507c3241Smlf 	GACTION_EARLY_TIMEOUT = 0,	/* timed-out before started */
78*507c3241Smlf 	GACTION_EARLY_ABORT,		/* scsi_abort() before started */
79*507c3241Smlf 	GACTION_ABORT_CMD,		/* abort a specific request */
80*507c3241Smlf 	GACTION_ABORT_DEV,		/* abort everything on specifici dev */
81*507c3241Smlf 	GACTION_RESET_TARGET,		/* reset a specific dev */
82*507c3241Smlf 	GACTION_RESET_BUS,		/* reset the whole bus */
83*507c3241Smlf 	GACTION_INCOMPLETE		/* giving up on incomplete request */
84*507c3241Smlf } gact_t;
85*507c3241Smlf 
86*507c3241Smlf /*
87*507c3241Smlf  * types of ghd_timer_poll() invocations
88*507c3241Smlf  */
89*507c3241Smlf 
90*507c3241Smlf typedef enum {
91*507c3241Smlf 	GHD_TIMER_POLL_ALL = 0,		/* time out all expired commands */
92*507c3241Smlf 	GHD_TIMER_POLL_ONE		/* time out one, let caller loop */
93*507c3241Smlf } gtimer_poll_t;
94*507c3241Smlf 
95*507c3241Smlf /*
96*507c3241Smlf  * the common portion of the Command Control Block
97*507c3241Smlf  */
98*507c3241Smlf 
99*507c3241Smlf typedef struct ghd_cmd {
100*507c3241Smlf 	L2el_t		 cmd_q;		/* link for for done/active CCB Qs */
101*507c3241Smlf 	cmdstate_t	 cmd_state;	/* request's current state */
102*507c3241Smlf 	ulong_t		 cmd_waitq_level; /* which wait Q this request is on */
103*507c3241Smlf 	int		 cmd_flags;	/* generic magic info */
104*507c3241Smlf 
105*507c3241Smlf 	L2el_t		 cmd_timer_link; /* ccb timer doubly linked list */
106*507c3241Smlf 	ulong_t		 cmd_start_time; /* lbolt at start of request */
107*507c3241Smlf 	ulong_t		 cmd_timeout;	/* how long to wait */
108*507c3241Smlf 
109*507c3241Smlf 	opaque_t	 cmd_private;	/* used by the HBA driver */
110*507c3241Smlf 	void		*cmd_pktp;	/* request packet */
111*507c3241Smlf 	gtgt_t		*cmd_gtgtp;	/* dev instance for this request */
112*507c3241Smlf 
113*507c3241Smlf 	int		 cmd_dma_flags;
114*507c3241Smlf 	ddi_dma_handle_t cmd_dma_handle;
115*507c3241Smlf 	ddi_dma_win_t	 cmd_dmawin;
116*507c3241Smlf 	ddi_dma_seg_t	 cmd_dmaseg;
117*507c3241Smlf 
118*507c3241Smlf 	uint_t		 cmd_wcount;	/* ddi_dma_attr: window count */
119*507c3241Smlf 	uint_t		 cmd_windex;	/* ddi_dma_attr: current window */
120*507c3241Smlf 	uint_t		 cmd_ccount;	/* ddi_dma_attr: cookie count */
121*507c3241Smlf 	uint_t		 cmd_cindex;	/* ddi_dma_attr: current cookie */
122*507c3241Smlf 
123*507c3241Smlf 	long		 cmd_totxfer;	/* # bytes transferred so far */
124*507c3241Smlf 	ddi_dma_cookie_t cmd_first_cookie;
125*507c3241Smlf 	int		 use_first;
126*507c3241Smlf } gcmd_t;
127*507c3241Smlf 
128*507c3241Smlf 
129*507c3241Smlf /* definitions for cmd_flags */
130*507c3241Smlf #define	GCMDFLG_RESET_NOTIFY	1	/* command is a reset notification */
131*507c3241Smlf 
132*507c3241Smlf /*
133*507c3241Smlf  * Initialize the gcmd_t structure
134*507c3241Smlf  */
135*507c3241Smlf 
136*507c3241Smlf #define	GHD_GCMD_INIT(gcmdp, cmdp, gtgtp)	\
137*507c3241Smlf 	(L2_INIT(&(gcmdp)->cmd_q),		\
138*507c3241Smlf 	L2_INIT(&(gcmdp)->cmd_timer_link),	\
139*507c3241Smlf 	(gcmdp)->cmd_private = (cmdp),		\
140*507c3241Smlf 	(gcmdp)->cmd_gtgtp = (gtgtp)		\
141*507c3241Smlf )
142*507c3241Smlf 
143*507c3241Smlf 
144*507c3241Smlf /*
145*507c3241Smlf  * CMD/CCB timer config structure - one per HBA driver module
146*507c3241Smlf  */
147*507c3241Smlf typedef struct tmr_conf {
148*507c3241Smlf 	kmutex_t	t_mutex;	/* mutex to protect t_ccc_listp */
149*507c3241Smlf 	timeout_id_t	t_timeout_id;	/* handle for timeout() function */
150*507c3241Smlf 	long		t_ticks;	/* periodic timeout in clock ticks */
151*507c3241Smlf 	int		t_refs;		/* reference count */
152*507c3241Smlf 	struct cmd_ctl	*t_ccc_listp;	/* control struct list, one per HBA */
153*507c3241Smlf } tmr_t;
154*507c3241Smlf 
155*507c3241Smlf 
156*507c3241Smlf 
157*507c3241Smlf /*
158*507c3241Smlf  * CMD/CCB timer control structure - one per HBA instance (per board)
159*507c3241Smlf  */
160*507c3241Smlf typedef struct cmd_ctl {
161*507c3241Smlf 	struct cmd_ctl	*ccc_nextp;	/* list of control structs */
162*507c3241Smlf 	struct tmr_conf	*ccc_tmrp;	/* back ptr to config struct */
163*507c3241Smlf 	char		*ccc_label;	/* name of this HBA driver */
164*507c3241Smlf 
165*507c3241Smlf 	kmutex_t ccc_activel_mutex;	/* mutex to protect list ... */
166*507c3241Smlf 	L2el_t	 ccc_activel;		/* ... list of active CMD/CCBs */
167*507c3241Smlf 
168*507c3241Smlf 	dev_info_t *ccc_hba_dip;
169*507c3241Smlf 	ddi_iblock_cookie_t ccc_iblock;
170*507c3241Smlf 	ddi_softintr_t  ccc_soft_id;	/* ID for timeout softintr */
171*507c3241Smlf 
172*507c3241Smlf 	kmutex_t ccc_hba_mutex;		/* mutex for HBA soft-state */
173*507c3241Smlf 	int	 ccc_hba_pollmode;	/* FLAG_NOINTR mode active? */
174*507c3241Smlf 
175*507c3241Smlf 	L1_t	 ccc_devs;		/* unsorted list of attached devs */
176*507c3241Smlf 	kmutex_t ccc_waitq_mutex;	/* mutex to protect device wait Qs */
177*507c3241Smlf 	Q_t	 ccc_waitq;		/* the HBA's wait queue */
178*507c3241Smlf 	clock_t	 ccc_waitq_freezetime;	/* time the waitq was frozen, ticks */
179*507c3241Smlf 	uint_t	 ccc_waitq_freezedelay;	/* delta time until waitq thaws, ms */
180*507c3241Smlf 
181*507c3241Smlf 	ddi_softintr_t  ccc_doneq_softid; /* ID for doneq softintr */
182*507c3241Smlf 	kmutex_t ccc_doneq_mutex;	/* mutex to protect the doneq */
183*507c3241Smlf 	L2el_t	 ccc_doneq; 		/* completed cmd_t's */
184*507c3241Smlf 
185*507c3241Smlf 	void	*ccc_hba_handle;
186*507c3241Smlf 	int	(*ccc_ccballoc)();	/* alloc/init gcmd and ccb */
187*507c3241Smlf 	void	(*ccc_ccbfree)();
188*507c3241Smlf 	void	(*ccc_sg_func)();
189*507c3241Smlf 	int	(*ccc_hba_start)(void *handle, gcmd_t *);
190*507c3241Smlf 	void    (*ccc_hba_complete)(void *handle, gcmd_t *, int);
191*507c3241Smlf 	void	(*ccc_process_intr)(void *handle, void *intr_status);
192*507c3241Smlf 	int	(*ccc_get_status)(void *handle, void *intr_status);
193*507c3241Smlf 	int	(*ccc_timeout_func)(void *handle, gcmd_t *cmdp, gtgt_t *gtgtp,
194*507c3241Smlf 			gact_t action, int calltype);
195*507c3241Smlf 	void 	(*ccc_hba_reset_notify_callback)(gtgt_t *gtgtp,
196*507c3241Smlf 			void (*callback)(caddr_t),
197*507c3241Smlf 			caddr_t arg);
198*507c3241Smlf 	L2el_t	 ccc_reset_notify_list;	/* list of reset notifications */
199*507c3241Smlf 	kmutex_t ccc_reset_notify_mutex; /* and a mutex to protect it */
200*507c3241Smlf 	char	 ccc_timeout_pending;	/* timeout Q's softintr is triggered */
201*507c3241Smlf 	char	 ccc_waitq_frozen;	/* ccc_waitq_freezetime non-null */
202*507c3241Smlf 	char	 ccc_waitq_held;	/* frozen, but no freezetime */
203*507c3241Smlf } ccc_t;
204*507c3241Smlf 
205*507c3241Smlf #define	GHBA_QHEAD(cccp)	((cccp)->ccc_waitq.Q_qhead)
206*507c3241Smlf #define	GHBA_MAXACTIVE(cccp)	((cccp)->ccc_waitq.Q_maxactive)
207*507c3241Smlf #define	GHBA_NACTIVE(cccp)	((cccp)->ccc_waitq.Q_nactive)
208*507c3241Smlf 
209*507c3241Smlf /* Initialize the HBA's list headers */
210*507c3241Smlf #define	CCCP_INIT(cccp)	{				\
211*507c3241Smlf 		L1HEADER_INIT(&(cccp)->ccc_devs);	\
212*507c3241Smlf 		L2_INIT(&(cccp)->ccc_doneq);		\
213*507c3241Smlf 		L2_INIT(&(cccp)->ccc_reset_notify_list);	\
214*507c3241Smlf }
215*507c3241Smlf 
216*507c3241Smlf 
217*507c3241Smlf #define	CCCP2GDEVP(cccp)					\
218*507c3241Smlf 	(L1_EMPTY(&(cccp)->ccc_devs)				\
219*507c3241Smlf 	? (gdev_t *)NULL					\
220*507c3241Smlf 	: (gdev_t *)((cccp)->ccc_devs.l1_headp->le_datap))
221*507c3241Smlf 
222*507c3241Smlf 
223*507c3241Smlf /*
224*507c3241Smlf  * reset_notify handling: these elements are on the ccc_t's
225*507c3241Smlf  * reset_notify_list, one for each notification requested.  The
226*507c3241Smlf  * gtgtp isn't needed except for debug.
227*507c3241Smlf  */
228*507c3241Smlf 
229*507c3241Smlf typedef struct ghd_reset_notify_list {
230*507c3241Smlf 	gtgt_t *gtgtp;
231*507c3241Smlf 	void (*callback)(caddr_t);
232*507c3241Smlf 	caddr_t	arg;
233*507c3241Smlf 	L2el_t l2_link;
234*507c3241Smlf } ghd_reset_notify_list_t;
235*507c3241Smlf 
236*507c3241Smlf /* ******************************************************************* */
237*507c3241Smlf 
238*507c3241Smlf #include "ghd_scsa.h"
239*507c3241Smlf #include "ghd_dma.h"
240*507c3241Smlf 
241*507c3241Smlf /*
242*507c3241Smlf  * GHD Entry Points
243*507c3241Smlf  */
244*507c3241Smlf void	 ghd_complete(ccc_t *cccp, gcmd_t *cmdp);
245*507c3241Smlf void	 ghd_doneq_put_head(ccc_t *cccp, gcmd_t *cmdp);
246*507c3241Smlf void	 ghd_doneq_put_tail(ccc_t *cccp, gcmd_t *cmdp);
247*507c3241Smlf 
248*507c3241Smlf int	 ghd_intr(ccc_t *cccp, void *status);
249*507c3241Smlf int	 ghd_register(char *, ccc_t *, dev_info_t *, int, void *hba_handle,
250*507c3241Smlf 			int (*ccc_ccballoc)(gtgt_t *, gcmd_t *, int, int,
251*507c3241Smlf 					    int, int),
252*507c3241Smlf 			void (*ccc_ccbfree)(gcmd_t *),
253*507c3241Smlf 			void (*ccc_sg_func)(gcmd_t *, ddi_dma_cookie_t *,
254*507c3241Smlf 					    int, int),
255*507c3241Smlf 			int  (*hba_start)(void *, gcmd_t *),
256*507c3241Smlf 			void (*hba_complete)(void *, gcmd_t *, int),
257*507c3241Smlf 			uint_t (*int_handler)(caddr_t),
258*507c3241Smlf 			int  (*get_status)(void *, void *),
259*507c3241Smlf 			void (*process_intr)(void *, void *),
260*507c3241Smlf 			int  (*timeout_func)(void *, gcmd_t *, gtgt_t *,
261*507c3241Smlf 				gact_t, int),
262*507c3241Smlf 			tmr_t *tmrp,
263*507c3241Smlf 			void (*hba_reset_notify_callback)(gtgt_t *,
264*507c3241Smlf 				void (*)(caddr_t), caddr_t));
265*507c3241Smlf void	ghd_unregister(ccc_t *cccp);
266*507c3241Smlf 
267*507c3241Smlf int	ghd_transport(ccc_t *cccp, gcmd_t *cmdp, gtgt_t *gtgtp,
268*507c3241Smlf 	    ulong_t timeout, int polled, void *intr_status);
269*507c3241Smlf 
270*507c3241Smlf int	ghd_tran_abort(ccc_t *cccp, gcmd_t *cmdp, gtgt_t *gtgtp,
271*507c3241Smlf 	    void *intr_status);
272*507c3241Smlf int	ghd_tran_abort_lun(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status);
273*507c3241Smlf int	ghd_tran_reset_target(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status);
274*507c3241Smlf int	ghd_tran_reset_bus(ccc_t *cccp, gtgt_t *gtgtp, void *intr_status);
275*507c3241Smlf int	ghd_reset_notify(ccc_t *cccp, gtgt_t *gtgtp, int flag,
276*507c3241Smlf 	    void (*callback)(caddr_t), caddr_t arg);
277*507c3241Smlf void	ghd_freeze_waitq(ccc_t *cccp, int delay);
278*507c3241Smlf void	ghd_trigger_reset_notify(ccc_t *cccp);
279*507c3241Smlf 
280*507c3241Smlf void	 ghd_queue_hold(ccc_t *cccp);
281*507c3241Smlf void	 ghd_queue_unhold(ccc_t *cccp);
282*507c3241Smlf 
283*507c3241Smlf /*
284*507c3241Smlf  * Allocate a gcmd_t wrapper and HBA private area
285*507c3241Smlf  */
286*507c3241Smlf gcmd_t	*ghd_gcmd_alloc(gtgt_t *gtgtp, int ccblen, int sleep);
287*507c3241Smlf 
288*507c3241Smlf /*
289*507c3241Smlf  * Free the gcmd_t wrapper and HBA private area
290*507c3241Smlf  */
291*507c3241Smlf void	ghd_gcmd_free(gcmd_t *gcmdp);
292*507c3241Smlf 
293*507c3241Smlf 
294*507c3241Smlf /*
295*507c3241Smlf  * GHD CMD/CCB timer Entry points
296*507c3241Smlf  */
297*507c3241Smlf 
298*507c3241Smlf int	ghd_timer_attach(ccc_t *cccp, tmr_t *tmrp,
299*507c3241Smlf 	    int (*timeout_func)(void *handle, gcmd_t *, gtgt_t *,
300*507c3241Smlf 	    gact_t, int));
301*507c3241Smlf void	ghd_timer_detach(ccc_t *cccp);
302*507c3241Smlf void	ghd_timer_fini(tmr_t *tmrp);
303*507c3241Smlf void	ghd_timer_init(tmr_t *tmrp, long ticks);
304*507c3241Smlf void	ghd_timer_newstate(ccc_t *cccp, gcmd_t *cmdp, gtgt_t *gtgtp,
305*507c3241Smlf 	    gact_t action, int calltype);
306*507c3241Smlf void	ghd_timer_poll(ccc_t *cccp, gtimer_poll_t calltype);
307*507c3241Smlf void	ghd_timer_start(ccc_t *cccp, gcmd_t *cmdp, long cmd_timeout);
308*507c3241Smlf void	ghd_timer_stop(ccc_t *cccp, gcmd_t *cmdp);
309*507c3241Smlf 
310*507c3241Smlf 
311*507c3241Smlf /*
312*507c3241Smlf  * Wait queue utility routines
313*507c3241Smlf  */
314*507c3241Smlf 
315*507c3241Smlf gtgt_t	*ghd_target_init(dev_info_t *, dev_info_t *, ccc_t *, size_t,
316*507c3241Smlf 	    void *, ushort_t, uchar_t);
317*507c3241Smlf void	 ghd_target_free(dev_info_t *, dev_info_t *, ccc_t *, gtgt_t *);
318*507c3241Smlf void	 ghd_waitq_shuffle_up(ccc_t *, gdev_t *);
319*507c3241Smlf void	 ghd_waitq_delete(ccc_t *, gcmd_t *);
320*507c3241Smlf int	 ghd_waitq_process_and_mutex_hold(ccc_t *);
321*507c3241Smlf void	 ghd_waitq_process_and_mutex_exit(ccc_t *);
322*507c3241Smlf 
323*507c3241Smlf 
324*507c3241Smlf /*
325*507c3241Smlf  * The values for the calltype arg for the ghd_timer_newstate() function,
326*507c3241Smlf  * and the HBA timeout-action function (ccc_timeout_func)
327*507c3241Smlf  */
328*507c3241Smlf 
329*507c3241Smlf #define	GHD_TGTREQ		0
330*507c3241Smlf #define	GHD_TIMEOUT		1
331*507c3241Smlf 
332*507c3241Smlf /* ******************************************************************* */
333*507c3241Smlf 
334*507c3241Smlf /*
335*507c3241Smlf  * specify GHD_INLINE to get optimized versions
336*507c3241Smlf  */
337*507c3241Smlf #define	GHD_INLINE	1
338*507c3241Smlf #if defined(GHD_DEBUG) || defined(DEBUG) || defined(__lint)
339*507c3241Smlf #undef	GHD_INLINE
340*507c3241Smlf #endif
341*507c3241Smlf 
342*507c3241Smlf #if defined(GHD_INLINE)
343*507c3241Smlf #define	GHD_COMPLETE(cccp, gcmpd)	GHD_COMPLETE_INLINE(cccp, gcmdp)
344*507c3241Smlf #define	GHD_TIMER_STOP(cccp, gcmdp)	GHD_TIMER_STOP_INLINE(cccp, gcmdp)
345*507c3241Smlf #define	GHD_DONEQ_PUT_HEAD(cccp, gcmdp)	GHD_DONEQ_PUT_HEAD_INLINE(cccp, gcmdp)
346*507c3241Smlf #define	GHD_DONEQ_PUT_TAIL(cccp, gcmdp)	GHD_DONEQ_PUT_TAIL_INLINE(cccp, gcmdp)
347*507c3241Smlf #else
348*507c3241Smlf #define	GHD_COMPLETE(cccp, gcmpd)	ghd_complete(cccp, gcmdp)
349*507c3241Smlf #define	GHD_TIMER_STOP(cccp, gcmdp)	ghd_timer_stop(cccp, gcmdp)
350*507c3241Smlf #define	GHD_DONEQ_PUT_HEAD(cccp, gcmdp)	ghd_doneq_put_head(cccp, gcmdp)
351*507c3241Smlf #define	GHD_DONEQ_PUT_TAIL(cccp, gcmdp)	ghd_doneq_put_tail(cccp, gcmdp)
352*507c3241Smlf #endif
353*507c3241Smlf 
354*507c3241Smlf /*
355*507c3241Smlf  * request is complete, stop the request timer and add to doneq
356*507c3241Smlf  */
357*507c3241Smlf #define	GHD_COMPLETE_INLINE(cccp, gcmdp)	\
358*507c3241Smlf {						\
359*507c3241Smlf 	ghd_waitq_delete(cccp, gcmdp);		\
360*507c3241Smlf 	(gcmdp)->cmd_state = GCMD_STATE_DONEQ;	\
361*507c3241Smlf 	GHD_TIMER_STOP((cccp), (gcmdp));	\
362*507c3241Smlf 	GHD_DONEQ_PUT_TAIL((cccp), (gcmdp));	\
363*507c3241Smlf }
364*507c3241Smlf 
365*507c3241Smlf #define	GHD_TIMER_STOP_INLINE(cccp, gcmdp)	\
366*507c3241Smlf {						\
367*507c3241Smlf 	mutex_enter(&(cccp)->ccc_activel_mutex);\
368*507c3241Smlf 	L2_delete(&(gcmdp)->cmd_timer_link);	\
369*507c3241Smlf 	mutex_exit(&(cccp)->ccc_activel_mutex);	\
370*507c3241Smlf }
371*507c3241Smlf 
372*507c3241Smlf /*
373*507c3241Smlf  * mark the request done and append it to the head of the doneq
374*507c3241Smlf  */
375*507c3241Smlf #define	GHD_DONEQ_PUT_HEAD_INLINE(cccp, gcmdp)			\
376*507c3241Smlf {								\
377*507c3241Smlf 	kmutex_t *doneq_mutexp = &(cccp)->ccc_doneq_mutex;	\
378*507c3241Smlf 								\
379*507c3241Smlf 	mutex_enter(doneq_mutexp);				\
380*507c3241Smlf 	(gcmdp)->cmd_state = GCMD_STATE_DONEQ;			\
381*507c3241Smlf 	L2_add_head(&(cccp)->ccc_doneq, &(gcmdp)->cmd_q, (gcmdp));	\
382*507c3241Smlf 	if (!(cccp)->ccc_hba_pollmode)				\
383*507c3241Smlf 		ddi_trigger_softintr((cccp)->ccc_doneq_softid);	\
384*507c3241Smlf 	mutex_exit(doneq_mutexp);				\
385*507c3241Smlf }
386*507c3241Smlf 
387*507c3241Smlf /*
388*507c3241Smlf  * mark the request done and append it to the tail of the doneq
389*507c3241Smlf  */
390*507c3241Smlf #define	GHD_DONEQ_PUT_TAIL_INLINE(cccp, gcmdp)			\
391*507c3241Smlf {								\
392*507c3241Smlf 	kmutex_t *doneq_mutexp = &(cccp)->ccc_doneq_mutex;	\
393*507c3241Smlf 								\
394*507c3241Smlf 	mutex_enter(doneq_mutexp);				\
395*507c3241Smlf 	(gcmdp)->cmd_state = GCMD_STATE_DONEQ;			\
396*507c3241Smlf 	L2_add(&(cccp)->ccc_doneq, &(gcmdp)->cmd_q, (gcmdp));	\
397*507c3241Smlf 	if (!(cccp)->ccc_hba_pollmode)				\
398*507c3241Smlf 		ddi_trigger_softintr((cccp)->ccc_doneq_softid);	\
399*507c3241Smlf 	mutex_exit(doneq_mutexp);				\
400*507c3241Smlf }
401*507c3241Smlf 
402*507c3241Smlf /* ******************************************************************* */
403*507c3241Smlf 
404*507c3241Smlf /*
405*507c3241Smlf  * These are shortcut macros for linkages setup by GHD
406*507c3241Smlf  */
407*507c3241Smlf 
408*507c3241Smlf /*
409*507c3241Smlf  * (gcmd_t *) to (struct scsi_pkt *)
410*507c3241Smlf  */
411*507c3241Smlf #define	GCMDP2PKTP(gcmdp)	((gcmdp)->cmd_pktp)
412*507c3241Smlf 
413*507c3241Smlf /*
414*507c3241Smlf  * (gcmd_t *) to (gtgt_t *)
415*507c3241Smlf  */
416*507c3241Smlf #define	GCMDP2GTGTP(gcmdp)	((gcmdp)->cmd_gtgtp)
417*507c3241Smlf 
418*507c3241Smlf /*
419*507c3241Smlf  * (gcmd_t *) to (gdev_t *)
420*507c3241Smlf  */
421*507c3241Smlf #define	GCMDP2GDEVP(gcmdp)	((gcmdp)->cmd_gtgtp->gt_gdevp)
422*507c3241Smlf 
423*507c3241Smlf /*
424*507c3241Smlf  * (gcmd_t *) to (ccc_t *)
425*507c3241Smlf  */
426*507c3241Smlf #define	GCMDP2CCCP(gcmdp)	(GCMDP2GTGTP(gcmdp)->gt_ccc)
427*507c3241Smlf 
428*507c3241Smlf /*
429*507c3241Smlf  * (struct scsi_pkt *) to (gcmd_t *)
430*507c3241Smlf  */
431*507c3241Smlf #define	PKTP2GCMDP(pktp)	((gcmd_t *)(pktp)->pkt_ha_private)
432*507c3241Smlf 
433*507c3241Smlf 
434*507c3241Smlf /* These are shortcut macros for linkages setup by SCSA */
435*507c3241Smlf 
436*507c3241Smlf /*
437*507c3241Smlf  * (struct scsi_address *) to (scsi_hba_tran *)
438*507c3241Smlf  */
439*507c3241Smlf #define	ADDR2TRAN(ap)		((ap)->a_hba_tran)
440*507c3241Smlf 
441*507c3241Smlf /*
442*507c3241Smlf  * (struct scsi_device *) to (scsi_address *)
443*507c3241Smlf  */
444*507c3241Smlf #define	SDEV2ADDR(sdp)		(&(sdp)->sd_address)
445*507c3241Smlf 
446*507c3241Smlf /*
447*507c3241Smlf  * (struct scsi_device *) to (scsi_hba_tran *)
448*507c3241Smlf  */
449*507c3241Smlf #define	SDEV2TRAN(sdp)		ADDR2TRAN(SDEV2ADDR(sdp))
450*507c3241Smlf 
451*507c3241Smlf /*
452*507c3241Smlf  * (struct scsi_pkt *) to (scsi_hba_tran *)
453*507c3241Smlf  */
454*507c3241Smlf #define	PKTP2TRAN(pktp)		ADDR2TRAN(&(pktp)->pkt_address)
455*507c3241Smlf 
456*507c3241Smlf /*
457*507c3241Smlf  * (scsi_hba_tran_t *) to (per-target-soft-state *)
458*507c3241Smlf  */
459*507c3241Smlf #define	TRAN2GTGTP(tranp)	((gtgt_t *)((tranp)->tran_tgt_private))
460*507c3241Smlf 
461*507c3241Smlf /*
462*507c3241Smlf  * (struct scsi_device *) to (per-target-soft-state *)
463*507c3241Smlf  */
464*507c3241Smlf #define	SDEV2GTGTP(sd)  	TRAN2GTGTP(SDEV2TRAN(sd))
465*507c3241Smlf 
466*507c3241Smlf /*
467*507c3241Smlf  * (struct scsi_pkt *) to (per-target-soft-state *)
468*507c3241Smlf  */
469*507c3241Smlf #define	PKTP2GTGTP(pktp)	TRAN2GTGTP(PKTP2TRAN(pktp))
470*507c3241Smlf 
471*507c3241Smlf 
472*507c3241Smlf /*
473*507c3241Smlf  * (scsi_hba_tran_t *) to (per-HBA-soft-state *)
474*507c3241Smlf  */
475*507c3241Smlf #define	TRAN2HBA(tranp)		((tranp)->tran_hba_private)
476*507c3241Smlf 
477*507c3241Smlf 
478*507c3241Smlf /*
479*507c3241Smlf  * (struct scsi_device *) to (per-HBA-soft-state *)
480*507c3241Smlf  */
481*507c3241Smlf #define	SDEV2HBA(sd)		TRAN2HBA(SDEV2TRAN(sd))
482*507c3241Smlf 
483*507c3241Smlf /*
484*507c3241Smlf  * (struct scsi_address *) to (per-target-soft-state *)
485*507c3241Smlf  */
486*507c3241Smlf #define	ADDR2GTGTP(ap)  	TRAN2GTGTP(ADDR2TRAN(ap))
487*507c3241Smlf 
488*507c3241Smlf /* ******************************************************************* */
489*507c3241Smlf 
490*507c3241Smlf 
491*507c3241Smlf #ifdef __cplusplus
492*507c3241Smlf }
493*507c3241Smlf #endif
494*507c3241Smlf 
495*507c3241Smlf #endif /* _GHD_H */
496