xref: /onnv-gate/usr/src/uts/sun4v/sys/ds_impl.h (revision 9916:1b3679ce7b31)
11991Sheppo /*
21991Sheppo  * CDDL HEADER START
31991Sheppo  *
41991Sheppo  * The contents of this file are subject to the terms of the
51991Sheppo  * Common Development and Distribution License (the "License").
61991Sheppo  * You may not use this file except in compliance with the License.
71991Sheppo  *
81991Sheppo  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91991Sheppo  * or http://www.opensolaris.org/os/licensing.
101991Sheppo  * See the License for the specific language governing permissions
111991Sheppo  * and limitations under the License.
121991Sheppo  *
131991Sheppo  * When distributing Covered Code, include this CDDL HEADER in each
141991Sheppo  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151991Sheppo  * If applicable, add the following below this CDDL HEADER, with the
161991Sheppo  * fields enclosed by brackets "[]" replaced with your own identifying
171991Sheppo  * information: Portions Copyright [yyyy] [name of copyright owner]
181991Sheppo  *
191991Sheppo  * CDDL HEADER END
201991Sheppo  */
211991Sheppo 
221991Sheppo /*
239535SMichael.Christensen@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
241991Sheppo  * Use is subject to license terms.
251991Sheppo  */
261991Sheppo 
271991Sheppo #ifndef _DS_IMPL_H
281991Sheppo #define	_DS_IMPL_H
291991Sheppo 
301991Sheppo #ifdef __cplusplus
311991Sheppo extern "C" {
321991Sheppo #endif
331991Sheppo 
349535SMichael.Christensen@Sun.COM #include <sys/bitmap.h>
359535SMichael.Christensen@Sun.COM #include <sys/ldoms.h>
367697SMichael.Christensen@Sun.COM 
377697SMichael.Christensen@Sun.COM 
381991Sheppo /*
391991Sheppo  * The Domain Services Protocol
401991Sheppo  *
411991Sheppo  * The DS protocol is divided into two parts. The first is fixed and
421991Sheppo  * must remain exactly the same for *all* versions of the DS protocol.
431991Sheppo  * The only messages supported by the fixed portion of the protocol are
441991Sheppo  * to negotiate a version to use for the rest of the protocol.
451991Sheppo  */
461991Sheppo 
471991Sheppo /*
481991Sheppo  * Domain Services Header
491991Sheppo  */
501991Sheppo typedef struct ds_hdr {
511991Sheppo 	uint32_t	msg_type;	/* message type */
521991Sheppo 	uint32_t	payload_len;	/* payload length */
531991Sheppo } ds_hdr_t;
541991Sheppo 
551991Sheppo #define	DS_HDR_SZ	(sizeof (ds_hdr_t))
561991Sheppo 
571991Sheppo /*
581991Sheppo  * DS Fixed Message Types
591991Sheppo  */
601991Sheppo #define	DS_INIT_REQ		0x0	/* initiate DS connection */
617697SMichael.Christensen@Sun.COM #define	DS_INIT_ACK		0x1	/* initiation acknowledgement */
621991Sheppo #define	DS_INIT_NACK		0x2	/* initiation negative acknowledgment */
631991Sheppo 
641991Sheppo /*
651991Sheppo  * DS Fixed Initialization Messages
661991Sheppo  */
671991Sheppo typedef struct ds_init_req {
681991Sheppo 	uint16_t	major_vers;	/* requested major version */
691991Sheppo 	uint16_t	minor_vers;	/* requested minor version */
701991Sheppo } ds_init_req_t;
711991Sheppo 
721991Sheppo typedef struct ds_init_ack {
731991Sheppo 	uint16_t	minor_vers;	/* highest supported minor version */
741991Sheppo } ds_init_ack_t;
751991Sheppo 
761991Sheppo typedef struct ds_init_nack {
771991Sheppo 	uint16_t	major_vers;	/* alternate supported major version */
781991Sheppo } ds_init_nack_t;
791991Sheppo 
801991Sheppo /*
811991Sheppo  * DS Message Types for Version 1.0
821991Sheppo  */
831991Sheppo #define	DS_REG_REQ		0x3	/* register a service */
847697SMichael.Christensen@Sun.COM #define	DS_REG_ACK		0x4	/* register acknowledgement */
851991Sheppo #define	DS_REG_NACK		0x5	/* register failed */
861991Sheppo #define	DS_UNREG		0x6	/* unregister a service */
877697SMichael.Christensen@Sun.COM #define	DS_UNREG_ACK		0x7	/* unregister acknowledgement */
881991Sheppo #define	DS_UNREG_NACK		0x8	/* unregister failed */
891991Sheppo #define	DS_DATA			0x9	/* data message */
901991Sheppo #define	DS_NACK			0xa	/* data error */
911991Sheppo 
921991Sheppo /* result codes */
931991Sheppo #define	DS_OK			0x0	/* success */
941991Sheppo #define	DS_REG_VER_NACK		0x1	/* unsupported major version */
951991Sheppo #define	DS_REG_DUP		0x2	/* duplicate registration attempted */
961991Sheppo #define	DS_INV_HDL		0x3	/* service handle not valid */
971991Sheppo #define	DS_TYPE_UNKNOWN		0x4	/* unknown message type received */
981991Sheppo 
991991Sheppo /*
1001991Sheppo  * Service Register Messages
1011991Sheppo  */
1021991Sheppo typedef struct ds_reg_req {
1031991Sheppo 	uint64_t	svc_handle;	/* service handle to register */
1041991Sheppo 	uint16_t	major_vers;	/* requested major version */
1051991Sheppo 	uint16_t	minor_vers;	/* requested minor version */
1061991Sheppo 	char		svc_id[1];	/* service identifier string */
1071991Sheppo } ds_reg_req_t;
1081991Sheppo 
1091991Sheppo typedef struct ds_reg_ack {
1101991Sheppo 	uint64_t	svc_handle;	/* service handle sent in register */
1111991Sheppo 	uint16_t	minor_vers;	/* highest supported minor version */
1121991Sheppo } ds_reg_ack_t;
1131991Sheppo 
1141991Sheppo typedef struct ds_reg_nack {
1151991Sheppo 	uint64_t	svc_handle;	/* service handle sent in register */
1161991Sheppo 	uint64_t	result;		/* reason for the failure */
1171991Sheppo 	uint16_t	major_vers;	/* alternate supported major version */
1181991Sheppo } ds_reg_nack_t;
1191991Sheppo 
1201991Sheppo /*
1211991Sheppo  * Service Unregister Messages
1221991Sheppo  */
1231991Sheppo typedef struct ds_unreg_req {
1241991Sheppo 	uint64_t	svc_handle;	/* service handle to unregister */
1251991Sheppo } ds_unreg_req_t;
1261991Sheppo 
1271991Sheppo typedef struct ds_unreg_ack {
1281991Sheppo 	uint64_t	svc_handle;	/* service handle sent in unregister */
1291991Sheppo } ds_unreg_ack_t;
1301991Sheppo 
1311991Sheppo typedef struct ds_unreg_nack {
1321991Sheppo 	uint64_t	svc_handle;	/* service handle sent in unregister */
1331991Sheppo } ds_unreg_nack_t;
1341991Sheppo 
1351991Sheppo /*
1361991Sheppo  * Data Transfer Messages
1371991Sheppo  */
1381991Sheppo typedef struct ds_data_handle {
1391991Sheppo 	uint64_t	svc_handle;	/* service handle for data */
1401991Sheppo } ds_data_handle_t;
1411991Sheppo 
1421991Sheppo typedef struct ds_data_nack {
1431991Sheppo 	uint64_t	svc_handle;	/* service handle sent in data msg */
1441991Sheppo 	uint64_t	result;		/* reason for failure */
1451991Sheppo } ds_data_nack_t;
1461991Sheppo 
1471991Sheppo /*
1481991Sheppo  * Message Processing Utilities
1491991Sheppo  */
1501991Sheppo #define	DS_MSG_TYPE_VALID(type)		((type) <= DS_NACK)
1511991Sheppo #define	DS_MSG_LEN(ds_type)		(sizeof (ds_hdr_t) + sizeof (ds_type))
1521991Sheppo 
1531991Sheppo 
1541991Sheppo /*
1551991Sheppo  * Domain Service Port
1561991Sheppo  *
1571991Sheppo  * A DS port is a logical representation of an LDC dedicated to
1581991Sheppo  * communication between DS endpoints. The ds_port_t maintains state
1591991Sheppo  * associated with a connection to a remote endpoint. This includes
1601991Sheppo  * the state of the port, the LDC state, the current version of the
1611991Sheppo  * DS protocol in use on the port, and other port properties.
1621991Sheppo  *
1631991Sheppo  * Locking: The port is protected by a single mutex. It must be held
1641991Sheppo  *   while the port structure is being accessed and also when data is
1651991Sheppo  *   being read or written using the port
1661991Sheppo  */
1671991Sheppo typedef enum {
1681991Sheppo 	DS_PORT_FREE,			/* port structure not in use */
1691991Sheppo 	DS_PORT_INIT,			/* port structure created */
1701991Sheppo 	DS_PORT_LDC_INIT,		/* ldc successfully initialized */
1711991Sheppo 	DS_PORT_INIT_REQ,		/* initialization handshake sent */
1721991Sheppo 	DS_PORT_READY			/* init handshake completed */
1731991Sheppo } ds_port_state_t;
1741991Sheppo 
1751991Sheppo typedef struct ds_ldc {
1761991Sheppo 	uint64_t	id;		/* LDC id */
1771991Sheppo 	ldc_handle_t	hdl;		/* LDC handle */
1781991Sheppo 	ldc_status_t	state;		/* current LDC state */
1791991Sheppo } ds_ldc_t;
1801991Sheppo 
1817697SMichael.Christensen@Sun.COM typedef uint64_t ds_domain_hdl_t;
1827697SMichael.Christensen@Sun.COM 
1837697SMichael.Christensen@Sun.COM #define	DS_DHDL_INVALID			((ds_domain_hdl_t)0xffffffff)
1847697SMichael.Christensen@Sun.COM 
1857697SMichael.Christensen@Sun.COM /* port flags */
1867697SMichael.Christensen@Sun.COM #define	DS_PORT_MUTEX_INITED	0x1	/* mutexes inited? */
1877697SMichael.Christensen@Sun.COM 
1881991Sheppo typedef struct ds_port {
1897697SMichael.Christensen@Sun.COM 	uint32_t	flags;		/* port flags */
1907697SMichael.Christensen@Sun.COM 	kmutex_t	lock;		/* port and service state lock */
1917697SMichael.Christensen@Sun.COM 	kmutex_t	tx_lock;	/* tx port lock */
1927697SMichael.Christensen@Sun.COM 	kmutex_t	rcv_lock;	/* rcv port lock */
1931991Sheppo 	uint64_t	id;		/* port id from MD */
1941991Sheppo 	ds_port_state_t	state;		/* state of the port */
1951991Sheppo 	ds_ver_t	ver;		/* DS protocol version in use */
1961991Sheppo 	uint32_t	ver_idx;	/* index of version during handshake */
1971991Sheppo 	ds_ldc_t	ldc;		/* LDC for this port */
1987697SMichael.Christensen@Sun.COM 	ds_domain_hdl_t	domain_hdl;	/* LDOMs domain hdl assoc. with port */
1997697SMichael.Christensen@Sun.COM 	char 		*domain_name;	/* LDOMs domain name assoc. with port */
2001991Sheppo } ds_port_t;
2011991Sheppo 
2027697SMichael.Christensen@Sun.COM #define	IS_DS_PORT(port)	1	/* VBSC code compatability */
2037697SMichael.Christensen@Sun.COM #define	PORTID(port)		((ulong_t)((port)->id))
2047697SMichael.Christensen@Sun.COM #define	PTR_TO_LONG(ptr)	((uint64_t)(ptr))
2057697SMichael.Christensen@Sun.COM 
2061991Sheppo /*
2071991Sheppo  * A DS portset is a bitmap that represents a collection of DS
2089535SMichael.Christensen@Sun.COM  * ports. Each bit represent a particular port id.  We need
2099535SMichael.Christensen@Sun.COM  * to allocate for the max. number of domains supported,
2109535SMichael.Christensen@Sun.COM  * plus a small number (e.g. for the SP connection).
2111991Sheppo  */
2129535SMichael.Christensen@Sun.COM #define	DS_EXTRA_PORTS			16
2139535SMichael.Christensen@Sun.COM #define	DS_MAX_PORTS			(LDOMS_MAX_DOMAINS + DS_EXTRA_PORTS)
2149535SMichael.Christensen@Sun.COM #define	DS_PORTSET_SIZE			BT_BITOUL(DS_MAX_PORTS)
2151991Sheppo 
2169535SMichael.Christensen@Sun.COM typedef ulong_t ds_portset_t[DS_PORTSET_SIZE];
2179535SMichael.Christensen@Sun.COM 
2189535SMichael.Christensen@Sun.COM extern ds_portset_t ds_nullport;
2199535SMichael.Christensen@Sun.COM 
2209603SMichael.Christensen@Sun.COM #define	DS_PORTID_INVALID		((uint64_t)-1)
2219603SMichael.Christensen@Sun.COM 
2229603SMichael.Christensen@Sun.COM /* DS SP Port ID */
2239603SMichael.Christensen@Sun.COM extern uint64_t ds_sp_port_id;
2249603SMichael.Christensen@Sun.COM 
2251991Sheppo #define	DS_MAX_PORT_ID			(DS_MAX_PORTS - 1)
2261991Sheppo 
2279535SMichael.Christensen@Sun.COM #define	DS_PORT_IN_SET(set, port)	BT_TEST((set), (port))
2289535SMichael.Christensen@Sun.COM #define	DS_PORTSET_ADD(set, port)	BT_SET((set), (port))
2299535SMichael.Christensen@Sun.COM #define	DS_PORTSET_DEL(set, port)	BT_CLEAR((set), (port))
2309535SMichael.Christensen@Sun.COM #define	DS_PORTSET_ISNULL(set)		(memcmp((set), ds_nullport, \
2319535SMichael.Christensen@Sun.COM 					    sizeof (set)) == 0)
2329535SMichael.Christensen@Sun.COM #define	DS_PORTSET_SETNULL(set)		((void)memset((set), 0, sizeof (set)))
2339535SMichael.Christensen@Sun.COM #define	DS_PORTSET_DUP(set1, set2)	((void)memcpy((set1), (set2), \
2349535SMichael.Christensen@Sun.COM 					    sizeof (set1)))
2357697SMichael.Christensen@Sun.COM 
2367697SMichael.Christensen@Sun.COM /*
2377697SMichael.Christensen@Sun.COM  * A DS event consists of a buffer on a port.  We explictly use a link to
2387697SMichael.Christensen@Sun.COM  * enequeue/dequeue on non-Solaris environments.  On Solaris we use taskq.
2397697SMichael.Christensen@Sun.COM  */
2407697SMichael.Christensen@Sun.COM typedef struct ds_event {
2417697SMichael.Christensen@Sun.COM 	ds_port_t	*port;
2427697SMichael.Christensen@Sun.COM 	char		*buf;
2437697SMichael.Christensen@Sun.COM 	size_t		buflen;
2447697SMichael.Christensen@Sun.COM } ds_event_t;
2451991Sheppo 
2461991Sheppo /*
2471991Sheppo  * LDC Information
2481991Sheppo  */
2497697SMichael.Christensen@Sun.COM #define	DS_STREAM_MTU	4096
2501991Sheppo 
2511991Sheppo /*
2521991Sheppo  * Machine Description Constants
2531991Sheppo  */
2542793Slm66018 #define	DS_MD_ROOT_NAME		"domain-services"
2551991Sheppo #define	DS_MD_PORT_NAME		"domain-services-port"
2561991Sheppo #define	DS_MD_CHAN_NAME		"channel-endpoint"
2571991Sheppo 
2581991Sheppo /*
2591991Sheppo  * DS Services
2601991Sheppo  *
2611991Sheppo  * A DS Service is a mapping between a DS capability and a client
2621991Sheppo  * of the DS framework that provides that capability. It includes
2631991Sheppo  * information on the state of the service, the currently negotiated
2641991Sheppo  * version of the capability specific protocol, the port that is
2651991Sheppo  * currently in use by the capability, etc.
2661991Sheppo  */
2671991Sheppo 
2681991Sheppo typedef enum {
2691991Sheppo 	DS_SVC_INVAL,			/* svc structure uninitialized */
2701991Sheppo 	DS_SVC_FREE,			/* svc structure not in use */
2711991Sheppo 	DS_SVC_INACTIVE,		/* svc not registered */
2721991Sheppo 	DS_SVC_REG_PENDING,		/* register message sent */
2737697SMichael.Christensen@Sun.COM 	DS_SVC_ACTIVE,			/* register message acknowledged */
2747697SMichael.Christensen@Sun.COM 	DS_SVC_UNREG_PENDING		/* unregister is pending */
2751991Sheppo } ds_svc_state_t;
2761991Sheppo 
2777697SMichael.Christensen@Sun.COM /* ds_svc flags bits */
2787697SMichael.Christensen@Sun.COM #define	DSSF_ISCLIENT		0x0001	/* client service */
2797697SMichael.Christensen@Sun.COM #define	DSSF_ISUSER		0x0002	/* user land service */
2807697SMichael.Christensen@Sun.COM #define	DSSF_REGCB_VALID	0x0004	/* ops register callback is valid */
2817697SMichael.Christensen@Sun.COM #define	DSSF_UNREGCB_VALID	0x0008	/* ops unregister callback is valid */
2827697SMichael.Christensen@Sun.COM #define	DSSF_DATACB_VALID	0x0010	/* ops data callback is valid */
2837697SMichael.Christensen@Sun.COM #define	DSSF_LOOPBACK		0x0020	/* loopback */
2847697SMichael.Christensen@Sun.COM #define	DSSF_PEND_UNREG		0x0040	/* pending unregister */
2857697SMichael.Christensen@Sun.COM #define	DSSF_ANYCB_VALID	(DSSF_REGCB_VALID | DSSF_UNREGCB_VALID | \
2867697SMichael.Christensen@Sun.COM 				    DSSF_DATACB_VALID)
2877697SMichael.Christensen@Sun.COM #define	DSSF_USERFLAGS		(DSSF_ISCLIENT | DSSF_ISUSER | DSSF_ANYCB_VALID)
2887697SMichael.Christensen@Sun.COM 
2891991Sheppo typedef struct ds_svc {
2901991Sheppo 	ds_capability_t	cap;		/* capability information */
2911991Sheppo 	ds_clnt_ops_t	ops;		/* client ops vector */
2921991Sheppo 	ds_svc_hdl_t	hdl;		/* handle assigned by DS */
2937697SMichael.Christensen@Sun.COM 	ds_svc_hdl_t	svc_hdl;	/* remote svc hdl if client svc */
2941991Sheppo 	ds_svc_state_t	state;		/* current service state */
2951991Sheppo 	ds_ver_t	ver;		/* svc protocol version in use */
2961991Sheppo 	uint_t		ver_idx;	/* index into client version array */
2971991Sheppo 	ds_port_t	*port;		/* port for this service */
2981991Sheppo 	ds_portset_t	avail;		/* ports available to this service */
2997697SMichael.Christensen@Sun.COM 	ds_portset_t	tried;		/* ports tried by this service */
3007697SMichael.Christensen@Sun.COM 	int		fixed;		/* is svc fixed to port */
3017697SMichael.Christensen@Sun.COM 	uint_t		flags;		/* service flags */
3027697SMichael.Christensen@Sun.COM 	ds_cb_arg_t	uarg;		/* user arg for user callbacks */
3037697SMichael.Christensen@Sun.COM 	uint_t		drvi;		/* driver instance */
3047697SMichael.Christensen@Sun.COM 	void		*drv_psp;	/* driver per svc ptr */
3051991Sheppo } ds_svc_t;
3061991Sheppo 
3077697SMichael.Christensen@Sun.COM typedef struct ds_svcs {
3087697SMichael.Christensen@Sun.COM 	ds_svc_t	**tbl;		/* ptr to table */
3097697SMichael.Christensen@Sun.COM 	kmutex_t	lock;
3107697SMichael.Christensen@Sun.COM 	uint_t		maxsvcs;	/* size of the table */
3117697SMichael.Christensen@Sun.COM 	uint_t		nsvcs;		/* current number of items */
3127697SMichael.Christensen@Sun.COM } ds_svcs_t;
3137697SMichael.Christensen@Sun.COM 
3141991Sheppo #define	DS_SVC_ISFREE(svc)	((svc == NULL) || (svc->state == DS_SVC_FREE))
3157697SMichael.Christensen@Sun.COM #ifndef	DS_MAXSVCS_INIT
3167697SMichael.Christensen@Sun.COM #define	DS_MAXSVCS_INIT	32
3177697SMichael.Christensen@Sun.COM #endif
3181991Sheppo 
3191991Sheppo /*
3207697SMichael.Christensen@Sun.COM  * A service handle is a 64 bit value with three pieces of information
3211991Sheppo  * encoded in it. The upper 32 bits is the index into the table of
3227697SMichael.Christensen@Sun.COM  * a particular service structure. Bit 31 indicates whether the handle
3237697SMichael.Christensen@Sun.COM  * represents a service privider or service client. The lower 31 bits is
3247697SMichael.Christensen@Sun.COM  * a counter that is incremented each time a service structure is reused.
3251991Sheppo  */
3261991Sheppo #define	DS_IDX_SHIFT			32
3277697SMichael.Christensen@Sun.COM #define	DS_COUNT_MASK			0x7fffffffull
3287697SMichael.Christensen@Sun.COM #define	DS_HDL_ISCLIENT_BIT		0x80000000ull
3291991Sheppo 
3301991Sheppo #define	DS_ALLOC_HDL(_idx, _count)	(((uint64_t)_idx << DS_IDX_SHIFT) | \
3311991Sheppo 					((uint64_t)(_count + 1) &	    \
3321991Sheppo 					DS_COUNT_MASK))
3331991Sheppo #define	DS_HDL2IDX(hdl)			(hdl >> DS_IDX_SHIFT)
3341991Sheppo #define	DS_HDL2COUNT(hdl)		(hdl & DS_COUNT_MASK)
3357697SMichael.Christensen@Sun.COM #define	DS_HDL_ISCLIENT(hdl)		((hdl) & DS_HDL_ISCLIENT_BIT)
3367697SMichael.Christensen@Sun.COM #define	DS_HDL_SET_ISCLIENT(hdl)	((hdl) |= DS_HDL_ISCLIENT_BIT)
3377697SMichael.Christensen@Sun.COM 
3387697SMichael.Christensen@Sun.COM #define	DS_INVALID_INSTANCE		(-1)
3397697SMichael.Christensen@Sun.COM 
3407697SMichael.Christensen@Sun.COM /* enable/disable taskq processing */
3417697SMichael.Christensen@Sun.COM extern boolean_t ds_enabled;
3421991Sheppo 
3431991Sheppo /*
3441991Sheppo  * DS Message Logging
3451991Sheppo  *
3461991Sheppo  * The DS framework logs all incoming and outgoing messages to a
3471991Sheppo  * ring buffer. This provides the ability to reconstruct a trace
3481991Sheppo  * of DS activity for use in debugging. In addition to the message
3491991Sheppo  * data, each log entry contains a timestamp and the destination
3501991Sheppo  * of the message. The destination is based on the port number the
3511991Sheppo  * message passed through (port number + 1). The sign of the dest
3521991Sheppo  * field distinguishes incoming messages from outgoing messages.
3531991Sheppo  * Incoming messages have a negative destination field.
3541991Sheppo  */
3551991Sheppo 
3561991Sheppo typedef struct ds_log_entry {
3571991Sheppo 	struct ds_log_entry	*next;		/* next in log or free list */
3581991Sheppo 	struct ds_log_entry	*prev;		/* previous in log */
3591991Sheppo 	time_t			timestamp;	/* time message added to log */
3601991Sheppo 	size_t			datasz;		/* size of the data */
3611991Sheppo 	void			*data;		/* the data itself */
3621991Sheppo 	int32_t			dest;		/* message destination */
3631991Sheppo } ds_log_entry_t;
3641991Sheppo 
3651991Sheppo #define	DS_LOG_IN(pid)		(-(pid + 1))
3661991Sheppo #define	DS_LOG_OUT(pid)		(pid + 1)
3671991Sheppo 
3681991Sheppo /*
3691991Sheppo  * DS Log Limits:
3701991Sheppo  *
3711991Sheppo  * The size of the log is controlled by two limits. The first is
3721991Sheppo  * a soft limit that is configurable by the user (via the global
3731991Sheppo  * variable ds_log_sz). When this limit is exceeded, each new
3741991Sheppo  * message that is added to the log replaces the oldest message.
3751991Sheppo  *
3761991Sheppo  * The second is a hard limit that is calculated based on the soft
3771991Sheppo  * limit (DS_LOG_LIMIT). It is defined to be ~3% above the soft limit.
3781991Sheppo  * Once this limit is exceeded, a thread is scheduled to delete old
3791991Sheppo  * messages until the size of the log is below the soft limit.
3801991Sheppo  */
3815364Srsmaeda #define	DS_LOG_DEFAULT_SZ	(4 * 1024 * 1024)	/* 4 MB */
3821991Sheppo 
3831991Sheppo #define	DS_LOG_LIMIT		(ds_log_sz + (ds_log_sz >> 5))
3841991Sheppo 
3851991Sheppo #define	DS_LOG_ENTRY_SZ(ep)	(sizeof (ds_log_entry_t) + (ep)->datasz)
3861991Sheppo 
3871991Sheppo /*
3881991Sheppo  * DS Log Memory Usage:
3891991Sheppo  *
3901991Sheppo  * The log free list is initialized from a pre-allocated pool of entry
3911991Sheppo  * structures (the global ds_log_entry_pool). The number of entries
3921991Sheppo  * in the pool (DS_LOG_NPOOL) is the number of entries that would
3931991Sheppo  * take up half the default size of the log.
3941991Sheppo  *
3951991Sheppo  * As messages are added to the log, entry structures are pulled from
3961991Sheppo  * the free list. If the free list is empty, memory is allocated for
3971991Sheppo  * the entry. When entries are removed from the log, they are placed
3981991Sheppo  * on the free list. Allocated memory is only deallocated when the
3991991Sheppo  * entire log is destroyed.
4001991Sheppo  */
4011991Sheppo #define	DS_LOG_NPOOL		((DS_LOG_DEFAULT_SZ >> 1) / \
4021991Sheppo 				sizeof (ds_log_entry_t))
4031991Sheppo 
4041991Sheppo #define	DS_LOG_POOL_END		(ds_log_entry_pool + DS_LOG_NPOOL)
4051991Sheppo 
4061991Sheppo #define	DS_IS_POOL_ENTRY(ep)	(((ep) >= ds_log_entry_pool) && \
4071991Sheppo 				((ep) <= &(ds_log_entry_pool[DS_LOG_NPOOL])))
4081991Sheppo 
4097697SMichael.Christensen@Sun.COM /* VBSC code compatability related defines */
4107697SMichael.Christensen@Sun.COM 
4117697SMichael.Christensen@Sun.COM /* VBSC malloc/free are similar to user malloc/free */
4127697SMichael.Christensen@Sun.COM #define	DS_MALLOC(size)		kmem_zalloc(size, KM_SLEEP)
4137697SMichael.Christensen@Sun.COM #define	DS_FREE(ptr, size)	kmem_free(ptr, size)
4147697SMichael.Christensen@Sun.COM 
4157697SMichael.Christensen@Sun.COM /* VBSC debug print needs newline, Solaris cmn_err doesn't */
4167697SMichael.Christensen@Sun.COM #define	DS_EOL
4177697SMichael.Christensen@Sun.COM 
4187697SMichael.Christensen@Sun.COM /*
4197697SMichael.Christensen@Sun.COM  * Results of checking version array with ds_vers_isvalid()
4207697SMichael.Christensen@Sun.COM  */
4217697SMichael.Christensen@Sun.COM typedef enum {
4227697SMichael.Christensen@Sun.COM 	DS_VERS_OK,
4237697SMichael.Christensen@Sun.COM 	DS_VERS_INCREASING_MAJOR_ERR,
4247697SMichael.Christensen@Sun.COM 	DS_VERS_INCREASING_MINOR_ERR
4257697SMichael.Christensen@Sun.COM } ds_vers_check_t;
4267697SMichael.Christensen@Sun.COM 
4277697SMichael.Christensen@Sun.COM /* System specific interfaces */
4287697SMichael.Christensen@Sun.COM extern void ds_sys_port_init(ds_port_t *port);
4297697SMichael.Christensen@Sun.COM extern void ds_sys_port_fini(ds_port_t *port);
4307697SMichael.Christensen@Sun.COM extern void ds_sys_drain_events(ds_port_t *port);
4317697SMichael.Christensen@Sun.COM extern int ds_sys_dispatch_func(void (func)(void *), void *arg);
4327697SMichael.Christensen@Sun.COM extern void ds_sys_ldc_init(ds_port_t *port);
4337697SMichael.Christensen@Sun.COM 
4347697SMichael.Christensen@Sun.COM /* vlds cb access to svc structure */
4357697SMichael.Christensen@Sun.COM void ds_cbarg_get_hdl(ds_cb_arg_t arg, ds_svc_hdl_t *hdlp);
4367697SMichael.Christensen@Sun.COM void ds_cbarg_get_flags(ds_cb_arg_t arg, uint32_t *flagsp);
4377697SMichael.Christensen@Sun.COM void ds_cbarg_get_drv_info(ds_cb_arg_t arg, int *drvip);
4387697SMichael.Christensen@Sun.COM void ds_cbarg_get_drv_per_svc_ptr(ds_cb_arg_t arg, void **dpspp);
4397697SMichael.Christensen@Sun.COM void ds_cbarg_get_domain(ds_cb_arg_t arg, ds_domain_hdl_t *dhdlp);
4407697SMichael.Christensen@Sun.COM void ds_cbarg_get_service_id(ds_cb_arg_t arg, char **servicep);
4417697SMichael.Christensen@Sun.COM void ds_cbarg_set_drv_per_svc_ptr(ds_cb_arg_t arg, void *dpsp);
4427697SMichael.Christensen@Sun.COM int ds_hdl_get_cbarg(ds_svc_hdl_t hdl, ds_cb_arg_t *cbargp);
4437697SMichael.Christensen@Sun.COM void ds_cbarg_set_cookie(ds_svc_t *svc);
4447697SMichael.Christensen@Sun.COM int ds_is_my_hdl(ds_svc_hdl_t hdl, int instance);
4458172SMichael.Christensen@Sun.COM void ds_set_my_dom_hdl_name(ds_domain_hdl_t dhdl, char *name);
4467697SMichael.Christensen@Sun.COM 
4477697SMichael.Christensen@Sun.COM /* initialization functions */
4487697SMichael.Christensen@Sun.COM void ds_common_init(void);
4497697SMichael.Christensen@Sun.COM int ds_ldc_fini(ds_port_t *port);
4507697SMichael.Christensen@Sun.COM void ds_init_svcs_tbl(uint_t nentries);
4517697SMichael.Christensen@Sun.COM 
4527697SMichael.Christensen@Sun.COM /* message sending functions */
4537697SMichael.Christensen@Sun.COM void ds_send_init_req(ds_port_t *port);
4547697SMichael.Christensen@Sun.COM int ds_send_unreg_req(ds_svc_t *svc);
4557697SMichael.Christensen@Sun.COM 
4567697SMichael.Christensen@Sun.COM /* walker functions */
4577697SMichael.Christensen@Sun.COM typedef int (*svc_cb_t)(ds_svc_t *svc, void *arg);
4587697SMichael.Christensen@Sun.COM int ds_walk_svcs(svc_cb_t svc_cb, void *arg);
4597697SMichael.Christensen@Sun.COM int ds_svc_ismatch(ds_svc_t *svc, void *arg);
4607697SMichael.Christensen@Sun.COM int ds_svc_free(ds_svc_t *svc, void *arg);
4617697SMichael.Christensen@Sun.COM int ds_svc_register(ds_svc_t *svc, void *arg);
4627697SMichael.Christensen@Sun.COM 
4637697SMichael.Christensen@Sun.COM /* service utilities */
4647697SMichael.Christensen@Sun.COM ds_svc_t *ds_alloc_svc(void);
4657697SMichael.Christensen@Sun.COM ds_svc_t *ds_sys_find_svc_by_id_port(char *svc_id, ds_port_t *port,
4667697SMichael.Christensen@Sun.COM     int is_client);
4677697SMichael.Christensen@Sun.COM ds_svc_t *ds_get_svc(ds_svc_hdl_t hdl);
4687697SMichael.Christensen@Sun.COM 
4697697SMichael.Christensen@Sun.COM /* port utilities */
4707697SMichael.Christensen@Sun.COM void ds_port_common_init(ds_port_t *port);
471*9916SMichael.Christensen@Sun.COM void ds_port_common_fini(ds_port_t *port);
4727697SMichael.Christensen@Sun.COM 
4737697SMichael.Christensen@Sun.COM /* misc utilities */
4747697SMichael.Christensen@Sun.COM ds_vers_check_t ds_vers_isvalid(ds_ver_t *vers, int nvers);
4757697SMichael.Christensen@Sun.COM char *ds_errno_to_str(int ds_errno, char *ebuf);
4767697SMichael.Christensen@Sun.COM char *ds_strdup(char *str);
4777697SMichael.Christensen@Sun.COM boolean_t negotiate_version(int num_versions, ds_ver_t *sup_versionsp,
4787697SMichael.Christensen@Sun.COM     uint16_t req_major, uint16_t *new_majorp, uint16_t *new_minorp);
4797697SMichael.Christensen@Sun.COM 
4807697SMichael.Christensen@Sun.COM /* log functions */
4817697SMichael.Christensen@Sun.COM int ds_log_add_msg(int32_t dest, uint8_t *msg, size_t sz);
4827697SMichael.Christensen@Sun.COM 
4837697SMichael.Christensen@Sun.COM /* vlds driver interfaces to ds module */
4847697SMichael.Christensen@Sun.COM int ds_ucap_init(ds_capability_t *cap, ds_clnt_ops_t *ops, uint_t flags,
4857697SMichael.Christensen@Sun.COM     int instance, ds_svc_hdl_t *hdlp);
4867697SMichael.Christensen@Sun.COM int ds_unreg_hdl(ds_svc_hdl_t hdl);
4877697SMichael.Christensen@Sun.COM int ds_hdl_lookup(char *service, uint_t is_client, ds_svc_hdl_t *hdlp,
4887697SMichael.Christensen@Sun.COM     uint_t maxhdls, uint_t *nhdlsp);
4897697SMichael.Christensen@Sun.COM int ds_service_lookup(ds_svc_hdl_t hdl, char **servicep, uint_t *is_client);
4907697SMichael.Christensen@Sun.COM int ds_domain_lookup(ds_svc_hdl_t hdl, ds_domain_hdl_t *dhdlp);
4917697SMichael.Christensen@Sun.COM int ds_hdl_isready(ds_svc_hdl_t hdl, uint_t *is_ready);
4927697SMichael.Christensen@Sun.COM void ds_unreg_all(int instance);
4937697SMichael.Christensen@Sun.COM int ds_dom_name_to_hdl(char *domain_name, ds_domain_hdl_t *dhdlp);
4947697SMichael.Christensen@Sun.COM int ds_dom_hdl_to_name(ds_domain_hdl_t dhdl, char **domain_namep);
4957697SMichael.Christensen@Sun.COM int ds_add_port(uint64_t port_id, uint64_t ldc_id, ds_domain_hdl_t dhdl,
4967697SMichael.Christensen@Sun.COM     char *dom_name, int verbose);
4977697SMichael.Christensen@Sun.COM int ds_remove_port(uint64_t portid, int is_fini);
4987697SMichael.Christensen@Sun.COM 
4997697SMichael.Christensen@Sun.COM /* ds_ucap_init flags */
5007697SMichael.Christensen@Sun.COM #define	DS_UCAP_CLNT		0x0	/* Service is Client */
5017697SMichael.Christensen@Sun.COM #define	DS_UCAP_SVC		0x1	/* Service is Server */
5027697SMichael.Christensen@Sun.COM 
5037697SMichael.Christensen@Sun.COM /*
5047697SMichael.Christensen@Sun.COM  * Error buffer size for ds_errno_to_str
5057697SMichael.Christensen@Sun.COM  */
5067697SMichael.Christensen@Sun.COM #define	DS_EBUFSIZE	80
5077697SMichael.Christensen@Sun.COM 
5087697SMichael.Christensen@Sun.COM /*
5097697SMichael.Christensen@Sun.COM  * Debugging Features
5107697SMichael.Christensen@Sun.COM  */
5117697SMichael.Christensen@Sun.COM #ifdef DEBUG
5127697SMichael.Christensen@Sun.COM 
5137697SMichael.Christensen@Sun.COM #define	DS_DBG_BASIC			0x001
5147697SMichael.Christensen@Sun.COM #define	DS_DBG_FLAG_LDC			0x002
5157697SMichael.Christensen@Sun.COM #define	DS_DBG_FLAG_LOG			0x004
5167697SMichael.Christensen@Sun.COM #define	DS_DBG_DUMP_LDC_MSG		0x008
5177697SMichael.Christensen@Sun.COM #define	DS_DBG_FLAG_MD			0x010
5187697SMichael.Christensen@Sun.COM #define	DS_DBG_FLAG_USR			0x020
5197697SMichael.Christensen@Sun.COM #define	DS_DBG_FLAG_VLDS		0x040
5207697SMichael.Christensen@Sun.COM #define	DS_DBG_FLAG_PRCL		0x080
5217697SMichael.Christensen@Sun.COM #define	DS_DBG_FLAG_RCVQ		0x100
5227697SMichael.Christensen@Sun.COM #define	DS_DBG_FLAG_LOOP		0x200
5237697SMichael.Christensen@Sun.COM 
5247697SMichael.Christensen@Sun.COM #define	DS_DBG				if (ds_debug & DS_DBG_BASIC) cmn_err
5257697SMichael.Christensen@Sun.COM #define	DS_DBG_LDC			if (ds_debug & DS_DBG_FLAG_LDC) cmn_err
5267697SMichael.Christensen@Sun.COM #define	DS_DBG_LOG			if (ds_debug & DS_DBG_FLAG_LOG) cmn_err
5277697SMichael.Christensen@Sun.COM #define	DS_DBG_MD			if (ds_debug & DS_DBG_FLAG_MD) cmn_err
5287697SMichael.Christensen@Sun.COM #define	DS_DBG_USR			if (ds_debug & DS_DBG_FLAG_USR) cmn_err
5297697SMichael.Christensen@Sun.COM #define	DS_DBG_VLDS			if (ds_debug & DS_DBG_FLAG_VLDS) cmn_err
5307697SMichael.Christensen@Sun.COM #define	DS_DBG_PRCL			if (ds_debug & DS_DBG_FLAG_PRCL) cmn_err
5317697SMichael.Christensen@Sun.COM #define	DS_DBG_RCVQ			if (ds_debug & DS_DBG_FLAG_RCVQ) cmn_err
5327697SMichael.Christensen@Sun.COM #define	DS_DBG_LOOP			if (ds_debug & DS_DBG_FLAG_LOOP) cmn_err
5337697SMichael.Christensen@Sun.COM 
5347697SMichael.Christensen@Sun.COM #define	DS_DUMP_MSG(flags, buf, len)	if (ds_debug & (flags)) \
5357697SMichael.Christensen@Sun.COM 					    ds_dump_msg(buf, len)
5367697SMichael.Christensen@Sun.COM 
5377697SMichael.Christensen@Sun.COM extern uint_t ds_debug;
5387697SMichael.Christensen@Sun.COM void ds_dump_msg(void *buf, size_t len);
5397697SMichael.Christensen@Sun.COM 
5407697SMichael.Christensen@Sun.COM #define	DS_BADHDL1			(ds_svc_hdl_t)(0xdeadbed1deadbed1ull)
5417697SMichael.Christensen@Sun.COM #define	DS_BADHDL2			(ds_svc_hdl_t)(0x2deadbed2deadbedull)
5427697SMichael.Christensen@Sun.COM 
5437697SMichael.Christensen@Sun.COM #else /* DEBUG */
5447697SMichael.Christensen@Sun.COM 
5457697SMichael.Christensen@Sun.COM #define	DS_DBG				if (0) cmn_err
5467697SMichael.Christensen@Sun.COM #define	DS_DBG_LDC			DS_DBG
5477697SMichael.Christensen@Sun.COM #define	DS_DBG_LOG			DS_DBG
5487697SMichael.Christensen@Sun.COM #define	DS_DBG_MD			DS_DBG
5497697SMichael.Christensen@Sun.COM #define	DS_DBG_USR			DS_DBG
5507697SMichael.Christensen@Sun.COM #define	DS_DBG_VLDS			DS_DBG
5517697SMichael.Christensen@Sun.COM #define	DS_DBG_PRCL			DS_DBG
5527697SMichael.Christensen@Sun.COM #define	DS_DBG_RCVQ			DS_DBG
5537697SMichael.Christensen@Sun.COM #define	DS_DBG_LOOP			DS_DBG
5547697SMichael.Christensen@Sun.COM #define	DS_DUMP_MSG(flags, buf, len)
5557697SMichael.Christensen@Sun.COM #define	DS_DUMP_LDC_MSG(buf, len)
5567697SMichael.Christensen@Sun.COM 
5577697SMichael.Christensen@Sun.COM #define	DS_BADHDL1			NULL
5587697SMichael.Christensen@Sun.COM #define	DS_BADHDL2			NULL
5597697SMichael.Christensen@Sun.COM 
5607697SMichael.Christensen@Sun.COM #endif /* DEBUG */
5617697SMichael.Christensen@Sun.COM 
5621991Sheppo #ifdef __cplusplus
5631991Sheppo }
5641991Sheppo #endif
5651991Sheppo 
5661991Sheppo #endif /* _DS_IMPL_H */
567