Home | History | Annotate | Download | only in sys
      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_portset_t ds_nullport;
    219 
    220 #define	DS_PORTID_INVALID		((uint64_t)-1)
    221 
    222 /* DS SP Port ID */
    223 extern uint64_t ds_sp_port_id;
    224 
    225 #define	DS_MAX_PORT_ID			(DS_MAX_PORTS - 1)
    226 
    227 #define	DS_PORT_IN_SET(set, port)	BT_TEST((set), (port))
    228 #define	DS_PORTSET_ADD(set, port)	BT_SET((set), (port))
    229 #define	DS_PORTSET_DEL(set, port)	BT_CLEAR((set), (port))
    230 #define	DS_PORTSET_ISNULL(set)		(memcmp((set), ds_nullport, \
    231 					    sizeof (set)) == 0)
    232 #define	DS_PORTSET_SETNULL(set)		((void)memset((set), 0, sizeof (set)))
    233 #define	DS_PORTSET_DUP(set1, set2)	((void)memcpy((set1), (set2), \
    234 					    sizeof (set1)))
    235 
    236 /*
    237  * A DS event consists of a buffer on a port.  We explictly use a link to
    238  * enequeue/dequeue on non-Solaris environments.  On Solaris we use taskq.
    239  */
    240 typedef struct ds_event {
    241 	ds_port_t	*port;
    242 	char		*buf;
    243 	size_t		buflen;
    244 } ds_event_t;
    245 
    246 /*
    247  * LDC Information
    248  */
    249 #define	DS_STREAM_MTU	4096
    250 
    251 /*
    252  * Machine Description Constants
    253  */
    254 #define	DS_MD_ROOT_NAME		"domain-services"
    255 #define	DS_MD_PORT_NAME		"domain-services-port"
    256 #define	DS_MD_CHAN_NAME		"channel-endpoint"
    257 
    258 /*
    259  * DS Services
    260  *
    261  * A DS Service is a mapping between a DS capability and a client
    262  * of the DS framework that provides that capability. It includes
    263  * information on the state of the service, the currently negotiated
    264  * version of the capability specific protocol, the port that is
    265  * currently in use by the capability, etc.
    266  */
    267 
    268 typedef enum {
    269 	DS_SVC_INVAL,			/* svc structure uninitialized */
    270 	DS_SVC_FREE,			/* svc structure not in use */
    271 	DS_SVC_INACTIVE,		/* svc not registered */
    272 	DS_SVC_REG_PENDING,		/* register message sent */
    273 	DS_SVC_ACTIVE,			/* register message acknowledged */
    274 	DS_SVC_UNREG_PENDING		/* unregister is pending */
    275 } ds_svc_state_t;
    276 
    277 /* ds_svc flags bits */
    278 #define	DSSF_ISCLIENT		0x0001	/* client service */
    279 #define	DSSF_ISUSER		0x0002	/* user land service */
    280 #define	DSSF_REGCB_VALID	0x0004	/* ops register callback is valid */
    281 #define	DSSF_UNREGCB_VALID	0x0008	/* ops unregister callback is valid */
    282 #define	DSSF_DATACB_VALID	0x0010	/* ops data callback is valid */
    283 #define	DSSF_LOOPBACK		0x0020	/* loopback */
    284 #define	DSSF_PEND_UNREG		0x0040	/* pending unregister */
    285 #define	DSSF_ANYCB_VALID	(DSSF_REGCB_VALID | DSSF_UNREGCB_VALID | \
    286 				    DSSF_DATACB_VALID)
    287 #define	DSSF_USERFLAGS		(DSSF_ISCLIENT | DSSF_ISUSER | DSSF_ANYCB_VALID)
    288 
    289 typedef struct ds_svc {
    290 	ds_capability_t	cap;		/* capability information */
    291 	ds_clnt_ops_t	ops;		/* client ops vector */
    292 	ds_svc_hdl_t	hdl;		/* handle assigned by DS */
    293 	ds_svc_hdl_t	svc_hdl;	/* remote svc hdl if client svc */
    294 	ds_svc_state_t	state;		/* current service state */
    295 	ds_ver_t	ver;		/* svc protocol version in use */
    296 	uint_t		ver_idx;	/* index into client version array */
    297 	ds_port_t	*port;		/* port for this service */
    298 	ds_portset_t	avail;		/* ports available to this service */
    299 	ds_portset_t	tried;		/* ports tried by this service */
    300 	int		fixed;		/* is svc fixed to port */
    301 	uint_t		flags;		/* service flags */
    302 	ds_cb_arg_t	uarg;		/* user arg for user callbacks */
    303 	uint_t		drvi;		/* driver instance */
    304 	void		*drv_psp;	/* driver per svc ptr */
    305 } ds_svc_t;
    306 
    307 typedef struct ds_svcs {
    308 	ds_svc_t	**tbl;		/* ptr to table */
    309 	kmutex_t	lock;
    310 	uint_t		maxsvcs;	/* size of the table */
    311 	uint_t		nsvcs;		/* current number of items */
    312 } ds_svcs_t;
    313 
    314 #define	DS_SVC_ISFREE(svc)	((svc == NULL) || (svc->state == DS_SVC_FREE))
    315 #ifndef	DS_MAXSVCS_INIT
    316 #define	DS_MAXSVCS_INIT	32
    317 #endif
    318 
    319 /*
    320  * A service handle is a 64 bit value with three pieces of information
    321  * encoded in it. The upper 32 bits is the index into the table of
    322  * a particular service structure. Bit 31 indicates whether the handle
    323  * represents a service privider or service client. The lower 31 bits is
    324  * a counter that is incremented each time a service structure is reused.
    325  */
    326 #define	DS_IDX_SHIFT			32
    327 #define	DS_COUNT_MASK			0x7fffffffull
    328 #define	DS_HDL_ISCLIENT_BIT		0x80000000ull
    329 
    330 #define	DS_ALLOC_HDL(_idx, _count)	(((uint64_t)_idx << DS_IDX_SHIFT) | \
    331 					((uint64_t)(_count + 1) &	    \
    332 					DS_COUNT_MASK))
    333 #define	DS_HDL2IDX(hdl)			(hdl >> DS_IDX_SHIFT)
    334 #define	DS_HDL2COUNT(hdl)		(hdl & DS_COUNT_MASK)
    335 #define	DS_HDL_ISCLIENT(hdl)		((hdl) & DS_HDL_ISCLIENT_BIT)
    336 #define	DS_HDL_SET_ISCLIENT(hdl)	((hdl) |= DS_HDL_ISCLIENT_BIT)
    337 
    338 #define	DS_INVALID_INSTANCE		(-1)
    339 
    340 /* enable/disable taskq processing */
    341 extern boolean_t ds_enabled;
    342 
    343 /*
    344  * DS Message Logging
    345  *
    346  * The DS framework logs all incoming and outgoing messages to a
    347  * ring buffer. This provides the ability to reconstruct a trace
    348  * of DS activity for use in debugging. In addition to the message
    349  * data, each log entry contains a timestamp and the destination
    350  * of the message. The destination is based on the port number the
    351  * message passed through (port number + 1). The sign of the dest
    352  * field distinguishes incoming messages from outgoing messages.
    353  * Incoming messages have a negative destination field.
    354  */
    355 
    356 typedef struct ds_log_entry {
    357 	struct ds_log_entry	*next;		/* next in log or free list */
    358 	struct ds_log_entry	*prev;		/* previous in log */
    359 	time_t			timestamp;	/* time message added to log */
    360 	size_t			datasz;		/* size of the data */
    361 	void			*data;		/* the data itself */
    362 	int32_t			dest;		/* message destination */
    363 } ds_log_entry_t;
    364 
    365 #define	DS_LOG_IN(pid)		(-(pid + 1))
    366 #define	DS_LOG_OUT(pid)		(pid + 1)
    367 
    368 /*
    369  * DS Log Limits:
    370  *
    371  * The size of the log is controlled by two limits. The first is
    372  * a soft limit that is configurable by the user (via the global
    373  * variable ds_log_sz). When this limit is exceeded, each new
    374  * message that is added to the log replaces the oldest message.
    375  *
    376  * The second is a hard limit that is calculated based on the soft
    377  * limit (DS_LOG_LIMIT). It is defined to be ~3% above the soft limit.
    378  * Once this limit is exceeded, a thread is scheduled to delete old
    379  * messages until the size of the log is below the soft limit.
    380  */
    381 #define	DS_LOG_DEFAULT_SZ	(4 * 1024 * 1024)	/* 4 MB */
    382 
    383 #define	DS_LOG_LIMIT		(ds_log_sz + (ds_log_sz >> 5))
    384 
    385 #define	DS_LOG_ENTRY_SZ(ep)	(sizeof (ds_log_entry_t) + (ep)->datasz)
    386 
    387 /*
    388  * DS Log Memory Usage:
    389  *
    390  * The log free list is initialized from a pre-allocated pool of entry
    391  * structures (the global ds_log_entry_pool). The number of entries
    392  * in the pool (DS_LOG_NPOOL) is the number of entries that would
    393  * take up half the default size of the log.
    394  *
    395  * As messages are added to the log, entry structures are pulled from
    396  * the free list. If the free list is empty, memory is allocated for
    397  * the entry. When entries are removed from the log, they are placed
    398  * on the free list. Allocated memory is only deallocated when the
    399  * entire log is destroyed.
    400  */
    401 #define	DS_LOG_NPOOL		((DS_LOG_DEFAULT_SZ >> 1) / \
    402 				sizeof (ds_log_entry_t))
    403 
    404 #define	DS_LOG_POOL_END		(ds_log_entry_pool + DS_LOG_NPOOL)
    405 
    406 #define	DS_IS_POOL_ENTRY(ep)	(((ep) >= ds_log_entry_pool) && \
    407 				((ep) <= &(ds_log_entry_pool[DS_LOG_NPOOL])))
    408 
    409 /* VBSC code compatability related defines */
    410 
    411 /* VBSC malloc/free are similar to user malloc/free */
    412 #define	DS_MALLOC(size)		kmem_zalloc(size, KM_SLEEP)
    413 #define	DS_FREE(ptr, size)	kmem_free(ptr, size)
    414 
    415 /* VBSC debug print needs newline, Solaris cmn_err doesn't */
    416 #define	DS_EOL
    417 
    418 /*
    419  * Results of checking version array with ds_vers_isvalid()
    420  */
    421 typedef enum {
    422 	DS_VERS_OK,
    423 	DS_VERS_INCREASING_MAJOR_ERR,
    424 	DS_VERS_INCREASING_MINOR_ERR
    425 } ds_vers_check_t;
    426 
    427 /* System specific interfaces */
    428 extern void ds_sys_port_init(ds_port_t *port);
    429 extern void ds_sys_port_fini(ds_port_t *port);
    430 extern void ds_sys_drain_events(ds_port_t *port);
    431 extern int ds_sys_dispatch_func(void (func)(void *), void *arg);
    432 extern void ds_sys_ldc_init(ds_port_t *port);
    433 
    434 /* vlds cb access to svc structure */
    435 void ds_cbarg_get_hdl(ds_cb_arg_t arg, ds_svc_hdl_t *hdlp);
    436 void ds_cbarg_get_flags(ds_cb_arg_t arg, uint32_t *flagsp);
    437 void ds_cbarg_get_drv_info(ds_cb_arg_t arg, int *drvip);
    438 void ds_cbarg_get_drv_per_svc_ptr(ds_cb_arg_t arg, void **dpspp);
    439 void ds_cbarg_get_domain(ds_cb_arg_t arg, ds_domain_hdl_t *dhdlp);
    440 void ds_cbarg_get_service_id(ds_cb_arg_t arg, char **servicep);
    441 void ds_cbarg_set_drv_per_svc_ptr(ds_cb_arg_t arg, void *dpsp);
    442 int ds_hdl_get_cbarg(ds_svc_hdl_t hdl, ds_cb_arg_t *cbargp);
    443 void ds_cbarg_set_cookie(ds_svc_t *svc);
    444 int ds_is_my_hdl(ds_svc_hdl_t hdl, int instance);
    445 void ds_set_my_dom_hdl_name(ds_domain_hdl_t dhdl, char *name);
    446 
    447 /* initialization functions */
    448 void ds_common_init(void);
    449 int ds_ldc_fini(ds_port_t *port);
    450 void ds_init_svcs_tbl(uint_t nentries);
    451 
    452 /* message sending functions */
    453 void ds_send_init_req(ds_port_t *port);
    454 int ds_send_unreg_req(ds_svc_t *svc);
    455 
    456 /* walker functions */
    457 typedef int (*svc_cb_t)(ds_svc_t *svc, void *arg);
    458 int ds_walk_svcs(svc_cb_t svc_cb, void *arg);
    459 int ds_svc_ismatch(ds_svc_t *svc, void *arg);
    460 int ds_svc_free(ds_svc_t *svc, void *arg);
    461 int ds_svc_register(ds_svc_t *svc, void *arg);
    462 
    463 /* service utilities */
    464 ds_svc_t *ds_alloc_svc(void);
    465 ds_svc_t *ds_sys_find_svc_by_id_port(char *svc_id, ds_port_t *port,
    466     int is_client);
    467 ds_svc_t *ds_get_svc(ds_svc_hdl_t hdl);
    468 
    469 /* port utilities */
    470 void ds_port_common_init(ds_port_t *port);
    471 void ds_port_common_fini(ds_port_t *port);
    472 
    473 /* misc utilities */
    474 ds_vers_check_t ds_vers_isvalid(ds_ver_t *vers, int nvers);
    475 char *ds_errno_to_str(int ds_errno, char *ebuf);
    476 char *ds_strdup(char *str);
    477 boolean_t negotiate_version(int num_versions, ds_ver_t *sup_versionsp,
    478     uint16_t req_major, uint16_t *new_majorp, uint16_t *new_minorp);
    479 
    480 /* log functions */
    481 int ds_log_add_msg(int32_t dest, uint8_t *msg, size_t sz);
    482 
    483 /* vlds driver interfaces to ds module */
    484 int ds_ucap_init(ds_capability_t *cap, ds_clnt_ops_t *ops, uint_t flags,
    485     int instance, ds_svc_hdl_t *hdlp);
    486 int ds_unreg_hdl(ds_svc_hdl_t hdl);
    487 int ds_hdl_lookup(char *service, uint_t is_client, ds_svc_hdl_t *hdlp,
    488     uint_t maxhdls, uint_t *nhdlsp);
    489 int ds_service_lookup(ds_svc_hdl_t hdl, char **servicep, uint_t *is_client);
    490 int ds_domain_lookup(ds_svc_hdl_t hdl, ds_domain_hdl_t *dhdlp);
    491 int ds_hdl_isready(ds_svc_hdl_t hdl, uint_t *is_ready);
    492 void ds_unreg_all(int instance);
    493 int ds_dom_name_to_hdl(char *domain_name, ds_domain_hdl_t *dhdlp);
    494 int ds_dom_hdl_to_name(ds_domain_hdl_t dhdl, char **domain_namep);
    495 int ds_add_port(uint64_t port_id, uint64_t ldc_id, ds_domain_hdl_t dhdl,
    496     char *dom_name, int verbose);
    497 int ds_remove_port(uint64_t portid, int is_fini);
    498 
    499 /* ds_ucap_init flags */
    500 #define	DS_UCAP_CLNT		0x0	/* Service is Client */
    501 #define	DS_UCAP_SVC		0x1	/* Service is Server */
    502 
    503 /*
    504  * Error buffer size for ds_errno_to_str
    505  */
    506 #define	DS_EBUFSIZE	80
    507 
    508 /*
    509  * Debugging Features
    510  */
    511 #ifdef DEBUG
    512 
    513 #define	DS_DBG_BASIC			0x001
    514 #define	DS_DBG_FLAG_LDC			0x002
    515 #define	DS_DBG_FLAG_LOG			0x004
    516 #define	DS_DBG_DUMP_LDC_MSG		0x008
    517 #define	DS_DBG_FLAG_MD			0x010
    518 #define	DS_DBG_FLAG_USR			0x020
    519 #define	DS_DBG_FLAG_VLDS		0x040
    520 #define	DS_DBG_FLAG_PRCL		0x080
    521 #define	DS_DBG_FLAG_RCVQ		0x100
    522 #define	DS_DBG_FLAG_LOOP		0x200
    523 
    524 #define	DS_DBG				if (ds_debug & DS_DBG_BASIC) cmn_err
    525 #define	DS_DBG_LDC			if (ds_debug & DS_DBG_FLAG_LDC) cmn_err
    526 #define	DS_DBG_LOG			if (ds_debug & DS_DBG_FLAG_LOG) cmn_err
    527 #define	DS_DBG_MD			if (ds_debug & DS_DBG_FLAG_MD) cmn_err
    528 #define	DS_DBG_USR			if (ds_debug & DS_DBG_FLAG_USR) cmn_err
    529 #define	DS_DBG_VLDS			if (ds_debug & DS_DBG_FLAG_VLDS) cmn_err
    530 #define	DS_DBG_PRCL			if (ds_debug & DS_DBG_FLAG_PRCL) cmn_err
    531 #define	DS_DBG_RCVQ			if (ds_debug & DS_DBG_FLAG_RCVQ) cmn_err
    532 #define	DS_DBG_LOOP			if (ds_debug & DS_DBG_FLAG_LOOP) cmn_err
    533 
    534 #define	DS_DUMP_MSG(flags, buf, len)	if (ds_debug & (flags)) \
    535 					    ds_dump_msg(buf, len)
    536 
    537 extern uint_t ds_debug;
    538 void ds_dump_msg(void *buf, size_t len);
    539 
    540 #define	DS_BADHDL1			(ds_svc_hdl_t)(0xdeadbed1deadbed1ull)
    541 #define	DS_BADHDL2			(ds_svc_hdl_t)(0x2deadbed2deadbedull)
    542 
    543 #else /* DEBUG */
    544 
    545 #define	DS_DBG				if (0) cmn_err
    546 #define	DS_DBG_LDC			DS_DBG
    547 #define	DS_DBG_LOG			DS_DBG
    548 #define	DS_DBG_MD			DS_DBG
    549 #define	DS_DBG_USR			DS_DBG
    550 #define	DS_DBG_VLDS			DS_DBG
    551 #define	DS_DBG_PRCL			DS_DBG
    552 #define	DS_DBG_RCVQ			DS_DBG
    553 #define	DS_DBG_LOOP			DS_DBG
    554 #define	DS_DUMP_MSG(flags, buf, len)
    555 #define	DS_DUMP_LDC_MSG(buf, len)
    556 
    557 #define	DS_BADHDL1			NULL
    558 #define	DS_BADHDL2			NULL
    559 
    560 #endif /* DEBUG */
    561 
    562 #ifdef __cplusplus
    563 }
    564 #endif
    565 
    566 #endif /* _DS_IMPL_H */
    567