xref: /illumos-gate/usr/src/uts/sun4v/sys/ds_impl.h (revision 5f41bf46ca5230bc3ee6b7d6a714a3a16a390261)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef _DS_IMPL_H
28 #define	_DS_IMPL_H
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 
35 
36 /*
37  * The Domain Services Protocol
38  *
39  * The DS protocol is divided into two parts. The first is fixed and
40  * must remain exactly the same for *all* versions of the DS protocol.
41  * The only messages supported by the fixed portion of the protocol are
42  * to negotiate a version to use for the rest of the protocol.
43  */
44 
45 /*
46  * Domain Services Header
47  */
48 typedef struct ds_hdr {
49 	uint32_t	msg_type;	/* message type */
50 	uint32_t	payload_len;	/* payload length */
51 } ds_hdr_t;
52 
53 #define	DS_HDR_SZ	(sizeof (ds_hdr_t))
54 
55 /*
56  * DS Fixed Message Types
57  */
58 #define	DS_INIT_REQ		0x0	/* initiate DS connection */
59 #define	DS_INIT_ACK		0x1	/* initiation acknowledgement */
60 #define	DS_INIT_NACK		0x2	/* initiation negative acknowledgment */
61 
62 /*
63  * DS Fixed Initialization Messages
64  */
65 typedef struct ds_init_req {
66 	uint16_t	major_vers;	/* requested major version */
67 	uint16_t	minor_vers;	/* requested minor version */
68 } ds_init_req_t;
69 
70 typedef struct ds_init_ack {
71 	uint16_t	minor_vers;	/* highest supported minor version */
72 } ds_init_ack_t;
73 
74 typedef struct ds_init_nack {
75 	uint16_t	major_vers;	/* alternate supported major version */
76 } ds_init_nack_t;
77 
78 /*
79  * DS Message Types for Version 1.0
80  */
81 #define	DS_REG_REQ		0x3	/* register a service */
82 #define	DS_REG_ACK		0x4	/* register acknowledgement */
83 #define	DS_REG_NACK		0x5	/* register failed */
84 #define	DS_UNREG		0x6	/* unregister a service */
85 #define	DS_UNREG_ACK		0x7	/* unregister acknowledgement */
86 #define	DS_UNREG_NACK		0x8	/* unregister failed */
87 #define	DS_DATA			0x9	/* data message */
88 #define	DS_NACK			0xa	/* data error */
89 
90 /* result codes */
91 #define	DS_OK			0x0	/* success */
92 #define	DS_REG_VER_NACK		0x1	/* unsupported major version */
93 #define	DS_REG_DUP		0x2	/* duplicate registration attempted */
94 #define	DS_INV_HDL		0x3	/* service handle not valid */
95 #define	DS_TYPE_UNKNOWN		0x4	/* unknown message type received */
96 
97 /*
98  * Service Register Messages
99  */
100 typedef struct ds_reg_req {
101 	uint64_t	svc_handle;	/* service handle to register */
102 	uint16_t	major_vers;	/* requested major version */
103 	uint16_t	minor_vers;	/* requested minor version */
104 	char		svc_id[1];	/* service identifier string */
105 } ds_reg_req_t;
106 
107 typedef struct ds_reg_ack {
108 	uint64_t	svc_handle;	/* service handle sent in register */
109 	uint16_t	minor_vers;	/* highest supported minor version */
110 } ds_reg_ack_t;
111 
112 typedef struct ds_reg_nack {
113 	uint64_t	svc_handle;	/* service handle sent in register */
114 	uint64_t	result;		/* reason for the failure */
115 	uint16_t	major_vers;	/* alternate supported major version */
116 } ds_reg_nack_t;
117 
118 /*
119  * Service Unregister Messages
120  */
121 typedef struct ds_unreg_req {
122 	uint64_t	svc_handle;	/* service handle to unregister */
123 } ds_unreg_req_t;
124 
125 typedef struct ds_unreg_ack {
126 	uint64_t	svc_handle;	/* service handle sent in unregister */
127 } ds_unreg_ack_t;
128 
129 typedef struct ds_unreg_nack {
130 	uint64_t	svc_handle;	/* service handle sent in unregister */
131 } ds_unreg_nack_t;
132 
133 /*
134  * Data Transfer Messages
135  */
136 typedef struct ds_data_handle {
137 	uint64_t	svc_handle;	/* service handle for data */
138 } ds_data_handle_t;
139 
140 typedef struct ds_data_nack {
141 	uint64_t	svc_handle;	/* service handle sent in data msg */
142 	uint64_t	result;		/* reason for failure */
143 } ds_data_nack_t;
144 
145 /*
146  * Message Processing Utilities
147  */
148 #define	DS_MSG_TYPE_VALID(type)		((type) <= DS_NACK)
149 #define	DS_MSG_LEN(ds_type)		(sizeof (ds_hdr_t) + sizeof (ds_type))
150 
151 
152 /*
153  * Domain Service Port
154  *
155  * A DS port is a logical representation of an LDC dedicated to
156  * communication between DS endpoints. The ds_port_t maintains state
157  * associated with a connection to a remote endpoint. This includes
158  * the state of the port, the LDC state, the current version of the
159  * DS protocol in use on the port, and other port properties.
160  *
161  * Locking: The port is protected by a single mutex. It must be held
162  *   while the port structure is being accessed and also when data is
163  *   being read or written using the port
164  */
165 typedef enum {
166 	DS_PORT_FREE,			/* port structure not in use */
167 	DS_PORT_INIT,			/* port structure created */
168 	DS_PORT_LDC_INIT,		/* ldc successfully initialized */
169 	DS_PORT_INIT_REQ,		/* initialization handshake sent */
170 	DS_PORT_READY			/* init handshake completed */
171 } ds_port_state_t;
172 
173 typedef struct ds_ldc {
174 	uint64_t	id;		/* LDC id */
175 	ldc_handle_t	hdl;		/* LDC handle */
176 	ldc_status_t	state;		/* current LDC state */
177 } ds_ldc_t;
178 
179 typedef uint64_t ds_domain_hdl_t;
180 
181 #define	DS_DHDL_INVALID			((ds_domain_hdl_t)0xffffffff)
182 
183 /* port flags */
184 #define	DS_PORT_MUTEX_INITED	0x1	/* mutexes inited? */
185 
186 typedef struct ds_port {
187 	uint32_t	flags;		/* port flags */
188 	kmutex_t	lock;		/* port and service state lock */
189 	kmutex_t	tx_lock;	/* tx port lock */
190 	kmutex_t	rcv_lock;	/* rcv port lock */
191 	uint64_t	id;		/* port id from MD */
192 	ds_port_state_t	state;		/* state of the port */
193 	ds_ver_t	ver;		/* DS protocol version in use */
194 	uint32_t	ver_idx;	/* index of version during handshake */
195 	ds_ldc_t	ldc;		/* LDC for this port */
196 	ds_domain_hdl_t	domain_hdl;	/* LDOMs domain hdl assoc. with port */
197 	char 		*domain_name;	/* LDOMs domain name assoc. with port */
198 } ds_port_t;
199 
200 #define	IS_DS_PORT(port)	1	/* VBSC code compatability */
201 #define	PORTID(port)		((ulong_t)((port)->id))
202 #define	PTR_TO_LONG(ptr)	((uint64_t)(ptr))
203 
204 
205 /*
206  * A DS portset is a bitmap that represents a collection of DS
207  * ports. Each bit represent a particular port id. The current
208  * implementation constrains the maximum number of ports to 64.
209  */
210 typedef uint64_t ds_portset_t;
211 
212 #ifndef	DS_MAX_PORTS
213 #define	DS_MAX_PORTS			((sizeof (ds_portset_t)) * 8)
214 #endif
215 #define	DS_MAX_PORT_ID			(DS_MAX_PORTS - 1)
216 
217 #define	DS_PORT_SET(port)		(1UL << (port))
218 #define	DS_PORT_IN_SET(set, port)	((set) & DS_PORT_SET(port))
219 #define	DS_PORTSET_ADD(set, port)	((void)((set) |= DS_PORT_SET(port)))
220 #define	DS_PORTSET_DEL(set, port)	((void)((set) &= ~DS_PORT_SET(port)))
221 #define	DS_PORTSET_ISNULL(set)		((set) == 0)
222 #define	DS_PORTSET_SETNULL(set)		((void)((set) = 0))
223 #define	DS_PORTSET_DUP(set1, set2)	((void)((set1) = (set2)))
224 #define	DS_PORTSET_NOT(set1, set2)	((void)((set1) = ~(set2)))
225 #define	DS_PORTSET_AND(set1, set2)	((void)((set1) &= (set2)))
226 
227 /*
228  * A DS event consists of a buffer on a port.  We explictly use a link to
229  * enequeue/dequeue on non-Solaris environments.  On Solaris we use taskq.
230  */
231 typedef struct ds_event {
232 	ds_port_t	*port;
233 	char		*buf;
234 	size_t		buflen;
235 } ds_event_t;
236 
237 /*
238  * LDC Information
239  */
240 #define	DS_STREAM_MTU	4096
241 
242 /*
243  * Machine Description Constants
244  */
245 #define	DS_MD_ROOT_NAME		"domain-services"
246 #define	DS_MD_PORT_NAME		"domain-services-port"
247 #define	DS_MD_CHAN_NAME		"channel-endpoint"
248 
249 /*
250  * DS Services
251  *
252  * A DS Service is a mapping between a DS capability and a client
253  * of the DS framework that provides that capability. It includes
254  * information on the state of the service, the currently negotiated
255  * version of the capability specific protocol, the port that is
256  * currently in use by the capability, etc.
257  */
258 
259 typedef enum {
260 	DS_SVC_INVAL,			/* svc structure uninitialized */
261 	DS_SVC_FREE,			/* svc structure not in use */
262 	DS_SVC_INACTIVE,		/* svc not registered */
263 	DS_SVC_REG_PENDING,		/* register message sent */
264 	DS_SVC_ACTIVE,			/* register message acknowledged */
265 	DS_SVC_UNREG_PENDING		/* unregister is pending */
266 } ds_svc_state_t;
267 
268 /* ds_svc flags bits */
269 #define	DSSF_ISCLIENT		0x0001	/* client service */
270 #define	DSSF_ISUSER		0x0002	/* user land service */
271 #define	DSSF_REGCB_VALID	0x0004	/* ops register callback is valid */
272 #define	DSSF_UNREGCB_VALID	0x0008	/* ops unregister callback is valid */
273 #define	DSSF_DATACB_VALID	0x0010	/* ops data callback is valid */
274 #define	DSSF_LOOPBACK		0x0020	/* loopback */
275 #define	DSSF_PEND_UNREG		0x0040	/* pending unregister */
276 #define	DSSF_ANYCB_VALID	(DSSF_REGCB_VALID | DSSF_UNREGCB_VALID | \
277 				    DSSF_DATACB_VALID)
278 #define	DSSF_USERFLAGS		(DSSF_ISCLIENT | DSSF_ISUSER | DSSF_ANYCB_VALID)
279 
280 typedef struct ds_svc {
281 	ds_capability_t	cap;		/* capability information */
282 	ds_clnt_ops_t	ops;		/* client ops vector */
283 	ds_svc_hdl_t	hdl;		/* handle assigned by DS */
284 	ds_svc_hdl_t	svc_hdl;	/* remote svc hdl if client svc */
285 	ds_svc_state_t	state;		/* current service state */
286 	ds_ver_t	ver;		/* svc protocol version in use */
287 	uint_t		ver_idx;	/* index into client version array */
288 	ds_port_t	*port;		/* port for this service */
289 	ds_portset_t	avail;		/* ports available to this service */
290 	ds_portset_t	tried;		/* ports tried by this service */
291 	int		fixed;		/* is svc fixed to port */
292 	uint_t		flags;		/* service flags */
293 	ds_cb_arg_t	uarg;		/* user arg for user callbacks */
294 	uint_t		drvi;		/* driver instance */
295 	void		*drv_psp;	/* driver per svc ptr */
296 } ds_svc_t;
297 
298 typedef struct ds_svcs {
299 	ds_svc_t	**tbl;		/* ptr to table */
300 	kmutex_t	lock;
301 	uint_t		maxsvcs;	/* size of the table */
302 	uint_t		nsvcs;		/* current number of items */
303 } ds_svcs_t;
304 
305 #define	DS_SVC_ISFREE(svc)	((svc == NULL) || (svc->state == DS_SVC_FREE))
306 #ifndef	DS_MAXSVCS_INIT
307 #define	DS_MAXSVCS_INIT	32
308 #endif
309 
310 /*
311  * A service handle is a 64 bit value with three pieces of information
312  * encoded in it. The upper 32 bits is the index into the table of
313  * a particular service structure. Bit 31 indicates whether the handle
314  * represents a service privider or service client. The lower 31 bits is
315  * a counter that is incremented each time a service structure is reused.
316  */
317 #define	DS_IDX_SHIFT			32
318 #define	DS_COUNT_MASK			0x7fffffffull
319 #define	DS_HDL_ISCLIENT_BIT		0x80000000ull
320 
321 #define	DS_ALLOC_HDL(_idx, _count)	(((uint64_t)_idx << DS_IDX_SHIFT) | \
322 					((uint64_t)(_count + 1) &	    \
323 					DS_COUNT_MASK))
324 #define	DS_HDL2IDX(hdl)			(hdl >> DS_IDX_SHIFT)
325 #define	DS_HDL2COUNT(hdl)		(hdl & DS_COUNT_MASK)
326 #define	DS_HDL_ISCLIENT(hdl)		((hdl) & DS_HDL_ISCLIENT_BIT)
327 #define	DS_HDL_SET_ISCLIENT(hdl)	((hdl) |= DS_HDL_ISCLIENT_BIT)
328 
329 #define	DS_INVALID_INSTANCE		(-1)
330 
331 /* enable/disable taskq processing */
332 extern boolean_t ds_enabled;
333 
334 /*
335  * DS Message Logging
336  *
337  * The DS framework logs all incoming and outgoing messages to a
338  * ring buffer. This provides the ability to reconstruct a trace
339  * of DS activity for use in debugging. In addition to the message
340  * data, each log entry contains a timestamp and the destination
341  * of the message. The destination is based on the port number the
342  * message passed through (port number + 1). The sign of the dest
343  * field distinguishes incoming messages from outgoing messages.
344  * Incoming messages have a negative destination field.
345  */
346 
347 typedef struct ds_log_entry {
348 	struct ds_log_entry	*next;		/* next in log or free list */
349 	struct ds_log_entry	*prev;		/* previous in log */
350 	time_t			timestamp;	/* time message added to log */
351 	size_t			datasz;		/* size of the data */
352 	void			*data;		/* the data itself */
353 	int32_t			dest;		/* message destination */
354 } ds_log_entry_t;
355 
356 #define	DS_LOG_IN(pid)		(-(pid + 1))
357 #define	DS_LOG_OUT(pid)		(pid + 1)
358 
359 /*
360  * DS Log Limits:
361  *
362  * The size of the log is controlled by two limits. The first is
363  * a soft limit that is configurable by the user (via the global
364  * variable ds_log_sz). When this limit is exceeded, each new
365  * message that is added to the log replaces the oldest message.
366  *
367  * The second is a hard limit that is calculated based on the soft
368  * limit (DS_LOG_LIMIT). It is defined to be ~3% above the soft limit.
369  * Once this limit is exceeded, a thread is scheduled to delete old
370  * messages until the size of the log is below the soft limit.
371  */
372 #define	DS_LOG_DEFAULT_SZ	(4 * 1024 * 1024)	/* 4 MB */
373 
374 #define	DS_LOG_LIMIT		(ds_log_sz + (ds_log_sz >> 5))
375 
376 #define	DS_LOG_ENTRY_SZ(ep)	(sizeof (ds_log_entry_t) + (ep)->datasz)
377 
378 /*
379  * DS Log Memory Usage:
380  *
381  * The log free list is initialized from a pre-allocated pool of entry
382  * structures (the global ds_log_entry_pool). The number of entries
383  * in the pool (DS_LOG_NPOOL) is the number of entries that would
384  * take up half the default size of the log.
385  *
386  * As messages are added to the log, entry structures are pulled from
387  * the free list. If the free list is empty, memory is allocated for
388  * the entry. When entries are removed from the log, they are placed
389  * on the free list. Allocated memory is only deallocated when the
390  * entire log is destroyed.
391  */
392 #define	DS_LOG_NPOOL		((DS_LOG_DEFAULT_SZ >> 1) / \
393 				sizeof (ds_log_entry_t))
394 
395 #define	DS_LOG_POOL_END		(ds_log_entry_pool + DS_LOG_NPOOL)
396 
397 #define	DS_IS_POOL_ENTRY(ep)	(((ep) >= ds_log_entry_pool) && \
398 				((ep) <= &(ds_log_entry_pool[DS_LOG_NPOOL])))
399 
400 /* VBSC code compatability related defines */
401 
402 /* VBSC malloc/free are similar to user malloc/free */
403 #define	DS_MALLOC(size)		kmem_zalloc(size, KM_SLEEP)
404 #define	DS_FREE(ptr, size)	kmem_free(ptr, size)
405 
406 /* VBSC debug print needs newline, Solaris cmn_err doesn't */
407 #define	DS_EOL
408 
409 /*
410  * Results of checking version array with ds_vers_isvalid()
411  */
412 typedef enum {
413 	DS_VERS_OK,
414 	DS_VERS_INCREASING_MAJOR_ERR,
415 	DS_VERS_INCREASING_MINOR_ERR
416 } ds_vers_check_t;
417 
418 /* System specific interfaces */
419 extern void ds_sys_port_init(ds_port_t *port);
420 extern void ds_sys_port_fini(ds_port_t *port);
421 extern void ds_sys_drain_events(ds_port_t *port);
422 extern int ds_sys_dispatch_func(void (func)(void *), void *arg);
423 extern void ds_sys_ldc_init(ds_port_t *port);
424 
425 /* vlds cb access to svc structure */
426 void ds_cbarg_get_hdl(ds_cb_arg_t arg, ds_svc_hdl_t *hdlp);
427 void ds_cbarg_get_flags(ds_cb_arg_t arg, uint32_t *flagsp);
428 void ds_cbarg_get_drv_info(ds_cb_arg_t arg, int *drvip);
429 void ds_cbarg_get_drv_per_svc_ptr(ds_cb_arg_t arg, void **dpspp);
430 void ds_cbarg_get_domain(ds_cb_arg_t arg, ds_domain_hdl_t *dhdlp);
431 void ds_cbarg_get_service_id(ds_cb_arg_t arg, char **servicep);
432 void ds_cbarg_set_drv_per_svc_ptr(ds_cb_arg_t arg, void *dpsp);
433 int ds_hdl_get_cbarg(ds_svc_hdl_t hdl, ds_cb_arg_t *cbargp);
434 void ds_cbarg_set_cookie(ds_svc_t *svc);
435 int ds_is_my_hdl(ds_svc_hdl_t hdl, int instance);
436 void ds_set_my_dom_hdl_name(ds_domain_hdl_t dhdl, char *name);
437 
438 /* initialization functions */
439 void ds_common_init(void);
440 int ds_ldc_fini(ds_port_t *port);
441 void ds_init_svcs_tbl(uint_t nentries);
442 
443 /* message sending functions */
444 void ds_send_init_req(ds_port_t *port);
445 int ds_send_unreg_req(ds_svc_t *svc);
446 
447 /* walker functions */
448 typedef int (*svc_cb_t)(ds_svc_t *svc, void *arg);
449 int ds_walk_svcs(svc_cb_t svc_cb, void *arg);
450 int ds_svc_ismatch(ds_svc_t *svc, void *arg);
451 int ds_svc_free(ds_svc_t *svc, void *arg);
452 int ds_svc_register(ds_svc_t *svc, void *arg);
453 
454 /* service utilities */
455 ds_svc_t *ds_alloc_svc(void);
456 ds_svc_t *ds_sys_find_svc_by_id_port(char *svc_id, ds_port_t *port,
457     int is_client);
458 ds_svc_t *ds_get_svc(ds_svc_hdl_t hdl);
459 
460 /* port utilities */
461 void ds_port_common_init(ds_port_t *port);
462 void ds_port_common_fini(ds_port_t *port, int is_fini);
463 
464 /* misc utilities */
465 ds_vers_check_t ds_vers_isvalid(ds_ver_t *vers, int nvers);
466 char *ds_errno_to_str(int ds_errno, char *ebuf);
467 char *ds_strdup(char *str);
468 boolean_t negotiate_version(int num_versions, ds_ver_t *sup_versionsp,
469     uint16_t req_major, uint16_t *new_majorp, uint16_t *new_minorp);
470 
471 /* log functions */
472 int ds_log_add_msg(int32_t dest, uint8_t *msg, size_t sz);
473 
474 /* vlds driver interfaces to ds module */
475 int ds_ucap_init(ds_capability_t *cap, ds_clnt_ops_t *ops, uint_t flags,
476     int instance, ds_svc_hdl_t *hdlp);
477 int ds_unreg_hdl(ds_svc_hdl_t hdl);
478 int ds_hdl_lookup(char *service, uint_t is_client, ds_svc_hdl_t *hdlp,
479     uint_t maxhdls, uint_t *nhdlsp);
480 int ds_service_lookup(ds_svc_hdl_t hdl, char **servicep, uint_t *is_client);
481 int ds_domain_lookup(ds_svc_hdl_t hdl, ds_domain_hdl_t *dhdlp);
482 int ds_hdl_isready(ds_svc_hdl_t hdl, uint_t *is_ready);
483 void ds_unreg_all(int instance);
484 int ds_dom_name_to_hdl(char *domain_name, ds_domain_hdl_t *dhdlp);
485 int ds_dom_hdl_to_name(ds_domain_hdl_t dhdl, char **domain_namep);
486 int ds_add_port(uint64_t port_id, uint64_t ldc_id, ds_domain_hdl_t dhdl,
487     char *dom_name, int verbose);
488 int ds_remove_port(uint64_t portid, int is_fini);
489 
490 /* ds_ucap_init flags */
491 #define	DS_UCAP_CLNT		0x0	/* Service is Client */
492 #define	DS_UCAP_SVC		0x1	/* Service is Server */
493 
494 /*
495  * Error buffer size for ds_errno_to_str
496  */
497 #define	DS_EBUFSIZE	80
498 
499 /*
500  * Debugging Features
501  */
502 #ifdef DEBUG
503 
504 #define	DS_DBG_BASIC			0x001
505 #define	DS_DBG_FLAG_LDC			0x002
506 #define	DS_DBG_FLAG_LOG			0x004
507 #define	DS_DBG_DUMP_LDC_MSG		0x008
508 #define	DS_DBG_FLAG_MD			0x010
509 #define	DS_DBG_FLAG_USR			0x020
510 #define	DS_DBG_FLAG_VLDS		0x040
511 #define	DS_DBG_FLAG_PRCL		0x080
512 #define	DS_DBG_FLAG_RCVQ		0x100
513 #define	DS_DBG_FLAG_LOOP		0x200
514 
515 #define	DS_DBG				if (ds_debug & DS_DBG_BASIC) cmn_err
516 #define	DS_DBG_LDC			if (ds_debug & DS_DBG_FLAG_LDC) cmn_err
517 #define	DS_DBG_LOG			if (ds_debug & DS_DBG_FLAG_LOG) cmn_err
518 #define	DS_DBG_MD			if (ds_debug & DS_DBG_FLAG_MD) cmn_err
519 #define	DS_DBG_USR			if (ds_debug & DS_DBG_FLAG_USR) cmn_err
520 #define	DS_DBG_VLDS			if (ds_debug & DS_DBG_FLAG_VLDS) cmn_err
521 #define	DS_DBG_PRCL			if (ds_debug & DS_DBG_FLAG_PRCL) cmn_err
522 #define	DS_DBG_RCVQ			if (ds_debug & DS_DBG_FLAG_RCVQ) cmn_err
523 #define	DS_DBG_LOOP			if (ds_debug & DS_DBG_FLAG_LOOP) cmn_err
524 
525 #define	DS_DUMP_MSG(flags, buf, len)	if (ds_debug & (flags)) \
526 					    ds_dump_msg(buf, len)
527 
528 extern uint_t ds_debug;
529 void ds_dump_msg(void *buf, size_t len);
530 
531 #define	DS_BADHDL1			(ds_svc_hdl_t)(0xdeadbed1deadbed1ull)
532 #define	DS_BADHDL2			(ds_svc_hdl_t)(0x2deadbed2deadbedull)
533 
534 #else /* DEBUG */
535 
536 #define	DS_DBG				if (0) cmn_err
537 #define	DS_DBG_LDC			DS_DBG
538 #define	DS_DBG_LOG			DS_DBG
539 #define	DS_DBG_MD			DS_DBG
540 #define	DS_DBG_USR			DS_DBG
541 #define	DS_DBG_VLDS			DS_DBG
542 #define	DS_DBG_PRCL			DS_DBG
543 #define	DS_DBG_RCVQ			DS_DBG
544 #define	DS_DBG_LOOP			DS_DBG
545 #define	DS_DUMP_MSG(flags, buf, len)
546 #define	DS_DUMP_LDC_MSG(buf, len)
547 
548 #define	DS_BADHDL1			NULL
549 #define	DS_BADHDL2			NULL
550 
551 #endif /* DEBUG */
552 
553 #ifdef __cplusplus
554 }
555 #endif
556 
557 #endif /* _DS_IMPL_H */
558