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) 1999-2001 by Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate  * All rights reserved.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #ifndef	_SYS_RSM_RSMKA_PATH_INT_H
28*7c478bd9Sstevel@tonic-gate #define	_SYS_RSM_RSMKA_PATH_INT_H
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
31*7c478bd9Sstevel@tonic-gate extern "C" {
32*7c478bd9Sstevel@tonic-gate #endif
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate #include <sys/rsm/rsm_common.h>
35*7c478bd9Sstevel@tonic-gate #include <sys/rsm/rsm.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/rsm/rsmpi.h>
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate /*
39*7c478bd9Sstevel@tonic-gate  * Taskq setup
40*7c478bd9Sstevel@tonic-gate  * Only one taskq thread is created and only one task is executed
41*7c478bd9Sstevel@tonic-gate  * the task is executed as an infinite loop
42*7c478bd9Sstevel@tonic-gate  */
43*7c478bd9Sstevel@tonic-gate #define	RSMKA_ONE_THREAD	1
44*7c478bd9Sstevel@tonic-gate #define	RSMKA_ONE_TASK		1
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate /* Path (path_t) States */
47*7c478bd9Sstevel@tonic-gate #define	RSMKA_PATH_DOWN	1
48*7c478bd9Sstevel@tonic-gate #define	RSMKA_PATH_UP	2
49*7c478bd9Sstevel@tonic-gate #define	RSMKA_PATH_ACTIVE	3
50*7c478bd9Sstevel@tonic-gate #define	RSMKA_PATH_GOING_DOWN	4
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate #define	RSMKA_OPCODE_TYPES	2
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate /*
55*7c478bd9Sstevel@tonic-gate  * Deferred Work Token Index
56*7c478bd9Sstevel@tonic-gate  */
57*7c478bd9Sstevel@tonic-gate #define	RSMKA_IPC_DOWN_INDEX	0
58*7c478bd9Sstevel@tonic-gate #define	RSMKA_IPC_UP_INDEX	1
59*7c478bd9Sstevel@tonic-gate 
60*7c478bd9Sstevel@tonic-gate /* Deferred Work Opcodes */
61*7c478bd9Sstevel@tonic-gate #define	RSMKA_IPC_DOWN	1
62*7c478bd9Sstevel@tonic-gate #define	RSMKA_IPC_UP	2
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate /* Flags */
65*7c478bd9Sstevel@tonic-gate #define	RSMKA_NO_SLEEP			1
66*7c478bd9Sstevel@tonic-gate #define	RSMKA_USE_COOKIE		2
67*7c478bd9Sstevel@tonic-gate #define	RSMKA_NOHOLD			4
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate /*
71*7c478bd9Sstevel@tonic-gate  * A work token is enqueued on the workqueue (singly linked list)
72*7c478bd9Sstevel@tonic-gate  * when pathup or pathdown processing is to be done by the deferred work
73*7c478bd9Sstevel@tonic-gate  * thread.  Token are enqueued at the end of the queue and processed
74*7c478bd9Sstevel@tonic-gate  * from the front of the queue.
75*7c478bd9Sstevel@tonic-gate  */
76*7c478bd9Sstevel@tonic-gate typedef struct work_token {
77*7c478bd9Sstevel@tonic-gate 	struct work_token	*next;		/* pointer to next token */
78*7c478bd9Sstevel@tonic-gate 	int			opcode;		/* opcode for work to do */
79*7c478bd9Sstevel@tonic-gate } work_token_t;
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate typedef struct workqueue {
82*7c478bd9Sstevel@tonic-gate 	work_token_t	*head;		/* start of work queue		*/
83*7c478bd9Sstevel@tonic-gate 	work_token_t	*tail;		/* end of work queue		*/
84*7c478bd9Sstevel@tonic-gate 	kmutex_t	work_mutex;	/* protects queue add/delete    */
85*7c478bd9Sstevel@tonic-gate 	kcondvar_t	work_cv;	/* synchronize deferred thread  */
86*7c478bd9Sstevel@tonic-gate } work_queue_t;
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate /*
89*7c478bd9Sstevel@tonic-gate  * a pointer to srv_handler_arg is registered along with the handler
90*7c478bd9Sstevel@tonic-gate  * and is passed to the rsm_srv_func - the service handler when it
91*7c478bd9Sstevel@tonic-gate  * is invoked.
92*7c478bd9Sstevel@tonic-gate  */
93*7c478bd9Sstevel@tonic-gate typedef struct srv_handler_arg {
94*7c478bd9Sstevel@tonic-gate 	char		adapter_name[MAXNAMELEN];
95*7c478bd9Sstevel@tonic-gate 	int		adapter_instance;
96*7c478bd9Sstevel@tonic-gate 	rsm_addr_t	adapter_hwaddr;
97*7c478bd9Sstevel@tonic-gate } srv_handler_arg_t;
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate typedef struct msgbuf_elem {
100*7c478bd9Sstevel@tonic-gate 	boolean_t		active;
101*7c478bd9Sstevel@tonic-gate 	rsmipc_request_t	msg;
102*7c478bd9Sstevel@tonic-gate } msgbuf_elem_t;
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate /*
105*7c478bd9Sstevel@tonic-gate  * receive buffer object
106*7c478bd9Sstevel@tonic-gate  * procmsg_cnt - receivers count of messages processed since sending credits
107*7c478bd9Sstevel@tonic-gate  * msgbuf_queue - an array-based circular queue of messages received
108*7c478bd9Sstevel@tonic-gate  * msgbuf_head - index pointing to the head of msgbuf_queue
109*7c478bd9Sstevel@tonic-gate  * msgbuf_head - index pointing to the tail of msgbuf_queue
110*7c478bd9Sstevel@tonic-gate  * msgbuf_cnt - number of valid entries in msgbuf_queue
111*7c478bd9Sstevel@tonic-gate  */
112*7c478bd9Sstevel@tonic-gate typedef struct recv_info {
113*7c478bd9Sstevel@tonic-gate 	int				procmsg_cnt;
114*7c478bd9Sstevel@tonic-gate 	int				rem_sendq_ready;
115*7c478bd9Sstevel@tonic-gate 	taskq_t				*recv_taskq;
116*7c478bd9Sstevel@tonic-gate 	msgbuf_elem_t			*msgbuf_queue;
117*7c478bd9Sstevel@tonic-gate 	int				msgbuf_head;
118*7c478bd9Sstevel@tonic-gate 	int				msgbuf_tail;
119*7c478bd9Sstevel@tonic-gate 	int				msgbuf_cnt;
120*7c478bd9Sstevel@tonic-gate } recv_info_t;
121*7c478bd9Sstevel@tonic-gate 
122*7c478bd9Sstevel@tonic-gate /*
123*7c478bd9Sstevel@tonic-gate  * sendq_tokens are inserted in a circular list of the ipc_info descriptor
124*7c478bd9Sstevel@tonic-gate  * when a path is added for a remote node.  When the path is active the
125*7c478bd9Sstevel@tonic-gate  * rsmpi_sendq_handle will be valid and the sendq token can be used for
126*7c478bd9Sstevel@tonic-gate  * ipc.  The sendq_tokens are used in a round robin fashion.
127*7c478bd9Sstevel@tonic-gate  *
128*7c478bd9Sstevel@tonic-gate  * msgbuf_avail - used by sender, number of avail slots in recvrs msgbuf_queue
129*7c478bd9Sstevel@tonic-gate  */
130*7c478bd9Sstevel@tonic-gate typedef struct sendq_token {
131*7c478bd9Sstevel@tonic-gate 	struct sendq_token		*next;
132*7c478bd9Sstevel@tonic-gate 	rsm_send_q_handle_t		rsmpi_sendq_handle;
133*7c478bd9Sstevel@tonic-gate 	int				ref_cnt;
134*7c478bd9Sstevel@tonic-gate 	int				msgbuf_avail;
135*7c478bd9Sstevel@tonic-gate 	kcondvar_t			sendq_cv;
136*7c478bd9Sstevel@tonic-gate }sendq_token_t;
137*7c478bd9Sstevel@tonic-gate 
138*7c478bd9Sstevel@tonic-gate 
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate typedef struct path {
142*7c478bd9Sstevel@tonic-gate 	struct path		*next_path;
143*7c478bd9Sstevel@tonic-gate 	rsm_node_id_t		remote_node;
144*7c478bd9Sstevel@tonic-gate 	int			remote_devinst;
145*7c478bd9Sstevel@tonic-gate 	rsm_addr_t		remote_hwaddr;
146*7c478bd9Sstevel@tonic-gate 	int			state;
147*7c478bd9Sstevel@tonic-gate 	int			flags;
148*7c478bd9Sstevel@tonic-gate #define	RSMKA_WAIT_FOR_SQACK	0x0001	/* waiting for SQREADY_ACK	*/
149*7c478bd9Sstevel@tonic-gate #define	RSMKA_SQCREATE_PENDING	0x0002	/* sendq_create is pending	*/
150*7c478bd9Sstevel@tonic-gate 	kmutex_t		mutex;
151*7c478bd9Sstevel@tonic-gate 	struct adapter		*local_adapter;
152*7c478bd9Sstevel@tonic-gate 	sendq_token_t		sendq_token;
153*7c478bd9Sstevel@tonic-gate 	work_token_t		work_token[RSMKA_OPCODE_TYPES];
154*7c478bd9Sstevel@tonic-gate 	recv_info_t		recv_buffer;
155*7c478bd9Sstevel@tonic-gate #define	procmsg_cnt	recv_buffer.procmsg_cnt
156*7c478bd9Sstevel@tonic-gate #define	rem_sendq_ready	recv_buffer.rem_sendq_ready
157*7c478bd9Sstevel@tonic-gate #define	msgbuf_queue	recv_buffer.msgbuf_queue
158*7c478bd9Sstevel@tonic-gate #define	msgbuf_head	recv_buffer.msgbuf_head
159*7c478bd9Sstevel@tonic-gate #define	msgbuf_tail	recv_buffer.msgbuf_tail
160*7c478bd9Sstevel@tonic-gate #define	msgbuf_cnt	recv_buffer.msgbuf_cnt
161*7c478bd9Sstevel@tonic-gate #define	recv_taskq	recv_buffer.recv_taskq
162*7c478bd9Sstevel@tonic-gate 	int64_t			local_incn;
163*7c478bd9Sstevel@tonic-gate 	int64_t			remote_incn;
164*7c478bd9Sstevel@tonic-gate #define	RSM_UNKNOWN_INCN	0
165*7c478bd9Sstevel@tonic-gate 	int			ref_cnt;
166*7c478bd9Sstevel@tonic-gate 	kcondvar_t 		hold_cv;
167*7c478bd9Sstevel@tonic-gate } path_t;
168*7c478bd9Sstevel@tonic-gate 
169*7c478bd9Sstevel@tonic-gate 
170*7c478bd9Sstevel@tonic-gate typedef struct adapter {
171*7c478bd9Sstevel@tonic-gate 	struct adapter		*next;
172*7c478bd9Sstevel@tonic-gate 	struct adapter_listhead *listhead;
173*7c478bd9Sstevel@tonic-gate 	int			ref_cnt;
174*7c478bd9Sstevel@tonic-gate 	kmutex_t		mutex;
175*7c478bd9Sstevel@tonic-gate 	int			instance;
176*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip;
177*7c478bd9Sstevel@tonic-gate 	rsm_addr_t		hwaddr;
178*7c478bd9Sstevel@tonic-gate 	path_t			*next_path;
179*7c478bd9Sstevel@tonic-gate 	rsm_controller_handle_t rsmpi_handle;
180*7c478bd9Sstevel@tonic-gate 	rsm_controller_attr_t	rsm_attr;
181*7c478bd9Sstevel@tonic-gate 	rsm_ops_t		*rsmpi_ops;
182*7c478bd9Sstevel@tonic-gate 	srv_handler_arg_t	*hdlr_argp;
183*7c478bd9Sstevel@tonic-gate } adapter_t;
184*7c478bd9Sstevel@tonic-gate 
185*7c478bd9Sstevel@tonic-gate 
186*7c478bd9Sstevel@tonic-gate /*
187*7c478bd9Sstevel@tonic-gate  * typedef struct {
188*7c478bd9Sstevel@tonic-gate  *	adapter_t		*next_chunk;
189*7c478bd9Sstevel@tonic-gate  *	int			base;
190*7c478bd9Sstevel@tonic-gate  *	int			next_index;
191*7c478bd9Sstevel@tonic-gate  *	int			used_count;
192*7c478bd9Sstevel@tonic-gate  *	adapter_t		*phys_adapters[MAX_CHUNK_INDEX];
193*7c478bd9Sstevel@tonic-gate  * } adapter_map_chunks_t;
194*7c478bd9Sstevel@tonic-gate  */
195*7c478bd9Sstevel@tonic-gate 
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate /*
198*7c478bd9Sstevel@tonic-gate  * There is one adapter_listhead for each adapter devname. This
199*7c478bd9Sstevel@tonic-gate  * adapter_listhead stores the number of adapters belonging to
200*7c478bd9Sstevel@tonic-gate  * it. It also stores the number of paths for all the adapters
201*7c478bd9Sstevel@tonic-gate  * belonging to it.
202*7c478bd9Sstevel@tonic-gate  */
203*7c478bd9Sstevel@tonic-gate typedef struct adapter_listhead {
204*7c478bd9Sstevel@tonic-gate 	struct adapter_listhead	*next_listhead;
205*7c478bd9Sstevel@tonic-gate 	char			adapter_devname[MAXNAMELEN];
206*7c478bd9Sstevel@tonic-gate 	adapter_t		*next_adapter;
207*7c478bd9Sstevel@tonic-gate 	int			ref_cnt;
208*7c478bd9Sstevel@tonic-gate 	kmutex_t		mutex;
209*7c478bd9Sstevel@tonic-gate 	int			adapter_count;
210*7c478bd9Sstevel@tonic-gate 	int			path_count;
211*7c478bd9Sstevel@tonic-gate } adapter_listhead_t;
212*7c478bd9Sstevel@tonic-gate 
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate struct adapter_listhead_list {
215*7c478bd9Sstevel@tonic-gate 	adapter_listhead_t	*next;
216*7c478bd9Sstevel@tonic-gate 	kmutex_t		listlock;
217*7c478bd9Sstevel@tonic-gate };
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate /*
221*7c478bd9Sstevel@tonic-gate  * One ipc_info descriptor for each remote node
222*7c478bd9Sstevel@tonic-gate  */
223*7c478bd9Sstevel@tonic-gate typedef struct ipc_info {
224*7c478bd9Sstevel@tonic-gate 	struct ipc_info			*next;
225*7c478bd9Sstevel@tonic-gate 	rsm_node_id_t			remote_node;
226*7c478bd9Sstevel@tonic-gate 	boolean_t			node_is_alive;
227*7c478bd9Sstevel@tonic-gate 	sendq_token_t			*token_list;
228*7c478bd9Sstevel@tonic-gate 	sendq_token_t			*current_token;
229*7c478bd9Sstevel@tonic-gate 	kmutex_t			token_list_mutex;
230*7c478bd9Sstevel@tonic-gate 	int				ref_cnt;
231*7c478bd9Sstevel@tonic-gate } ipc_info_t;
232*7c478bd9Sstevel@tonic-gate 
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate #define	SQ_TOKEN_TO_PATH(token) 	\
235*7c478bd9Sstevel@tonic-gate 	((path_t *)((char *)(token) - ((char *)(&((path_t *)0)->sendq_token))))
236*7c478bd9Sstevel@tonic-gate 
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate 
239*7c478bd9Sstevel@tonic-gate #define	WORK_TOKEN_TO_PATH(token, index) \
240*7c478bd9Sstevel@tonic-gate 	((path_t *)((char *)(token) - 	\
241*7c478bd9Sstevel@tonic-gate 		((char *)(&((path_t *)0)->work_token[(index)]))))
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate 
244*7c478bd9Sstevel@tonic-gate 
245*7c478bd9Sstevel@tonic-gate 
246*7c478bd9Sstevel@tonic-gate /*
247*7c478bd9Sstevel@tonic-gate  * Descriptor Reference Count macros
248*7c478bd9Sstevel@tonic-gate  */
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate #define	ADAPTER_HOLD(adapter)	{	\
251*7c478bd9Sstevel@tonic-gate 		mutex_enter(&((adapter)->mutex)); 	\
252*7c478bd9Sstevel@tonic-gate 		(adapter)->ref_cnt++;		\
253*7c478bd9Sstevel@tonic-gate 		ASSERT((adapter)->ref_cnt != 0);	\
254*7c478bd9Sstevel@tonic-gate 		mutex_exit(&((adapter)->mutex));	\
255*7c478bd9Sstevel@tonic-gate }
256*7c478bd9Sstevel@tonic-gate 
257*7c478bd9Sstevel@tonic-gate #define	ADAPTER_RELE(adapter)	{			\
258*7c478bd9Sstevel@tonic-gate 		mutex_enter(&((adapter)->mutex)); 	\
259*7c478bd9Sstevel@tonic-gate 		(adapter)->ref_cnt--;			\
260*7c478bd9Sstevel@tonic-gate 		ASSERT((adapter)->ref_cnt >= 0);	\
261*7c478bd9Sstevel@tonic-gate 		mutex_exit(&((adapter)->mutex));	\
262*7c478bd9Sstevel@tonic-gate }
263*7c478bd9Sstevel@tonic-gate 
264*7c478bd9Sstevel@tonic-gate #define	ADAPTER_RELE_NOLOCK(adapter)	{		\
265*7c478bd9Sstevel@tonic-gate 		ASSERT(MUTEX_HELD(&(adapter)->mutex));	\
266*7c478bd9Sstevel@tonic-gate 		(adapter)->ref_cnt--;			\
267*7c478bd9Sstevel@tonic-gate 		ASSERT((adapter)->ref_cnt >= 0);	\
268*7c478bd9Sstevel@tonic-gate }
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate #define	PATH_HOLD(path)	{			\
271*7c478bd9Sstevel@tonic-gate 		mutex_enter(&(path)->mutex); 	\
272*7c478bd9Sstevel@tonic-gate 		(path)->ref_cnt++;		\
273*7c478bd9Sstevel@tonic-gate 		ASSERT((path)->ref_cnt != 0);	\
274*7c478bd9Sstevel@tonic-gate 		mutex_exit(&(path)->mutex);	\
275*7c478bd9Sstevel@tonic-gate }
276*7c478bd9Sstevel@tonic-gate 
277*7c478bd9Sstevel@tonic-gate #define	PATH_HOLD_NOLOCK(path)	{			\
278*7c478bd9Sstevel@tonic-gate 		ASSERT(MUTEX_HELD(&(path)->mutex));	\
279*7c478bd9Sstevel@tonic-gate 		(path)->ref_cnt++;			\
280*7c478bd9Sstevel@tonic-gate 		ASSERT((path)->ref_cnt != 0);		\
281*7c478bd9Sstevel@tonic-gate }
282*7c478bd9Sstevel@tonic-gate 
283*7c478bd9Sstevel@tonic-gate #define	PATH_RELE(path)	{				\
284*7c478bd9Sstevel@tonic-gate 		mutex_enter(&(path)->mutex); 		\
285*7c478bd9Sstevel@tonic-gate 		(path)->ref_cnt--;			\
286*7c478bd9Sstevel@tonic-gate 		ASSERT((path)->ref_cnt >= 0);		\
287*7c478bd9Sstevel@tonic-gate 		if ((path)->ref_cnt == 0)		\
288*7c478bd9Sstevel@tonic-gate 			cv_signal(&(path)->hold_cv);	\
289*7c478bd9Sstevel@tonic-gate 		mutex_exit(&(path)->mutex);		\
290*7c478bd9Sstevel@tonic-gate }
291*7c478bd9Sstevel@tonic-gate 
292*7c478bd9Sstevel@tonic-gate #define	PATH_RELE_NOLOCK(path)	{			\
293*7c478bd9Sstevel@tonic-gate 		ASSERT(MUTEX_HELD(&(path)->mutex));	\
294*7c478bd9Sstevel@tonic-gate 		(path)->ref_cnt--;			\
295*7c478bd9Sstevel@tonic-gate 		ASSERT((path)->ref_cnt >= 0);		\
296*7c478bd9Sstevel@tonic-gate 		if ((path)->ref_cnt == 0)		\
297*7c478bd9Sstevel@tonic-gate 			cv_signal(&(path)->hold_cv);	\
298*7c478bd9Sstevel@tonic-gate }
299*7c478bd9Sstevel@tonic-gate 
300*7c478bd9Sstevel@tonic-gate #define	SENDQ_TOKEN_HOLD(path)	{				\
301*7c478bd9Sstevel@tonic-gate 		(path)->sendq_token.ref_cnt++;			\
302*7c478bd9Sstevel@tonic-gate 		ASSERT((path)->sendq_token.ref_cnt != 0);	\
303*7c478bd9Sstevel@tonic-gate }
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate #define	SENDQ_TOKEN_RELE(path)	{					\
306*7c478bd9Sstevel@tonic-gate 		(path)->sendq_token.ref_cnt--;				\
307*7c478bd9Sstevel@tonic-gate 		ASSERT((path)->sendq_token.ref_cnt >= 0);		\
308*7c478bd9Sstevel@tonic-gate 		if ((path)->sendq_token.ref_cnt == 0)			\
309*7c478bd9Sstevel@tonic-gate 			cv_signal(&(path)->sendq_token.sendq_cv);	\
310*7c478bd9Sstevel@tonic-gate }
311*7c478bd9Sstevel@tonic-gate 
312*7c478bd9Sstevel@tonic-gate #define	IPCINFO_HOLD(ipc_info)	{			\
313*7c478bd9Sstevel@tonic-gate 		mutex_enter(&ipc_info_lock); 		\
314*7c478bd9Sstevel@tonic-gate 		(ipc_info)->ref_cnt++;			\
315*7c478bd9Sstevel@tonic-gate 		ASSERT((ipc_info)->ref_cnt != 0); 	\
316*7c478bd9Sstevel@tonic-gate 		mutex_exit(&ipc_info_lock);		\
317*7c478bd9Sstevel@tonic-gate }
318*7c478bd9Sstevel@tonic-gate 
319*7c478bd9Sstevel@tonic-gate #define	IPCINFO_HOLD_NOLOCK(ipc_info)	{		\
320*7c478bd9Sstevel@tonic-gate 		ASSERT(MUTEX_HELD(&ipc_info_lock));	\
321*7c478bd9Sstevel@tonic-gate 		(ipc_info)->ref_cnt++;			\
322*7c478bd9Sstevel@tonic-gate 		ASSERT((ipc_info)->ref_cnt != 0); 	\
323*7c478bd9Sstevel@tonic-gate }
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate #define	IPCINFO_RELE(ipc_info)	{			\
326*7c478bd9Sstevel@tonic-gate 		mutex_enter(&ipc_info_lock); 		\
327*7c478bd9Sstevel@tonic-gate 		(ipc_info)->ref_cnt--;			\
328*7c478bd9Sstevel@tonic-gate 		ASSERT((ipc_info)->ref_cnt >= 0); 	\
329*7c478bd9Sstevel@tonic-gate 		mutex_exit(&ipc_info_lock);		\
330*7c478bd9Sstevel@tonic-gate }
331*7c478bd9Sstevel@tonic-gate 
332*7c478bd9Sstevel@tonic-gate #define	IPCINFO_RELE_NOLOCK(ipc_info)	{		\
333*7c478bd9Sstevel@tonic-gate 		ASSERT(MUTEX_HELD(&ipc_info_lock));	\
334*7c478bd9Sstevel@tonic-gate 		(ipc_info)->ref_cnt--;			\
335*7c478bd9Sstevel@tonic-gate 		ASSERT((ipc_info)->ref_cnt >= 0); 	\
336*7c478bd9Sstevel@tonic-gate }
337*7c478bd9Sstevel@tonic-gate /*
338*7c478bd9Sstevel@tonic-gate  * Topology data structures - The primary structure is struct rsm_topology_t
339*7c478bd9Sstevel@tonic-gate  * The key interconnect data required for segment operations includes the
340*7c478bd9Sstevel@tonic-gate  * cluster nodeids and the controllers (name, hardware address); with
341*7c478bd9Sstevel@tonic-gate  * the fundamental constraint that the controller specified for a segment
342*7c478bd9Sstevel@tonic-gate  * import must have a physical connection with the contorller used in the
343*7c478bd9Sstevel@tonic-gate  * export of the segment. To facilitate applications in the establishment
344*7c478bd9Sstevel@tonic-gate  * of proper and efficient export and import policies, a delineation of the
345*7c478bd9Sstevel@tonic-gate  * interconnect topology is provided by these data structures.
346*7c478bd9Sstevel@tonic-gate  *
347*7c478bd9Sstevel@tonic-gate  * A pointer to an instance of this structure type is returned by a call
348*7c478bd9Sstevel@tonic-gate  * to rsm_get_interconnect_topology(). The application is responsible for
349*7c478bd9Sstevel@tonic-gate  * calling rsm_free_interconnect_topology() to free the allocated memory.
350*7c478bd9Sstevel@tonic-gate  *
351*7c478bd9Sstevel@tonic-gate  * Note: the rsmka_connections_t structure should be always double-word
352*7c478bd9Sstevel@tonic-gate  *	aligned.
353*7c478bd9Sstevel@tonic-gate  */
354*7c478bd9Sstevel@tonic-gate 
355*7c478bd9Sstevel@tonic-gate 
356*7c478bd9Sstevel@tonic-gate #define	RSM_CONNECTION_ACTIVE	3
357*7c478bd9Sstevel@tonic-gate 
358*7c478bd9Sstevel@tonic-gate 
359*7c478bd9Sstevel@tonic-gate typedef struct {
360*7c478bd9Sstevel@tonic-gate 	rsm_node_id_t		local_nodeid;
361*7c478bd9Sstevel@tonic-gate 	int			local_cntlr_count;
362*7c478bd9Sstevel@tonic-gate } rsmka_topology_hdr_t;
363*7c478bd9Sstevel@tonic-gate 
364*7c478bd9Sstevel@tonic-gate typedef struct {
365*7c478bd9Sstevel@tonic-gate 	char		cntlr_name[MAXNAMELEN];
366*7c478bd9Sstevel@tonic-gate 	rsm_addr_t	local_hwaddr;
367*7c478bd9Sstevel@tonic-gate 	int		remote_cntlr_count;
368*7c478bd9Sstevel@tonic-gate } rsmka_connections_hdr_t;
369*7c478bd9Sstevel@tonic-gate 
370*7c478bd9Sstevel@tonic-gate 
371*7c478bd9Sstevel@tonic-gate /*
372*7c478bd9Sstevel@tonic-gate  * An application must not attempt to use a connection unless the
373*7c478bd9Sstevel@tonic-gate  * the connection_state element of struct remote_cntlr_t is equal to
374*7c478bd9Sstevel@tonic-gate  * RSM_CONNECTION_ACTIVE
375*7c478bd9Sstevel@tonic-gate  */
376*7c478bd9Sstevel@tonic-gate typedef struct {
377*7c478bd9Sstevel@tonic-gate 	rsm_node_id_t		remote_nodeid;
378*7c478bd9Sstevel@tonic-gate 	char			remote_cntlrname[MAXNAMELEN];
379*7c478bd9Sstevel@tonic-gate 	rsm_addr_t		remote_hwaddr;
380*7c478bd9Sstevel@tonic-gate 	uint_t			connection_state;
381*7c478bd9Sstevel@tonic-gate } rsmka_remote_cntlr_t;
382*7c478bd9Sstevel@tonic-gate 
383*7c478bd9Sstevel@tonic-gate 
384*7c478bd9Sstevel@tonic-gate /*
385*7c478bd9Sstevel@tonic-gate  * The actual size of the remote_cntlr array is equal to the remote_cntlr_count
386*7c478bd9Sstevel@tonic-gate  * of the connections_hdr_t struct.
387*7c478bd9Sstevel@tonic-gate  */
388*7c478bd9Sstevel@tonic-gate typedef struct {
389*7c478bd9Sstevel@tonic-gate 	rsmka_connections_hdr_t	hdr;
390*7c478bd9Sstevel@tonic-gate 	rsmka_remote_cntlr_t	remote_cntlr[1];
391*7c478bd9Sstevel@tonic-gate } rsmka_connections_t;
392*7c478bd9Sstevel@tonic-gate 
393*7c478bd9Sstevel@tonic-gate /*
394*7c478bd9Sstevel@tonic-gate  * A pointer to an instance of this structure type is returned by a call
395*7c478bd9Sstevel@tonic-gate  * to rsm_get_interconnect_topology().  The actual size of the connections
396*7c478bd9Sstevel@tonic-gate  * array is equal to the local_cntlr_count of the topology_hdr_t struct.
397*7c478bd9Sstevel@tonic-gate  */
398*7c478bd9Sstevel@tonic-gate typedef struct {
399*7c478bd9Sstevel@tonic-gate 	rsmka_topology_hdr_t	topology_hdr;
400*7c478bd9Sstevel@tonic-gate 	caddr_t			connections[1];
401*7c478bd9Sstevel@tonic-gate } rsmka_topology_t;
402*7c478bd9Sstevel@tonic-gate 
403*7c478bd9Sstevel@tonic-gate #ifdef _SYSCALL32
404*7c478bd9Sstevel@tonic-gate typedef struct {
405*7c478bd9Sstevel@tonic-gate 	rsmka_topology_hdr_t	topology_hdr;
406*7c478bd9Sstevel@tonic-gate 	caddr32_t		connections[1];
407*7c478bd9Sstevel@tonic-gate } rsmka_topology32_t;
408*7c478bd9Sstevel@tonic-gate #endif
409*7c478bd9Sstevel@tonic-gate 
410*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
411*7c478bd9Sstevel@tonic-gate }
412*7c478bd9Sstevel@tonic-gate #endif
413*7c478bd9Sstevel@tonic-gate 
414*7c478bd9Sstevel@tonic-gate #endif	/* _SYS_RSM_RSMKA_PATH_INT_H */
415