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