1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1997, Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate  * All Rights Reserved.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #ifndef _GHD_WAITQ_H
28*7c478bd9Sstevel@tonic-gate #define	_GHD_WAITQ_H
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
33*7c478bd9Sstevel@tonic-gate extern "C" {
34*7c478bd9Sstevel@tonic-gate #endif
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate /*
38*7c478bd9Sstevel@tonic-gate  * there's a waitq_t per target device and one per HBA
39*7c478bd9Sstevel@tonic-gate  */
40*7c478bd9Sstevel@tonic-gate 
41*7c478bd9Sstevel@tonic-gate typedef struct ghd_q {
42*7c478bd9Sstevel@tonic-gate 	struct ghd_q *Q_nextp;	/* ptr to next level of queuing */
43*7c478bd9Sstevel@tonic-gate 	L2el_t	Q_qhead;	/* Q of waiting gcmds */
44*7c478bd9Sstevel@tonic-gate 	long	Q_nactive;	/* current # of outstanding gcmds */
45*7c478bd9Sstevel@tonic-gate 	long	Q_maxactive;	/* max gcmds to release concurrently */
46*7c478bd9Sstevel@tonic-gate } Q_t;
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate #define	GHD_WAITQ_INIT(qp, nxtp, maxactive)	\
49*7c478bd9Sstevel@tonic-gate 	(L2_INIT(&(qp)->Q_qhead), 		\
50*7c478bd9Sstevel@tonic-gate 	(qp)->Q_nextp = (nxtp),			\
51*7c478bd9Sstevel@tonic-gate 	(qp)->Q_nactive = 0,			\
52*7c478bd9Sstevel@tonic-gate 	(qp)->Q_maxactive = (maxactive))
53*7c478bd9Sstevel@tonic-gate /*
54*7c478bd9Sstevel@tonic-gate  * one per target device
55*7c478bd9Sstevel@tonic-gate  */
56*7c478bd9Sstevel@tonic-gate typedef struct ghd_device {
57*7c478bd9Sstevel@tonic-gate 	Q_t	gd_waitq;	/* the queue structure for this device */
58*7c478bd9Sstevel@tonic-gate 	L1el_t	gd_devlist;	/* all gdevs for a HBA are linked together */
59*7c478bd9Sstevel@tonic-gate 	uint32_t gd_target;	/*  ... and are located by searching for */
60*7c478bd9Sstevel@tonic-gate 	uint32_t gd_lun;	/*  ... a match on the (target,lun) values */
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate 	L1_t 	gd_ilist;	/* linked list of instances for this device */
63*7c478bd9Sstevel@tonic-gate 	uint32_t gd_ninstances;	/* # of instances for this device */
64*7c478bd9Sstevel@tonic-gate } gdev_t;
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate #define	GDEV_QHEAD(gdevp)	((gdevp)->gd_waitq.Q_qhead)
67*7c478bd9Sstevel@tonic-gate #define	GDEV_NACTIVE(gdevp)	((gdevp)->gd_waitq.Q_nactive)
68*7c478bd9Sstevel@tonic-gate #define	GDEV_MAXACTIVE(gdevp)	((gdevp)->gd_waitq.Q_maxactive)
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate /*
71*7c478bd9Sstevel@tonic-gate  * Be careful, this macro assumes there's a least one
72*7c478bd9Sstevel@tonic-gate  * target instance attached to this dev structure, Otherwise, l1_headp
73*7c478bd9Sstevel@tonic-gate  * is NULL.
74*7c478bd9Sstevel@tonic-gate  */
75*7c478bd9Sstevel@tonic-gate #define	GDEVP2GTGTP(gdevp)	\
76*7c478bd9Sstevel@tonic-gate 	(gtgt_t *)((gdevp)->gd_ilist.l1_headp->le_datap)
77*7c478bd9Sstevel@tonic-gate 
78*7c478bd9Sstevel@tonic-gate #define	GDEV_NEXTP(gdevp)						\
79*7c478bd9Sstevel@tonic-gate 	((gdevp)->gd_devlist.le_nextp					\
80*7c478bd9Sstevel@tonic-gate 		? (gdev_t *)((gdevp)->gd_devlist.le_nextp->le_datap)	\
81*7c478bd9Sstevel@tonic-gate 		: (gdev_t *)NULL)
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate #define	GDEV_QATTACH(gdevp, cccp, max)	{				\
84*7c478bd9Sstevel@tonic-gate 	GHD_WAITQ_INIT(&(gdevp)->gd_waitq, &(cccp)->ccc_waitq, (max));	\
85*7c478bd9Sstevel@tonic-gate 	L1EL_INIT(&gdevp->gd_devlist);					\
86*7c478bd9Sstevel@tonic-gate 	L1HEADER_INIT(&gdevp->gd_ilist);				\
87*7c478bd9Sstevel@tonic-gate 	/* add the per device structure to the HBA's device list */	\
88*7c478bd9Sstevel@tonic-gate 	L1_add(&(cccp)->ccc_devs, &(gdevp)->gd_devlist, (gdevp));	\
89*7c478bd9Sstevel@tonic-gate }
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate #define	GDEV_QDETACH(gdevp, cccp)			\
92*7c478bd9Sstevel@tonic-gate 	L1_delete(&(cccp)->ccc_devs, &(gdevp)->gd_devlist)
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate /*
95*7c478bd9Sstevel@tonic-gate  * GHD target structure, one per attached target driver instance
96*7c478bd9Sstevel@tonic-gate  */
97*7c478bd9Sstevel@tonic-gate typedef	struct	ghd_target_instance {
98*7c478bd9Sstevel@tonic-gate 	L1el_t	 gt_ilist;	/* list of other instances for this device */
99*7c478bd9Sstevel@tonic-gate 	gdev_t	*gt_gdevp;	/* ptr to info shared by all instances */
100*7c478bd9Sstevel@tonic-gate 	uint32_t gt_maxactive;	/* max gcmds to release concurrently */
101*7c478bd9Sstevel@tonic-gate 	void	*gt_hba_private; /* ptr to soft state of this HBA instance */
102*7c478bd9Sstevel@tonic-gate 	void	*gt_tgt_private; /* ptr to soft state of this target instance */
103*7c478bd9Sstevel@tonic-gate 	size_t	 gt_size;	/* size including tgt_private */
104*7c478bd9Sstevel@tonic-gate 	uint32_t gt_target;	/* target number of this instance */
105*7c478bd9Sstevel@tonic-gate 	uint32_t gt_lun;	/* LUN of this instance */
106*7c478bd9Sstevel@tonic-gate } gtgt_t;
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate #define	GTGTP2TARGET(gtgtp)	((gtgtp)->gt_tgt_private)
109*7c478bd9Sstevel@tonic-gate #define	GTGTP2HBA(gtgtp)	((gtgtp)->gt_hba_private)
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate #define	GTGT_INIT(gtgtp)	L1EL_INIT(&(gtgtp)->gt_ilist)
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate /* Add the per instance structure to the per device list  */
114*7c478bd9Sstevel@tonic-gate #define	GTGT_ATTACH(gtgtp, gdevp)	{				\
115*7c478bd9Sstevel@tonic-gate 	(gdevp)->gd_ninstances++;					\
116*7c478bd9Sstevel@tonic-gate 	L1_add(&(gdevp)->gd_ilist, &(gtgtp)->gt_ilist, (gtgtp));	\
117*7c478bd9Sstevel@tonic-gate }
118*7c478bd9Sstevel@tonic-gate 
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate /* remove this per-instance-structure from the device list */
121*7c478bd9Sstevel@tonic-gate #define	GTGT_DEATTACH(gtgtp, gdevp)	{			\
122*7c478bd9Sstevel@tonic-gate 	(gdevp)->gd_ninstances--;				\
123*7c478bd9Sstevel@tonic-gate 	L1_delete(&(gdevp)->gd_ilist, &(gtgtp)->gt_ilist);	\
124*7c478bd9Sstevel@tonic-gate }
125*7c478bd9Sstevel@tonic-gate 
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
129*7c478bd9Sstevel@tonic-gate }
130*7c478bd9Sstevel@tonic-gate #endif
131*7c478bd9Sstevel@tonic-gate 
132*7c478bd9Sstevel@tonic-gate #endif /* _GHD_WAITQ_H */
133