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