#ifndef _DS_IMPL_H
#define _DS_IMPL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/bitmap.h>
#include <sys/ldoms.h>
typedef struct ds_hdr {
uint32_t msg_type;
uint32_t payload_len;
} ds_hdr_t;
#define DS_HDR_SZ (sizeof (ds_hdr_t))
#define DS_INIT_REQ 0x0
#define DS_INIT_ACK 0x1
#define DS_INIT_NACK 0x2
typedef struct ds_init_req {
uint16_t major_vers;
uint16_t minor_vers;
} ds_init_req_t;
typedef struct ds_init_ack {
uint16_t minor_vers;
} ds_init_ack_t;
typedef struct ds_init_nack {
uint16_t major_vers;
} ds_init_nack_t;
#define DS_REG_REQ 0x3
#define DS_REG_ACK 0x4
#define DS_REG_NACK 0x5
#define DS_UNREG 0x6
#define DS_UNREG_ACK 0x7
#define DS_UNREG_NACK 0x8
#define DS_DATA 0x9
#define DS_NACK 0xa
#define DS_OK 0x0
#define DS_REG_VER_NACK 0x1
#define DS_REG_DUP 0x2
#define DS_INV_HDL 0x3
#define DS_TYPE_UNKNOWN 0x4
typedef struct ds_reg_req {
uint64_t svc_handle;
uint16_t major_vers;
uint16_t minor_vers;
char svc_id[1];
} ds_reg_req_t;
typedef struct ds_reg_ack {
uint64_t svc_handle;
uint16_t minor_vers;
} ds_reg_ack_t;
typedef struct ds_reg_nack {
uint64_t svc_handle;
uint64_t result;
uint16_t major_vers;
} ds_reg_nack_t;
typedef struct ds_unreg_req {
uint64_t svc_handle;
} ds_unreg_req_t;
typedef struct ds_unreg_ack {
uint64_t svc_handle;
} ds_unreg_ack_t;
typedef struct ds_unreg_nack {
uint64_t svc_handle;
} ds_unreg_nack_t;
typedef struct ds_data_handle {
uint64_t svc_handle;
} ds_data_handle_t;
typedef struct ds_data_nack {
uint64_t svc_handle;
uint64_t result;
} ds_data_nack_t;
#define DS_MSG_TYPE_VALID(type) ((type) <= DS_NACK)
#define DS_MSG_LEN(ds_type) (sizeof (ds_hdr_t) + sizeof (ds_type))
typedef enum {
DS_PORT_FREE,
DS_PORT_INIT,
DS_PORT_LDC_INIT,
DS_PORT_INIT_REQ,
DS_PORT_READY
} ds_port_state_t;
typedef struct ds_ldc {
uint64_t id;
ldc_handle_t hdl;
ldc_status_t state;
} ds_ldc_t;
typedef uint64_t ds_domain_hdl_t;
#define DS_DHDL_INVALID ((ds_domain_hdl_t)0xffffffff)
#define DS_PORT_MUTEX_INITED 0x1
typedef struct ds_port {
uint32_t flags;
kmutex_t lock;
kmutex_t tx_lock;
kmutex_t rcv_lock;
uint64_t id;
ds_port_state_t state;
ds_ver_t ver;
uint32_t ver_idx;
ds_ldc_t ldc;
ds_domain_hdl_t domain_hdl;
char *domain_name;
} ds_port_t;
#define IS_DS_PORT(port) 1
#define PORTID(port) ((ulong_t)((port)->id))
#define PTR_TO_LONG(ptr) ((uint64_t)(ptr))
#define DS_EXTRA_PORTS 16
#define DS_MAX_PORTS (LDOMS_MAX_DOMAINS + DS_EXTRA_PORTS)
#define DS_PORTSET_SIZE BT_BITOUL(DS_MAX_PORTS)
typedef ulong_t ds_portset_t[DS_PORTSET_SIZE];
extern ds_port_t ds_ports[DS_MAX_PORTS];
extern ds_portset_t ds_allports;
extern ds_portset_t ds_nullport;
#define DS_PORTID_INVALID ((uint64_t)-1)
extern uint64_t ds_sp_port_id;
#define DS_MAX_PORT_ID (DS_MAX_PORTS - 1)
#define DS_PORT_IN_SET(set, port) BT_TEST((set), (port))
#define DS_PORTSET_ADD(set, port) BT_SET((set), (port))
#define DS_PORTSET_DEL(set, port) BT_CLEAR((set), (port))
#define DS_PORTSET_ISNULL(set) (memcmp((set), ds_nullport, \
sizeof (set)) == 0)
#define DS_PORTSET_SETNULL(set) ((void)memset((set), 0, sizeof (set)))
#define DS_PORTSET_DUP(set1, set2) ((void)memcpy((set1), (set2), \
sizeof (set1)))
typedef struct ds_event {
ds_port_t *port;
char *buf;
size_t buflen;
} ds_event_t;
#define DS_STREAM_MTU 4096
#define DS_MD_ROOT_NAME "domain-services"
#define DS_MD_PORT_NAME "domain-services-port"
#define DS_MD_CHAN_NAME "channel-endpoint"
typedef enum {
DS_SVC_INVAL,
DS_SVC_FREE,
DS_SVC_INACTIVE,
DS_SVC_REG_PENDING,
DS_SVC_ACTIVE,
DS_SVC_UNREG_PENDING
} ds_svc_state_t;
#define DSSF_ISCLIENT 0x0001
#define DSSF_ISUSER 0x0002
#define DSSF_REGCB_VALID 0x0004
#define DSSF_UNREGCB_VALID 0x0008
#define DSSF_DATACB_VALID 0x0010
#define DSSF_LOOPBACK 0x0020
#define DSSF_PEND_UNREG 0x0040
#define DSSF_ANYCB_VALID (DSSF_REGCB_VALID | DSSF_UNREGCB_VALID | \
DSSF_DATACB_VALID)
#define DSSF_USERFLAGS (DSSF_ISCLIENT | DSSF_ISUSER | DSSF_ANYCB_VALID)
typedef struct ds_svc {
ds_capability_t cap;
ds_clnt_ops_t ops;
ds_svc_hdl_t hdl;
ds_svc_hdl_t svc_hdl;
ds_svc_state_t state;
ds_ver_t ver;
uint_t ver_idx;
ds_port_t *port;
ds_portset_t avail;
ds_portset_t tried;
int fixed;
uint_t flags;
ds_cb_arg_t uarg;
uint_t drvi;
void *drv_psp;
} ds_svc_t;
typedef struct ds_svcs {
ds_svc_t **tbl;
kmutex_t lock;
uint_t maxsvcs;
uint_t nsvcs;
} ds_svcs_t;
#define DS_SVC_ISFREE(svc) ((svc == NULL) || (svc->state == DS_SVC_FREE))
#ifndef DS_MAXSVCS_INIT
#define DS_MAXSVCS_INIT 32
#endif
#define DS_IDX_SHIFT 32
#define DS_COUNT_MASK 0x7fffffffull
#define DS_HDL_ISCLIENT_BIT 0x80000000ull
#define DS_ALLOC_HDL(_idx, _count) (((uint64_t)_idx << DS_IDX_SHIFT) | \
((uint64_t)(_count + 1) & \
DS_COUNT_MASK))
#define DS_HDL2IDX(hdl) (hdl >> DS_IDX_SHIFT)
#define DS_HDL2COUNT(hdl) (hdl & DS_COUNT_MASK)
#define DS_HDL_ISCLIENT(hdl) ((hdl) & DS_HDL_ISCLIENT_BIT)
#define DS_HDL_SET_ISCLIENT(hdl) ((hdl) |= DS_HDL_ISCLIENT_BIT)
#define DS_INVALID_INSTANCE (-1)
extern boolean_t ds_enabled;
extern ds_svcs_t ds_svcs;
typedef struct ds_log_entry {
struct ds_log_entry *next;
struct ds_log_entry *prev;
time_t timestamp;
size_t datasz;
void *data;
int32_t dest;
} ds_log_entry_t;
#define DS_LOG_IN(pid) (-(pid + 1))
#define DS_LOG_OUT(pid) (pid + 1)
#define DS_LOG_DEFAULT_SZ (4 * 1024 * 1024)
#define DS_LOG_LIMIT (ds_log_sz + (ds_log_sz >> 5))
#define DS_LOG_ENTRY_SZ(ep) (sizeof (ds_log_entry_t) + (ep)->datasz)
#define DS_LOG_NPOOL ((DS_LOG_DEFAULT_SZ >> 1) / \
sizeof (ds_log_entry_t))
#define DS_LOG_POOL_END (ds_log_entry_pool + DS_LOG_NPOOL)
#define DS_IS_POOL_ENTRY(ep) (((ep) >= ds_log_entry_pool) && \
((ep) < &(ds_log_entry_pool[DS_LOG_NPOOL])))
#define DS_MALLOC(size) kmem_zalloc(size, KM_SLEEP)
#define DS_FREE(ptr, size) kmem_free(ptr, size)
#define DS_EOL
typedef enum {
DS_VERS_OK,
DS_VERS_INCREASING_MAJOR_ERR,
DS_VERS_INCREASING_MINOR_ERR
} ds_vers_check_t;
extern void ds_sys_port_init(ds_port_t *port);
extern void ds_sys_port_fini(ds_port_t *port);
extern void ds_sys_drain_events(ds_port_t *port);
extern int ds_sys_dispatch_func(void (func)(void *), void *arg);
extern void ds_sys_ldc_init(ds_port_t *port);
void ds_cbarg_get_hdl(ds_cb_arg_t arg, ds_svc_hdl_t *hdlp);
void ds_cbarg_get_flags(ds_cb_arg_t arg, uint32_t *flagsp);
void ds_cbarg_get_drv_info(ds_cb_arg_t arg, int *drvip);
void ds_cbarg_get_drv_per_svc_ptr(ds_cb_arg_t arg, void **dpspp);
void ds_cbarg_get_domain(ds_cb_arg_t arg, ds_domain_hdl_t *dhdlp);
void ds_cbarg_get_service_id(ds_cb_arg_t arg, char **servicep);
void ds_cbarg_set_drv_per_svc_ptr(ds_cb_arg_t arg, void *dpsp);
int ds_hdl_get_cbarg(ds_svc_hdl_t hdl, ds_cb_arg_t *cbargp);
void ds_cbarg_set_cookie(ds_svc_t *svc);
int ds_is_my_hdl(ds_svc_hdl_t hdl, int instance);
void ds_set_my_dom_hdl_name(ds_domain_hdl_t dhdl, char *name);
void ds_common_init(void);
int ds_ldc_fini(ds_port_t *port);
void ds_init_svcs_tbl(uint_t nentries);
void ds_send_init_req(ds_port_t *port);
int ds_send_unreg_req(ds_svc_t *svc);
typedef int (*svc_cb_t)(ds_svc_t *svc, void *arg);
int ds_walk_svcs(svc_cb_t svc_cb, void *arg);
int ds_svc_ismatch(ds_svc_t *svc, void *arg);
int ds_svc_free(ds_svc_t *svc, void *arg);
int ds_svc_register(ds_svc_t *svc, void *arg);
ds_svc_t *ds_alloc_svc(void);
ds_svc_t *ds_sys_find_svc_by_id_port(char *svc_id, ds_port_t *port,
int is_client);
ds_svc_t *ds_get_svc(ds_svc_hdl_t hdl);
void ds_port_common_init(ds_port_t *port);
void ds_port_common_fini(ds_port_t *port);
ds_vers_check_t ds_vers_isvalid(ds_ver_t *vers, int nvers);
char *ds_errno_to_str(int ds_errno, char *ebuf);
char *ds_strdup(char *str);
boolean_t negotiate_version(int num_versions, ds_ver_t *sup_versionsp,
uint16_t req_major, uint16_t *new_majorp, uint16_t *new_minorp);
int ds_log_add_msg(int32_t dest, uint8_t *msg, size_t sz);
int ds_ucap_init(ds_capability_t *cap, ds_clnt_ops_t *ops, uint_t flags,
int instance, ds_svc_hdl_t *hdlp);
int ds_unreg_hdl(ds_svc_hdl_t hdl);
int ds_hdl_lookup(char *service, uint_t is_client, ds_svc_hdl_t *hdlp,
uint_t maxhdls, uint_t *nhdlsp);
int ds_service_lookup(ds_svc_hdl_t hdl, char **servicep, uint_t *is_client);
int ds_domain_lookup(ds_svc_hdl_t hdl, ds_domain_hdl_t *dhdlp);
int ds_hdl_isready(ds_svc_hdl_t hdl, uint_t *is_ready);
void ds_unreg_all(int instance);
int ds_dom_name_to_hdl(char *domain_name, ds_domain_hdl_t *dhdlp);
int ds_dom_hdl_to_name(ds_domain_hdl_t dhdl, char **domain_namep);
int ds_add_port(uint64_t port_id, uint64_t ldc_id, ds_domain_hdl_t dhdl,
char *dom_name, int verbose);
int ds_remove_port(uint64_t portid, int is_fini);
#define DS_UCAP_CLNT 0x0
#define DS_UCAP_SVC 0x1
#define DS_EBUFSIZE 80
#ifdef DEBUG
#define DS_DBG_BASIC 0x001
#define DS_DBG_FLAG_LDC 0x002
#define DS_DBG_FLAG_LOG 0x004
#define DS_DBG_DUMP_LDC_MSG 0x008
#define DS_DBG_FLAG_MD 0x010
#define DS_DBG_FLAG_USR 0x020
#define DS_DBG_FLAG_VLDS 0x040
#define DS_DBG_FLAG_PRCL 0x080
#define DS_DBG_FLAG_RCVQ 0x100
#define DS_DBG_FLAG_LOOP 0x200
#define DS_DBG if (ds_debug & DS_DBG_BASIC) cmn_err
#define DS_DBG_LDC if (ds_debug & DS_DBG_FLAG_LDC) cmn_err
#define DS_DBG_LOG if (ds_debug & DS_DBG_FLAG_LOG) cmn_err
#define DS_DBG_MD if (ds_debug & DS_DBG_FLAG_MD) cmn_err
#define DS_DBG_USR if (ds_debug & DS_DBG_FLAG_USR) cmn_err
#define DS_DBG_VLDS if (ds_debug & DS_DBG_FLAG_VLDS) cmn_err
#define DS_DBG_PRCL if (ds_debug & DS_DBG_FLAG_PRCL) cmn_err
#define DS_DBG_RCVQ if (ds_debug & DS_DBG_FLAG_RCVQ) cmn_err
#define DS_DBG_LOOP if (ds_debug & DS_DBG_FLAG_LOOP) cmn_err
#define DS_DUMP_MSG(flags, buf, len) if (ds_debug & (flags)) \
ds_dump_msg(buf, len)
extern uint_t ds_debug;
void ds_dump_msg(void *buf, size_t len);
#define DS_BADHDL1 (ds_svc_hdl_t)(0xdeadbed1deadbed1ull)
#define DS_BADHDL2 (ds_svc_hdl_t)(0x2deadbed2deadbedull)
#else
#define DS_DBG if (0) cmn_err
#define DS_DBG_LDC DS_DBG
#define DS_DBG_LOG DS_DBG
#define DS_DBG_MD DS_DBG
#define DS_DBG_USR DS_DBG
#define DS_DBG_VLDS DS_DBG
#define DS_DBG_PRCL DS_DBG
#define DS_DBG_RCVQ DS_DBG
#define DS_DBG_LOOP DS_DBG
#define DS_DUMP_MSG(flags, buf, len)
#define DS_DUMP_LDC_MSG(buf, len)
#define DS_BADHDL1 (ds_svc_hdl_t)0
#define DS_BADHDL2 (ds_svc_hdl_t)0
#endif
#ifdef __cplusplus
}
#endif
#endif