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