1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1999-2001 by Sun Microsystems, Inc. 24*7c478bd9Sstevel@tonic-gate * All rights reserved. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #ifndef _SYS_RSM_RSMKA_PATH_INT_H 28*7c478bd9Sstevel@tonic-gate #define _SYS_RSM_RSMKA_PATH_INT_H 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 31*7c478bd9Sstevel@tonic-gate extern "C" { 32*7c478bd9Sstevel@tonic-gate #endif 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate #include <sys/rsm/rsm_common.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/rsm/rsm.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/rsm/rsmpi.h> 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate /* 39*7c478bd9Sstevel@tonic-gate * Taskq setup 40*7c478bd9Sstevel@tonic-gate * Only one taskq thread is created and only one task is executed 41*7c478bd9Sstevel@tonic-gate * the task is executed as an infinite loop 42*7c478bd9Sstevel@tonic-gate */ 43*7c478bd9Sstevel@tonic-gate #define RSMKA_ONE_THREAD 1 44*7c478bd9Sstevel@tonic-gate #define RSMKA_ONE_TASK 1 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate /* Path (path_t) States */ 47*7c478bd9Sstevel@tonic-gate #define RSMKA_PATH_DOWN 1 48*7c478bd9Sstevel@tonic-gate #define RSMKA_PATH_UP 2 49*7c478bd9Sstevel@tonic-gate #define RSMKA_PATH_ACTIVE 3 50*7c478bd9Sstevel@tonic-gate #define RSMKA_PATH_GOING_DOWN 4 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate #define RSMKA_OPCODE_TYPES 2 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate /* 55*7c478bd9Sstevel@tonic-gate * Deferred Work Token Index 56*7c478bd9Sstevel@tonic-gate */ 57*7c478bd9Sstevel@tonic-gate #define RSMKA_IPC_DOWN_INDEX 0 58*7c478bd9Sstevel@tonic-gate #define RSMKA_IPC_UP_INDEX 1 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate /* Deferred Work Opcodes */ 61*7c478bd9Sstevel@tonic-gate #define RSMKA_IPC_DOWN 1 62*7c478bd9Sstevel@tonic-gate #define RSMKA_IPC_UP 2 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate /* Flags */ 65*7c478bd9Sstevel@tonic-gate #define RSMKA_NO_SLEEP 1 66*7c478bd9Sstevel@tonic-gate #define RSMKA_USE_COOKIE 2 67*7c478bd9Sstevel@tonic-gate #define RSMKA_NOHOLD 4 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate /* 71*7c478bd9Sstevel@tonic-gate * A work token is enqueued on the workqueue (singly linked list) 72*7c478bd9Sstevel@tonic-gate * when pathup or pathdown processing is to be done by the deferred work 73*7c478bd9Sstevel@tonic-gate * thread. Token are enqueued at the end of the queue and processed 74*7c478bd9Sstevel@tonic-gate * from the front of the queue. 75*7c478bd9Sstevel@tonic-gate */ 76*7c478bd9Sstevel@tonic-gate typedef struct work_token { 77*7c478bd9Sstevel@tonic-gate struct work_token *next; /* pointer to next token */ 78*7c478bd9Sstevel@tonic-gate int opcode; /* opcode for work to do */ 79*7c478bd9Sstevel@tonic-gate } work_token_t; 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate typedef struct workqueue { 82*7c478bd9Sstevel@tonic-gate work_token_t *head; /* start of work queue */ 83*7c478bd9Sstevel@tonic-gate work_token_t *tail; /* end of work queue */ 84*7c478bd9Sstevel@tonic-gate kmutex_t work_mutex; /* protects queue add/delete */ 85*7c478bd9Sstevel@tonic-gate kcondvar_t work_cv; /* synchronize deferred thread */ 86*7c478bd9Sstevel@tonic-gate } work_queue_t; 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate /* 89*7c478bd9Sstevel@tonic-gate * a pointer to srv_handler_arg is registered along with the handler 90*7c478bd9Sstevel@tonic-gate * and is passed to the rsm_srv_func - the service handler when it 91*7c478bd9Sstevel@tonic-gate * is invoked. 92*7c478bd9Sstevel@tonic-gate */ 93*7c478bd9Sstevel@tonic-gate typedef struct srv_handler_arg { 94*7c478bd9Sstevel@tonic-gate char adapter_name[MAXNAMELEN]; 95*7c478bd9Sstevel@tonic-gate int adapter_instance; 96*7c478bd9Sstevel@tonic-gate rsm_addr_t adapter_hwaddr; 97*7c478bd9Sstevel@tonic-gate } srv_handler_arg_t; 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate typedef struct msgbuf_elem { 100*7c478bd9Sstevel@tonic-gate boolean_t active; 101*7c478bd9Sstevel@tonic-gate rsmipc_request_t msg; 102*7c478bd9Sstevel@tonic-gate } msgbuf_elem_t; 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate /* 105*7c478bd9Sstevel@tonic-gate * receive buffer object 106*7c478bd9Sstevel@tonic-gate * procmsg_cnt - receivers count of messages processed since sending credits 107*7c478bd9Sstevel@tonic-gate * msgbuf_queue - an array-based circular queue of messages received 108*7c478bd9Sstevel@tonic-gate * msgbuf_head - index pointing to the head of msgbuf_queue 109*7c478bd9Sstevel@tonic-gate * msgbuf_head - index pointing to the tail of msgbuf_queue 110*7c478bd9Sstevel@tonic-gate * msgbuf_cnt - number of valid entries in msgbuf_queue 111*7c478bd9Sstevel@tonic-gate */ 112*7c478bd9Sstevel@tonic-gate typedef struct recv_info { 113*7c478bd9Sstevel@tonic-gate int procmsg_cnt; 114*7c478bd9Sstevel@tonic-gate int rem_sendq_ready; 115*7c478bd9Sstevel@tonic-gate taskq_t *recv_taskq; 116*7c478bd9Sstevel@tonic-gate msgbuf_elem_t *msgbuf_queue; 117*7c478bd9Sstevel@tonic-gate int msgbuf_head; 118*7c478bd9Sstevel@tonic-gate int msgbuf_tail; 119*7c478bd9Sstevel@tonic-gate int msgbuf_cnt; 120*7c478bd9Sstevel@tonic-gate } recv_info_t; 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate /* 123*7c478bd9Sstevel@tonic-gate * sendq_tokens are inserted in a circular list of the ipc_info descriptor 124*7c478bd9Sstevel@tonic-gate * when a path is added for a remote node. When the path is active the 125*7c478bd9Sstevel@tonic-gate * rsmpi_sendq_handle will be valid and the sendq token can be used for 126*7c478bd9Sstevel@tonic-gate * ipc. The sendq_tokens are used in a round robin fashion. 127*7c478bd9Sstevel@tonic-gate * 128*7c478bd9Sstevel@tonic-gate * msgbuf_avail - used by sender, number of avail slots in recvrs msgbuf_queue 129*7c478bd9Sstevel@tonic-gate */ 130*7c478bd9Sstevel@tonic-gate typedef struct sendq_token { 131*7c478bd9Sstevel@tonic-gate struct sendq_token *next; 132*7c478bd9Sstevel@tonic-gate rsm_send_q_handle_t rsmpi_sendq_handle; 133*7c478bd9Sstevel@tonic-gate int ref_cnt; 134*7c478bd9Sstevel@tonic-gate int msgbuf_avail; 135*7c478bd9Sstevel@tonic-gate kcondvar_t sendq_cv; 136*7c478bd9Sstevel@tonic-gate }sendq_token_t; 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate typedef struct path { 142*7c478bd9Sstevel@tonic-gate struct path *next_path; 143*7c478bd9Sstevel@tonic-gate rsm_node_id_t remote_node; 144*7c478bd9Sstevel@tonic-gate int remote_devinst; 145*7c478bd9Sstevel@tonic-gate rsm_addr_t remote_hwaddr; 146*7c478bd9Sstevel@tonic-gate int state; 147*7c478bd9Sstevel@tonic-gate int flags; 148*7c478bd9Sstevel@tonic-gate #define RSMKA_WAIT_FOR_SQACK 0x0001 /* waiting for SQREADY_ACK */ 149*7c478bd9Sstevel@tonic-gate #define RSMKA_SQCREATE_PENDING 0x0002 /* sendq_create is pending */ 150*7c478bd9Sstevel@tonic-gate kmutex_t mutex; 151*7c478bd9Sstevel@tonic-gate struct adapter *local_adapter; 152*7c478bd9Sstevel@tonic-gate sendq_token_t sendq_token; 153*7c478bd9Sstevel@tonic-gate work_token_t work_token[RSMKA_OPCODE_TYPES]; 154*7c478bd9Sstevel@tonic-gate recv_info_t recv_buffer; 155*7c478bd9Sstevel@tonic-gate #define procmsg_cnt recv_buffer.procmsg_cnt 156*7c478bd9Sstevel@tonic-gate #define rem_sendq_ready recv_buffer.rem_sendq_ready 157*7c478bd9Sstevel@tonic-gate #define msgbuf_queue recv_buffer.msgbuf_queue 158*7c478bd9Sstevel@tonic-gate #define msgbuf_head recv_buffer.msgbuf_head 159*7c478bd9Sstevel@tonic-gate #define msgbuf_tail recv_buffer.msgbuf_tail 160*7c478bd9Sstevel@tonic-gate #define msgbuf_cnt recv_buffer.msgbuf_cnt 161*7c478bd9Sstevel@tonic-gate #define recv_taskq recv_buffer.recv_taskq 162*7c478bd9Sstevel@tonic-gate int64_t local_incn; 163*7c478bd9Sstevel@tonic-gate int64_t remote_incn; 164*7c478bd9Sstevel@tonic-gate #define RSM_UNKNOWN_INCN 0 165*7c478bd9Sstevel@tonic-gate int ref_cnt; 166*7c478bd9Sstevel@tonic-gate kcondvar_t hold_cv; 167*7c478bd9Sstevel@tonic-gate } path_t; 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate 170*7c478bd9Sstevel@tonic-gate typedef struct adapter { 171*7c478bd9Sstevel@tonic-gate struct adapter *next; 172*7c478bd9Sstevel@tonic-gate struct adapter_listhead *listhead; 173*7c478bd9Sstevel@tonic-gate int ref_cnt; 174*7c478bd9Sstevel@tonic-gate kmutex_t mutex; 175*7c478bd9Sstevel@tonic-gate int instance; 176*7c478bd9Sstevel@tonic-gate dev_info_t *dip; 177*7c478bd9Sstevel@tonic-gate rsm_addr_t hwaddr; 178*7c478bd9Sstevel@tonic-gate path_t *next_path; 179*7c478bd9Sstevel@tonic-gate rsm_controller_handle_t rsmpi_handle; 180*7c478bd9Sstevel@tonic-gate rsm_controller_attr_t rsm_attr; 181*7c478bd9Sstevel@tonic-gate rsm_ops_t *rsmpi_ops; 182*7c478bd9Sstevel@tonic-gate srv_handler_arg_t *hdlr_argp; 183*7c478bd9Sstevel@tonic-gate } adapter_t; 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate /* 187*7c478bd9Sstevel@tonic-gate * typedef struct { 188*7c478bd9Sstevel@tonic-gate * adapter_t *next_chunk; 189*7c478bd9Sstevel@tonic-gate * int base; 190*7c478bd9Sstevel@tonic-gate * int next_index; 191*7c478bd9Sstevel@tonic-gate * int used_count; 192*7c478bd9Sstevel@tonic-gate * adapter_t *phys_adapters[MAX_CHUNK_INDEX]; 193*7c478bd9Sstevel@tonic-gate * } adapter_map_chunks_t; 194*7c478bd9Sstevel@tonic-gate */ 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate /* 198*7c478bd9Sstevel@tonic-gate * There is one adapter_listhead for each adapter devname. This 199*7c478bd9Sstevel@tonic-gate * adapter_listhead stores the number of adapters belonging to 200*7c478bd9Sstevel@tonic-gate * it. It also stores the number of paths for all the adapters 201*7c478bd9Sstevel@tonic-gate * belonging to it. 202*7c478bd9Sstevel@tonic-gate */ 203*7c478bd9Sstevel@tonic-gate typedef struct adapter_listhead { 204*7c478bd9Sstevel@tonic-gate struct adapter_listhead *next_listhead; 205*7c478bd9Sstevel@tonic-gate char adapter_devname[MAXNAMELEN]; 206*7c478bd9Sstevel@tonic-gate adapter_t *next_adapter; 207*7c478bd9Sstevel@tonic-gate int ref_cnt; 208*7c478bd9Sstevel@tonic-gate kmutex_t mutex; 209*7c478bd9Sstevel@tonic-gate int adapter_count; 210*7c478bd9Sstevel@tonic-gate int path_count; 211*7c478bd9Sstevel@tonic-gate } adapter_listhead_t; 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate struct adapter_listhead_list { 215*7c478bd9Sstevel@tonic-gate adapter_listhead_t *next; 216*7c478bd9Sstevel@tonic-gate kmutex_t listlock; 217*7c478bd9Sstevel@tonic-gate }; 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate /* 221*7c478bd9Sstevel@tonic-gate * One ipc_info descriptor for each remote node 222*7c478bd9Sstevel@tonic-gate */ 223*7c478bd9Sstevel@tonic-gate typedef struct ipc_info { 224*7c478bd9Sstevel@tonic-gate struct ipc_info *next; 225*7c478bd9Sstevel@tonic-gate rsm_node_id_t remote_node; 226*7c478bd9Sstevel@tonic-gate boolean_t node_is_alive; 227*7c478bd9Sstevel@tonic-gate sendq_token_t *token_list; 228*7c478bd9Sstevel@tonic-gate sendq_token_t *current_token; 229*7c478bd9Sstevel@tonic-gate kmutex_t token_list_mutex; 230*7c478bd9Sstevel@tonic-gate int ref_cnt; 231*7c478bd9Sstevel@tonic-gate } ipc_info_t; 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate #define SQ_TOKEN_TO_PATH(token) \ 235*7c478bd9Sstevel@tonic-gate ((path_t *)((char *)(token) - ((char *)(&((path_t *)0)->sendq_token)))) 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate #define WORK_TOKEN_TO_PATH(token, index) \ 240*7c478bd9Sstevel@tonic-gate ((path_t *)((char *)(token) - \ 241*7c478bd9Sstevel@tonic-gate ((char *)(&((path_t *)0)->work_token[(index)])))) 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate /* 247*7c478bd9Sstevel@tonic-gate * Descriptor Reference Count macros 248*7c478bd9Sstevel@tonic-gate */ 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate #define ADAPTER_HOLD(adapter) { \ 251*7c478bd9Sstevel@tonic-gate mutex_enter(&((adapter)->mutex)); \ 252*7c478bd9Sstevel@tonic-gate (adapter)->ref_cnt++; \ 253*7c478bd9Sstevel@tonic-gate ASSERT((adapter)->ref_cnt != 0); \ 254*7c478bd9Sstevel@tonic-gate mutex_exit(&((adapter)->mutex)); \ 255*7c478bd9Sstevel@tonic-gate } 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate #define ADAPTER_RELE(adapter) { \ 258*7c478bd9Sstevel@tonic-gate mutex_enter(&((adapter)->mutex)); \ 259*7c478bd9Sstevel@tonic-gate (adapter)->ref_cnt--; \ 260*7c478bd9Sstevel@tonic-gate ASSERT((adapter)->ref_cnt >= 0); \ 261*7c478bd9Sstevel@tonic-gate mutex_exit(&((adapter)->mutex)); \ 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate #define ADAPTER_RELE_NOLOCK(adapter) { \ 265*7c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&(adapter)->mutex)); \ 266*7c478bd9Sstevel@tonic-gate (adapter)->ref_cnt--; \ 267*7c478bd9Sstevel@tonic-gate ASSERT((adapter)->ref_cnt >= 0); \ 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate #define PATH_HOLD(path) { \ 271*7c478bd9Sstevel@tonic-gate mutex_enter(&(path)->mutex); \ 272*7c478bd9Sstevel@tonic-gate (path)->ref_cnt++; \ 273*7c478bd9Sstevel@tonic-gate ASSERT((path)->ref_cnt != 0); \ 274*7c478bd9Sstevel@tonic-gate mutex_exit(&(path)->mutex); \ 275*7c478bd9Sstevel@tonic-gate } 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate #define PATH_HOLD_NOLOCK(path) { \ 278*7c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&(path)->mutex)); \ 279*7c478bd9Sstevel@tonic-gate (path)->ref_cnt++; \ 280*7c478bd9Sstevel@tonic-gate ASSERT((path)->ref_cnt != 0); \ 281*7c478bd9Sstevel@tonic-gate } 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate #define PATH_RELE(path) { \ 284*7c478bd9Sstevel@tonic-gate mutex_enter(&(path)->mutex); \ 285*7c478bd9Sstevel@tonic-gate (path)->ref_cnt--; \ 286*7c478bd9Sstevel@tonic-gate ASSERT((path)->ref_cnt >= 0); \ 287*7c478bd9Sstevel@tonic-gate if ((path)->ref_cnt == 0) \ 288*7c478bd9Sstevel@tonic-gate cv_signal(&(path)->hold_cv); \ 289*7c478bd9Sstevel@tonic-gate mutex_exit(&(path)->mutex); \ 290*7c478bd9Sstevel@tonic-gate } 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate #define PATH_RELE_NOLOCK(path) { \ 293*7c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&(path)->mutex)); \ 294*7c478bd9Sstevel@tonic-gate (path)->ref_cnt--; \ 295*7c478bd9Sstevel@tonic-gate ASSERT((path)->ref_cnt >= 0); \ 296*7c478bd9Sstevel@tonic-gate if ((path)->ref_cnt == 0) \ 297*7c478bd9Sstevel@tonic-gate cv_signal(&(path)->hold_cv); \ 298*7c478bd9Sstevel@tonic-gate } 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate #define SENDQ_TOKEN_HOLD(path) { \ 301*7c478bd9Sstevel@tonic-gate (path)->sendq_token.ref_cnt++; \ 302*7c478bd9Sstevel@tonic-gate ASSERT((path)->sendq_token.ref_cnt != 0); \ 303*7c478bd9Sstevel@tonic-gate } 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate #define SENDQ_TOKEN_RELE(path) { \ 306*7c478bd9Sstevel@tonic-gate (path)->sendq_token.ref_cnt--; \ 307*7c478bd9Sstevel@tonic-gate ASSERT((path)->sendq_token.ref_cnt >= 0); \ 308*7c478bd9Sstevel@tonic-gate if ((path)->sendq_token.ref_cnt == 0) \ 309*7c478bd9Sstevel@tonic-gate cv_signal(&(path)->sendq_token.sendq_cv); \ 310*7c478bd9Sstevel@tonic-gate } 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate #define IPCINFO_HOLD(ipc_info) { \ 313*7c478bd9Sstevel@tonic-gate mutex_enter(&ipc_info_lock); \ 314*7c478bd9Sstevel@tonic-gate (ipc_info)->ref_cnt++; \ 315*7c478bd9Sstevel@tonic-gate ASSERT((ipc_info)->ref_cnt != 0); \ 316*7c478bd9Sstevel@tonic-gate mutex_exit(&ipc_info_lock); \ 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate #define IPCINFO_HOLD_NOLOCK(ipc_info) { \ 320*7c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ipc_info_lock)); \ 321*7c478bd9Sstevel@tonic-gate (ipc_info)->ref_cnt++; \ 322*7c478bd9Sstevel@tonic-gate ASSERT((ipc_info)->ref_cnt != 0); \ 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate #define IPCINFO_RELE(ipc_info) { \ 326*7c478bd9Sstevel@tonic-gate mutex_enter(&ipc_info_lock); \ 327*7c478bd9Sstevel@tonic-gate (ipc_info)->ref_cnt--; \ 328*7c478bd9Sstevel@tonic-gate ASSERT((ipc_info)->ref_cnt >= 0); \ 329*7c478bd9Sstevel@tonic-gate mutex_exit(&ipc_info_lock); \ 330*7c478bd9Sstevel@tonic-gate } 331*7c478bd9Sstevel@tonic-gate 332*7c478bd9Sstevel@tonic-gate #define IPCINFO_RELE_NOLOCK(ipc_info) { \ 333*7c478bd9Sstevel@tonic-gate ASSERT(MUTEX_HELD(&ipc_info_lock)); \ 334*7c478bd9Sstevel@tonic-gate (ipc_info)->ref_cnt--; \ 335*7c478bd9Sstevel@tonic-gate ASSERT((ipc_info)->ref_cnt >= 0); \ 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate /* 338*7c478bd9Sstevel@tonic-gate * Topology data structures - The primary structure is struct rsm_topology_t 339*7c478bd9Sstevel@tonic-gate * The key interconnect data required for segment operations includes the 340*7c478bd9Sstevel@tonic-gate * cluster nodeids and the controllers (name, hardware address); with 341*7c478bd9Sstevel@tonic-gate * the fundamental constraint that the controller specified for a segment 342*7c478bd9Sstevel@tonic-gate * import must have a physical connection with the contorller used in the 343*7c478bd9Sstevel@tonic-gate * export of the segment. To facilitate applications in the establishment 344*7c478bd9Sstevel@tonic-gate * of proper and efficient export and import policies, a delineation of the 345*7c478bd9Sstevel@tonic-gate * interconnect topology is provided by these data structures. 346*7c478bd9Sstevel@tonic-gate * 347*7c478bd9Sstevel@tonic-gate * A pointer to an instance of this structure type is returned by a call 348*7c478bd9Sstevel@tonic-gate * to rsm_get_interconnect_topology(). The application is responsible for 349*7c478bd9Sstevel@tonic-gate * calling rsm_free_interconnect_topology() to free the allocated memory. 350*7c478bd9Sstevel@tonic-gate * 351*7c478bd9Sstevel@tonic-gate * Note: the rsmka_connections_t structure should be always double-word 352*7c478bd9Sstevel@tonic-gate * aligned. 353*7c478bd9Sstevel@tonic-gate */ 354*7c478bd9Sstevel@tonic-gate 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate #define RSM_CONNECTION_ACTIVE 3 357*7c478bd9Sstevel@tonic-gate 358*7c478bd9Sstevel@tonic-gate 359*7c478bd9Sstevel@tonic-gate typedef struct { 360*7c478bd9Sstevel@tonic-gate rsm_node_id_t local_nodeid; 361*7c478bd9Sstevel@tonic-gate int local_cntlr_count; 362*7c478bd9Sstevel@tonic-gate } rsmka_topology_hdr_t; 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate typedef struct { 365*7c478bd9Sstevel@tonic-gate char cntlr_name[MAXNAMELEN]; 366*7c478bd9Sstevel@tonic-gate rsm_addr_t local_hwaddr; 367*7c478bd9Sstevel@tonic-gate int remote_cntlr_count; 368*7c478bd9Sstevel@tonic-gate } rsmka_connections_hdr_t; 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate /* 372*7c478bd9Sstevel@tonic-gate * An application must not attempt to use a connection unless the 373*7c478bd9Sstevel@tonic-gate * the connection_state element of struct remote_cntlr_t is equal to 374*7c478bd9Sstevel@tonic-gate * RSM_CONNECTION_ACTIVE 375*7c478bd9Sstevel@tonic-gate */ 376*7c478bd9Sstevel@tonic-gate typedef struct { 377*7c478bd9Sstevel@tonic-gate rsm_node_id_t remote_nodeid; 378*7c478bd9Sstevel@tonic-gate char remote_cntlrname[MAXNAMELEN]; 379*7c478bd9Sstevel@tonic-gate rsm_addr_t remote_hwaddr; 380*7c478bd9Sstevel@tonic-gate uint_t connection_state; 381*7c478bd9Sstevel@tonic-gate } rsmka_remote_cntlr_t; 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate /* 385*7c478bd9Sstevel@tonic-gate * The actual size of the remote_cntlr array is equal to the remote_cntlr_count 386*7c478bd9Sstevel@tonic-gate * of the connections_hdr_t struct. 387*7c478bd9Sstevel@tonic-gate */ 388*7c478bd9Sstevel@tonic-gate typedef struct { 389*7c478bd9Sstevel@tonic-gate rsmka_connections_hdr_t hdr; 390*7c478bd9Sstevel@tonic-gate rsmka_remote_cntlr_t remote_cntlr[1]; 391*7c478bd9Sstevel@tonic-gate } rsmka_connections_t; 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate /* 394*7c478bd9Sstevel@tonic-gate * A pointer to an instance of this structure type is returned by a call 395*7c478bd9Sstevel@tonic-gate * to rsm_get_interconnect_topology(). The actual size of the connections 396*7c478bd9Sstevel@tonic-gate * array is equal to the local_cntlr_count of the topology_hdr_t struct. 397*7c478bd9Sstevel@tonic-gate */ 398*7c478bd9Sstevel@tonic-gate typedef struct { 399*7c478bd9Sstevel@tonic-gate rsmka_topology_hdr_t topology_hdr; 400*7c478bd9Sstevel@tonic-gate caddr_t connections[1]; 401*7c478bd9Sstevel@tonic-gate } rsmka_topology_t; 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate #ifdef _SYSCALL32 404*7c478bd9Sstevel@tonic-gate typedef struct { 405*7c478bd9Sstevel@tonic-gate rsmka_topology_hdr_t topology_hdr; 406*7c478bd9Sstevel@tonic-gate caddr32_t connections[1]; 407*7c478bd9Sstevel@tonic-gate } rsmka_topology32_t; 408*7c478bd9Sstevel@tonic-gate #endif 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 411*7c478bd9Sstevel@tonic-gate } 412*7c478bd9Sstevel@tonic-gate #endif 413*7c478bd9Sstevel@tonic-gate 414*7c478bd9Sstevel@tonic-gate #endif /* _SYS_RSM_RSMKA_PATH_INT_H */ 415