xref: /onnv-gate/usr/src/lib/librsm/common/rsmlib.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 1996-2002 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include "synonyms.h"
30*0Sstevel@tonic-gate #include <stdio.h>
31*0Sstevel@tonic-gate #include <stdlib.h>
32*0Sstevel@tonic-gate #include <unistd.h>
33*0Sstevel@tonic-gate #include <stdarg.h>
34*0Sstevel@tonic-gate #include <string.h>
35*0Sstevel@tonic-gate #include <strings.h>
36*0Sstevel@tonic-gate #include <ctype.h>
37*0Sstevel@tonic-gate #include <sys/types.h>
38*0Sstevel@tonic-gate #include <sys/stat.h>
39*0Sstevel@tonic-gate #include <sys/mman.h>
40*0Sstevel@tonic-gate #include <sys/uio.h>
41*0Sstevel@tonic-gate #include <sys/sysmacros.h>
42*0Sstevel@tonic-gate #include <sys/resource.h>
43*0Sstevel@tonic-gate #include <errno.h>
44*0Sstevel@tonic-gate #include <assert.h>
45*0Sstevel@tonic-gate #include <fcntl.h>
46*0Sstevel@tonic-gate #include <dlfcn.h>
47*0Sstevel@tonic-gate #include <sched.h>
48*0Sstevel@tonic-gate #include <stropts.h>
49*0Sstevel@tonic-gate #include <poll.h>
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate #include <rsmapi.h>
52*0Sstevel@tonic-gate #include <sys/rsm/rsmndi.h>
53*0Sstevel@tonic-gate #include <rsmlib_in.h>
54*0Sstevel@tonic-gate #include <sys/rsm/rsm.h>
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate #ifdef __STDC__
57*0Sstevel@tonic-gate 
58*0Sstevel@tonic-gate #pragma weak rsm_get_controller = _rsm_get_controller
59*0Sstevel@tonic-gate #pragma weak rsm_get_controller_attr = _rsm_get_controller_attr
60*0Sstevel@tonic-gate #pragma weak rsm_release_controller = _rsm_release_controller
61*0Sstevel@tonic-gate #pragma weak rsm_get_interconnect_topology = _rsm_get_interconnect_topology
62*0Sstevel@tonic-gate #pragma weak rsm_free_interconnect_topology = _rsm_free_interconnect_topology
63*0Sstevel@tonic-gate #pragma weak rsm_memseg_export_create = _rsm_memseg_export_create
64*0Sstevel@tonic-gate #pragma weak rsm_memseg_export_destroy = _rsm_memseg_export_destroy
65*0Sstevel@tonic-gate #pragma weak rsm_memseg_export_rebind = _rsm_memseg_export_rebind
66*0Sstevel@tonic-gate #pragma weak rsm_memseg_export_publish = _rsm_memseg_export_publish
67*0Sstevel@tonic-gate #pragma weak rsm_memseg_export_unpublish = _rsm_memseg_export_unpublish
68*0Sstevel@tonic-gate #pragma weak rsm_memseg_export_republish = _rsm_memseg_export_republish
69*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_connect = _rsm_memseg_import_connect
70*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_disconnect = _rsm_memseg_import_disconnect
71*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_get8 = _rsm_memseg_import_get8
72*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_get16 = _rsm_memseg_import_get16
73*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_get32 = _rsm_memseg_import_get32
74*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_get64 = _rsm_memseg_import_get64
75*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_get = _rsm_memseg_import_get
76*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_getv = _rsm_memseg_import_getv
77*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_put8 = _rsm_memseg_import_put8
78*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_put16 = _rsm_memseg_import_put16
79*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_put32 = _rsm_memseg_import_put32
80*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_put64 = _rsm_memseg_import_put64
81*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_put = _rsm_memseg_import_put
82*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_putv = _rsm_memseg_import_putv
83*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_map = _rsm_memseg_import_map
84*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_unmap = _rsm_memseg_import_unmap
85*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_init_barrier = _rsm_memseg_import_init_barrier
86*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_open_barrier = _rsm_memseg_import_open_barrier
87*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_close_barrier = _rsm_memseg_import_close_barrier
88*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_order_barrier = _rsm_memseg_import_order_barrier
89*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_destroy_barrier = \
90*0Sstevel@tonic-gate 				_rsm_memseg_import_destroy_barrier
91*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_get_mode = _rsm_memseg_import_get_mode
92*0Sstevel@tonic-gate #pragma weak rsm_memseg_import_set_mode = _rsm_memseg_import_set_mode
93*0Sstevel@tonic-gate #pragma weak rsm_create_localmemory_handle = _rsm_create_localmemory_handle
94*0Sstevel@tonic-gate #pragma weak rsm_free_localmemory_handle = _rsm_free_localmemory_handle
95*0Sstevel@tonic-gate #pragma weak rsm_intr_signal_post = _rsm_intr_signal_post
96*0Sstevel@tonic-gate #pragma weak rsm_intr_signal_wait = _rsm_intr_signal_wait
97*0Sstevel@tonic-gate #pragma weak rsm_intr_signal_wait_pollfd = _rsm_intr_signal_wait_pollfd
98*0Sstevel@tonic-gate #pragma weak rsm_memseg_get_pollfd = _rsm_memseg_get_pollfd
99*0Sstevel@tonic-gate #pragma weak rsm_memseg_release_pollfd = _rsm_memseg_release_pollfd
100*0Sstevel@tonic-gate #pragma weak rsm_get_segmentid_range = _rsm_get_segmentid_range
101*0Sstevel@tonic-gate 
102*0Sstevel@tonic-gate #endif /* __STDC__ */
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate /* lint -w2 */
105*0Sstevel@tonic-gate extern void __rsmloopback_init_ops(rsm_segops_t *);
106*0Sstevel@tonic-gate extern void __rsmdefault_setops(rsm_segops_t *);
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate typedef void (*rsm_access_func_t)(void *, void *, rsm_access_size_t);
109*0Sstevel@tonic-gate 
110*0Sstevel@tonic-gate #ifdef DEBUG
111*0Sstevel@tonic-gate 
112*0Sstevel@tonic-gate #define	RSMLOG_BUF_SIZE 256
113*0Sstevel@tonic-gate FILE *rsmlog_fd = NULL;
114*0Sstevel@tonic-gate static mutex_t rsmlog_lock;
115*0Sstevel@tonic-gate int rsmlibdbg_category = RSM_LIBRARY;
116*0Sstevel@tonic-gate int rsmlibdbg_level = RSM_ERR;
117*0Sstevel@tonic-gate void dbg_printf(int category, int level, char *fmt, ...);
118*0Sstevel@tonic-gate 
119*0Sstevel@tonic-gate #endif /* DEBUG */
120*0Sstevel@tonic-gate 
121*0Sstevel@tonic-gate rsm_node_id_t rsm_local_nodeid = 0;
122*0Sstevel@tonic-gate 
123*0Sstevel@tonic-gate static rsm_controller_t *controller_list = NULL;
124*0Sstevel@tonic-gate 
125*0Sstevel@tonic-gate static rsm_segops_t loopback_ops;
126*0Sstevel@tonic-gate 
127*0Sstevel@tonic-gate #define	MAX_STRLEN	80
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate #define	RSM_IOTYPE_PUTGET	1
130*0Sstevel@tonic-gate #define	RSM_IOTYPE_SCATGATH	2
131*0Sstevel@tonic-gate 
132*0Sstevel@tonic-gate #define	RSMFILE_BUFSIZE		256
133*0Sstevel@tonic-gate 
134*0Sstevel@tonic-gate #pragma init(_rsm_librsm_init)
135*0Sstevel@tonic-gate 
136*0Sstevel@tonic-gate static mutex_t _rsm_lock;
137*0Sstevel@tonic-gate 
138*0Sstevel@tonic-gate static int _rsm_fd = -1;
139*0Sstevel@tonic-gate static rsm_gnum_t *bar_va, bar_fixed = 0;
140*0Sstevel@tonic-gate static rsm_pollfd_table_t pollfd_table;
141*0Sstevel@tonic-gate 
142*0Sstevel@tonic-gate static int _rsm_get_hwaddr(rsmapi_controller_handle_t handle,
143*0Sstevel@tonic-gate rsm_node_id_t, rsm_addr_t *hwaddrp);
144*0Sstevel@tonic-gate static int _rsm_get_nodeid(rsmapi_controller_handle_t,
145*0Sstevel@tonic-gate rsm_addr_t, rsm_node_id_t *);
146*0Sstevel@tonic-gate static int __rsm_import_implicit_map(rsmseg_handle_t *, int);
147*0Sstevel@tonic-gate static int __rsm_intr_signal_wait_common(struct pollfd [], minor_t [],
148*0Sstevel@tonic-gate     nfds_t, int, int *);
149*0Sstevel@tonic-gate 
150*0Sstevel@tonic-gate static	rsm_lib_funcs_t lib_functions = {
151*0Sstevel@tonic-gate 	RSM_LIB_FUNCS_VERSION,
152*0Sstevel@tonic-gate 	_rsm_get_hwaddr,
153*0Sstevel@tonic-gate 	_rsm_get_nodeid
154*0Sstevel@tonic-gate };
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate int _rsm_get_interconnect_topology(rsm_topology_t **);
157*0Sstevel@tonic-gate void _rsm_free_interconnect_topology(rsm_topology_t *);
158*0Sstevel@tonic-gate int _rsm_memseg_import_open_barrier(rsmapi_barrier_t *);
159*0Sstevel@tonic-gate int _rsm_memseg_import_close_barrier(rsmapi_barrier_t *);
160*0Sstevel@tonic-gate int _rsm_memseg_import_unmap(rsm_memseg_import_handle_t);
161*0Sstevel@tonic-gate 
162*0Sstevel@tonic-gate rsm_topology_t *tp;
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate 
165*0Sstevel@tonic-gate 
166*0Sstevel@tonic-gate /*
167*0Sstevel@tonic-gate  * service module function templates:
168*0Sstevel@tonic-gate  */
169*0Sstevel@tonic-gate 
170*0Sstevel@tonic-gate /*
171*0Sstevel@tonic-gate  * The _rsm_librsm_init function is called the first time an application
172*0Sstevel@tonic-gate  * references the RSMAPI library
173*0Sstevel@tonic-gate  */
174*0Sstevel@tonic-gate int
175*0Sstevel@tonic-gate _rsm_librsm_init()
176*0Sstevel@tonic-gate {
177*0Sstevel@tonic-gate 	rsm_ioctlmsg_t 		msg;
178*0Sstevel@tonic-gate 	int e, tmpfd;
179*0Sstevel@tonic-gate 	int i;
180*0Sstevel@tonic-gate 	char logname[MAXNAMELEN];
181*0Sstevel@tonic-gate 
182*0Sstevel@tonic-gate 	mutex_init(&_rsm_lock, USYNC_THREAD, NULL);
183*0Sstevel@tonic-gate 
184*0Sstevel@tonic-gate #ifdef DEBUG
185*0Sstevel@tonic-gate 	mutex_init(&rsmlog_lock, USYNC_THREAD, NULL);
186*0Sstevel@tonic-gate 	sprintf(logname, "%s.%d", TRACELOG, getpid());
187*0Sstevel@tonic-gate 	rsmlog_fd = fopen(logname, "w+");
188*0Sstevel@tonic-gate 	if (rsmlog_fd == NULL) {
189*0Sstevel@tonic-gate 		fprintf(stderr, "Log file open failed\n");
190*0Sstevel@tonic-gate 		return (errno);
191*0Sstevel@tonic-gate 	}
192*0Sstevel@tonic-gate 
193*0Sstevel@tonic-gate #endif /* DEBUG */
194*0Sstevel@tonic-gate 
195*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
196*0Sstevel@tonic-gate 	    "_rsm_librsm_init: enter\n"));
197*0Sstevel@tonic-gate 
198*0Sstevel@tonic-gate 	/* initialize the pollfd_table */
199*0Sstevel@tonic-gate 	mutex_init(&pollfd_table.lock, USYNC_THREAD, NULL);
200*0Sstevel@tonic-gate 
201*0Sstevel@tonic-gate 	for (i = 0; i < RSM_MAX_BUCKETS; i++) {
202*0Sstevel@tonic-gate 		pollfd_table.buckets[i] = NULL;
203*0Sstevel@tonic-gate 	}
204*0Sstevel@tonic-gate 
205*0Sstevel@tonic-gate 	/* open /dev/rsm and mmap barrier generation pages */
206*0Sstevel@tonic-gate 	mutex_lock(&_rsm_lock);
207*0Sstevel@tonic-gate 	_rsm_fd = open(DEVRSM, O_RDONLY);
208*0Sstevel@tonic-gate 	if (_rsm_fd < 0) {
209*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
210*0Sstevel@tonic-gate 		    "unable to open /dev/rsm\n"));
211*0Sstevel@tonic-gate 		mutex_unlock(&_rsm_lock);
212*0Sstevel@tonic-gate 		return (errno);
213*0Sstevel@tonic-gate 	}
214*0Sstevel@tonic-gate 
215*0Sstevel@tonic-gate 	/*
216*0Sstevel@tonic-gate 	 * DUP the opened file descriptor to something greater than
217*0Sstevel@tonic-gate 	 * STDERR_FILENO so that we never use the STDIN_FILENO,
218*0Sstevel@tonic-gate 	 * STDOUT_FILENO or STDERR_FILENO.
219*0Sstevel@tonic-gate 	 */
220*0Sstevel@tonic-gate 	tmpfd = fcntl(_rsm_fd, F_DUPFD, 3);
221*0Sstevel@tonic-gate 	if (tmpfd < 0) {
222*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
223*0Sstevel@tonic-gate 		    "F_DUPFD failed\n"));
224*0Sstevel@tonic-gate 	} else {
225*0Sstevel@tonic-gate 		(void) close(_rsm_fd);
226*0Sstevel@tonic-gate 		_rsm_fd = tmpfd;
227*0Sstevel@tonic-gate 	}
228*0Sstevel@tonic-gate 
229*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
230*0Sstevel@tonic-gate 	    "_rsm_fd is %d\n", _rsm_fd));
231*0Sstevel@tonic-gate 
232*0Sstevel@tonic-gate 	if (fcntl(_rsm_fd, F_SETFD, FD_CLOEXEC) < 0) {
233*0Sstevel@tonic-gate 	    DBPRINTF((RSM_LIBRARY, RSM_ERR,
234*0Sstevel@tonic-gate 		"F_SETFD failed\n"));
235*0Sstevel@tonic-gate 	}
236*0Sstevel@tonic-gate 
237*0Sstevel@tonic-gate 	/* get mapping generation number page info */
238*0Sstevel@tonic-gate 	if (ioctl(_rsm_fd, RSM_IOCTL_BAR_INFO, &msg) < 0) {
239*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
240*0Sstevel@tonic-gate 		    "RSM_IOCTL_BAR_INFO failed\n"));
241*0Sstevel@tonic-gate 		mutex_unlock(&_rsm_lock);
242*0Sstevel@tonic-gate 		return (errno);
243*0Sstevel@tonic-gate 	}
244*0Sstevel@tonic-gate 
245*0Sstevel@tonic-gate 	/*
246*0Sstevel@tonic-gate 	 * bar_va is mapped to the mapping generation number page
247*0Sstevel@tonic-gate 	 * in order to support close barrier
248*0Sstevel@tonic-gate 	 */
249*0Sstevel@tonic-gate 	/* LINTED */
250*0Sstevel@tonic-gate 	bar_va = (rsm_gnum_t *)mmap(NULL, msg.len,
251*0Sstevel@tonic-gate 	    PROT_READ, MAP_SHARED, _rsm_fd, msg.off);
252*0Sstevel@tonic-gate 	if (bar_va == (rsm_gnum_t *)MAP_FAILED) {
253*0Sstevel@tonic-gate 		bar_va = NULL;
254*0Sstevel@tonic-gate 		mutex_unlock(&_rsm_lock);
255*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
256*0Sstevel@tonic-gate 		    "unable to map barrier page\n"));
257*0Sstevel@tonic-gate 		return (RSMERR_MAP_FAILED);
258*0Sstevel@tonic-gate 	}
259*0Sstevel@tonic-gate 
260*0Sstevel@tonic-gate 	mutex_unlock(&_rsm_lock);
261*0Sstevel@tonic-gate 
262*0Sstevel@tonic-gate 	/* get local nodeid */
263*0Sstevel@tonic-gate 	e = rsm_get_interconnect_topology(&tp);
264*0Sstevel@tonic-gate 	if (e != RSM_SUCCESS) {
265*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
266*0Sstevel@tonic-gate 		    "unable to obtain topology data\n"));
267*0Sstevel@tonic-gate 		return (e);
268*0Sstevel@tonic-gate 	} else
269*0Sstevel@tonic-gate 	    rsm_local_nodeid = tp->topology_hdr.local_nodeid;
270*0Sstevel@tonic-gate 
271*0Sstevel@tonic-gate 	rsm_free_interconnect_topology(tp);
272*0Sstevel@tonic-gate 
273*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
274*0Sstevel@tonic-gate 	    "_rsm_librsm_init: exit\n"));
275*0Sstevel@tonic-gate 
276*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
277*0Sstevel@tonic-gate }
278*0Sstevel@tonic-gate 
279*0Sstevel@tonic-gate static int
280*0Sstevel@tonic-gate _rsm_loopbackload(caddr_t name, int unit, rsm_controller_t **chdl)
281*0Sstevel@tonic-gate {
282*0Sstevel@tonic-gate 	rsm_controller_t *p;
283*0Sstevel@tonic-gate 	rsm_ioctlmsg_t msg;
284*0Sstevel@tonic-gate 
285*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE,
286*0Sstevel@tonic-gate 	    "_rsm_loopbackload: enter\n"));
287*0Sstevel@tonic-gate 	/*
288*0Sstevel@tonic-gate 	 * For now do this, but we should open some file and read the
289*0Sstevel@tonic-gate 	 * list of supported controllers and there numbers.
290*0Sstevel@tonic-gate 	 */
291*0Sstevel@tonic-gate 
292*0Sstevel@tonic-gate 	p = (rsm_controller_t *)malloc(sizeof (*p) + strlen(name) + 1);
293*0Sstevel@tonic-gate 	if (!p) {
294*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_ERR,
295*0Sstevel@tonic-gate 		    "not enough memory\n"));
296*0Sstevel@tonic-gate 		return (RSMERR_INSUFFICIENT_MEM);
297*0Sstevel@tonic-gate 	}
298*0Sstevel@tonic-gate 
299*0Sstevel@tonic-gate 	msg.cname = name;
300*0Sstevel@tonic-gate 	msg.cname_len = strlen(name) +1;
301*0Sstevel@tonic-gate 	msg.cnum = unit;
302*0Sstevel@tonic-gate 	msg.arg = (caddr_t)&p->cntr_attr;
303*0Sstevel@tonic-gate 	if (ioctl(_rsm_fd, RSM_IOCTL_ATTR, &msg) < 0) {
304*0Sstevel@tonic-gate 		int error = errno;
305*0Sstevel@tonic-gate 		free((void *)p);
306*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_ERR,
307*0Sstevel@tonic-gate 		    "RSM_IOCTL_ATTR failed\n"));
308*0Sstevel@tonic-gate 		return (error);
309*0Sstevel@tonic-gate 	}
310*0Sstevel@tonic-gate 
311*0Sstevel@tonic-gate 	__rsmloopback_init_ops(&loopback_ops);
312*0Sstevel@tonic-gate 	__rsmdefault_setops(&loopback_ops);
313*0Sstevel@tonic-gate 	p->cntr_segops = &loopback_ops;
314*0Sstevel@tonic-gate 
315*0Sstevel@tonic-gate 	/*
316*0Sstevel@tonic-gate 	 * Should add this entry into list
317*0Sstevel@tonic-gate 	 */
318*0Sstevel@tonic-gate 	p->cntr_fd = _rsm_fd;
319*0Sstevel@tonic-gate 	p->cntr_name = strcpy((char *)(p+1), name);
320*0Sstevel@tonic-gate 	p->cntr_unit = unit;
321*0Sstevel@tonic-gate 	p->cntr_refcnt = 1;
322*0Sstevel@tonic-gate 
323*0Sstevel@tonic-gate 
324*0Sstevel@tonic-gate 	mutex_init(&p->cntr_lock, USYNC_THREAD, NULL);
325*0Sstevel@tonic-gate 	cond_init(&p->cntr_cv, USYNC_THREAD, NULL);
326*0Sstevel@tonic-gate 	p->cntr_rqlist = NULL;
327*0Sstevel@tonic-gate 	p->cntr_segops->rsm_get_lib_attr(&p->cntr_lib_attr);
328*0Sstevel@tonic-gate 	p->cntr_next = controller_list;
329*0Sstevel@tonic-gate 	controller_list = p;
330*0Sstevel@tonic-gate 
331*0Sstevel@tonic-gate 	*chdl = p;
332*0Sstevel@tonic-gate 
333*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE,
334*0Sstevel@tonic-gate 	    "_rsm_loopbackload: exit\n"));
335*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
336*0Sstevel@tonic-gate 
337*0Sstevel@tonic-gate }
338*0Sstevel@tonic-gate 
339*0Sstevel@tonic-gate static int
340*0Sstevel@tonic-gate _rsm_modload(caddr_t name, int unit, rsmapi_controller_handle_t *controller)
341*0Sstevel@tonic-gate {
342*0Sstevel@tonic-gate 	int error = RSM_SUCCESS;
343*0Sstevel@tonic-gate 	char clib[MAX_STRLEN];
344*0Sstevel@tonic-gate 	rsm_controller_t *p = NULL;
345*0Sstevel@tonic-gate 	void *dlh;
346*0Sstevel@tonic-gate 	rsm_attach_entry_t fptr;
347*0Sstevel@tonic-gate 	rsm_ioctlmsg_t msg;
348*0Sstevel@tonic-gate 
349*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
350*0Sstevel@tonic-gate 	    "_rsm_modload: enter\n"));
351*0Sstevel@tonic-gate 
352*0Sstevel@tonic-gate 	(void) sprintf(clib, "%s.so", name);
353*0Sstevel@tonic-gate 
354*0Sstevel@tonic-gate 	/* found entry, try to load library */
355*0Sstevel@tonic-gate 	dlh = dlopen(clib, RTLD_LAZY);
356*0Sstevel@tonic-gate 	if (dlh == NULL) {
357*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
358*0Sstevel@tonic-gate 		    "unable to find plugin library\n"));
359*0Sstevel@tonic-gate 		error = RSMERR_CTLR_NOT_PRESENT;
360*0Sstevel@tonic-gate 		goto skiplib;
361*0Sstevel@tonic-gate 	}
362*0Sstevel@tonic-gate 
363*0Sstevel@tonic-gate 	(void) sprintf(clib, "%s_opendevice", name);
364*0Sstevel@tonic-gate 
365*0Sstevel@tonic-gate 	fptr = (rsm_attach_entry_t)dlsym(dlh, clib); /* lint !e611 */
366*0Sstevel@tonic-gate 	if (fptr != NULL) {
367*0Sstevel@tonic-gate 		/* allocate new lib structure */
368*0Sstevel@tonic-gate 		/* get ops handler, attr and ops */
369*0Sstevel@tonic-gate 		p = (rsm_controller_t *)malloc(sizeof (*p) + strlen(name) + 1);
370*0Sstevel@tonic-gate 		if (p != NULL) {
371*0Sstevel@tonic-gate 			error = fptr(unit, &p->cntr_segops);
372*0Sstevel@tonic-gate 		} else {
373*0Sstevel@tonic-gate 			error = RSMERR_INSUFFICIENT_MEM;
374*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY, RSM_ERR,
375*0Sstevel@tonic-gate 			    "not enough memory\n"));
376*0Sstevel@tonic-gate 		}
377*0Sstevel@tonic-gate 	} else {
378*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
379*0Sstevel@tonic-gate 		    "can't find symbol %s\n", clib));
380*0Sstevel@tonic-gate 		error = RSMERR_CTLR_NOT_PRESENT;
381*0Sstevel@tonic-gate 		(void) dlclose(dlh);
382*0Sstevel@tonic-gate 	}
383*0Sstevel@tonic-gate 
384*0Sstevel@tonic-gate skiplib:
385*0Sstevel@tonic-gate 	if ((error != RSM_SUCCESS) || (p == NULL)) {
386*0Sstevel@tonic-gate 		if (p != NULL)
387*0Sstevel@tonic-gate 			free((void *)p);
388*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
389*0Sstevel@tonic-gate 		    "_rsm_modload error %d\n", error));
390*0Sstevel@tonic-gate 		return (error);
391*0Sstevel@tonic-gate 	}
392*0Sstevel@tonic-gate 
393*0Sstevel@tonic-gate 	/* check the version number */
394*0Sstevel@tonic-gate 	if (p->cntr_segops->rsm_version != RSM_LIB_VERSION) {
395*0Sstevel@tonic-gate 		/* bad version number */
396*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
397*0Sstevel@tonic-gate 		    "wrong version; "
398*0Sstevel@tonic-gate 		    "found %d, expected %d\n",
399*0Sstevel@tonic-gate 		    p->cntr_segops->rsm_version, RSM_LIB_VERSION));
400*0Sstevel@tonic-gate 		free(p);
401*0Sstevel@tonic-gate 		return (RSMERR_BAD_LIBRARY_VERSION);
402*0Sstevel@tonic-gate 	} else {
403*0Sstevel@tonic-gate 		/* pass the fuctions to NDI library */
404*0Sstevel@tonic-gate 		if ((p->cntr_segops->rsm_register_lib_funcs == NULL) ||
405*0Sstevel@tonic-gate 		    (p->cntr_segops->rsm_register_lib_funcs(
406*0Sstevel@tonic-gate 		    &lib_functions) != RSM_SUCCESS)) {
407*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY, RSM_ERR,
408*0Sstevel@tonic-gate 			    "RSMNDI library not registering lib functions\n"));
409*0Sstevel@tonic-gate 		}
410*0Sstevel@tonic-gate 
411*0Sstevel@tonic-gate 		/* get controller attributes */
412*0Sstevel@tonic-gate 		msg.cnum = unit;
413*0Sstevel@tonic-gate 		msg.cname = name;
414*0Sstevel@tonic-gate 		msg.cname_len = strlen(name) +1;
415*0Sstevel@tonic-gate 		msg.arg = (caddr_t)&p->cntr_attr;
416*0Sstevel@tonic-gate 		if (ioctl(_rsm_fd, RSM_IOCTL_ATTR, &msg) < 0) {
417*0Sstevel@tonic-gate 			error = errno;
418*0Sstevel@tonic-gate 			free((void *)p);
419*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY, RSM_ERR,
420*0Sstevel@tonic-gate 			    "RSM_IOCTL_ATTR failed\n"));
421*0Sstevel@tonic-gate 			return (error);
422*0Sstevel@tonic-gate 		}
423*0Sstevel@tonic-gate 
424*0Sstevel@tonic-gate 		/* set controller access functions */
425*0Sstevel@tonic-gate 		__rsmdefault_setops(p->cntr_segops);
426*0Sstevel@tonic-gate 
427*0Sstevel@tonic-gate 		mutex_init(&p->cntr_lock, USYNC_THREAD, NULL);
428*0Sstevel@tonic-gate 		cond_init(&p->cntr_cv, USYNC_THREAD, NULL);
429*0Sstevel@tonic-gate 		p->cntr_rqlist = NULL;
430*0Sstevel@tonic-gate 		p->cntr_segops->rsm_get_lib_attr(&p->cntr_lib_attr);
431*0Sstevel@tonic-gate 		/* insert into list of controllers */
432*0Sstevel@tonic-gate 		p->cntr_name = strcpy((char *)(p+1), name);
433*0Sstevel@tonic-gate 		p->cntr_fd = _rsm_fd;
434*0Sstevel@tonic-gate 		p->cntr_unit = unit;
435*0Sstevel@tonic-gate 		p->cntr_refcnt = 1;	/* first reference */
436*0Sstevel@tonic-gate 		p->cntr_next = controller_list;
437*0Sstevel@tonic-gate 		controller_list = p;
438*0Sstevel@tonic-gate 		*controller = (rsmapi_controller_handle_t)p;
439*0Sstevel@tonic-gate 		errno = RSM_SUCCESS;
440*0Sstevel@tonic-gate 	}
441*0Sstevel@tonic-gate 
442*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
443*0Sstevel@tonic-gate 	    "_rsm_modload: exit\n"));
444*0Sstevel@tonic-gate 	return (error);
445*0Sstevel@tonic-gate }
446*0Sstevel@tonic-gate 
447*0Sstevel@tonic-gate /*
448*0Sstevel@tonic-gate  * inserts a given segment handle into the pollfd table, this is called
449*0Sstevel@tonic-gate  * when rsm_memseg_get_pollfd() is called the first time on a segment handle.
450*0Sstevel@tonic-gate  * Returns RSM_SUCCESS if successful otherwise the error code is returned
451*0Sstevel@tonic-gate  */
452*0Sstevel@tonic-gate static int
453*0Sstevel@tonic-gate _rsm_insert_pollfd_table(int segfd, minor_t segrnum)
454*0Sstevel@tonic-gate {
455*0Sstevel@tonic-gate 	int i;
456*0Sstevel@tonic-gate 	int hash;
457*0Sstevel@tonic-gate 	rsm_pollfd_chunk_t *chunk;
458*0Sstevel@tonic-gate 
459*0Sstevel@tonic-gate 	hash = RSM_POLLFD_HASH(segfd);
460*0Sstevel@tonic-gate 
461*0Sstevel@tonic-gate 	mutex_lock(&pollfd_table.lock);
462*0Sstevel@tonic-gate 
463*0Sstevel@tonic-gate 	chunk = pollfd_table.buckets[hash];
464*0Sstevel@tonic-gate 	while (chunk) {
465*0Sstevel@tonic-gate 		if (chunk->nfree > 0)
466*0Sstevel@tonic-gate 			break;
467*0Sstevel@tonic-gate 		chunk = chunk->next;
468*0Sstevel@tonic-gate 	}
469*0Sstevel@tonic-gate 
470*0Sstevel@tonic-gate 	if (!chunk) { /* couldn't find a free chunk - allocate a new one */
471*0Sstevel@tonic-gate 		chunk = malloc(sizeof (rsm_pollfd_chunk_t));
472*0Sstevel@tonic-gate 		if (!chunk) {
473*0Sstevel@tonic-gate 			mutex_unlock(&pollfd_table.lock);
474*0Sstevel@tonic-gate 			return (RSMERR_INSUFFICIENT_MEM);
475*0Sstevel@tonic-gate 		}
476*0Sstevel@tonic-gate 		chunk->nfree = RSM_POLLFD_PER_CHUNK - 1;
477*0Sstevel@tonic-gate 		chunk->fdarray[0].fd = segfd;
478*0Sstevel@tonic-gate 		chunk->fdarray[0].segrnum = segrnum;
479*0Sstevel@tonic-gate 		for (i = 1; i < RSM_POLLFD_PER_CHUNK; i++) {
480*0Sstevel@tonic-gate 			chunk->fdarray[i].fd = -1;
481*0Sstevel@tonic-gate 			chunk->fdarray[i].segrnum = 0;
482*0Sstevel@tonic-gate 		}
483*0Sstevel@tonic-gate 		/* insert this into the hash table */
484*0Sstevel@tonic-gate 		chunk->next = pollfd_table.buckets[hash];
485*0Sstevel@tonic-gate 		pollfd_table.buckets[hash] = chunk;
486*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
487*0Sstevel@tonic-gate 		    "rsm_insert_pollfd: new chunk(%p) @ %d for %d:%d\n",
488*0Sstevel@tonic-gate 		    chunk, hash, segfd, segrnum));
489*0Sstevel@tonic-gate 	} else { /* a chunk with free slot was found */
490*0Sstevel@tonic-gate 		for (i = 0; i < RSM_POLLFD_PER_CHUNK; i++) {
491*0Sstevel@tonic-gate 			if (chunk->fdarray[i].fd == -1) {
492*0Sstevel@tonic-gate 				chunk->fdarray[i].fd = segfd;
493*0Sstevel@tonic-gate 				chunk->fdarray[i].segrnum = segrnum;
494*0Sstevel@tonic-gate 				chunk->nfree--;
495*0Sstevel@tonic-gate 				break;
496*0Sstevel@tonic-gate 			}
497*0Sstevel@tonic-gate 		}
498*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
499*0Sstevel@tonic-gate 		    "rsm_insert_pollfd: inserted @ %d for %d:%d chunk(%p)\n",
500*0Sstevel@tonic-gate 		    hash, segfd, segrnum, chunk));
501*0Sstevel@tonic-gate 		assert(i < RSM_POLLFD_PER_CHUNK);
502*0Sstevel@tonic-gate 	}
503*0Sstevel@tonic-gate 
504*0Sstevel@tonic-gate 	mutex_unlock(&pollfd_table.lock);
505*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
506*0Sstevel@tonic-gate }
507*0Sstevel@tonic-gate 
508*0Sstevel@tonic-gate /*
509*0Sstevel@tonic-gate  * Given a file descriptor returns the corresponding segment handles
510*0Sstevel@tonic-gate  * resource number, if the fd is not found returns 0. 0 is not a valid
511*0Sstevel@tonic-gate  * minor number for a rsmapi segment since it is used for the barrier
512*0Sstevel@tonic-gate  * resource.
513*0Sstevel@tonic-gate  */
514*0Sstevel@tonic-gate static minor_t
515*0Sstevel@tonic-gate _rsm_lookup_pollfd_table(int segfd)
516*0Sstevel@tonic-gate {
517*0Sstevel@tonic-gate 	int i;
518*0Sstevel@tonic-gate 	rsm_pollfd_chunk_t	*chunk;
519*0Sstevel@tonic-gate 
520*0Sstevel@tonic-gate 	if (segfd < 0)
521*0Sstevel@tonic-gate 		return (0);
522*0Sstevel@tonic-gate 
523*0Sstevel@tonic-gate 	mutex_lock(&pollfd_table.lock);
524*0Sstevel@tonic-gate 
525*0Sstevel@tonic-gate 	chunk = pollfd_table.buckets[RSM_POLLFD_HASH(segfd)];
526*0Sstevel@tonic-gate 	while (chunk) {
527*0Sstevel@tonic-gate 		assert(chunk->nfree < RSM_POLLFD_PER_CHUNK);
528*0Sstevel@tonic-gate 
529*0Sstevel@tonic-gate 		for (i = 0; i < RSM_POLLFD_PER_CHUNK; i++) {
530*0Sstevel@tonic-gate 			if (chunk->fdarray[i].fd == segfd) {
531*0Sstevel@tonic-gate 				mutex_unlock(&pollfd_table.lock);
532*0Sstevel@tonic-gate 				DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
533*0Sstevel@tonic-gate 				    "rsm_lookup_pollfd: found(%d) rnum(%d)\n",
534*0Sstevel@tonic-gate 				    segfd, chunk->fdarray[i].segrnum));
535*0Sstevel@tonic-gate 				return (chunk->fdarray[i].segrnum);
536*0Sstevel@tonic-gate 			}
537*0Sstevel@tonic-gate 		}
538*0Sstevel@tonic-gate 		chunk = chunk->next;
539*0Sstevel@tonic-gate 	}
540*0Sstevel@tonic-gate 
541*0Sstevel@tonic-gate 	mutex_unlock(&pollfd_table.lock);
542*0Sstevel@tonic-gate 
543*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
544*0Sstevel@tonic-gate 	    "rsm_lookup_pollfd: not found(%d)\n", segfd));
545*0Sstevel@tonic-gate 
546*0Sstevel@tonic-gate 	return (0);
547*0Sstevel@tonic-gate }
548*0Sstevel@tonic-gate 
549*0Sstevel@tonic-gate /*
550*0Sstevel@tonic-gate  * Remove the entry corresponding to the given file descriptor from the
551*0Sstevel@tonic-gate  * pollfd table.
552*0Sstevel@tonic-gate  */
553*0Sstevel@tonic-gate static void
554*0Sstevel@tonic-gate _rsm_remove_pollfd_table(int segfd)
555*0Sstevel@tonic-gate {
556*0Sstevel@tonic-gate 	int i;
557*0Sstevel@tonic-gate 	int hash;
558*0Sstevel@tonic-gate 	rsm_pollfd_chunk_t	*chunk;
559*0Sstevel@tonic-gate 	rsm_pollfd_chunk_t	*prev_chunk;
560*0Sstevel@tonic-gate 
561*0Sstevel@tonic-gate 	if (segfd < 0)
562*0Sstevel@tonic-gate 		return;
563*0Sstevel@tonic-gate 
564*0Sstevel@tonic-gate 	hash = RSM_POLLFD_HASH(segfd);
565*0Sstevel@tonic-gate 
566*0Sstevel@tonic-gate 	mutex_lock(&pollfd_table.lock);
567*0Sstevel@tonic-gate 
568*0Sstevel@tonic-gate 	prev_chunk = chunk = pollfd_table.buckets[hash];
569*0Sstevel@tonic-gate 	while (chunk) {
570*0Sstevel@tonic-gate 		assert(chunk->nfree < RSM_POLLFD_PER_CHUNK);
571*0Sstevel@tonic-gate 
572*0Sstevel@tonic-gate 		for (i = 0; i < RSM_POLLFD_PER_CHUNK; i++) {
573*0Sstevel@tonic-gate 			if (chunk->fdarray[i].fd == segfd) {
574*0Sstevel@tonic-gate 				DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
575*0Sstevel@tonic-gate 				    "rsm_remove_pollfd: %d:%d\n",
576*0Sstevel@tonic-gate 				    chunk->fdarray[i].fd,
577*0Sstevel@tonic-gate 				    chunk->fdarray[i].segrnum));
578*0Sstevel@tonic-gate 				chunk->fdarray[i].fd = -1;
579*0Sstevel@tonic-gate 				chunk->fdarray[i].segrnum = 0;
580*0Sstevel@tonic-gate 				chunk->nfree++;
581*0Sstevel@tonic-gate 				if (chunk->nfree == RSM_POLLFD_PER_CHUNK) {
582*0Sstevel@tonic-gate 					/* chunk is empty free it */
583*0Sstevel@tonic-gate 					if (prev_chunk == chunk) {
584*0Sstevel@tonic-gate 						pollfd_table.buckets[hash] =
585*0Sstevel@tonic-gate 						    chunk->next;
586*0Sstevel@tonic-gate 					} else {
587*0Sstevel@tonic-gate 						prev_chunk->next = chunk->next;
588*0Sstevel@tonic-gate 					}
589*0Sstevel@tonic-gate 					DBPRINTF((RSM_LIBRARY,
590*0Sstevel@tonic-gate 					    RSM_DEBUG_VERBOSE,
591*0Sstevel@tonic-gate 					    "rsm_remove_pollfd:free(%p)\n",
592*0Sstevel@tonic-gate 					    chunk));
593*0Sstevel@tonic-gate 					free(chunk);
594*0Sstevel@tonic-gate 					mutex_unlock(&pollfd_table.lock);
595*0Sstevel@tonic-gate 					return;
596*0Sstevel@tonic-gate 				}
597*0Sstevel@tonic-gate 			}
598*0Sstevel@tonic-gate 		}
599*0Sstevel@tonic-gate 		prev_chunk = chunk;
600*0Sstevel@tonic-gate 		chunk = chunk->next;
601*0Sstevel@tonic-gate 	}
602*0Sstevel@tonic-gate 
603*0Sstevel@tonic-gate 	mutex_unlock(&pollfd_table.lock);
604*0Sstevel@tonic-gate }
605*0Sstevel@tonic-gate 
606*0Sstevel@tonic-gate int
607*0Sstevel@tonic-gate _rsm_get_controller(char *name, rsmapi_controller_handle_t *chdl)
608*0Sstevel@tonic-gate {
609*0Sstevel@tonic-gate 	rsm_controller_t *p;
610*0Sstevel@tonic-gate 	char	cntr_name[MAXNAMELEN];	/* cntr_name=<cntr_type><unit> */
611*0Sstevel@tonic-gate 	char	*cntr_type;
612*0Sstevel@tonic-gate 	int	unit = 0;
613*0Sstevel@tonic-gate 	int	i, e;
614*0Sstevel@tonic-gate 
615*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
616*0Sstevel@tonic-gate 	    "rsm_get_controller: enter\n"));
617*0Sstevel@tonic-gate 	/*
618*0Sstevel@tonic-gate 	 * Lookup controller name and return ops vector and controller
619*0Sstevel@tonic-gate 	 * structure
620*0Sstevel@tonic-gate 	 */
621*0Sstevel@tonic-gate 
622*0Sstevel@tonic-gate 	if (!chdl) {
623*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
624*0Sstevel@tonic-gate 		    "Invalid controller handle\n"));
625*0Sstevel@tonic-gate 		return (RSMERR_BAD_CTLR_HNDL);
626*0Sstevel@tonic-gate 	}
627*0Sstevel@tonic-gate 	if (!name) {
628*0Sstevel@tonic-gate 		/* use loopback if null */
629*0Sstevel@tonic-gate 		cntr_type = LOOPBACK;
630*0Sstevel@tonic-gate 	} else {
631*0Sstevel@tonic-gate 		(void) strcpy(cntr_name, name);
632*0Sstevel@tonic-gate 		/* scan from the end till a non-digit is found */
633*0Sstevel@tonic-gate 		for (i = strlen(cntr_name) - 1; i >= 0; i--) {
634*0Sstevel@tonic-gate 			if (! isdigit((int)cntr_name[i]))
635*0Sstevel@tonic-gate 				break;
636*0Sstevel@tonic-gate 		}
637*0Sstevel@tonic-gate 		i++;
638*0Sstevel@tonic-gate 		unit = atoi((char *)cntr_name+i);
639*0Sstevel@tonic-gate 		cntr_name[i] = '\0';	/* null terminate the cntr_type part */
640*0Sstevel@tonic-gate 		cntr_type = (char *)cntr_name;
641*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
642*0Sstevel@tonic-gate 		    "cntr_type=%s, instance=%d\n",
643*0Sstevel@tonic-gate 		    cntr_type, unit));
644*0Sstevel@tonic-gate 	}
645*0Sstevel@tonic-gate 
646*0Sstevel@tonic-gate 	/* protect the controller_list by locking the device/library */
647*0Sstevel@tonic-gate 	mutex_lock(&_rsm_lock);
648*0Sstevel@tonic-gate 
649*0Sstevel@tonic-gate 	for (p = controller_list; p; p = p->cntr_next) {
650*0Sstevel@tonic-gate 		if (!strcasecmp(p->cntr_name, cntr_type) &&
651*0Sstevel@tonic-gate 		    !strcasecmp(cntr_type, LOOPBACK)) {
652*0Sstevel@tonic-gate 			p->cntr_refcnt++;
653*0Sstevel@tonic-gate 			*chdl = (rsmapi_controller_handle_t)p;
654*0Sstevel@tonic-gate 			mutex_unlock(&_rsm_lock);
655*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
656*0Sstevel@tonic-gate 			    "rsm_get_controller: exit\n"));
657*0Sstevel@tonic-gate 			return (RSM_SUCCESS);
658*0Sstevel@tonic-gate 		} else if (!strcasecmp(p->cntr_name, cntr_type) &&
659*0Sstevel@tonic-gate 		    (p->cntr_unit == unit)) {
660*0Sstevel@tonic-gate 			p->cntr_refcnt++;
661*0Sstevel@tonic-gate 			*chdl = (rsmapi_controller_handle_t)p;
662*0Sstevel@tonic-gate 			mutex_unlock(&_rsm_lock);
663*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
664*0Sstevel@tonic-gate 			    "rsm_get_controller: exit\n"));
665*0Sstevel@tonic-gate 			return (RSM_SUCCESS);
666*0Sstevel@tonic-gate 		}
667*0Sstevel@tonic-gate 	}
668*0Sstevel@tonic-gate 
669*0Sstevel@tonic-gate 
670*0Sstevel@tonic-gate 	if (!strcasecmp(cntr_type, LOOPBACK)) {
671*0Sstevel@tonic-gate 		e = _rsm_loopbackload(cntr_type, unit,
672*0Sstevel@tonic-gate 		    (rsm_controller_t **)chdl);
673*0Sstevel@tonic-gate 	} else {
674*0Sstevel@tonic-gate 		e = _rsm_modload(cntr_type, unit, chdl);
675*0Sstevel@tonic-gate 	}
676*0Sstevel@tonic-gate 
677*0Sstevel@tonic-gate 	mutex_unlock(&_rsm_lock);
678*0Sstevel@tonic-gate 
679*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
680*0Sstevel@tonic-gate 	    " rsm_get_controller: exit\n"));
681*0Sstevel@tonic-gate 	return (e);
682*0Sstevel@tonic-gate }
683*0Sstevel@tonic-gate 
684*0Sstevel@tonic-gate int
685*0Sstevel@tonic-gate _rsm_release_controller(rsmapi_controller_handle_t cntr_handle)
686*0Sstevel@tonic-gate {
687*0Sstevel@tonic-gate 	int			e = RSM_SUCCESS;
688*0Sstevel@tonic-gate 	rsm_controller_t	*chdl = (rsm_controller_t *)cntr_handle;
689*0Sstevel@tonic-gate 	rsm_controller_t	*curr, *prev;
690*0Sstevel@tonic-gate 
691*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
692*0Sstevel@tonic-gate 	    "rsm_release_controller: enter\n"));
693*0Sstevel@tonic-gate 
694*0Sstevel@tonic-gate 	mutex_lock(&_rsm_lock);
695*0Sstevel@tonic-gate 
696*0Sstevel@tonic-gate 	if (chdl->cntr_refcnt == 0) {
697*0Sstevel@tonic-gate 		mutex_unlock(&_rsm_lock);
698*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
699*0Sstevel@tonic-gate 		    "controller reference count is zero\n"));
700*0Sstevel@tonic-gate 		return (RSMERR_BAD_CTLR_HNDL);
701*0Sstevel@tonic-gate 	}
702*0Sstevel@tonic-gate 
703*0Sstevel@tonic-gate 	chdl->cntr_refcnt--;
704*0Sstevel@tonic-gate 
705*0Sstevel@tonic-gate 	if (chdl->cntr_refcnt > 0) {
706*0Sstevel@tonic-gate 		mutex_unlock(&_rsm_lock);
707*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
708*0Sstevel@tonic-gate 		    "rsm_release_controller: exit\n"));
709*0Sstevel@tonic-gate 		return (RSM_SUCCESS);
710*0Sstevel@tonic-gate 	}
711*0Sstevel@tonic-gate 
712*0Sstevel@tonic-gate 	e = chdl->cntr_segops->rsm_closedevice(cntr_handle);
713*0Sstevel@tonic-gate 
714*0Sstevel@tonic-gate 	/*
715*0Sstevel@tonic-gate 	 * remove the controller in any case from the controller list
716*0Sstevel@tonic-gate 	 */
717*0Sstevel@tonic-gate 
718*0Sstevel@tonic-gate 	prev = curr = controller_list;
719*0Sstevel@tonic-gate 	while (curr != NULL) {
720*0Sstevel@tonic-gate 		if (curr == chdl) {
721*0Sstevel@tonic-gate 			if (curr == prev) {
722*0Sstevel@tonic-gate 				controller_list = curr->cntr_next;
723*0Sstevel@tonic-gate 			} else {
724*0Sstevel@tonic-gate 				prev->cntr_next = curr->cntr_next;
725*0Sstevel@tonic-gate 			}
726*0Sstevel@tonic-gate 			free(curr);
727*0Sstevel@tonic-gate 			break;
728*0Sstevel@tonic-gate 		}
729*0Sstevel@tonic-gate 		prev = curr;
730*0Sstevel@tonic-gate 		curr = curr->cntr_next;
731*0Sstevel@tonic-gate 	}
732*0Sstevel@tonic-gate 	mutex_unlock(&_rsm_lock);
733*0Sstevel@tonic-gate 
734*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
735*0Sstevel@tonic-gate 	    "rsm_release_controller: exit\n"));
736*0Sstevel@tonic-gate 
737*0Sstevel@tonic-gate 	return (e);
738*0Sstevel@tonic-gate }
739*0Sstevel@tonic-gate 
740*0Sstevel@tonic-gate int _rsm_get_controller_attr(rsmapi_controller_handle_t chandle,
741*0Sstevel@tonic-gate     rsmapi_controller_attr_t *attr)
742*0Sstevel@tonic-gate {
743*0Sstevel@tonic-gate 	rsm_controller_t *p;
744*0Sstevel@tonic-gate 
745*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
746*0Sstevel@tonic-gate 	    "rsm_get_controller_attr: enter\n"));
747*0Sstevel@tonic-gate 
748*0Sstevel@tonic-gate 	if (!chandle) {
749*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
750*0Sstevel@tonic-gate 		    "invalid controller handle\n"));
751*0Sstevel@tonic-gate 		return (RSMERR_BAD_CTLR_HNDL);
752*0Sstevel@tonic-gate 	}
753*0Sstevel@tonic-gate 
754*0Sstevel@tonic-gate 	if (!attr) {
755*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
756*0Sstevel@tonic-gate 		    "invalid attribute pointer\n"));
757*0Sstevel@tonic-gate 		return (RSMERR_BAD_ADDR);
758*0Sstevel@tonic-gate 	}
759*0Sstevel@tonic-gate 
760*0Sstevel@tonic-gate 	p = (rsm_controller_t *)chandle;
761*0Sstevel@tonic-gate 
762*0Sstevel@tonic-gate 	mutex_lock(&_rsm_lock);
763*0Sstevel@tonic-gate 	if (p->cntr_refcnt == 0) {
764*0Sstevel@tonic-gate 		mutex_unlock(&_rsm_lock);
765*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
766*0Sstevel@tonic-gate 		    "cntr refcnt is 0\n"));
767*0Sstevel@tonic-gate 		return (RSMERR_CTLR_NOT_PRESENT);
768*0Sstevel@tonic-gate 	}
769*0Sstevel@tonic-gate 
770*0Sstevel@tonic-gate 	/* copy only the user part of the attr structure */
771*0Sstevel@tonic-gate 	attr->attr_direct_access_sizes =
772*0Sstevel@tonic-gate 	    p->cntr_attr.attr_direct_access_sizes;
773*0Sstevel@tonic-gate 	attr->attr_atomic_sizes =
774*0Sstevel@tonic-gate 	    p->cntr_attr.attr_atomic_sizes;
775*0Sstevel@tonic-gate 	attr->attr_page_size =
776*0Sstevel@tonic-gate 	    p->cntr_attr.attr_page_size;
777*0Sstevel@tonic-gate 	attr->attr_max_export_segment_size =
778*0Sstevel@tonic-gate 	    p->cntr_attr.attr_max_export_segment_size;
779*0Sstevel@tonic-gate 	attr->attr_tot_export_segment_size =
780*0Sstevel@tonic-gate 	    p->cntr_attr.attr_tot_export_segment_size;
781*0Sstevel@tonic-gate 	attr->attr_max_export_segments =
782*0Sstevel@tonic-gate 	    p->cntr_attr.attr_max_export_segments;
783*0Sstevel@tonic-gate 	attr->attr_max_import_map_size =
784*0Sstevel@tonic-gate 	    p->cntr_attr.attr_max_import_map_size;
785*0Sstevel@tonic-gate 	attr->attr_tot_import_map_size =
786*0Sstevel@tonic-gate 	    p->cntr_attr.attr_tot_import_map_size;
787*0Sstevel@tonic-gate 	attr->attr_max_import_segments =
788*0Sstevel@tonic-gate 	    p->cntr_attr.attr_max_import_segments;
789*0Sstevel@tonic-gate 
790*0Sstevel@tonic-gate 	mutex_unlock(&_rsm_lock);
791*0Sstevel@tonic-gate 
792*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
793*0Sstevel@tonic-gate 	    "rsm_get_controller_attr: exit\n"));
794*0Sstevel@tonic-gate 
795*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
796*0Sstevel@tonic-gate }
797*0Sstevel@tonic-gate 
798*0Sstevel@tonic-gate 
799*0Sstevel@tonic-gate 
800*0Sstevel@tonic-gate /*
801*0Sstevel@tonic-gate  * Create a segment handle for the virtual address range specified
802*0Sstevel@tonic-gate  * by vaddr and size
803*0Sstevel@tonic-gate  */
804*0Sstevel@tonic-gate int
805*0Sstevel@tonic-gate _rsm_memseg_export_create(rsmapi_controller_handle_t controller,
806*0Sstevel@tonic-gate     rsm_memseg_export_handle_t *memseg,
807*0Sstevel@tonic-gate     void *vaddr,
808*0Sstevel@tonic-gate     size_t length,
809*0Sstevel@tonic-gate     uint_t flags)
810*0Sstevel@tonic-gate {
811*0Sstevel@tonic-gate 
812*0Sstevel@tonic-gate 	rsm_controller_t *chdl = (rsm_controller_t *)controller;
813*0Sstevel@tonic-gate 	rsmseg_handle_t *p;
814*0Sstevel@tonic-gate 	rsm_ioctlmsg_t msg;
815*0Sstevel@tonic-gate 	int e;
816*0Sstevel@tonic-gate #ifndef	_LP64
817*0Sstevel@tonic-gate 	int tmpfd;
818*0Sstevel@tonic-gate #endif
819*0Sstevel@tonic-gate 
820*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE,
821*0Sstevel@tonic-gate 	    "rsm_memseg_export_create: enter\n"));
822*0Sstevel@tonic-gate 
823*0Sstevel@tonic-gate 	if (!controller) {
824*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
825*0Sstevel@tonic-gate 		    "invalid controller handle\n"));
826*0Sstevel@tonic-gate 		return (RSMERR_BAD_CTLR_HNDL);
827*0Sstevel@tonic-gate 	}
828*0Sstevel@tonic-gate 	if (!memseg) {
829*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
830*0Sstevel@tonic-gate 		    "invalid segment handle\n"));
831*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
832*0Sstevel@tonic-gate 	}
833*0Sstevel@tonic-gate 
834*0Sstevel@tonic-gate 	*memseg = 0;
835*0Sstevel@tonic-gate 
836*0Sstevel@tonic-gate 	/*
837*0Sstevel@tonic-gate 	 * Check vaddr and size alignment, both must be mmu page size
838*0Sstevel@tonic-gate 	 * aligned
839*0Sstevel@tonic-gate 	 */
840*0Sstevel@tonic-gate 	if (!vaddr) {
841*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
842*0Sstevel@tonic-gate 		    "invalid arguments\n"));
843*0Sstevel@tonic-gate 		return (RSMERR_BAD_ADDR);
844*0Sstevel@tonic-gate 	}
845*0Sstevel@tonic-gate 
846*0Sstevel@tonic-gate 	if (!length) {
847*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
848*0Sstevel@tonic-gate 		    "invalid arguments\n"));
849*0Sstevel@tonic-gate 		return (RSMERR_BAD_LENGTH);
850*0Sstevel@tonic-gate 	}
851*0Sstevel@tonic-gate 
852*0Sstevel@tonic-gate 	if (((size_t)vaddr & (PAGESIZE - 1)) ||
853*0Sstevel@tonic-gate 		(length & (PAGESIZE - 1))) {
854*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
855*0Sstevel@tonic-gate 		    "invalid mem alignment for vaddr or length\n"));
856*0Sstevel@tonic-gate 		return (RSMERR_BAD_MEM_ALIGNMENT);
857*0Sstevel@tonic-gate 	}
858*0Sstevel@tonic-gate 
859*0Sstevel@tonic-gate 	/*
860*0Sstevel@tonic-gate 	 * The following check does not apply for loopback controller
861*0Sstevel@tonic-gate 	 * since for the loopback adapter, the attr_max_export_segment_size
862*0Sstevel@tonic-gate 	 * is always 0.
863*0Sstevel@tonic-gate 	 */
864*0Sstevel@tonic-gate 	if (strcasecmp(chdl->cntr_name, LOOPBACK)) {
865*0Sstevel@tonic-gate 		if (length > chdl->cntr_attr.attr_max_export_segment_size) {
866*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY, RSM_ERR,
867*0Sstevel@tonic-gate 			    "length exceeds controller limits\n"));
868*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY, RSM_ERR,
869*0Sstevel@tonic-gate 			    "controller limits %d\n",
870*0Sstevel@tonic-gate 			    chdl->cntr_attr.attr_max_export_segment_size));
871*0Sstevel@tonic-gate 			return (RSMERR_BAD_LENGTH);
872*0Sstevel@tonic-gate 		}
873*0Sstevel@tonic-gate 	}
874*0Sstevel@tonic-gate 
875*0Sstevel@tonic-gate 	p = (rsmseg_handle_t *)malloc(sizeof (*p));
876*0Sstevel@tonic-gate 	if (p == NULL) {
877*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
878*0Sstevel@tonic-gate 		    "not enough memory\n"));
879*0Sstevel@tonic-gate 		return (RSMERR_INSUFFICIENT_MEM);
880*0Sstevel@tonic-gate 	}
881*0Sstevel@tonic-gate 
882*0Sstevel@tonic-gate 	p->rsmseg_fd = open(DEVRSM, O_RDWR);
883*0Sstevel@tonic-gate 	if (p->rsmseg_fd < 0) {
884*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
885*0Sstevel@tonic-gate 		    "unable to open device /dev/rsm\n"));
886*0Sstevel@tonic-gate 		free((void *)p);
887*0Sstevel@tonic-gate 		return (RSMERR_INSUFFICIENT_RESOURCES);
888*0Sstevel@tonic-gate 	}
889*0Sstevel@tonic-gate 
890*0Sstevel@tonic-gate #ifndef	_LP64
891*0Sstevel@tonic-gate 	/*
892*0Sstevel@tonic-gate 	 * libc can't handle fd's greater than 255,  in order to
893*0Sstevel@tonic-gate 	 * insure that these values remain available make /dev/rsm
894*0Sstevel@tonic-gate 	 * fd > 255. Note: not needed for LP64
895*0Sstevel@tonic-gate 	 */
896*0Sstevel@tonic-gate 	tmpfd = fcntl(p->rsmseg_fd, F_DUPFD, 256);
897*0Sstevel@tonic-gate 	e = errno;
898*0Sstevel@tonic-gate 	if (tmpfd < 0) {
899*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
900*0Sstevel@tonic-gate 		    "F_DUPFD failed\n"));
901*0Sstevel@tonic-gate 	} else {
902*0Sstevel@tonic-gate 		(void) close(p->rsmseg_fd);
903*0Sstevel@tonic-gate 		p->rsmseg_fd = tmpfd;
904*0Sstevel@tonic-gate 	}
905*0Sstevel@tonic-gate #endif	/*	_LP64	*/
906*0Sstevel@tonic-gate 
907*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, ""
908*0Sstevel@tonic-gate 	    "rsmseg_fd is %d\n", p->rsmseg_fd));
909*0Sstevel@tonic-gate 
910*0Sstevel@tonic-gate 	if (fcntl(p->rsmseg_fd, F_SETFD, FD_CLOEXEC) < 0) {
911*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
912*0Sstevel@tonic-gate 		    "F_SETFD failed\n"));
913*0Sstevel@tonic-gate 	}
914*0Sstevel@tonic-gate 
915*0Sstevel@tonic-gate 	p->rsmseg_state = EXPORT_CREATE;
916*0Sstevel@tonic-gate 	p->rsmseg_size = length;
917*0Sstevel@tonic-gate 	/* increment controller handle */
918*0Sstevel@tonic-gate 	p->rsmseg_controller = chdl;
919*0Sstevel@tonic-gate 
920*0Sstevel@tonic-gate 	/* try to bind user address range */
921*0Sstevel@tonic-gate 	msg.cnum = chdl->cntr_unit;
922*0Sstevel@tonic-gate 	msg.cname = chdl->cntr_name;
923*0Sstevel@tonic-gate 	msg.cname_len = strlen(chdl->cntr_name) +1;
924*0Sstevel@tonic-gate 	msg.vaddr = vaddr;
925*0Sstevel@tonic-gate 	msg.len = length;
926*0Sstevel@tonic-gate 	msg.perm = flags;
927*0Sstevel@tonic-gate 	msg.off = 0;
928*0Sstevel@tonic-gate 	e = RSM_IOCTL_BIND;
929*0Sstevel@tonic-gate 
930*0Sstevel@tonic-gate 	/* Try to bind */
931*0Sstevel@tonic-gate 	if (ioctl(p->rsmseg_fd, e, &msg) < 0) {
932*0Sstevel@tonic-gate 		e = errno;
933*0Sstevel@tonic-gate 		(void) close(p->rsmseg_fd);
934*0Sstevel@tonic-gate 		free((void *)p);
935*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
936*0Sstevel@tonic-gate 		    "RSM_IOCTL_BIND failed\n"));
937*0Sstevel@tonic-gate 		return (e);
938*0Sstevel@tonic-gate 	}
939*0Sstevel@tonic-gate 	/* OK */
940*0Sstevel@tonic-gate 	p->rsmseg_type = RSM_EXPORT_SEG;
941*0Sstevel@tonic-gate 	p->rsmseg_vaddr = vaddr;
942*0Sstevel@tonic-gate 	p->rsmseg_size = length;
943*0Sstevel@tonic-gate 	p->rsmseg_state = EXPORT_BIND;
944*0Sstevel@tonic-gate 	p->rsmseg_pollfd_refcnt = 0;
945*0Sstevel@tonic-gate 	p->rsmseg_rnum = msg.rnum;
946*0Sstevel@tonic-gate 
947*0Sstevel@tonic-gate 	mutex_init(&p->rsmseg_lock, USYNC_THREAD, NULL);
948*0Sstevel@tonic-gate 
949*0Sstevel@tonic-gate 	*memseg = (rsm_memseg_export_handle_t)p;
950*0Sstevel@tonic-gate 
951*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE,
952*0Sstevel@tonic-gate 	    "rsm_memseg_export_create: exit\n"));
953*0Sstevel@tonic-gate 
954*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
955*0Sstevel@tonic-gate }
956*0Sstevel@tonic-gate 
957*0Sstevel@tonic-gate int
958*0Sstevel@tonic-gate _rsm_memseg_export_destroy(rsm_memseg_export_handle_t memseg)
959*0Sstevel@tonic-gate {
960*0Sstevel@tonic-gate 	rsmseg_handle_t *seg;
961*0Sstevel@tonic-gate 
962*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE,
963*0Sstevel@tonic-gate 	    "rsm_memseg_export_destroy: enter\n"));
964*0Sstevel@tonic-gate 
965*0Sstevel@tonic-gate 	if (!memseg) {
966*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
967*0Sstevel@tonic-gate 		    "invalid segment handle\n"));
968*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
969*0Sstevel@tonic-gate 	}
970*0Sstevel@tonic-gate 
971*0Sstevel@tonic-gate 	seg = (rsmseg_handle_t *)memseg;
972*0Sstevel@tonic-gate 
973*0Sstevel@tonic-gate 	mutex_lock(&seg->rsmseg_lock);
974*0Sstevel@tonic-gate 	if (seg->rsmseg_pollfd_refcnt) {
975*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
976*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
977*0Sstevel@tonic-gate 		    "segment reference count not zero\n"));
978*0Sstevel@tonic-gate 		return (RSMERR_POLLFD_IN_USE);
979*0Sstevel@tonic-gate 	}
980*0Sstevel@tonic-gate 	else
981*0Sstevel@tonic-gate 		seg->rsmseg_state = EXPORT_BIND;
982*0Sstevel@tonic-gate 
983*0Sstevel@tonic-gate 	mutex_unlock(&seg->rsmseg_lock);
984*0Sstevel@tonic-gate 
985*0Sstevel@tonic-gate 	(void) close(seg->rsmseg_fd);
986*0Sstevel@tonic-gate 	mutex_destroy(&seg->rsmseg_lock);
987*0Sstevel@tonic-gate 	free((void *)seg);
988*0Sstevel@tonic-gate 
989*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE,
990*0Sstevel@tonic-gate 	    "rsm_memseg_export_destroy: exit\n"));
991*0Sstevel@tonic-gate 
992*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
993*0Sstevel@tonic-gate }
994*0Sstevel@tonic-gate 
995*0Sstevel@tonic-gate int
996*0Sstevel@tonic-gate _rsm_memseg_export_rebind(rsm_memseg_export_handle_t memseg, void *vaddr,
997*0Sstevel@tonic-gate     offset_t off, size_t length)
998*0Sstevel@tonic-gate {
999*0Sstevel@tonic-gate 	rsm_ioctlmsg_t msg;
1000*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg;
1001*0Sstevel@tonic-gate 
1002*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE,
1003*0Sstevel@tonic-gate 	    "rsm_memseg_export_rebind: enter\n"));
1004*0Sstevel@tonic-gate 
1005*0Sstevel@tonic-gate 	off = off;
1006*0Sstevel@tonic-gate 
1007*0Sstevel@tonic-gate 	if (!seg) {
1008*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1009*0Sstevel@tonic-gate 		    "invalid segment handle\n"));
1010*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
1011*0Sstevel@tonic-gate 	}
1012*0Sstevel@tonic-gate 	if (!vaddr) {
1013*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1014*0Sstevel@tonic-gate 		    "invalid vaddr\n"));
1015*0Sstevel@tonic-gate 		return (RSMERR_BAD_ADDR);
1016*0Sstevel@tonic-gate 	}
1017*0Sstevel@tonic-gate 
1018*0Sstevel@tonic-gate 	/*
1019*0Sstevel@tonic-gate 	 * Same as bind except it's ok to have elimint in list.
1020*0Sstevel@tonic-gate 	 * Call into driver to remove any existing mappings.
1021*0Sstevel@tonic-gate 	 */
1022*0Sstevel@tonic-gate 	msg.vaddr = vaddr;
1023*0Sstevel@tonic-gate 	msg.len = length;
1024*0Sstevel@tonic-gate 	msg.off = 0;
1025*0Sstevel@tonic-gate 
1026*0Sstevel@tonic-gate 	mutex_lock(&seg->rsmseg_lock);
1027*0Sstevel@tonic-gate 	if (ioctl(seg->rsmseg_fd, RSM_IOCTL_REBIND, &msg) < 0) {
1028*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
1029*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1030*0Sstevel@tonic-gate 		    "RSM_IOCTL_REBIND failed\n"));
1031*0Sstevel@tonic-gate 		return (errno);
1032*0Sstevel@tonic-gate 	}
1033*0Sstevel@tonic-gate 
1034*0Sstevel@tonic-gate 	mutex_unlock(&seg->rsmseg_lock);
1035*0Sstevel@tonic-gate 
1036*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE,
1037*0Sstevel@tonic-gate 	    "rsm_memseg_export_rebind: exit\n"));
1038*0Sstevel@tonic-gate 
1039*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
1040*0Sstevel@tonic-gate }
1041*0Sstevel@tonic-gate 
1042*0Sstevel@tonic-gate int
1043*0Sstevel@tonic-gate _rsm_memseg_export_publish(rsm_memseg_export_handle_t memseg,
1044*0Sstevel@tonic-gate     rsm_memseg_id_t *seg_id,
1045*0Sstevel@tonic-gate     rsmapi_access_entry_t access_list[],
1046*0Sstevel@tonic-gate     uint_t access_list_length)
1047*0Sstevel@tonic-gate 
1048*0Sstevel@tonic-gate {
1049*0Sstevel@tonic-gate 	rsm_ioctlmsg_t msg;
1050*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg;
1051*0Sstevel@tonic-gate 
1052*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE,
1053*0Sstevel@tonic-gate 	    "rsm_memseg_export_publish: enter\n"));
1054*0Sstevel@tonic-gate 
1055*0Sstevel@tonic-gate 	if (seg_id == NULL) {
1056*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1057*0Sstevel@tonic-gate 		    "invalid segment id\n"));
1058*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEGID);
1059*0Sstevel@tonic-gate 	}
1060*0Sstevel@tonic-gate 
1061*0Sstevel@tonic-gate 	if (!seg) {
1062*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1063*0Sstevel@tonic-gate 		    "invalid segment handle\n"));
1064*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
1065*0Sstevel@tonic-gate 	}
1066*0Sstevel@tonic-gate 
1067*0Sstevel@tonic-gate 	if (access_list_length > 0 && !access_list) {
1068*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1069*0Sstevel@tonic-gate 		    "invalid access control list\n"));
1070*0Sstevel@tonic-gate 		return (RSMERR_BAD_ACL);
1071*0Sstevel@tonic-gate 	}
1072*0Sstevel@tonic-gate 
1073*0Sstevel@tonic-gate 	mutex_lock(&seg->rsmseg_lock);
1074*0Sstevel@tonic-gate 	if (seg->rsmseg_state != EXPORT_BIND) {
1075*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
1076*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1077*0Sstevel@tonic-gate 		    "invalid segment state\n"));
1078*0Sstevel@tonic-gate 		return (RSMERR_SEG_ALREADY_PUBLISHED);
1079*0Sstevel@tonic-gate 	}
1080*0Sstevel@tonic-gate 
1081*0Sstevel@tonic-gate 	/*
1082*0Sstevel@tonic-gate 	 * seg id < RSM_DLPI_END and in the RSM_USER_APP_ID range
1083*0Sstevel@tonic-gate 	 * are reserved for internal use.
1084*0Sstevel@tonic-gate 	 */
1085*0Sstevel@tonic-gate 	if ((*seg_id > 0) &&
1086*0Sstevel@tonic-gate 	    ((*seg_id <= RSM_DLPI_ID_END) ||
1087*0Sstevel@tonic-gate 	    BETWEEN (*seg_id, RSM_USER_APP_ID_BASE, RSM_USER_APP_ID_END))) {
1088*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
1089*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1090*0Sstevel@tonic-gate 		    "invalid segment id\n"));
1091*0Sstevel@tonic-gate 		return (RSMERR_RESERVED_SEGID);
1092*0Sstevel@tonic-gate 	}
1093*0Sstevel@tonic-gate 
1094*0Sstevel@tonic-gate 	msg.key = *seg_id;
1095*0Sstevel@tonic-gate 	msg.acl = access_list;
1096*0Sstevel@tonic-gate 	msg.acl_len = access_list_length;
1097*0Sstevel@tonic-gate 
1098*0Sstevel@tonic-gate 	if (ioctl(seg->rsmseg_fd, RSM_IOCTL_PUBLISH, &msg) < 0) {
1099*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
1100*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1101*0Sstevel@tonic-gate 		    "RSM_IOCTL_PUBLISH failed\n"));
1102*0Sstevel@tonic-gate 		return (errno);
1103*0Sstevel@tonic-gate 	}
1104*0Sstevel@tonic-gate 
1105*0Sstevel@tonic-gate 	seg->rsmseg_keyid = msg.key;
1106*0Sstevel@tonic-gate 	seg->rsmseg_state = EXPORT_PUBLISH;
1107*0Sstevel@tonic-gate 	mutex_unlock(&seg->rsmseg_lock);
1108*0Sstevel@tonic-gate 
1109*0Sstevel@tonic-gate 	if (*seg_id == 0)
1110*0Sstevel@tonic-gate 		*seg_id = msg.key;
1111*0Sstevel@tonic-gate 
1112*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE,
1113*0Sstevel@tonic-gate 	    "rsm_memseg_export_publish: exit\n"));
1114*0Sstevel@tonic-gate 
1115*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
1116*0Sstevel@tonic-gate 
1117*0Sstevel@tonic-gate }
1118*0Sstevel@tonic-gate 
1119*0Sstevel@tonic-gate int
1120*0Sstevel@tonic-gate _rsm_memseg_export_unpublish(rsm_memseg_export_handle_t memseg)
1121*0Sstevel@tonic-gate {
1122*0Sstevel@tonic-gate 	rsm_ioctlmsg_t msg;
1123*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg;
1124*0Sstevel@tonic-gate 
1125*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE,
1126*0Sstevel@tonic-gate 	    "rsm_memseg_export_unpublish: enter\n"));
1127*0Sstevel@tonic-gate 
1128*0Sstevel@tonic-gate 	if (!seg) {
1129*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1130*0Sstevel@tonic-gate 		    "invalid arguments\n"));
1131*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
1132*0Sstevel@tonic-gate 	}
1133*0Sstevel@tonic-gate 
1134*0Sstevel@tonic-gate 	mutex_lock(&seg->rsmseg_lock);
1135*0Sstevel@tonic-gate 	if (seg->rsmseg_state != EXPORT_PUBLISH) {
1136*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
1137*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1138*0Sstevel@tonic-gate 		    "segment not published %d\n",
1139*0Sstevel@tonic-gate 			seg->rsmseg_keyid));
1140*0Sstevel@tonic-gate 		return (RSMERR_SEG_NOT_PUBLISHED);
1141*0Sstevel@tonic-gate 	}
1142*0Sstevel@tonic-gate 
1143*0Sstevel@tonic-gate 	msg.key = seg->rsmseg_keyid;
1144*0Sstevel@tonic-gate 	if (ioctl(seg->rsmseg_fd, RSM_IOCTL_UNPUBLISH, &msg) < 0) {
1145*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
1146*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1147*0Sstevel@tonic-gate 		    "RSM_IOCTL_UNPUBLISH failed\n"));
1148*0Sstevel@tonic-gate 		return (errno);
1149*0Sstevel@tonic-gate 	}
1150*0Sstevel@tonic-gate 
1151*0Sstevel@tonic-gate 	seg->rsmseg_state = EXPORT_BIND;
1152*0Sstevel@tonic-gate 	mutex_unlock(&seg->rsmseg_lock);
1153*0Sstevel@tonic-gate 
1154*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE,
1155*0Sstevel@tonic-gate 	    "rsm_memseg_export_unpublish: exit\n"));
1156*0Sstevel@tonic-gate 
1157*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
1158*0Sstevel@tonic-gate }
1159*0Sstevel@tonic-gate 
1160*0Sstevel@tonic-gate 
1161*0Sstevel@tonic-gate int
1162*0Sstevel@tonic-gate _rsm_memseg_export_republish(rsm_memseg_export_handle_t memseg,
1163*0Sstevel@tonic-gate     rsmapi_access_entry_t access_list[],
1164*0Sstevel@tonic-gate     uint_t access_list_length)
1165*0Sstevel@tonic-gate {
1166*0Sstevel@tonic-gate 	rsm_ioctlmsg_t msg;
1167*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg;
1168*0Sstevel@tonic-gate 
1169*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE,
1170*0Sstevel@tonic-gate 	    "rsm_memseg_export_republish: enter\n"));
1171*0Sstevel@tonic-gate 
1172*0Sstevel@tonic-gate 	if (!seg) {
1173*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1174*0Sstevel@tonic-gate 		    "invalid segment or segment state\n"));
1175*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
1176*0Sstevel@tonic-gate 	}
1177*0Sstevel@tonic-gate 
1178*0Sstevel@tonic-gate 	mutex_lock(&seg->rsmseg_lock);
1179*0Sstevel@tonic-gate 	if (seg->rsmseg_state != EXPORT_PUBLISH) {
1180*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
1181*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1182*0Sstevel@tonic-gate 		    "segment not published\n"));
1183*0Sstevel@tonic-gate 		return (RSMERR_SEG_NOT_PUBLISHED);
1184*0Sstevel@tonic-gate 	}
1185*0Sstevel@tonic-gate 
1186*0Sstevel@tonic-gate 	if (access_list_length > 0 && !access_list) {
1187*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
1188*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1189*0Sstevel@tonic-gate 		    "invalid access control list\n"));
1190*0Sstevel@tonic-gate 		return (RSMERR_BAD_ACL);
1191*0Sstevel@tonic-gate 	}
1192*0Sstevel@tonic-gate 
1193*0Sstevel@tonic-gate 	msg.key = seg->rsmseg_keyid;
1194*0Sstevel@tonic-gate 	msg.acl = access_list;
1195*0Sstevel@tonic-gate 	msg.acl_len = access_list_length;
1196*0Sstevel@tonic-gate 
1197*0Sstevel@tonic-gate 	if (ioctl(seg->rsmseg_fd, RSM_IOCTL_REPUBLISH, &msg) < 0) {
1198*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
1199*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1200*0Sstevel@tonic-gate 		    "RSM_IOCTL_REPUBLISH failed\n"));
1201*0Sstevel@tonic-gate 		return (errno);
1202*0Sstevel@tonic-gate 	}
1203*0Sstevel@tonic-gate 	mutex_unlock(&seg->rsmseg_lock);
1204*0Sstevel@tonic-gate 
1205*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE,
1206*0Sstevel@tonic-gate 	    "rsm_memseg_export_republish: exit\n"));
1207*0Sstevel@tonic-gate 
1208*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
1209*0Sstevel@tonic-gate }
1210*0Sstevel@tonic-gate 
1211*0Sstevel@tonic-gate 
1212*0Sstevel@tonic-gate 	/*
1213*0Sstevel@tonic-gate 	 * import side memory segment operations:
1214*0Sstevel@tonic-gate 	 */
1215*0Sstevel@tonic-gate int
1216*0Sstevel@tonic-gate _rsm_memseg_import_connect(rsmapi_controller_handle_t controller,
1217*0Sstevel@tonic-gate     rsm_node_id_t node_id,
1218*0Sstevel@tonic-gate     rsm_memseg_id_t segment_id,
1219*0Sstevel@tonic-gate     rsm_permission_t perm,
1220*0Sstevel@tonic-gate     rsm_memseg_import_handle_t *im_memseg)
1221*0Sstevel@tonic-gate {
1222*0Sstevel@tonic-gate 	rsm_ioctlmsg_t msg;
1223*0Sstevel@tonic-gate 	rsmseg_handle_t *p;
1224*0Sstevel@tonic-gate 	rsm_controller_t *cntr = (rsm_controller_t *)controller;
1225*0Sstevel@tonic-gate #ifndef	_LP64		/* added for fd > 255 fix */
1226*0Sstevel@tonic-gate 	int tmpfd;
1227*0Sstevel@tonic-gate #endif
1228*0Sstevel@tonic-gate 	int e;
1229*0Sstevel@tonic-gate 
1230*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1231*0Sstevel@tonic-gate 	    "rsm_memseg_import_connect: enter\n"));
1232*0Sstevel@tonic-gate 
1233*0Sstevel@tonic-gate 	if (!cntr) {
1234*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1235*0Sstevel@tonic-gate 		    "invalid controller handle\n"));
1236*0Sstevel@tonic-gate 		return (RSMERR_BAD_CTLR_HNDL);
1237*0Sstevel@tonic-gate 	}
1238*0Sstevel@tonic-gate 
1239*0Sstevel@tonic-gate 	*im_memseg = 0;
1240*0Sstevel@tonic-gate 
1241*0Sstevel@tonic-gate 	p = (rsmseg_handle_t *)malloc(sizeof (*p));
1242*0Sstevel@tonic-gate 	if (!p) {
1243*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1244*0Sstevel@tonic-gate 		    "not enough memory\n"));
1245*0Sstevel@tonic-gate 		return (RSMERR_INSUFFICIENT_MEM);
1246*0Sstevel@tonic-gate 	}
1247*0Sstevel@tonic-gate 
1248*0Sstevel@tonic-gate 	if (perm & ~RSM_PERM_RDWR) {
1249*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1250*0Sstevel@tonic-gate 		    "invalid permissions\n"));
1251*0Sstevel@tonic-gate 		return (RSMERR_PERM_DENIED);
1252*0Sstevel@tonic-gate 	}
1253*0Sstevel@tonic-gate 
1254*0Sstevel@tonic-gate 	/*
1255*0Sstevel@tonic-gate 	 * Get size, va from driver
1256*0Sstevel@tonic-gate 	 */
1257*0Sstevel@tonic-gate 	msg.cnum = cntr->cntr_unit;
1258*0Sstevel@tonic-gate 	msg.cname = cntr->cntr_name;
1259*0Sstevel@tonic-gate 	msg.cname_len = strlen(cntr->cntr_name) +1;
1260*0Sstevel@tonic-gate 	msg.nodeid = node_id;
1261*0Sstevel@tonic-gate 	msg.key = segment_id;
1262*0Sstevel@tonic-gate 	msg.perm = perm;
1263*0Sstevel@tonic-gate 
1264*0Sstevel@tonic-gate 	p->rsmseg_fd = open(DEVRSM, O_RDWR);
1265*0Sstevel@tonic-gate 	if (p->rsmseg_fd < 0) {
1266*0Sstevel@tonic-gate 		    DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1267*0Sstevel@tonic-gate 			"unable to open /dev/rsm"));
1268*0Sstevel@tonic-gate 		free((void *)p);
1269*0Sstevel@tonic-gate 		return (RSMERR_INSUFFICIENT_RESOURCES);
1270*0Sstevel@tonic-gate 	}
1271*0Sstevel@tonic-gate 
1272*0Sstevel@tonic-gate #ifndef	_LP64
1273*0Sstevel@tonic-gate 	/*
1274*0Sstevel@tonic-gate 	 * libc can't handle fd's greater than 255,  in order to
1275*0Sstevel@tonic-gate 	 * insure that these values remain available make /dev/rsm
1276*0Sstevel@tonic-gate 	 * fd > 255. Note: not needed for LP64
1277*0Sstevel@tonic-gate 	 */
1278*0Sstevel@tonic-gate 	tmpfd = fcntl(p->rsmseg_fd, F_DUPFD, 256); /* make fd > 255 */
1279*0Sstevel@tonic-gate 	e = errno;
1280*0Sstevel@tonic-gate 	if (tmpfd < 0) {
1281*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1282*0Sstevel@tonic-gate 		    "F_DUPFD failed\n"));
1283*0Sstevel@tonic-gate 	} else {
1284*0Sstevel@tonic-gate 		(void) close(p->rsmseg_fd);
1285*0Sstevel@tonic-gate 		p->rsmseg_fd = tmpfd;
1286*0Sstevel@tonic-gate 	}
1287*0Sstevel@tonic-gate #endif	/* _LP64 */
1288*0Sstevel@tonic-gate 
1289*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
1290*0Sstevel@tonic-gate 	    "rsmseg_fd is %d\n", p->rsmseg_fd));
1291*0Sstevel@tonic-gate 
1292*0Sstevel@tonic-gate 	if (fcntl(p->rsmseg_fd, F_SETFD, FD_CLOEXEC) < 0) {
1293*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1294*0Sstevel@tonic-gate 		    "F_SETFD failed\n"));
1295*0Sstevel@tonic-gate 	}
1296*0Sstevel@tonic-gate 	if (ioctl(p->rsmseg_fd, RSM_IOCTL_CONNECT, &msg) < 0) {
1297*0Sstevel@tonic-gate 		e = errno;
1298*0Sstevel@tonic-gate 		(void) close(p->rsmseg_fd);
1299*0Sstevel@tonic-gate 		free((void *)p);
1300*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1301*0Sstevel@tonic-gate 		    "RSM_IOCTL_CONNECT failed\n"));
1302*0Sstevel@tonic-gate 		return (e);
1303*0Sstevel@tonic-gate 	}
1304*0Sstevel@tonic-gate 
1305*0Sstevel@tonic-gate 	/*
1306*0Sstevel@tonic-gate 	 * We connected ok.
1307*0Sstevel@tonic-gate 	 */
1308*0Sstevel@tonic-gate 	p->rsmseg_type = RSM_IMPORT_SEG;
1309*0Sstevel@tonic-gate 	p->rsmseg_state = IMPORT_CONNECT;
1310*0Sstevel@tonic-gate 	p->rsmseg_keyid = segment_id;
1311*0Sstevel@tonic-gate 	p->rsmseg_nodeid = node_id;
1312*0Sstevel@tonic-gate 	p->rsmseg_size = msg.len;
1313*0Sstevel@tonic-gate 	p->rsmseg_perm = perm;
1314*0Sstevel@tonic-gate 	p->rsmseg_controller = cntr;
1315*0Sstevel@tonic-gate 	p->rsmseg_barrier = NULL;
1316*0Sstevel@tonic-gate 	p->rsmseg_barmode = RSM_BARRIER_MODE_IMPLICIT;
1317*0Sstevel@tonic-gate 	p->rsmseg_bar = (bar_va ? bar_va + msg.off : &bar_fixed);
1318*0Sstevel@tonic-gate 	p->rsmseg_gnum = msg.gnum;
1319*0Sstevel@tonic-gate 	p->rsmseg_pollfd_refcnt = 0;
1320*0Sstevel@tonic-gate 	p->rsmseg_maplen = 0;    /* initialized, set in import_map */
1321*0Sstevel@tonic-gate 	p->rsmseg_mapoffset = 0;
1322*0Sstevel@tonic-gate 	p->rsmseg_flags = 0;
1323*0Sstevel@tonic-gate 	p->rsmseg_rnum = msg.rnum;
1324*0Sstevel@tonic-gate 	mutex_init(&p->rsmseg_lock, USYNC_THREAD, NULL);
1325*0Sstevel@tonic-gate 
1326*0Sstevel@tonic-gate 	p->rsmseg_ops = cntr->cntr_segops;
1327*0Sstevel@tonic-gate 
1328*0Sstevel@tonic-gate 	/*
1329*0Sstevel@tonic-gate 	 * XXX: Based on permission and controller direct_access attribute
1330*0Sstevel@tonic-gate 	 * we fix the segment ops vector
1331*0Sstevel@tonic-gate 	 */
1332*0Sstevel@tonic-gate 
1333*0Sstevel@tonic-gate 	p->rsmseg_vaddr = 0; /* defer mapping till using maps or trys to rw */
1334*0Sstevel@tonic-gate 
1335*0Sstevel@tonic-gate 	*im_memseg = (rsm_memseg_import_handle_t)p;
1336*0Sstevel@tonic-gate 
1337*0Sstevel@tonic-gate 	e =  p->rsmseg_ops->rsm_memseg_import_connect(controller,
1338*0Sstevel@tonic-gate 	    node_id, segment_id, perm, im_memseg);
1339*0Sstevel@tonic-gate 
1340*0Sstevel@tonic-gate 	if (e != RSM_SUCCESS) {
1341*0Sstevel@tonic-gate 		(void) close(p->rsmseg_fd);
1342*0Sstevel@tonic-gate 		mutex_destroy(&p->rsmseg_lock);
1343*0Sstevel@tonic-gate 		free((void *)p);
1344*0Sstevel@tonic-gate 	}
1345*0Sstevel@tonic-gate 
1346*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1347*0Sstevel@tonic-gate 	    "rsm_memseg_import_connect: exit\n"));
1348*0Sstevel@tonic-gate 
1349*0Sstevel@tonic-gate 	return (e);
1350*0Sstevel@tonic-gate }
1351*0Sstevel@tonic-gate 
1352*0Sstevel@tonic-gate 
1353*0Sstevel@tonic-gate int
1354*0Sstevel@tonic-gate _rsm_memseg_import_disconnect(rsm_memseg_import_handle_t im_memseg)
1355*0Sstevel@tonic-gate {
1356*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
1357*0Sstevel@tonic-gate 	int e;
1358*0Sstevel@tonic-gate 
1359*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1360*0Sstevel@tonic-gate 	    "rsm_memseg_import_disconnect: enter\n"));
1361*0Sstevel@tonic-gate 
1362*0Sstevel@tonic-gate 	if (!seg) {
1363*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1364*0Sstevel@tonic-gate 		    "invalid segment handle\n"));
1365*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
1366*0Sstevel@tonic-gate 	}
1367*0Sstevel@tonic-gate 
1368*0Sstevel@tonic-gate 	if (seg->rsmseg_state != IMPORT_CONNECT) {
1369*0Sstevel@tonic-gate 		if (seg->rsmseg_flags & RSM_IMPLICIT_MAP) {
1370*0Sstevel@tonic-gate 			e = rsm_memseg_import_unmap(im_memseg);
1371*0Sstevel@tonic-gate 			if (e != RSM_SUCCESS) {
1372*0Sstevel@tonic-gate 				DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1373*0Sstevel@tonic-gate 				    "unmap failure\n"));
1374*0Sstevel@tonic-gate 				return (e);
1375*0Sstevel@tonic-gate 			}
1376*0Sstevel@tonic-gate 		} else {
1377*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1378*0Sstevel@tonic-gate 			    "segment busy\n"));
1379*0Sstevel@tonic-gate 			return (RSMERR_SEG_STILL_MAPPED);
1380*0Sstevel@tonic-gate 		}
1381*0Sstevel@tonic-gate 	}
1382*0Sstevel@tonic-gate 
1383*0Sstevel@tonic-gate 	mutex_lock(&seg->rsmseg_lock);
1384*0Sstevel@tonic-gate 	if (seg->rsmseg_pollfd_refcnt) {
1385*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
1386*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR,
1387*0Sstevel@tonic-gate 		    "segment reference count not zero\n"));
1388*0Sstevel@tonic-gate 		return (RSMERR_POLLFD_IN_USE);
1389*0Sstevel@tonic-gate 	}
1390*0Sstevel@tonic-gate 	mutex_unlock(&seg->rsmseg_lock);
1391*0Sstevel@tonic-gate 
1392*0Sstevel@tonic-gate 	e =  seg->rsmseg_ops->rsm_memseg_import_disconnect(im_memseg);
1393*0Sstevel@tonic-gate 
1394*0Sstevel@tonic-gate 	if (e == RSM_SUCCESS) {
1395*0Sstevel@tonic-gate 		(void) close(seg->rsmseg_fd);
1396*0Sstevel@tonic-gate 		mutex_destroy(&seg->rsmseg_lock);
1397*0Sstevel@tonic-gate 		free((void *)seg);
1398*0Sstevel@tonic-gate 	}
1399*0Sstevel@tonic-gate 
1400*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1401*0Sstevel@tonic-gate 	    "rsm_memseg_import_disconnect: exit\n"));
1402*0Sstevel@tonic-gate 
1403*0Sstevel@tonic-gate 	return (e);
1404*0Sstevel@tonic-gate }
1405*0Sstevel@tonic-gate 
1406*0Sstevel@tonic-gate /*
1407*0Sstevel@tonic-gate  * import side memory segment operations (read access functions):
1408*0Sstevel@tonic-gate  */
1409*0Sstevel@tonic-gate 
1410*0Sstevel@tonic-gate static int
1411*0Sstevel@tonic-gate __rsm_import_verify_access(rsmseg_handle_t *seg,
1412*0Sstevel@tonic-gate     off_t offset,
1413*0Sstevel@tonic-gate     caddr_t datap,
1414*0Sstevel@tonic-gate     size_t len,
1415*0Sstevel@tonic-gate     rsm_permission_t perm,
1416*0Sstevel@tonic-gate     rsm_access_size_t das)
1417*0Sstevel@tonic-gate {
1418*0Sstevel@tonic-gate 	int	error;
1419*0Sstevel@tonic-gate 
1420*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1421*0Sstevel@tonic-gate 	    " __rsm_import_verify_access: enter\n"));
1422*0Sstevel@tonic-gate 
1423*0Sstevel@tonic-gate 	if (!seg) {
1424*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1425*0Sstevel@tonic-gate 		    "invalid segment handle\n"));
1426*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
1427*0Sstevel@tonic-gate 	}
1428*0Sstevel@tonic-gate 	if (!datap) {
1429*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1430*0Sstevel@tonic-gate 		    "invalid data pointer\n"));
1431*0Sstevel@tonic-gate 		return (RSMERR_BAD_ADDR);
1432*0Sstevel@tonic-gate 	}
1433*0Sstevel@tonic-gate 
1434*0Sstevel@tonic-gate 	/*
1435*0Sstevel@tonic-gate 	 * Check alignment of pointer
1436*0Sstevel@tonic-gate 	 */
1437*0Sstevel@tonic-gate 	if ((uintptr_t)datap & (das - 1)) {
1438*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1439*0Sstevel@tonic-gate 		    "invalid alignment of data pointer\n"));
1440*0Sstevel@tonic-gate 		return (RSMERR_BAD_MEM_ALIGNMENT);
1441*0Sstevel@tonic-gate 	}
1442*0Sstevel@tonic-gate 
1443*0Sstevel@tonic-gate 	if (offset & (das - 1)) {
1444*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1445*0Sstevel@tonic-gate 		    "invalid offset\n"));
1446*0Sstevel@tonic-gate 		return (RSMERR_BAD_MEM_ALIGNMENT);
1447*0Sstevel@tonic-gate 	}
1448*0Sstevel@tonic-gate 
1449*0Sstevel@tonic-gate 	/* make sure that the import seg is connected */
1450*0Sstevel@tonic-gate 	if (seg->rsmseg_state != IMPORT_CONNECT &&
1451*0Sstevel@tonic-gate 	    seg->rsmseg_state != IMPORT_MAP) {
1452*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1453*0Sstevel@tonic-gate 		    "incorrect segment state\n"));
1454*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
1455*0Sstevel@tonic-gate 	}
1456*0Sstevel@tonic-gate 
1457*0Sstevel@tonic-gate 	/* do an implicit map if required */
1458*0Sstevel@tonic-gate 	if (seg->rsmseg_state == IMPORT_CONNECT) {
1459*0Sstevel@tonic-gate 		error = __rsm_import_implicit_map(seg, RSM_IOTYPE_PUTGET);
1460*0Sstevel@tonic-gate 		if (error != RSM_SUCCESS) {
1461*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1462*0Sstevel@tonic-gate 			    "implicit map failure\n"));
1463*0Sstevel@tonic-gate 			return (error);
1464*0Sstevel@tonic-gate 		}
1465*0Sstevel@tonic-gate 	}
1466*0Sstevel@tonic-gate 
1467*0Sstevel@tonic-gate 	if ((seg->rsmseg_perm & perm) != perm) {
1468*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1469*0Sstevel@tonic-gate 		    "invalid permissions\n"));
1470*0Sstevel@tonic-gate 		return (RSMERR_PERM_DENIED);
1471*0Sstevel@tonic-gate 	}
1472*0Sstevel@tonic-gate 
1473*0Sstevel@tonic-gate 	if (seg->rsmseg_state == IMPORT_MAP) {
1474*0Sstevel@tonic-gate 		if ((offset < seg->rsmseg_mapoffset) ||
1475*0Sstevel@tonic-gate 		    (offset + len > seg->rsmseg_mapoffset +
1476*0Sstevel@tonic-gate 		    seg->rsmseg_maplen)) {
1477*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1478*0Sstevel@tonic-gate 			    "incorrect offset+length\n"));
1479*0Sstevel@tonic-gate 			return (RSMERR_BAD_OFFSET);
1480*0Sstevel@tonic-gate 		}
1481*0Sstevel@tonic-gate 	} else { /* IMPORT_CONNECT */
1482*0Sstevel@tonic-gate 		if ((len + offset) > seg->rsmseg_size) {
1483*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1484*0Sstevel@tonic-gate 			    "incorrect offset+length\n"));
1485*0Sstevel@tonic-gate 			return (RSMERR_BAD_LENGTH);
1486*0Sstevel@tonic-gate 		}
1487*0Sstevel@tonic-gate 	}
1488*0Sstevel@tonic-gate 
1489*0Sstevel@tonic-gate 	if ((seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) &&
1490*0Sstevel@tonic-gate 	    (seg->rsmseg_barrier == NULL)) {
1491*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1492*0Sstevel@tonic-gate 		    "invalid barrier\n"));
1493*0Sstevel@tonic-gate 		return (RSMERR_BARRIER_UNINITIALIZED);
1494*0Sstevel@tonic-gate 	}
1495*0Sstevel@tonic-gate 
1496*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1497*0Sstevel@tonic-gate 	    " __rsm_import_verify_access: exit\n"));
1498*0Sstevel@tonic-gate 
1499*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
1500*0Sstevel@tonic-gate }
1501*0Sstevel@tonic-gate 
1502*0Sstevel@tonic-gate static int
1503*0Sstevel@tonic-gate __rsm_import_implicit_map(rsmseg_handle_t *seg, int iotype)
1504*0Sstevel@tonic-gate {
1505*0Sstevel@tonic-gate 	caddr_t va;
1506*0Sstevel@tonic-gate 	int flag = MAP_SHARED;
1507*0Sstevel@tonic-gate 	int prot = PROT_READ|PROT_WRITE;
1508*0Sstevel@tonic-gate 	int mapping_reqd = 0;
1509*0Sstevel@tonic-gate 
1510*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1511*0Sstevel@tonic-gate 	    " __rsm_import_implicit_map: enter\n"));
1512*0Sstevel@tonic-gate 
1513*0Sstevel@tonic-gate 	if (iotype == RSM_IOTYPE_PUTGET)
1514*0Sstevel@tonic-gate 		mapping_reqd = seg->rsmseg_controller->cntr_lib_attr->
1515*0Sstevel@tonic-gate 		    rsm_putget_map_reqd;
1516*0Sstevel@tonic-gate 	else if (iotype == RSM_IOTYPE_SCATGATH)
1517*0Sstevel@tonic-gate 		mapping_reqd = seg->rsmseg_controller->cntr_lib_attr->
1518*0Sstevel@tonic-gate 		    rsm_scatgath_map_reqd;
1519*0Sstevel@tonic-gate 
1520*0Sstevel@tonic-gate 
1521*0Sstevel@tonic-gate 	if (mapping_reqd) {
1522*0Sstevel@tonic-gate 		va = mmap(NULL, seg->rsmseg_size, prot,
1523*0Sstevel@tonic-gate 		    flag, seg->rsmseg_fd, 0);
1524*0Sstevel@tonic-gate 
1525*0Sstevel@tonic-gate 		if (va == MAP_FAILED) {
1526*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1527*0Sstevel@tonic-gate 			    "implicit map failed\n"));
1528*0Sstevel@tonic-gate 			if (errno == ENOMEM || errno == ENXIO ||
1529*0Sstevel@tonic-gate 			    errno == EOVERFLOW)
1530*0Sstevel@tonic-gate 				return (RSMERR_BAD_LENGTH);
1531*0Sstevel@tonic-gate 			else if (errno == ENODEV)
1532*0Sstevel@tonic-gate 				return (RSMERR_CONN_ABORTED);
1533*0Sstevel@tonic-gate 			else if (errno == EAGAIN)
1534*0Sstevel@tonic-gate 				return (RSMERR_INSUFFICIENT_RESOURCES);
1535*0Sstevel@tonic-gate 			else if (errno == ENOTSUP)
1536*0Sstevel@tonic-gate 				return (RSMERR_MAP_FAILED);
1537*0Sstevel@tonic-gate 			else if (errno == EACCES)
1538*0Sstevel@tonic-gate 				return (RSMERR_BAD_PERMS);
1539*0Sstevel@tonic-gate 			else
1540*0Sstevel@tonic-gate 				return (RSMERR_MAP_FAILED);
1541*0Sstevel@tonic-gate 		}
1542*0Sstevel@tonic-gate 		seg->rsmseg_vaddr = va;
1543*0Sstevel@tonic-gate 		seg->rsmseg_maplen = seg->rsmseg_size;
1544*0Sstevel@tonic-gate 		seg->rsmseg_mapoffset = 0;
1545*0Sstevel@tonic-gate 		seg->rsmseg_state = IMPORT_MAP;
1546*0Sstevel@tonic-gate 		seg->rsmseg_flags |= RSM_IMPLICIT_MAP;
1547*0Sstevel@tonic-gate 	}
1548*0Sstevel@tonic-gate 
1549*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1550*0Sstevel@tonic-gate 	    " __rsm_import_implicit_map: exit\n"));
1551*0Sstevel@tonic-gate 
1552*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
1553*0Sstevel@tonic-gate }
1554*0Sstevel@tonic-gate 
1555*0Sstevel@tonic-gate int
1556*0Sstevel@tonic-gate _rsm_memseg_import_get8(rsm_memseg_import_handle_t im_memseg,
1557*0Sstevel@tonic-gate     off_t offset,
1558*0Sstevel@tonic-gate     uint8_t *datap,
1559*0Sstevel@tonic-gate     ulong_t rep_cnt)
1560*0Sstevel@tonic-gate {
1561*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
1562*0Sstevel@tonic-gate 	int e;
1563*0Sstevel@tonic-gate 
1564*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1565*0Sstevel@tonic-gate 	    "rsm_memseg_import_get8: enter\n"));
1566*0Sstevel@tonic-gate 
1567*0Sstevel@tonic-gate 	e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt,
1568*0Sstevel@tonic-gate 	    RSM_PERM_READ,
1569*0Sstevel@tonic-gate 	    RSM_DAS8);
1570*0Sstevel@tonic-gate 	if (e == RSM_SUCCESS) {
1571*0Sstevel@tonic-gate 		rsm_segops_t *ops = seg->rsmseg_ops;
1572*0Sstevel@tonic-gate 		rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier;
1573*0Sstevel@tonic-gate 
1574*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1575*0Sstevel@tonic-gate 			/* generation number snapshot */
1576*0Sstevel@tonic-gate 			bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum;
1577*0Sstevel@tonic-gate 		}
1578*0Sstevel@tonic-gate 
1579*0Sstevel@tonic-gate 		e = ops->rsm_memseg_import_get8(im_memseg, offset, datap,
1580*0Sstevel@tonic-gate 		    rep_cnt, 0);
1581*0Sstevel@tonic-gate 
1582*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1583*0Sstevel@tonic-gate 			/* check the generation number for force disconnects */
1584*0Sstevel@tonic-gate 			if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) {
1585*0Sstevel@tonic-gate 				return (RSMERR_CONN_ABORTED);
1586*0Sstevel@tonic-gate 			}
1587*0Sstevel@tonic-gate 		}
1588*0Sstevel@tonic-gate 	}
1589*0Sstevel@tonic-gate 
1590*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1591*0Sstevel@tonic-gate 	    "rsm_memseg_import_get8: exit\n"));
1592*0Sstevel@tonic-gate 
1593*0Sstevel@tonic-gate 	return (e);
1594*0Sstevel@tonic-gate }
1595*0Sstevel@tonic-gate 
1596*0Sstevel@tonic-gate int
1597*0Sstevel@tonic-gate _rsm_memseg_import_get16(rsm_memseg_import_handle_t im_memseg,
1598*0Sstevel@tonic-gate     off_t offset,
1599*0Sstevel@tonic-gate     uint16_t *datap,
1600*0Sstevel@tonic-gate     ulong_t rep_cnt)
1601*0Sstevel@tonic-gate {
1602*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
1603*0Sstevel@tonic-gate 	int e;
1604*0Sstevel@tonic-gate 
1605*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1606*0Sstevel@tonic-gate 	    "rsm_memseg_import_get16: enter\n"));
1607*0Sstevel@tonic-gate 
1608*0Sstevel@tonic-gate 	e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*2,
1609*0Sstevel@tonic-gate 	    RSM_PERM_READ,
1610*0Sstevel@tonic-gate 	    RSM_DAS16);
1611*0Sstevel@tonic-gate 	if (e == RSM_SUCCESS) {
1612*0Sstevel@tonic-gate 		rsm_segops_t *ops = seg->rsmseg_ops;
1613*0Sstevel@tonic-gate 		rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier;
1614*0Sstevel@tonic-gate 
1615*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1616*0Sstevel@tonic-gate 			/* generation number snapshot */
1617*0Sstevel@tonic-gate 			bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum;
1618*0Sstevel@tonic-gate 		}
1619*0Sstevel@tonic-gate 
1620*0Sstevel@tonic-gate 		e = ops->rsm_memseg_import_get16(im_memseg, offset, datap,
1621*0Sstevel@tonic-gate 		    rep_cnt, 0);
1622*0Sstevel@tonic-gate 
1623*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1624*0Sstevel@tonic-gate 			/* check the generation number for force disconnects */
1625*0Sstevel@tonic-gate 			if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) {
1626*0Sstevel@tonic-gate 				return (RSMERR_CONN_ABORTED);
1627*0Sstevel@tonic-gate 			}
1628*0Sstevel@tonic-gate 		}
1629*0Sstevel@tonic-gate 
1630*0Sstevel@tonic-gate 	}
1631*0Sstevel@tonic-gate 
1632*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1633*0Sstevel@tonic-gate 	    "rsm_memseg_import_get16: exit\n"));
1634*0Sstevel@tonic-gate 
1635*0Sstevel@tonic-gate 	return (e);
1636*0Sstevel@tonic-gate }
1637*0Sstevel@tonic-gate 
1638*0Sstevel@tonic-gate int
1639*0Sstevel@tonic-gate _rsm_memseg_import_get32(rsm_memseg_import_handle_t im_memseg,
1640*0Sstevel@tonic-gate     off_t offset,
1641*0Sstevel@tonic-gate     uint32_t *datap,
1642*0Sstevel@tonic-gate     ulong_t rep_cnt)
1643*0Sstevel@tonic-gate {
1644*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
1645*0Sstevel@tonic-gate 	int e;
1646*0Sstevel@tonic-gate 
1647*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1648*0Sstevel@tonic-gate 	    "rsm_memseg_import_get32: enter\n"));
1649*0Sstevel@tonic-gate 
1650*0Sstevel@tonic-gate 	e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*4,
1651*0Sstevel@tonic-gate 	    RSM_PERM_READ,
1652*0Sstevel@tonic-gate 	    RSM_DAS32);
1653*0Sstevel@tonic-gate 	if (e == RSM_SUCCESS) {
1654*0Sstevel@tonic-gate 		rsm_segops_t *ops = seg->rsmseg_ops;
1655*0Sstevel@tonic-gate 		rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier;
1656*0Sstevel@tonic-gate 
1657*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1658*0Sstevel@tonic-gate 			/* generation number snapshot */
1659*0Sstevel@tonic-gate 			bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum;
1660*0Sstevel@tonic-gate 		}
1661*0Sstevel@tonic-gate 
1662*0Sstevel@tonic-gate 		e = ops->rsm_memseg_import_get32(im_memseg, offset, datap,
1663*0Sstevel@tonic-gate 		    rep_cnt, 0);
1664*0Sstevel@tonic-gate 
1665*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1666*0Sstevel@tonic-gate 			/* check the generation number for force disconnects */
1667*0Sstevel@tonic-gate 			if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) {
1668*0Sstevel@tonic-gate 				return (RSMERR_CONN_ABORTED);
1669*0Sstevel@tonic-gate 			}
1670*0Sstevel@tonic-gate 		}
1671*0Sstevel@tonic-gate 	}
1672*0Sstevel@tonic-gate 
1673*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1674*0Sstevel@tonic-gate 	    "rsm_memseg_import_get32: exit\n"));
1675*0Sstevel@tonic-gate 
1676*0Sstevel@tonic-gate 	return (e);
1677*0Sstevel@tonic-gate }
1678*0Sstevel@tonic-gate 
1679*0Sstevel@tonic-gate int
1680*0Sstevel@tonic-gate _rsm_memseg_import_get64(rsm_memseg_import_handle_t im_memseg,
1681*0Sstevel@tonic-gate     off_t offset,
1682*0Sstevel@tonic-gate     uint64_t *datap,
1683*0Sstevel@tonic-gate     ulong_t rep_cnt)
1684*0Sstevel@tonic-gate {
1685*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
1686*0Sstevel@tonic-gate 	int e;
1687*0Sstevel@tonic-gate 
1688*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1689*0Sstevel@tonic-gate 	    "rsm_memseg_import_get64: enter\n"));
1690*0Sstevel@tonic-gate 
1691*0Sstevel@tonic-gate 	e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*8,
1692*0Sstevel@tonic-gate 	    RSM_PERM_READ,
1693*0Sstevel@tonic-gate 	    RSM_DAS64);
1694*0Sstevel@tonic-gate 	if (e == RSM_SUCCESS) {
1695*0Sstevel@tonic-gate 		rsm_segops_t *ops = seg->rsmseg_ops;
1696*0Sstevel@tonic-gate 		rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier;
1697*0Sstevel@tonic-gate 
1698*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1699*0Sstevel@tonic-gate 			/* generation number snapshot */
1700*0Sstevel@tonic-gate 			bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum;
1701*0Sstevel@tonic-gate 		}
1702*0Sstevel@tonic-gate 
1703*0Sstevel@tonic-gate 		e = ops->rsm_memseg_import_get64(im_memseg, offset, datap,
1704*0Sstevel@tonic-gate 		    rep_cnt, 0);
1705*0Sstevel@tonic-gate 
1706*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1707*0Sstevel@tonic-gate 			/* check the generation number for force disconnects */
1708*0Sstevel@tonic-gate 			if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) {
1709*0Sstevel@tonic-gate 				return (RSMERR_CONN_ABORTED);
1710*0Sstevel@tonic-gate 			}
1711*0Sstevel@tonic-gate 		}
1712*0Sstevel@tonic-gate 	}
1713*0Sstevel@tonic-gate 
1714*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1715*0Sstevel@tonic-gate 	    "rsm_memseg_import_get64: exit\n"));
1716*0Sstevel@tonic-gate 
1717*0Sstevel@tonic-gate 	return (e);
1718*0Sstevel@tonic-gate }
1719*0Sstevel@tonic-gate 
1720*0Sstevel@tonic-gate int
1721*0Sstevel@tonic-gate _rsm_memseg_import_get(rsm_memseg_import_handle_t im_memseg,
1722*0Sstevel@tonic-gate     off_t offset,
1723*0Sstevel@tonic-gate     void *dst_addr,
1724*0Sstevel@tonic-gate     size_t length)
1725*0Sstevel@tonic-gate {
1726*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
1727*0Sstevel@tonic-gate 	int e;
1728*0Sstevel@tonic-gate 
1729*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1730*0Sstevel@tonic-gate 	    "rsm_memseg_import_get: enter\n"));
1731*0Sstevel@tonic-gate 
1732*0Sstevel@tonic-gate 	e = __rsm_import_verify_access(seg, offset, (caddr_t)dst_addr, length,
1733*0Sstevel@tonic-gate 	    RSM_PERM_READ,
1734*0Sstevel@tonic-gate 	    RSM_DAS8);
1735*0Sstevel@tonic-gate 	if (e == RSM_SUCCESS) {
1736*0Sstevel@tonic-gate 		rsm_segops_t *ops = seg->rsmseg_ops;
1737*0Sstevel@tonic-gate 		rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier;
1738*0Sstevel@tonic-gate 
1739*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1740*0Sstevel@tonic-gate 			/* generation number snapshot */
1741*0Sstevel@tonic-gate 			bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum;
1742*0Sstevel@tonic-gate 		}
1743*0Sstevel@tonic-gate 
1744*0Sstevel@tonic-gate 		e = ops->rsm_memseg_import_get(im_memseg, offset, dst_addr,
1745*0Sstevel@tonic-gate 		    length);
1746*0Sstevel@tonic-gate 
1747*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1748*0Sstevel@tonic-gate 			/* check the generation number for force disconnects */
1749*0Sstevel@tonic-gate 			if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) {
1750*0Sstevel@tonic-gate 				return (RSMERR_CONN_ABORTED);
1751*0Sstevel@tonic-gate 			}
1752*0Sstevel@tonic-gate 		}
1753*0Sstevel@tonic-gate 	}
1754*0Sstevel@tonic-gate 
1755*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1756*0Sstevel@tonic-gate 	    "rsm_memseg_import_get: exit\n"));
1757*0Sstevel@tonic-gate 
1758*0Sstevel@tonic-gate 	return (e);
1759*0Sstevel@tonic-gate }
1760*0Sstevel@tonic-gate 
1761*0Sstevel@tonic-gate 
1762*0Sstevel@tonic-gate int
1763*0Sstevel@tonic-gate _rsm_memseg_import_getv(rsm_scat_gath_t *sg_io)
1764*0Sstevel@tonic-gate {
1765*0Sstevel@tonic-gate 	rsm_controller_t *cntrl;
1766*0Sstevel@tonic-gate 	rsmseg_handle_t *seg;
1767*0Sstevel@tonic-gate 	uint_t save_sg_io_flags;
1768*0Sstevel@tonic-gate 
1769*0Sstevel@tonic-gate 	int e;
1770*0Sstevel@tonic-gate 
1771*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1772*0Sstevel@tonic-gate 	    "rsm_memseg_import_getv: enter\n"));
1773*0Sstevel@tonic-gate 
1774*0Sstevel@tonic-gate 	if (sg_io == NULL) {
1775*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1776*0Sstevel@tonic-gate 		    "invalid sg_io structure\n"));
1777*0Sstevel@tonic-gate 		return (RSMERR_BAD_SGIO);
1778*0Sstevel@tonic-gate 	}
1779*0Sstevel@tonic-gate 
1780*0Sstevel@tonic-gate 	seg = (rsmseg_handle_t *)sg_io->remote_handle;
1781*0Sstevel@tonic-gate 	if (seg == NULL) {
1782*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1783*0Sstevel@tonic-gate 		    "invalid remote segment handle in sg_io\n"));
1784*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
1785*0Sstevel@tonic-gate 	}
1786*0Sstevel@tonic-gate 
1787*0Sstevel@tonic-gate 	cntrl = (rsm_controller_t *)seg->rsmseg_controller;
1788*0Sstevel@tonic-gate 	if (cntrl == NULL) {
1789*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1790*0Sstevel@tonic-gate 		    "invalid controller handle\n"));
1791*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
1792*0Sstevel@tonic-gate 	}
1793*0Sstevel@tonic-gate 
1794*0Sstevel@tonic-gate 	if ((sg_io->io_request_count > RSM_MAX_SGIOREQS) ||
1795*0Sstevel@tonic-gate 	    (sg_io->io_request_count == 0)) {
1796*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1797*0Sstevel@tonic-gate 		    "io_request_count value incorrect\n"));
1798*0Sstevel@tonic-gate 		return (RSMERR_BAD_SGIO);
1799*0Sstevel@tonic-gate 	}
1800*0Sstevel@tonic-gate 
1801*0Sstevel@tonic-gate 	if (seg->rsmseg_state == IMPORT_CONNECT) {
1802*0Sstevel@tonic-gate 		e = __rsm_import_implicit_map(seg, RSM_IOTYPE_SCATGATH);
1803*0Sstevel@tonic-gate 		if (e != RSM_SUCCESS) {
1804*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
1805*0Sstevel@tonic-gate 			    "implicit map failure\n"));
1806*0Sstevel@tonic-gate 			return (e);
1807*0Sstevel@tonic-gate 		}
1808*0Sstevel@tonic-gate 	}
1809*0Sstevel@tonic-gate 
1810*0Sstevel@tonic-gate 	/*
1811*0Sstevel@tonic-gate 	 * Copy the flags field of the sg_io structure in a local
1812*0Sstevel@tonic-gate 	 * variable.
1813*0Sstevel@tonic-gate 	 * This is required since the flags field can be
1814*0Sstevel@tonic-gate 	 * changed by the plugin library routine to indicate that
1815*0Sstevel@tonic-gate 	 * the signal post was done.
1816*0Sstevel@tonic-gate 	 * This change in the flags field of the sg_io structure
1817*0Sstevel@tonic-gate 	 * should not be reflected to the user. Hence once the flags
1818*0Sstevel@tonic-gate 	 * field has been used for the purpose of determining whether
1819*0Sstevel@tonic-gate 	 * the plugin executed a signal post, it must be restored to
1820*0Sstevel@tonic-gate 	 * its original value which is stored in the local variable.
1821*0Sstevel@tonic-gate 	 */
1822*0Sstevel@tonic-gate 	save_sg_io_flags = sg_io->flags;
1823*0Sstevel@tonic-gate 
1824*0Sstevel@tonic-gate 	e = cntrl->cntr_segops->rsm_memseg_import_getv(sg_io);
1825*0Sstevel@tonic-gate 
1826*0Sstevel@tonic-gate 	/*
1827*0Sstevel@tonic-gate 	 * At this point, if an implicit signal post was requested by
1828*0Sstevel@tonic-gate 	 * the user, there could be two possibilities that arise:
1829*0Sstevel@tonic-gate 	 * 1. the plugin routine has already executed the implicit
1830*0Sstevel@tonic-gate 	 *    signal post either successfully or unsuccessfully
1831*0Sstevel@tonic-gate 	 * 2. the plugin does not have the capability of doing an
1832*0Sstevel@tonic-gate 	 *    implicit signal post and hence the signal post needs
1833*0Sstevel@tonic-gate 	 *    to be done here.
1834*0Sstevel@tonic-gate 	 * The above two cases can be idenfied by the flags
1835*0Sstevel@tonic-gate 	 * field within the sg_io structure as follows:
1836*0Sstevel@tonic-gate 	 * In case 1, the RSM_IMPLICIT_SIGPOST bit is reset to 0 by the
1837*0Sstevel@tonic-gate 	 * plugin, indicating that the signal post was done.
1838*0Sstevel@tonic-gate 	 * In case 2, the bit remains set to a 1 as originally given
1839*0Sstevel@tonic-gate 	 * by the user, and hence a signal post needs to be done here.
1840*0Sstevel@tonic-gate 	 */
1841*0Sstevel@tonic-gate 	if (sg_io->flags & RSM_IMPLICIT_SIGPOST &&
1842*0Sstevel@tonic-gate 	    e == RSM_SUCCESS) {
1843*0Sstevel@tonic-gate 		/* Do the implicit signal post */
1844*0Sstevel@tonic-gate 
1845*0Sstevel@tonic-gate 		/*
1846*0Sstevel@tonic-gate 		 * The value of the second argument to this call
1847*0Sstevel@tonic-gate 		 * depends on the value of the sg_io->flags field.
1848*0Sstevel@tonic-gate 		 * If the RSM_SIGPOST_NO_ACCUMULATE flag has been
1849*0Sstevel@tonic-gate 		 * ored into the sg_io->flags field, this indicates
1850*0Sstevel@tonic-gate 		 * that the rsm_intr_signal_post is to be done with
1851*0Sstevel@tonic-gate 		 * the flags argument set to RSM_SIGPOST_NO_ACCUMULATE
1852*0Sstevel@tonic-gate 		 * Else, the flags argument is set to 0. These
1853*0Sstevel@tonic-gate 		 * semantics can be achieved simply by masking off
1854*0Sstevel@tonic-gate 		 * all other bits in the sg_io->flags field except the
1855*0Sstevel@tonic-gate 		 * RSM_SIGPOST_NO_ACCUMULATE bit and using the result
1856*0Sstevel@tonic-gate 		 * as the flags argument for the rsm_intr_signal_post.
1857*0Sstevel@tonic-gate 		 */
1858*0Sstevel@tonic-gate 
1859*0Sstevel@tonic-gate 		int sigpost_flags = sg_io->flags & RSM_SIGPOST_NO_ACCUMULATE;
1860*0Sstevel@tonic-gate 		e = rsm_intr_signal_post(seg, sigpost_flags);
1861*0Sstevel@tonic-gate 	}
1862*0Sstevel@tonic-gate 
1863*0Sstevel@tonic-gate 	/* Restore the flags field within the users scatter gather structure */
1864*0Sstevel@tonic-gate 	sg_io->flags = save_sg_io_flags;
1865*0Sstevel@tonic-gate 
1866*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1867*0Sstevel@tonic-gate 	    "rsm_memseg_import_getv: exit\n"));
1868*0Sstevel@tonic-gate 
1869*0Sstevel@tonic-gate 	return (e);
1870*0Sstevel@tonic-gate 
1871*0Sstevel@tonic-gate }
1872*0Sstevel@tonic-gate 
1873*0Sstevel@tonic-gate 	/*
1874*0Sstevel@tonic-gate 	 * import side memory segment operations (write access functions):
1875*0Sstevel@tonic-gate 	 */
1876*0Sstevel@tonic-gate 
1877*0Sstevel@tonic-gate int
1878*0Sstevel@tonic-gate _rsm_memseg_import_put8(rsm_memseg_import_handle_t im_memseg,
1879*0Sstevel@tonic-gate     off_t offset,
1880*0Sstevel@tonic-gate     uint8_t *datap,
1881*0Sstevel@tonic-gate     ulong_t rep_cnt)
1882*0Sstevel@tonic-gate {
1883*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
1884*0Sstevel@tonic-gate 	int e;
1885*0Sstevel@tonic-gate 
1886*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1887*0Sstevel@tonic-gate 	    "rsm_memseg_import_put8: enter\n"));
1888*0Sstevel@tonic-gate 
1889*0Sstevel@tonic-gate 	/* addr of data will always pass the alignment check, avoids	*/
1890*0Sstevel@tonic-gate 	/* need for a special case in verify_access for PUTs		*/
1891*0Sstevel@tonic-gate 	e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt,
1892*0Sstevel@tonic-gate 	    RSM_PERM_WRITE,
1893*0Sstevel@tonic-gate 	    RSM_DAS8);
1894*0Sstevel@tonic-gate 	if (e == RSM_SUCCESS) {
1895*0Sstevel@tonic-gate 		rsm_segops_t *ops = seg->rsmseg_ops;
1896*0Sstevel@tonic-gate 		rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier;
1897*0Sstevel@tonic-gate 
1898*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1899*0Sstevel@tonic-gate 			/* generation number snapshot */
1900*0Sstevel@tonic-gate 			bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum;
1901*0Sstevel@tonic-gate 		}
1902*0Sstevel@tonic-gate 
1903*0Sstevel@tonic-gate 		e = ops->rsm_memseg_import_put8(im_memseg, offset, datap,
1904*0Sstevel@tonic-gate 		    rep_cnt, 0);
1905*0Sstevel@tonic-gate 
1906*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1907*0Sstevel@tonic-gate 			/* check the generation number for force disconnects */
1908*0Sstevel@tonic-gate 			if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) {
1909*0Sstevel@tonic-gate 				return (RSMERR_CONN_ABORTED);
1910*0Sstevel@tonic-gate 			}
1911*0Sstevel@tonic-gate 		}
1912*0Sstevel@tonic-gate 	}
1913*0Sstevel@tonic-gate 
1914*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1915*0Sstevel@tonic-gate 	    "rsm_memseg_import_put8: exit\n"));
1916*0Sstevel@tonic-gate 
1917*0Sstevel@tonic-gate 	return (e);
1918*0Sstevel@tonic-gate }
1919*0Sstevel@tonic-gate 
1920*0Sstevel@tonic-gate int
1921*0Sstevel@tonic-gate _rsm_memseg_import_put16(rsm_memseg_import_handle_t im_memseg,
1922*0Sstevel@tonic-gate     off_t offset,
1923*0Sstevel@tonic-gate     uint16_t *datap,
1924*0Sstevel@tonic-gate     ulong_t rep_cnt)
1925*0Sstevel@tonic-gate {
1926*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
1927*0Sstevel@tonic-gate 	int e;
1928*0Sstevel@tonic-gate 
1929*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1930*0Sstevel@tonic-gate 	    "rsm_memseg_import_put16: enter\n"));
1931*0Sstevel@tonic-gate 
1932*0Sstevel@tonic-gate 	/* addr of data will always pass the alignment check, avoids	*/
1933*0Sstevel@tonic-gate 	/* need for a special case in verify_access for PUTs		*/
1934*0Sstevel@tonic-gate 	e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*2,
1935*0Sstevel@tonic-gate 	    RSM_PERM_WRITE,
1936*0Sstevel@tonic-gate 	    RSM_DAS16);
1937*0Sstevel@tonic-gate 	if (e == RSM_SUCCESS) {
1938*0Sstevel@tonic-gate 		rsm_segops_t *ops = seg->rsmseg_ops;
1939*0Sstevel@tonic-gate 		rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier;
1940*0Sstevel@tonic-gate 
1941*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1942*0Sstevel@tonic-gate 			/* generation number snapshot */
1943*0Sstevel@tonic-gate 			bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum;
1944*0Sstevel@tonic-gate 		}
1945*0Sstevel@tonic-gate 
1946*0Sstevel@tonic-gate 		e = ops->rsm_memseg_import_put16(im_memseg, offset, datap,
1947*0Sstevel@tonic-gate 		    rep_cnt, 0);
1948*0Sstevel@tonic-gate 
1949*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1950*0Sstevel@tonic-gate 			/* check the generation number for force disconnects */
1951*0Sstevel@tonic-gate 			if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) {
1952*0Sstevel@tonic-gate 				return (RSMERR_CONN_ABORTED);
1953*0Sstevel@tonic-gate 			}
1954*0Sstevel@tonic-gate 		}
1955*0Sstevel@tonic-gate 
1956*0Sstevel@tonic-gate 	}
1957*0Sstevel@tonic-gate 
1958*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1959*0Sstevel@tonic-gate 	    "rsm_memseg_import_put16: exit\n"));
1960*0Sstevel@tonic-gate 
1961*0Sstevel@tonic-gate 	return (e);
1962*0Sstevel@tonic-gate }
1963*0Sstevel@tonic-gate 
1964*0Sstevel@tonic-gate int
1965*0Sstevel@tonic-gate _rsm_memseg_import_put32(rsm_memseg_import_handle_t im_memseg,
1966*0Sstevel@tonic-gate     off_t offset,
1967*0Sstevel@tonic-gate     uint32_t *datap,
1968*0Sstevel@tonic-gate     ulong_t rep_cnt)
1969*0Sstevel@tonic-gate {
1970*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
1971*0Sstevel@tonic-gate 	int e;
1972*0Sstevel@tonic-gate 
1973*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
1974*0Sstevel@tonic-gate 	    "rsm_memseg_import_put32: enter\n"));
1975*0Sstevel@tonic-gate 
1976*0Sstevel@tonic-gate 	/* addr of data will always pass the alignment check, avoids	*/
1977*0Sstevel@tonic-gate 	/* need for a special case in verify_access for PUTs		*/
1978*0Sstevel@tonic-gate 	e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*4,
1979*0Sstevel@tonic-gate 	    RSM_PERM_WRITE,
1980*0Sstevel@tonic-gate 	    RSM_DAS32);
1981*0Sstevel@tonic-gate 	if (e == RSM_SUCCESS) {
1982*0Sstevel@tonic-gate 		rsm_segops_t *ops = seg->rsmseg_ops;
1983*0Sstevel@tonic-gate 		rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier;
1984*0Sstevel@tonic-gate 
1985*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1986*0Sstevel@tonic-gate 			/* generation number snapshot */
1987*0Sstevel@tonic-gate 			bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum;
1988*0Sstevel@tonic-gate 		}
1989*0Sstevel@tonic-gate 
1990*0Sstevel@tonic-gate 		e = ops->rsm_memseg_import_put32(im_memseg, offset, datap,
1991*0Sstevel@tonic-gate 		    rep_cnt, 0);
1992*0Sstevel@tonic-gate 
1993*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
1994*0Sstevel@tonic-gate 			/* check the generation number for force disconnects */
1995*0Sstevel@tonic-gate 			if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) {
1996*0Sstevel@tonic-gate 				return (RSMERR_CONN_ABORTED);
1997*0Sstevel@tonic-gate 			}
1998*0Sstevel@tonic-gate 		}
1999*0Sstevel@tonic-gate 	}
2000*0Sstevel@tonic-gate 
2001*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2002*0Sstevel@tonic-gate 	    "rsm_memseg_import_put32: exit\n"));
2003*0Sstevel@tonic-gate 
2004*0Sstevel@tonic-gate 	return (e);
2005*0Sstevel@tonic-gate }
2006*0Sstevel@tonic-gate 
2007*0Sstevel@tonic-gate int
2008*0Sstevel@tonic-gate _rsm_memseg_import_put64(rsm_memseg_import_handle_t im_memseg,
2009*0Sstevel@tonic-gate     off_t offset,
2010*0Sstevel@tonic-gate     uint64_t *datap,
2011*0Sstevel@tonic-gate     ulong_t rep_cnt)
2012*0Sstevel@tonic-gate {
2013*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
2014*0Sstevel@tonic-gate 	int		e;
2015*0Sstevel@tonic-gate 
2016*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2017*0Sstevel@tonic-gate 	    "rsm_memseg_import_put64: enter\n"));
2018*0Sstevel@tonic-gate 
2019*0Sstevel@tonic-gate 	/* addr of data will always pass the alignment check, avoids	*/
2020*0Sstevel@tonic-gate 	/* need for a special case in verify_access for PUTs		*/
2021*0Sstevel@tonic-gate 	e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*8,
2022*0Sstevel@tonic-gate 	    RSM_PERM_WRITE,
2023*0Sstevel@tonic-gate 	    RSM_DAS64);
2024*0Sstevel@tonic-gate 	if (e == RSM_SUCCESS) {
2025*0Sstevel@tonic-gate 		rsm_segops_t *ops = seg->rsmseg_ops;
2026*0Sstevel@tonic-gate 		rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier;
2027*0Sstevel@tonic-gate 
2028*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
2029*0Sstevel@tonic-gate 			/* generation number snapshot */
2030*0Sstevel@tonic-gate 			bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum;
2031*0Sstevel@tonic-gate 		}
2032*0Sstevel@tonic-gate 
2033*0Sstevel@tonic-gate 		e = ops->rsm_memseg_import_put64(im_memseg, offset, datap,
2034*0Sstevel@tonic-gate 		    rep_cnt, 0);
2035*0Sstevel@tonic-gate 
2036*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
2037*0Sstevel@tonic-gate 			/* check the generation number for force disconnects */
2038*0Sstevel@tonic-gate 			if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) {
2039*0Sstevel@tonic-gate 				return (RSMERR_CONN_ABORTED);
2040*0Sstevel@tonic-gate 			}
2041*0Sstevel@tonic-gate 		}
2042*0Sstevel@tonic-gate 	}
2043*0Sstevel@tonic-gate 
2044*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2045*0Sstevel@tonic-gate 	    "rsm_memseg_import_put64: exit\n"));
2046*0Sstevel@tonic-gate 
2047*0Sstevel@tonic-gate 	return (e);
2048*0Sstevel@tonic-gate }
2049*0Sstevel@tonic-gate 
2050*0Sstevel@tonic-gate int
2051*0Sstevel@tonic-gate _rsm_memseg_import_put(rsm_memseg_import_handle_t im_memseg,
2052*0Sstevel@tonic-gate     off_t offset,
2053*0Sstevel@tonic-gate     void *src_addr,
2054*0Sstevel@tonic-gate     size_t length)
2055*0Sstevel@tonic-gate {
2056*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
2057*0Sstevel@tonic-gate 	int e;
2058*0Sstevel@tonic-gate 
2059*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2060*0Sstevel@tonic-gate 	    "rsm_memseg_import_put: enter\n"));
2061*0Sstevel@tonic-gate 
2062*0Sstevel@tonic-gate 	e = __rsm_import_verify_access(seg, offset, (caddr_t)src_addr, length,
2063*0Sstevel@tonic-gate 	    RSM_PERM_WRITE,
2064*0Sstevel@tonic-gate 	    RSM_DAS8);
2065*0Sstevel@tonic-gate 	if (e == RSM_SUCCESS) {
2066*0Sstevel@tonic-gate 		rsm_segops_t *ops = seg->rsmseg_ops;
2067*0Sstevel@tonic-gate 		rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier;
2068*0Sstevel@tonic-gate 
2069*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
2070*0Sstevel@tonic-gate 			/* generation number snapshot */
2071*0Sstevel@tonic-gate 			bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum;
2072*0Sstevel@tonic-gate 		}
2073*0Sstevel@tonic-gate 
2074*0Sstevel@tonic-gate 		e = ops->rsm_memseg_import_put(im_memseg, offset, src_addr,
2075*0Sstevel@tonic-gate 		    length);
2076*0Sstevel@tonic-gate 
2077*0Sstevel@tonic-gate 		if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) {
2078*0Sstevel@tonic-gate 			/* check the generation number for force disconnects */
2079*0Sstevel@tonic-gate 			if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) {
2080*0Sstevel@tonic-gate 				return (RSMERR_CONN_ABORTED);
2081*0Sstevel@tonic-gate 			}
2082*0Sstevel@tonic-gate 		}
2083*0Sstevel@tonic-gate 
2084*0Sstevel@tonic-gate 	}
2085*0Sstevel@tonic-gate 
2086*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2087*0Sstevel@tonic-gate 	    "rsm_memseg_import_put: exit\n"));
2088*0Sstevel@tonic-gate 	return (e);
2089*0Sstevel@tonic-gate }
2090*0Sstevel@tonic-gate 
2091*0Sstevel@tonic-gate 
2092*0Sstevel@tonic-gate int
2093*0Sstevel@tonic-gate _rsm_memseg_import_putv(rsm_scat_gath_t *sg_io)
2094*0Sstevel@tonic-gate {
2095*0Sstevel@tonic-gate 	rsm_controller_t *cntrl;
2096*0Sstevel@tonic-gate 	rsmseg_handle_t *seg;
2097*0Sstevel@tonic-gate 	uint_t save_sg_io_flags;
2098*0Sstevel@tonic-gate 
2099*0Sstevel@tonic-gate 	int e;
2100*0Sstevel@tonic-gate 
2101*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2102*0Sstevel@tonic-gate 	    "rsm_memseg_import_putv: enter\n"));
2103*0Sstevel@tonic-gate 
2104*0Sstevel@tonic-gate 
2105*0Sstevel@tonic-gate 	if (sg_io == NULL) {
2106*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2107*0Sstevel@tonic-gate 		    "invalid sg_io structure\n"));
2108*0Sstevel@tonic-gate 		return (RSMERR_BAD_SGIO);
2109*0Sstevel@tonic-gate 	}
2110*0Sstevel@tonic-gate 
2111*0Sstevel@tonic-gate 	seg = (rsmseg_handle_t *)sg_io->remote_handle;
2112*0Sstevel@tonic-gate 	if (seg == NULL) {
2113*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2114*0Sstevel@tonic-gate 		    "invalid remote segment handle in sg_io\n"));
2115*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
2116*0Sstevel@tonic-gate 	}
2117*0Sstevel@tonic-gate 
2118*0Sstevel@tonic-gate 	cntrl = (rsm_controller_t *)seg->rsmseg_controller;
2119*0Sstevel@tonic-gate 	if (cntrl == NULL) {
2120*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2121*0Sstevel@tonic-gate 		    "invalid controller handle\n"));
2122*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
2123*0Sstevel@tonic-gate 	}
2124*0Sstevel@tonic-gate 
2125*0Sstevel@tonic-gate 	if ((sg_io->io_request_count > RSM_MAX_SGIOREQS) ||
2126*0Sstevel@tonic-gate 	    (sg_io->io_request_count == 0)) {
2127*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2128*0Sstevel@tonic-gate 		    "io_request_count value incorrect\n"));
2129*0Sstevel@tonic-gate 		return (RSMERR_BAD_SGIO);
2130*0Sstevel@tonic-gate 	}
2131*0Sstevel@tonic-gate 
2132*0Sstevel@tonic-gate 	/* do an implicit map if required */
2133*0Sstevel@tonic-gate 	if (seg->rsmseg_state == IMPORT_CONNECT) {
2134*0Sstevel@tonic-gate 		e = __rsm_import_implicit_map(seg, RSM_IOTYPE_SCATGATH);
2135*0Sstevel@tonic-gate 		if (e != RSM_SUCCESS) {
2136*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2137*0Sstevel@tonic-gate 			    "implicit map failed\n"));
2138*0Sstevel@tonic-gate 			return (e);
2139*0Sstevel@tonic-gate 		}
2140*0Sstevel@tonic-gate 	}
2141*0Sstevel@tonic-gate 
2142*0Sstevel@tonic-gate 	/*
2143*0Sstevel@tonic-gate 	 * Copy the flags field of the sg_io structure in a local
2144*0Sstevel@tonic-gate 	 * variable.
2145*0Sstevel@tonic-gate 	 * This is required since the flags field can be
2146*0Sstevel@tonic-gate 	 * changed by the plugin library routine to indicate that
2147*0Sstevel@tonic-gate 	 * the signal post was done.
2148*0Sstevel@tonic-gate 	 * This change in the flags field of the sg_io structure
2149*0Sstevel@tonic-gate 	 * should not be reflected to the user. Hence once the flags
2150*0Sstevel@tonic-gate 	 * field has been used for the purpose of determining whether
2151*0Sstevel@tonic-gate 	 * the plugin executed a signal post, it must be restored to
2152*0Sstevel@tonic-gate 	 * its original value which is stored in the local variable.
2153*0Sstevel@tonic-gate 	 */
2154*0Sstevel@tonic-gate 	save_sg_io_flags = sg_io->flags;
2155*0Sstevel@tonic-gate 
2156*0Sstevel@tonic-gate 	e = cntrl->cntr_segops->rsm_memseg_import_putv(sg_io);
2157*0Sstevel@tonic-gate 
2158*0Sstevel@tonic-gate 	/*
2159*0Sstevel@tonic-gate 	 * At this point, if an implicit signal post was requested by
2160*0Sstevel@tonic-gate 	 * the user, there could be two possibilities that arise:
2161*0Sstevel@tonic-gate 	 * 1. the plugin routine has already executed the implicit
2162*0Sstevel@tonic-gate 	 *    signal post either successfully or unsuccessfully
2163*0Sstevel@tonic-gate 	 * 2. the plugin does not have the capability of doing an
2164*0Sstevel@tonic-gate 	 *    implicit signal post and hence the signal post needs
2165*0Sstevel@tonic-gate 	 *    to be done here.
2166*0Sstevel@tonic-gate 	 * The above two cases can be idenfied by the flags
2167*0Sstevel@tonic-gate 	 * field within the sg_io structure as follows:
2168*0Sstevel@tonic-gate 	 * In case 1, the RSM_IMPLICIT_SIGPOST bit is reset to 0 by the
2169*0Sstevel@tonic-gate 	 * plugin, indicating that the signal post was done.
2170*0Sstevel@tonic-gate 	 * In case 2, the bit remains set to a 1 as originally given
2171*0Sstevel@tonic-gate 	 * by the user, and hence a signal post needs to be done here.
2172*0Sstevel@tonic-gate 	 */
2173*0Sstevel@tonic-gate 	if (sg_io->flags & RSM_IMPLICIT_SIGPOST &&
2174*0Sstevel@tonic-gate 		e == RSM_SUCCESS) {
2175*0Sstevel@tonic-gate 		/* Do the implicit signal post */
2176*0Sstevel@tonic-gate 
2177*0Sstevel@tonic-gate 		/*
2178*0Sstevel@tonic-gate 		 * The value of the second argument to this call
2179*0Sstevel@tonic-gate 		 * depends on the value of the sg_io->flags field.
2180*0Sstevel@tonic-gate 		 * If the RSM_SIGPOST_NO_ACCUMULATE flag has been
2181*0Sstevel@tonic-gate 		 * ored into the sg_io->flags field, this indicates
2182*0Sstevel@tonic-gate 		 * that the rsm_intr_signal_post is to be done with
2183*0Sstevel@tonic-gate 		 * the flags argument set to RSM_SIGPOST_NO_ACCUMULATE
2184*0Sstevel@tonic-gate 		 * Else, the flags argument is set to 0. These
2185*0Sstevel@tonic-gate 		 * semantics can be achieved simply by masking off
2186*0Sstevel@tonic-gate 		 * all other bits in the sg_io->flags field except the
2187*0Sstevel@tonic-gate 		 * RSM_SIGPOST_NO_ACCUMULATE bit and using the result
2188*0Sstevel@tonic-gate 		 * as the flags argument for the rsm_intr_signal_post.
2189*0Sstevel@tonic-gate 		 */
2190*0Sstevel@tonic-gate 
2191*0Sstevel@tonic-gate 		int sigpost_flags = sg_io->flags & RSM_SIGPOST_NO_ACCUMULATE;
2192*0Sstevel@tonic-gate 		e = rsm_intr_signal_post(seg, sigpost_flags);
2193*0Sstevel@tonic-gate 
2194*0Sstevel@tonic-gate 	}
2195*0Sstevel@tonic-gate 
2196*0Sstevel@tonic-gate 	/* Restore the flags field within the users scatter gather structure */
2197*0Sstevel@tonic-gate 	sg_io->flags = save_sg_io_flags;
2198*0Sstevel@tonic-gate 
2199*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2200*0Sstevel@tonic-gate 	    "rsm_memseg_import_putv: exit\n"));
2201*0Sstevel@tonic-gate 
2202*0Sstevel@tonic-gate 	return (e);
2203*0Sstevel@tonic-gate }
2204*0Sstevel@tonic-gate 
2205*0Sstevel@tonic-gate 
2206*0Sstevel@tonic-gate 	/*
2207*0Sstevel@tonic-gate 	 * import side memory segment operations (mapping):
2208*0Sstevel@tonic-gate 	 */
2209*0Sstevel@tonic-gate int
2210*0Sstevel@tonic-gate _rsm_memseg_import_map(rsm_memseg_import_handle_t im_memseg,
2211*0Sstevel@tonic-gate     void **address,
2212*0Sstevel@tonic-gate     rsm_attribute_t attr,
2213*0Sstevel@tonic-gate     rsm_permission_t perm,
2214*0Sstevel@tonic-gate     off_t offset,
2215*0Sstevel@tonic-gate     size_t length)
2216*0Sstevel@tonic-gate {
2217*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
2218*0Sstevel@tonic-gate 	int flag = MAP_SHARED;
2219*0Sstevel@tonic-gate 	int prot;
2220*0Sstevel@tonic-gate 	caddr_t va;
2221*0Sstevel@tonic-gate 
2222*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2223*0Sstevel@tonic-gate 	    "rsm_memseg_import_map: enter\n"));
2224*0Sstevel@tonic-gate 
2225*0Sstevel@tonic-gate 	if (!seg) {
2226*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2227*0Sstevel@tonic-gate 		    "invalid segment\n"));
2228*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
2229*0Sstevel@tonic-gate 	}
2230*0Sstevel@tonic-gate 	if (!address) {
2231*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2232*0Sstevel@tonic-gate 		    "invalid address\n"));
2233*0Sstevel@tonic-gate 		return (RSMERR_BAD_ADDR);
2234*0Sstevel@tonic-gate 	}
2235*0Sstevel@tonic-gate 
2236*0Sstevel@tonic-gate 	/*
2237*0Sstevel@tonic-gate 	 * Only one map per segment handle!
2238*0Sstevel@tonic-gate 	 * XXX need to take a lock here
2239*0Sstevel@tonic-gate 	 */
2240*0Sstevel@tonic-gate 	mutex_lock(&seg->rsmseg_lock);
2241*0Sstevel@tonic-gate 
2242*0Sstevel@tonic-gate 	if (seg->rsmseg_state == IMPORT_MAP) {
2243*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
2244*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2245*0Sstevel@tonic-gate 		    "segment already mapped\n"));
2246*0Sstevel@tonic-gate 		return (RSMERR_SEG_ALREADY_MAPPED);
2247*0Sstevel@tonic-gate 	}
2248*0Sstevel@tonic-gate 
2249*0Sstevel@tonic-gate 	/* Only import segments allowed to map */
2250*0Sstevel@tonic-gate 	if (seg->rsmseg_state != IMPORT_CONNECT) {
2251*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
2252*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
2253*0Sstevel@tonic-gate 	}
2254*0Sstevel@tonic-gate 
2255*0Sstevel@tonic-gate 	/* check for permissions */
2256*0Sstevel@tonic-gate 	if (perm > RSM_PERM_RDWR) {
2257*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2258*0Sstevel@tonic-gate 		    "bad permissions when mapping\n"));
2259*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
2260*0Sstevel@tonic-gate 		return (RSMERR_BAD_PERMS);
2261*0Sstevel@tonic-gate 	}
2262*0Sstevel@tonic-gate 
2263*0Sstevel@tonic-gate 	if (length == 0) {
2264*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2265*0Sstevel@tonic-gate 		    "mapping with length 0\n"));
2266*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
2267*0Sstevel@tonic-gate 		return (RSMERR_BAD_LENGTH);
2268*0Sstevel@tonic-gate 	}
2269*0Sstevel@tonic-gate 
2270*0Sstevel@tonic-gate 	if (offset + length > seg->rsmseg_size) {
2271*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2272*0Sstevel@tonic-gate 		    "map length + offset exceed segment size\n"));
2273*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
2274*0Sstevel@tonic-gate 		return (RSMERR_BAD_LENGTH);
2275*0Sstevel@tonic-gate 	}
2276*0Sstevel@tonic-gate 
2277*0Sstevel@tonic-gate 	if ((size_t)offset & (PAGESIZE - 1)) {
2278*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
2279*0Sstevel@tonic-gate 		    "bad mem alignment\n"));
2280*0Sstevel@tonic-gate 		return (RSMERR_BAD_MEM_ALIGNMENT);
2281*0Sstevel@tonic-gate 	}
2282*0Sstevel@tonic-gate 
2283*0Sstevel@tonic-gate 	if (attr & RSM_MAP_FIXED) {
2284*0Sstevel@tonic-gate 		if ((uintptr_t)(*address) & (PAGESIZE - 1)) {
2285*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY, RSM_ERR,
2286*0Sstevel@tonic-gate 			    "bad mem alignment\n"));
2287*0Sstevel@tonic-gate 			return (RSMERR_BAD_MEM_ALIGNMENT);
2288*0Sstevel@tonic-gate 		}
2289*0Sstevel@tonic-gate 		flag |= MAP_FIXED;
2290*0Sstevel@tonic-gate 	}
2291*0Sstevel@tonic-gate 
2292*0Sstevel@tonic-gate 	prot = PROT_NONE;
2293*0Sstevel@tonic-gate 	if (perm & RSM_PERM_READ)
2294*0Sstevel@tonic-gate 		prot |= PROT_READ;
2295*0Sstevel@tonic-gate 	if (perm & RSM_PERM_WRITE)
2296*0Sstevel@tonic-gate 		prot |= PROT_WRITE;
2297*0Sstevel@tonic-gate 
2298*0Sstevel@tonic-gate 	va = mmap(*address, length, prot, flag, seg->rsmseg_fd, offset);
2299*0Sstevel@tonic-gate 	if (va == MAP_FAILED) {
2300*0Sstevel@tonic-gate 		int e = errno;
2301*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2302*0Sstevel@tonic-gate 		    "error %d during map\n", e));
2303*0Sstevel@tonic-gate 
2304*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
2305*0Sstevel@tonic-gate 		if (e == ENXIO || e == EOVERFLOW ||
2306*0Sstevel@tonic-gate 		    e == ENOMEM)
2307*0Sstevel@tonic-gate 			return (RSMERR_BAD_LENGTH);
2308*0Sstevel@tonic-gate 		else if (e == ENODEV)
2309*0Sstevel@tonic-gate 			return (RSMERR_CONN_ABORTED);
2310*0Sstevel@tonic-gate 		else if (e == EAGAIN)
2311*0Sstevel@tonic-gate 			return (RSMERR_INSUFFICIENT_RESOURCES);
2312*0Sstevel@tonic-gate 		else if (e == ENOTSUP)
2313*0Sstevel@tonic-gate 			return (RSMERR_MAP_FAILED);
2314*0Sstevel@tonic-gate 		else if (e == EACCES)
2315*0Sstevel@tonic-gate 			return (RSMERR_BAD_PERMS);
2316*0Sstevel@tonic-gate 		else
2317*0Sstevel@tonic-gate 			return (RSMERR_MAP_FAILED);
2318*0Sstevel@tonic-gate 	}
2319*0Sstevel@tonic-gate 	*address = va;
2320*0Sstevel@tonic-gate 
2321*0Sstevel@tonic-gate 	/*
2322*0Sstevel@tonic-gate 	 * Fix segment ops vector to handle direct access.
2323*0Sstevel@tonic-gate 	 */
2324*0Sstevel@tonic-gate 	/*
2325*0Sstevel@tonic-gate 	 * XXX: Set this only for full segment mapping. Keep a list
2326*0Sstevel@tonic-gate 	 * of mappings to use for access functions
2327*0Sstevel@tonic-gate 	 */
2328*0Sstevel@tonic-gate 	seg->rsmseg_vaddr = va;
2329*0Sstevel@tonic-gate 	seg->rsmseg_maplen = length;
2330*0Sstevel@tonic-gate 	seg->rsmseg_mapoffset = offset;
2331*0Sstevel@tonic-gate 	seg->rsmseg_state = IMPORT_MAP;
2332*0Sstevel@tonic-gate 
2333*0Sstevel@tonic-gate 	mutex_unlock(&seg->rsmseg_lock);
2334*0Sstevel@tonic-gate 
2335*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2336*0Sstevel@tonic-gate 	    "rsm_memseg_import_map: exit\n"));
2337*0Sstevel@tonic-gate 
2338*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
2339*0Sstevel@tonic-gate }
2340*0Sstevel@tonic-gate 
2341*0Sstevel@tonic-gate int
2342*0Sstevel@tonic-gate _rsm_memseg_import_unmap(rsm_memseg_import_handle_t im_memseg)
2343*0Sstevel@tonic-gate {
2344*0Sstevel@tonic-gate 	/*
2345*0Sstevel@tonic-gate 	 * Until we fix the rsm driver to catch unload, we unload
2346*0Sstevel@tonic-gate 	 * the whole segment.
2347*0Sstevel@tonic-gate 	 */
2348*0Sstevel@tonic-gate 
2349*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
2350*0Sstevel@tonic-gate 
2351*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2352*0Sstevel@tonic-gate 	    "rsm_memseg_import_unmap: enter\n"));
2353*0Sstevel@tonic-gate 
2354*0Sstevel@tonic-gate 	if (!seg) {
2355*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2356*0Sstevel@tonic-gate 		    "invalid segment or segment state\n"));
2357*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
2358*0Sstevel@tonic-gate 	}
2359*0Sstevel@tonic-gate 
2360*0Sstevel@tonic-gate 	mutex_lock(&seg->rsmseg_lock);
2361*0Sstevel@tonic-gate 	if (seg->rsmseg_state != IMPORT_MAP) {
2362*0Sstevel@tonic-gate 		mutex_unlock(&seg->rsmseg_lock);
2363*0Sstevel@tonic-gate 		return (RSMERR_SEG_NOT_MAPPED);
2364*0Sstevel@tonic-gate 	}
2365*0Sstevel@tonic-gate 
2366*0Sstevel@tonic-gate 	seg->rsmseg_mapoffset = 0;   /* reset the offset */
2367*0Sstevel@tonic-gate 	seg->rsmseg_state = IMPORT_CONNECT;
2368*0Sstevel@tonic-gate 	seg->rsmseg_flags &= ~RSM_IMPLICIT_MAP;
2369*0Sstevel@tonic-gate 	(void) munmap(seg->rsmseg_vaddr, seg->rsmseg_maplen);
2370*0Sstevel@tonic-gate 
2371*0Sstevel@tonic-gate 	mutex_unlock(&seg->rsmseg_lock);
2372*0Sstevel@tonic-gate 
2373*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2374*0Sstevel@tonic-gate 	    "rsm_memseg_import_unmap: exit\n"));
2375*0Sstevel@tonic-gate 
2376*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
2377*0Sstevel@tonic-gate }
2378*0Sstevel@tonic-gate 
2379*0Sstevel@tonic-gate 
2380*0Sstevel@tonic-gate 	/*
2381*0Sstevel@tonic-gate 	 * import side memory segment operations (barriers):
2382*0Sstevel@tonic-gate 	 */
2383*0Sstevel@tonic-gate int
2384*0Sstevel@tonic-gate _rsm_memseg_import_init_barrier(rsm_memseg_import_handle_t im_memseg,
2385*0Sstevel@tonic-gate     rsm_barrier_type_t type,
2386*0Sstevel@tonic-gate     rsmapi_barrier_t *barrier)
2387*0Sstevel@tonic-gate {
2388*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
2389*0Sstevel@tonic-gate 	rsmbar_handle_t *bar;
2390*0Sstevel@tonic-gate 
2391*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2392*0Sstevel@tonic-gate 	    "rsm_memseg_import_init_barrier: enter\n"));
2393*0Sstevel@tonic-gate 
2394*0Sstevel@tonic-gate 	if (!seg) {
2395*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2396*0Sstevel@tonic-gate 		    "invalid segment or barrier\n"));
2397*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
2398*0Sstevel@tonic-gate 	}
2399*0Sstevel@tonic-gate 	if (!barrier) {
2400*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2401*0Sstevel@tonic-gate 		    "invalid barrier pointer\n"));
2402*0Sstevel@tonic-gate 		return (RSMERR_BAD_BARRIER_PTR);
2403*0Sstevel@tonic-gate 	}
2404*0Sstevel@tonic-gate 
2405*0Sstevel@tonic-gate 	bar = (rsmbar_handle_t *)barrier;
2406*0Sstevel@tonic-gate 	bar->rsmbar_seg = seg;
2407*0Sstevel@tonic-gate 
2408*0Sstevel@tonic-gate 	seg->rsmseg_barrier = barrier;  /* used in put/get fns */
2409*0Sstevel@tonic-gate 
2410*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2411*0Sstevel@tonic-gate 	    "rsm_memseg_import_init_barrier: exit\n"));
2412*0Sstevel@tonic-gate 
2413*0Sstevel@tonic-gate 	return (seg->rsmseg_ops->rsm_memseg_import_init_barrier(im_memseg,
2414*0Sstevel@tonic-gate 	    type, (rsm_barrier_handle_t)barrier));
2415*0Sstevel@tonic-gate }
2416*0Sstevel@tonic-gate 
2417*0Sstevel@tonic-gate int
2418*0Sstevel@tonic-gate _rsm_memseg_import_open_barrier(rsmapi_barrier_t *barrier)
2419*0Sstevel@tonic-gate {
2420*0Sstevel@tonic-gate 	rsmbar_handle_t *bar = (rsmbar_handle_t *)barrier;
2421*0Sstevel@tonic-gate 	rsm_segops_t *ops;
2422*0Sstevel@tonic-gate 
2423*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2424*0Sstevel@tonic-gate 	    "rsm_memseg_import_open_barrier: enter\n"));
2425*0Sstevel@tonic-gate 
2426*0Sstevel@tonic-gate 	if (!bar) {
2427*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2428*0Sstevel@tonic-gate 		    "invalid barrier\n"));
2429*0Sstevel@tonic-gate 		return (RSMERR_BAD_BARRIER_PTR);
2430*0Sstevel@tonic-gate 	}
2431*0Sstevel@tonic-gate 	if (!bar->rsmbar_seg) {
2432*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2433*0Sstevel@tonic-gate 		    "uninitialized barrier\n"));
2434*0Sstevel@tonic-gate 		return (RSMERR_BARRIER_UNINITIALIZED);
2435*0Sstevel@tonic-gate 	}
2436*0Sstevel@tonic-gate 
2437*0Sstevel@tonic-gate 	/* generation number snapshot */
2438*0Sstevel@tonic-gate 	bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; /* bar[0] */
2439*0Sstevel@tonic-gate 
2440*0Sstevel@tonic-gate 	ops = bar->rsmbar_seg->rsmseg_ops;
2441*0Sstevel@tonic-gate 
2442*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2443*0Sstevel@tonic-gate 	    "rsm_memseg_import_open_barrier: exit\n"));
2444*0Sstevel@tonic-gate 
2445*0Sstevel@tonic-gate 	return (ops->rsm_memseg_import_open_barrier(
2446*0Sstevel@tonic-gate 	    (rsm_barrier_handle_t)barrier));
2447*0Sstevel@tonic-gate }
2448*0Sstevel@tonic-gate 
2449*0Sstevel@tonic-gate int
2450*0Sstevel@tonic-gate _rsm_memseg_import_order_barrier(rsmapi_barrier_t *barrier)
2451*0Sstevel@tonic-gate {
2452*0Sstevel@tonic-gate 	rsmbar_handle_t *bar = (rsmbar_handle_t *)barrier;
2453*0Sstevel@tonic-gate 	rsm_segops_t *ops;
2454*0Sstevel@tonic-gate 
2455*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2456*0Sstevel@tonic-gate 	    "rsm_memseg_import_order_barrier: enter\n"));
2457*0Sstevel@tonic-gate 
2458*0Sstevel@tonic-gate 	if (!bar) {
2459*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2460*0Sstevel@tonic-gate 		    "invalid barrier\n"));
2461*0Sstevel@tonic-gate 		return (RSMERR_BAD_BARRIER_PTR);
2462*0Sstevel@tonic-gate 	}
2463*0Sstevel@tonic-gate 	if (!bar->rsmbar_seg) {
2464*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2465*0Sstevel@tonic-gate 		    "uninitialized barrier\n"));
2466*0Sstevel@tonic-gate 		return (RSMERR_BARRIER_UNINITIALIZED);
2467*0Sstevel@tonic-gate 	}
2468*0Sstevel@tonic-gate 
2469*0Sstevel@tonic-gate 	ops = bar->rsmbar_seg->rsmseg_ops;
2470*0Sstevel@tonic-gate 
2471*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2472*0Sstevel@tonic-gate 	    "rsm_memseg_import_order_barrier: exit\n"));
2473*0Sstevel@tonic-gate 
2474*0Sstevel@tonic-gate 	return (ops->rsm_memseg_import_order_barrier(
2475*0Sstevel@tonic-gate 	    (rsm_barrier_handle_t)barrier));
2476*0Sstevel@tonic-gate }
2477*0Sstevel@tonic-gate 
2478*0Sstevel@tonic-gate int
2479*0Sstevel@tonic-gate _rsm_memseg_import_close_barrier(rsmapi_barrier_t *barrier)
2480*0Sstevel@tonic-gate {
2481*0Sstevel@tonic-gate 	rsmbar_handle_t *bar = (rsmbar_handle_t *)barrier;
2482*0Sstevel@tonic-gate 	rsm_segops_t *ops;
2483*0Sstevel@tonic-gate 
2484*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2485*0Sstevel@tonic-gate 	    "rsm_memseg_import_close_barrier: enter\n"));
2486*0Sstevel@tonic-gate 
2487*0Sstevel@tonic-gate 	if (!bar) {
2488*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2489*0Sstevel@tonic-gate 		    "invalid barrier\n"));
2490*0Sstevel@tonic-gate 		return (RSMERR_BAD_BARRIER_PTR);
2491*0Sstevel@tonic-gate 	}
2492*0Sstevel@tonic-gate 	if (!bar->rsmbar_seg) {
2493*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2494*0Sstevel@tonic-gate 		    "uninitialized barrier\n"));
2495*0Sstevel@tonic-gate 		return (RSMERR_BARRIER_UNINITIALIZED);
2496*0Sstevel@tonic-gate 	}
2497*0Sstevel@tonic-gate 
2498*0Sstevel@tonic-gate 	/* generation number snapshot */
2499*0Sstevel@tonic-gate 	if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) {
2500*0Sstevel@tonic-gate 		return (RSMERR_CONN_ABORTED);
2501*0Sstevel@tonic-gate 	}
2502*0Sstevel@tonic-gate 
2503*0Sstevel@tonic-gate 	ops = bar->rsmbar_seg->rsmseg_ops;
2504*0Sstevel@tonic-gate 
2505*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2506*0Sstevel@tonic-gate 	    "rsm_memseg_import_close_barrier: exit\n"));
2507*0Sstevel@tonic-gate 
2508*0Sstevel@tonic-gate 	return (ops->rsm_memseg_import_close_barrier(
2509*0Sstevel@tonic-gate 	    (rsm_barrier_handle_t)barrier));
2510*0Sstevel@tonic-gate }
2511*0Sstevel@tonic-gate 
2512*0Sstevel@tonic-gate int
2513*0Sstevel@tonic-gate _rsm_memseg_import_destroy_barrier(rsmapi_barrier_t *barrier)
2514*0Sstevel@tonic-gate {
2515*0Sstevel@tonic-gate 	rsmbar_handle_t *bar = (rsmbar_handle_t *)barrier;
2516*0Sstevel@tonic-gate 	rsm_segops_t *ops;
2517*0Sstevel@tonic-gate 
2518*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2519*0Sstevel@tonic-gate 	    "rsm_memseg_import_destroy_barrier: enter\n"));
2520*0Sstevel@tonic-gate 
2521*0Sstevel@tonic-gate 	if (!bar) {
2522*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2523*0Sstevel@tonic-gate 		    "invalid barrier\n"));
2524*0Sstevel@tonic-gate 		return (RSMERR_BAD_BARRIER_PTR);
2525*0Sstevel@tonic-gate 	}
2526*0Sstevel@tonic-gate 	if (!bar->rsmbar_seg) {
2527*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2528*0Sstevel@tonic-gate 		    "uninitialized barrier\n"));
2529*0Sstevel@tonic-gate 		return (RSMERR_BARRIER_UNINITIALIZED);
2530*0Sstevel@tonic-gate 	}
2531*0Sstevel@tonic-gate 
2532*0Sstevel@tonic-gate 	bar->rsmbar_seg->rsmseg_barrier = NULL;
2533*0Sstevel@tonic-gate 
2534*0Sstevel@tonic-gate 	ops = bar->rsmbar_seg->rsmseg_ops;
2535*0Sstevel@tonic-gate 
2536*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2537*0Sstevel@tonic-gate 	    "rsm_memseg_import_destroy_barrier: exit\n"));
2538*0Sstevel@tonic-gate 
2539*0Sstevel@tonic-gate 	return (ops->rsm_memseg_import_destroy_barrier
2540*0Sstevel@tonic-gate 	    ((rsm_barrier_handle_t)barrier));
2541*0Sstevel@tonic-gate }
2542*0Sstevel@tonic-gate 
2543*0Sstevel@tonic-gate int
2544*0Sstevel@tonic-gate _rsm_memseg_import_get_mode(rsm_memseg_import_handle_t im_memseg,
2545*0Sstevel@tonic-gate     rsm_barrier_mode_t *mode)
2546*0Sstevel@tonic-gate {
2547*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
2548*0Sstevel@tonic-gate 
2549*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2550*0Sstevel@tonic-gate 	    "rsm_memseg_import_get_mode: enter\n"));
2551*0Sstevel@tonic-gate 
2552*0Sstevel@tonic-gate 	if (seg) {
2553*0Sstevel@tonic-gate 		*mode = seg->rsmseg_barmode;
2554*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2555*0Sstevel@tonic-gate 		    "rsm_memseg_import_get_mode: exit\n"));
2556*0Sstevel@tonic-gate 
2557*0Sstevel@tonic-gate 		return (seg->rsmseg_ops->rsm_memseg_import_get_mode(im_memseg,
2558*0Sstevel@tonic-gate 		    mode));
2559*0Sstevel@tonic-gate 	}
2560*0Sstevel@tonic-gate 
2561*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2562*0Sstevel@tonic-gate 	    "invalid arguments \n"));
2563*0Sstevel@tonic-gate 
2564*0Sstevel@tonic-gate 	return (RSMERR_BAD_SEG_HNDL);
2565*0Sstevel@tonic-gate 
2566*0Sstevel@tonic-gate }
2567*0Sstevel@tonic-gate 
2568*0Sstevel@tonic-gate int
2569*0Sstevel@tonic-gate _rsm_memseg_import_set_mode(rsm_memseg_import_handle_t im_memseg,
2570*0Sstevel@tonic-gate     rsm_barrier_mode_t mode)
2571*0Sstevel@tonic-gate {
2572*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg;
2573*0Sstevel@tonic-gate 
2574*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2575*0Sstevel@tonic-gate 	    "rsm_memseg_import_set_mode: enter\n"));
2576*0Sstevel@tonic-gate 	if (seg) {
2577*0Sstevel@tonic-gate 		if ((mode == RSM_BARRIER_MODE_IMPLICIT ||
2578*0Sstevel@tonic-gate 		    mode == RSM_BARRIER_MODE_EXPLICIT)) {
2579*0Sstevel@tonic-gate 			seg->rsmseg_barmode = mode;
2580*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2581*0Sstevel@tonic-gate 			    "rsm_memseg_import_set_mode: exit\n"));
2582*0Sstevel@tonic-gate 
2583*0Sstevel@tonic-gate 			return (seg->rsmseg_ops->rsm_memseg_import_set_mode(
2584*0Sstevel@tonic-gate 			    im_memseg,
2585*0Sstevel@tonic-gate 			    mode));
2586*0Sstevel@tonic-gate 		} else {
2587*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE,
2588*0Sstevel@tonic-gate 			    "bad barrier mode\n"));
2589*0Sstevel@tonic-gate 			return (RSMERR_BAD_MODE);
2590*0Sstevel@tonic-gate 		}
2591*0Sstevel@tonic-gate 	}
2592*0Sstevel@tonic-gate 
2593*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR,
2594*0Sstevel@tonic-gate 	    "invalid arguments\n"));
2595*0Sstevel@tonic-gate 
2596*0Sstevel@tonic-gate 	return (RSMERR_BAD_SEG_HNDL);
2597*0Sstevel@tonic-gate }
2598*0Sstevel@tonic-gate 
2599*0Sstevel@tonic-gate int
2600*0Sstevel@tonic-gate _rsm_intr_signal_post(void *memseg, uint_t flags)
2601*0Sstevel@tonic-gate {
2602*0Sstevel@tonic-gate 	rsm_ioctlmsg_t msg;
2603*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg;
2604*0Sstevel@tonic-gate 
2605*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2606*0Sstevel@tonic-gate 	    "rsm_intr_signal_post: enter\n"));
2607*0Sstevel@tonic-gate 
2608*0Sstevel@tonic-gate 	flags = flags;
2609*0Sstevel@tonic-gate 
2610*0Sstevel@tonic-gate 	if (!seg) {
2611*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
2612*0Sstevel@tonic-gate 		    "invalid segment handle\n"));
2613*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
2614*0Sstevel@tonic-gate 	}
2615*0Sstevel@tonic-gate 
2616*0Sstevel@tonic-gate 	if (ioctl(seg->rsmseg_fd, RSM_IOCTL_RING_BELL, &msg) < 0) {
2617*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
2618*0Sstevel@tonic-gate 		    "RSM_IOCTL_RING_BELL failed\n"));
2619*0Sstevel@tonic-gate 		return (errno);
2620*0Sstevel@tonic-gate 	}
2621*0Sstevel@tonic-gate 
2622*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2623*0Sstevel@tonic-gate 	    "rsm_intr_signal_post: exit\n"));
2624*0Sstevel@tonic-gate 
2625*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
2626*0Sstevel@tonic-gate }
2627*0Sstevel@tonic-gate 
2628*0Sstevel@tonic-gate int
2629*0Sstevel@tonic-gate _rsm_intr_signal_wait(void *memseg, int timeout)
2630*0Sstevel@tonic-gate {
2631*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg;
2632*0Sstevel@tonic-gate 	struct pollfd fds;
2633*0Sstevel@tonic-gate 	minor_t	rnum;
2634*0Sstevel@tonic-gate 
2635*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2636*0Sstevel@tonic-gate 	    "rsm_intr_signal_wait: enter\n"));
2637*0Sstevel@tonic-gate 
2638*0Sstevel@tonic-gate 	if (!seg) {
2639*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
2640*0Sstevel@tonic-gate 		    "invalid segment\n"));
2641*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
2642*0Sstevel@tonic-gate 	}
2643*0Sstevel@tonic-gate 
2644*0Sstevel@tonic-gate 	fds.fd = seg->rsmseg_fd;
2645*0Sstevel@tonic-gate 	fds.events = POLLRDNORM;
2646*0Sstevel@tonic-gate 
2647*0Sstevel@tonic-gate 	rnum = seg->rsmseg_rnum;
2648*0Sstevel@tonic-gate 
2649*0Sstevel@tonic-gate 	return (__rsm_intr_signal_wait_common(&fds, &rnum, 1, timeout, NULL));
2650*0Sstevel@tonic-gate }
2651*0Sstevel@tonic-gate 
2652*0Sstevel@tonic-gate int
2653*0Sstevel@tonic-gate _rsm_intr_signal_wait_pollfd(struct pollfd fds[], nfds_t nfds, int timeout,
2654*0Sstevel@tonic-gate 	int *numfdsp)
2655*0Sstevel@tonic-gate {
2656*0Sstevel@tonic-gate 	return (__rsm_intr_signal_wait_common(fds, NULL, nfds, timeout,
2657*0Sstevel@tonic-gate 	    numfdsp));
2658*0Sstevel@tonic-gate }
2659*0Sstevel@tonic-gate 
2660*0Sstevel@tonic-gate /*
2661*0Sstevel@tonic-gate  * This is the generic wait routine, it takes the following arguments
2662*0Sstevel@tonic-gate  *	- pollfd array
2663*0Sstevel@tonic-gate  *	- rnums array corresponding to the pollfd if known, if this is
2664*0Sstevel@tonic-gate  *	NULL then the fds are looked up from the pollfd_table.
2665*0Sstevel@tonic-gate  *	- number of fds in pollfd array,
2666*0Sstevel@tonic-gate  *	- timeout
2667*0Sstevel@tonic-gate  *	- pointer to a location where the number of fds with successful
2668*0Sstevel@tonic-gate  *	events is returned.
2669*0Sstevel@tonic-gate  */
2670*0Sstevel@tonic-gate static int
2671*0Sstevel@tonic-gate __rsm_intr_signal_wait_common(struct pollfd fds[], minor_t rnums[],
2672*0Sstevel@tonic-gate     nfds_t nfds, int timeout, int *numfdsp)
2673*0Sstevel@tonic-gate {
2674*0Sstevel@tonic-gate 	int	i;
2675*0Sstevel@tonic-gate 	int	numsegs = 0;
2676*0Sstevel@tonic-gate 	int	numfd;
2677*0Sstevel@tonic-gate 	int	fds_processed = 0;
2678*0Sstevel@tonic-gate 	minor_t	segrnum;
2679*0Sstevel@tonic-gate 	rsm_poll_event_t	event_arr[RSM_MAX_POLLFDS];
2680*0Sstevel@tonic-gate 	rsm_poll_event_t	*event_list = NULL;
2681*0Sstevel@tonic-gate 	rsm_poll_event_t	*events;
2682*0Sstevel@tonic-gate 	rsm_consume_event_msg_t msg;
2683*0Sstevel@tonic-gate 
2684*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, "wait_common enter\n"));
2685*0Sstevel@tonic-gate 
2686*0Sstevel@tonic-gate 	if (numfdsp) {
2687*0Sstevel@tonic-gate 		*numfdsp = 0;
2688*0Sstevel@tonic-gate 	}
2689*0Sstevel@tonic-gate 
2690*0Sstevel@tonic-gate 	numfd = poll(fds, nfds, timeout);
2691*0Sstevel@tonic-gate 
2692*0Sstevel@tonic-gate 	switch (numfd) {
2693*0Sstevel@tonic-gate 	case -1: /* poll returned error - map to RSMERR_... */
2694*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR, "signal wait pollfd err\n"));
2695*0Sstevel@tonic-gate 		switch (errno) {
2696*0Sstevel@tonic-gate 		case EAGAIN:
2697*0Sstevel@tonic-gate 			return (RSMERR_INSUFFICIENT_RESOURCES);
2698*0Sstevel@tonic-gate 		case EFAULT:
2699*0Sstevel@tonic-gate 			return (RSMERR_BAD_ADDR);
2700*0Sstevel@tonic-gate 		case EINTR:
2701*0Sstevel@tonic-gate 			return (RSMERR_INTERRUPTED);
2702*0Sstevel@tonic-gate 		case EINVAL:
2703*0Sstevel@tonic-gate 		default:
2704*0Sstevel@tonic-gate 			return (RSMERR_BAD_ARGS_ERRORS);
2705*0Sstevel@tonic-gate 		}
2706*0Sstevel@tonic-gate 	case 0: /* timedout - return from here */
2707*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
2708*0Sstevel@tonic-gate 		    "signal wait timed out\n"));
2709*0Sstevel@tonic-gate 		return (RSMERR_TIMEOUT);
2710*0Sstevel@tonic-gate 	default:
2711*0Sstevel@tonic-gate 		break;
2712*0Sstevel@tonic-gate 	}
2713*0Sstevel@tonic-gate 
2714*0Sstevel@tonic-gate 	if (numfd <= RSM_MAX_POLLFDS) {
2715*0Sstevel@tonic-gate 		/* use the event array on the stack */
2716*0Sstevel@tonic-gate 		events = (rsm_poll_event_t *)event_arr;
2717*0Sstevel@tonic-gate 	} else {
2718*0Sstevel@tonic-gate 		/*
2719*0Sstevel@tonic-gate 		 * actual number of fds corresponding to rsmapi segments might
2720*0Sstevel@tonic-gate 		 * be < numfd, don't want to scan the list to figure that out
2721*0Sstevel@tonic-gate 		 * lets just allocate on the heap
2722*0Sstevel@tonic-gate 		 */
2723*0Sstevel@tonic-gate 		event_list = (rsm_poll_event_t *)malloc(
2724*0Sstevel@tonic-gate 			sizeof (rsm_poll_event_t)*numfd);
2725*0Sstevel@tonic-gate 		if (!event_list) {
2726*0Sstevel@tonic-gate 			/*
2727*0Sstevel@tonic-gate 			 * return with error even if poll might have succeeded
2728*0Sstevel@tonic-gate 			 * since the application can retry and the events will
2729*0Sstevel@tonic-gate 			 * still be available.
2730*0Sstevel@tonic-gate 			 */
2731*0Sstevel@tonic-gate 			return (RSMERR_INSUFFICIENT_MEM);
2732*0Sstevel@tonic-gate 		}
2733*0Sstevel@tonic-gate 		events = event_list;
2734*0Sstevel@tonic-gate 	}
2735*0Sstevel@tonic-gate 
2736*0Sstevel@tonic-gate 	/*
2737*0Sstevel@tonic-gate 	 * process the fds for events and if it corresponds to an rsmapi
2738*0Sstevel@tonic-gate 	 * segment consume the event
2739*0Sstevel@tonic-gate 	 */
2740*0Sstevel@tonic-gate 	for (i = 0; i < nfds; i++) {
2741*0Sstevel@tonic-gate 		if (fds[i].revents == POLLRDNORM) {
2742*0Sstevel@tonic-gate 			/*
2743*0Sstevel@tonic-gate 			 * poll returned an event and if its POLLRDNORM, it
2744*0Sstevel@tonic-gate 			 * might correspond to an rsmapi segment
2745*0Sstevel@tonic-gate 			 */
2746*0Sstevel@tonic-gate 			if (rnums) { /* resource num is passed in */
2747*0Sstevel@tonic-gate 				segrnum = rnums[i];
2748*0Sstevel@tonic-gate 			} else { /* lookup pollfd table to get resource num */
2749*0Sstevel@tonic-gate 				segrnum = _rsm_lookup_pollfd_table(fds[i].fd);
2750*0Sstevel@tonic-gate 			}
2751*0Sstevel@tonic-gate 			if (segrnum) {
2752*0Sstevel@tonic-gate 				events[numsegs].rnum = segrnum;
2753*0Sstevel@tonic-gate 				events[numsegs].revent = 0;
2754*0Sstevel@tonic-gate 				events[numsegs].fdsidx = i; /* fdlist index */
2755*0Sstevel@tonic-gate 				numsegs++;
2756*0Sstevel@tonic-gate 			}
2757*0Sstevel@tonic-gate 		}
2758*0Sstevel@tonic-gate 
2759*0Sstevel@tonic-gate 		if ((fds[i].revents) && (++fds_processed == numfd)) {
2760*0Sstevel@tonic-gate 			/*
2761*0Sstevel@tonic-gate 			 * only "numfd" events have revents field set, once we
2762*0Sstevel@tonic-gate 			 * process that many break out of the loop
2763*0Sstevel@tonic-gate 			 */
2764*0Sstevel@tonic-gate 			break;
2765*0Sstevel@tonic-gate 		}
2766*0Sstevel@tonic-gate 	}
2767*0Sstevel@tonic-gate 
2768*0Sstevel@tonic-gate 	if (numsegs == 0) { /* No events for rsmapi segs in the fdlist */
2769*0Sstevel@tonic-gate 		if (event_list) {
2770*0Sstevel@tonic-gate 			free(event_list);
2771*0Sstevel@tonic-gate 		}
2772*0Sstevel@tonic-gate 		if (numfdsp) {
2773*0Sstevel@tonic-gate 			*numfdsp = numfd;
2774*0Sstevel@tonic-gate 		}
2775*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2776*0Sstevel@tonic-gate 		    "wait_common exit: no rsmapi segs\n"));
2777*0Sstevel@tonic-gate 		return (RSM_SUCCESS);
2778*0Sstevel@tonic-gate 	}
2779*0Sstevel@tonic-gate 
2780*0Sstevel@tonic-gate 	msg.seglist = (caddr_t)events;
2781*0Sstevel@tonic-gate 	msg.numents = numsegs;
2782*0Sstevel@tonic-gate 
2783*0Sstevel@tonic-gate 	if (ioctl(_rsm_fd, RSM_IOCTL_CONSUMEEVENT, &msg) < 0) {
2784*0Sstevel@tonic-gate 		int error = errno;
2785*0Sstevel@tonic-gate 		if (event_list) {
2786*0Sstevel@tonic-gate 			free(event_list);
2787*0Sstevel@tonic-gate 		}
2788*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_ERR,
2789*0Sstevel@tonic-gate 		    "RSM_IOCTL_CONSUMEEVENT failed(%d)\n", error));
2790*0Sstevel@tonic-gate 		return (error);
2791*0Sstevel@tonic-gate 	}
2792*0Sstevel@tonic-gate 
2793*0Sstevel@tonic-gate 	/* count the number of segs for which consumeevent was successful */
2794*0Sstevel@tonic-gate 	numfd -= numsegs;
2795*0Sstevel@tonic-gate 
2796*0Sstevel@tonic-gate 	for (i = 0; i < numsegs; i++) {
2797*0Sstevel@tonic-gate 		if (events[i].revent != 0) {
2798*0Sstevel@tonic-gate 			fds[events[i].fdsidx].revents = POLLRDNORM;
2799*0Sstevel@tonic-gate 			numfd++;
2800*0Sstevel@tonic-gate 		} else { /* failed to consume event so set revents to 0 */
2801*0Sstevel@tonic-gate 			fds[events[i].fdsidx].revents = 0;
2802*0Sstevel@tonic-gate 		}
2803*0Sstevel@tonic-gate 	}
2804*0Sstevel@tonic-gate 
2805*0Sstevel@tonic-gate 	if (event_list) {
2806*0Sstevel@tonic-gate 		free(event_list);
2807*0Sstevel@tonic-gate 	}
2808*0Sstevel@tonic-gate 
2809*0Sstevel@tonic-gate 	if (numfd > 0) {
2810*0Sstevel@tonic-gate 		if (numfdsp) {
2811*0Sstevel@tonic-gate 			*numfdsp = numfd;
2812*0Sstevel@tonic-gate 		}
2813*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2814*0Sstevel@tonic-gate 		    "wait_common exit\n"));
2815*0Sstevel@tonic-gate 		return (RSM_SUCCESS);
2816*0Sstevel@tonic-gate 	} else {
2817*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2818*0Sstevel@tonic-gate 		    "wait_common exit\n"));
2819*0Sstevel@tonic-gate 		return (RSMERR_TIMEOUT);
2820*0Sstevel@tonic-gate 	}
2821*0Sstevel@tonic-gate }
2822*0Sstevel@tonic-gate 
2823*0Sstevel@tonic-gate /*
2824*0Sstevel@tonic-gate  * This function provides the data (file descriptor and event) for
2825*0Sstevel@tonic-gate  * the specified pollfd struct.  The pollfd struct may then be
2826*0Sstevel@tonic-gate  * subsequently used with the poll system call to wait for an event
2827*0Sstevel@tonic-gate  * signalled by rsm_intr_signal_post.  The memory segment must be
2828*0Sstevel@tonic-gate  * currently published for a successful return with a valid pollfd.
2829*0Sstevel@tonic-gate  * A reference count for the descriptor is incremented.
2830*0Sstevel@tonic-gate  */
2831*0Sstevel@tonic-gate int
2832*0Sstevel@tonic-gate _rsm_memseg_get_pollfd(void *memseg,
2833*0Sstevel@tonic-gate 			struct pollfd *poll_fd)
2834*0Sstevel@tonic-gate {
2835*0Sstevel@tonic-gate 	int	i;
2836*0Sstevel@tonic-gate 	int	err = RSM_SUCCESS;
2837*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg;
2838*0Sstevel@tonic-gate 
2839*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2840*0Sstevel@tonic-gate 	    "rsm_memseg_get_pollfd: enter\n"));
2841*0Sstevel@tonic-gate 
2842*0Sstevel@tonic-gate 	if (!seg) {
2843*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
2844*0Sstevel@tonic-gate 		    "invalid segment\n"));
2845*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
2846*0Sstevel@tonic-gate 	}
2847*0Sstevel@tonic-gate 
2848*0Sstevel@tonic-gate 	mutex_lock(&seg->rsmseg_lock);
2849*0Sstevel@tonic-gate 
2850*0Sstevel@tonic-gate 	poll_fd->fd = seg->rsmseg_fd;
2851*0Sstevel@tonic-gate 	poll_fd->events = POLLRDNORM;
2852*0Sstevel@tonic-gate 	seg->rsmseg_pollfd_refcnt++;
2853*0Sstevel@tonic-gate 	if (seg->rsmseg_pollfd_refcnt == 1) {
2854*0Sstevel@tonic-gate 		/* insert the segment into the pollfd table */
2855*0Sstevel@tonic-gate 		err = _rsm_insert_pollfd_table(seg->rsmseg_fd,
2856*0Sstevel@tonic-gate 		    seg->rsmseg_rnum);
2857*0Sstevel@tonic-gate 	}
2858*0Sstevel@tonic-gate 
2859*0Sstevel@tonic-gate 	mutex_unlock(&seg->rsmseg_lock);
2860*0Sstevel@tonic-gate 
2861*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2862*0Sstevel@tonic-gate 	    "rsm_memseg_get_pollfd: exit(%d)\n", err));
2863*0Sstevel@tonic-gate 
2864*0Sstevel@tonic-gate 	return (err);
2865*0Sstevel@tonic-gate }
2866*0Sstevel@tonic-gate 
2867*0Sstevel@tonic-gate /*
2868*0Sstevel@tonic-gate  * This function decrements the segment pollfd reference count.
2869*0Sstevel@tonic-gate  * A segment unpublish or destroy operation will fail if the reference count is
2870*0Sstevel@tonic-gate  * non zero.
2871*0Sstevel@tonic-gate  */
2872*0Sstevel@tonic-gate int
2873*0Sstevel@tonic-gate _rsm_memseg_release_pollfd(void * memseg)
2874*0Sstevel@tonic-gate {
2875*0Sstevel@tonic-gate 	int	i;
2876*0Sstevel@tonic-gate 	rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg;
2877*0Sstevel@tonic-gate 
2878*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2879*0Sstevel@tonic-gate 	    "rsm_memseg_release_pollfd: enter\n"));
2880*0Sstevel@tonic-gate 
2881*0Sstevel@tonic-gate 	if (!seg) {
2882*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
2883*0Sstevel@tonic-gate 		    "invalid segment handle\n"));
2884*0Sstevel@tonic-gate 		return (RSMERR_BAD_SEG_HNDL);
2885*0Sstevel@tonic-gate 	}
2886*0Sstevel@tonic-gate 
2887*0Sstevel@tonic-gate 	mutex_lock(&seg->rsmseg_lock);
2888*0Sstevel@tonic-gate 
2889*0Sstevel@tonic-gate 	if (seg->rsmseg_pollfd_refcnt) {
2890*0Sstevel@tonic-gate 		seg->rsmseg_pollfd_refcnt--;
2891*0Sstevel@tonic-gate 		if (seg->rsmseg_pollfd_refcnt == 0) {
2892*0Sstevel@tonic-gate 			/* last reference removed - update the pollfd_table */
2893*0Sstevel@tonic-gate 			_rsm_remove_pollfd_table(seg->rsmseg_fd);
2894*0Sstevel@tonic-gate 		}
2895*0Sstevel@tonic-gate 	}
2896*0Sstevel@tonic-gate 
2897*0Sstevel@tonic-gate 	mutex_unlock(&seg->rsmseg_lock);
2898*0Sstevel@tonic-gate 
2899*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2900*0Sstevel@tonic-gate 	    "rsm_memseg_release_pollfd: exit\n"));
2901*0Sstevel@tonic-gate 
2902*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
2903*0Sstevel@tonic-gate }
2904*0Sstevel@tonic-gate 
2905*0Sstevel@tonic-gate /*
2906*0Sstevel@tonic-gate  * The interconnect topology data is obtained from the Kernel Agent
2907*0Sstevel@tonic-gate  * and stored in a memory buffer allocated by this function.  A pointer
2908*0Sstevel@tonic-gate  * to the buffer is stored in the location specified by the caller in
2909*0Sstevel@tonic-gate  * the function argument.  It is the callers responsibility to
2910*0Sstevel@tonic-gate  * call rsm_free_interconnect_topolgy() to free the allocated memory.
2911*0Sstevel@tonic-gate  */
2912*0Sstevel@tonic-gate int
2913*0Sstevel@tonic-gate _rsm_get_interconnect_topology(rsm_topology_t **topology_data)
2914*0Sstevel@tonic-gate {
2915*0Sstevel@tonic-gate 	uint32_t		topology_data_size;
2916*0Sstevel@tonic-gate 	rsm_topology_t		*topology_ptr;
2917*0Sstevel@tonic-gate 	int			error;
2918*0Sstevel@tonic-gate 
2919*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2920*0Sstevel@tonic-gate 	    "rsm_get_interconnect_topology: enter\n"));
2921*0Sstevel@tonic-gate 
2922*0Sstevel@tonic-gate 	if (topology_data == NULL)
2923*0Sstevel@tonic-gate 		return (RSMERR_BAD_TOPOLOGY_PTR);
2924*0Sstevel@tonic-gate 
2925*0Sstevel@tonic-gate 	*topology_data = NULL;
2926*0Sstevel@tonic-gate 
2927*0Sstevel@tonic-gate again:
2928*0Sstevel@tonic-gate 	/* obtain the size of the topology data */
2929*0Sstevel@tonic-gate 	if (ioctl(_rsm_fd, RSM_IOCTL_TOPOLOGY_SIZE, &topology_data_size) < 0) {
2930*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
2931*0Sstevel@tonic-gate 		    "RSM_IOCTL_TOPOLOGY_SIZE failed\n"));
2932*0Sstevel@tonic-gate 		return (errno);
2933*0Sstevel@tonic-gate 	}
2934*0Sstevel@tonic-gate 
2935*0Sstevel@tonic-gate 	/* allocate double-word aligned memory to hold the topology data */
2936*0Sstevel@tonic-gate 	topology_ptr = (rsm_topology_t *)memalign(8, topology_data_size);
2937*0Sstevel@tonic-gate 	if (topology_ptr == NULL) {
2938*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
2939*0Sstevel@tonic-gate 		    "not enough memory\n"));
2940*0Sstevel@tonic-gate 		return (RSMERR_INSUFFICIENT_MEM);
2941*0Sstevel@tonic-gate 	}
2942*0Sstevel@tonic-gate 
2943*0Sstevel@tonic-gate 	/*
2944*0Sstevel@tonic-gate 	 * Request the topology data.
2945*0Sstevel@tonic-gate 	 * Pass in the size to be used as a check in case
2946*0Sstevel@tonic-gate 	 * the data has grown since the size was obtained - if
2947*0Sstevel@tonic-gate 	 * it has, the errno value will be E2BIG.
2948*0Sstevel@tonic-gate 	 */
2949*0Sstevel@tonic-gate 	topology_ptr->topology_hdr.local_nodeid =
2950*0Sstevel@tonic-gate 	    (rsm_node_id_t)topology_data_size;
2951*0Sstevel@tonic-gate 	if (ioctl(_rsm_fd, RSM_IOCTL_TOPOLOGY_DATA, topology_ptr) < 0) {
2952*0Sstevel@tonic-gate 		error = errno;
2953*0Sstevel@tonic-gate 		free((void *)topology_ptr);
2954*0Sstevel@tonic-gate 		if (error == E2BIG)
2955*0Sstevel@tonic-gate 			goto again;
2956*0Sstevel@tonic-gate 		else {
2957*0Sstevel@tonic-gate 			DBPRINTF((RSM_LIBRARY, RSM_ERR,
2958*0Sstevel@tonic-gate 			    "RSM_IOCTL_TOPOLOGY_DATA failed\n"));
2959*0Sstevel@tonic-gate 			return (error);
2960*0Sstevel@tonic-gate 		}
2961*0Sstevel@tonic-gate 	} else
2962*0Sstevel@tonic-gate 		*topology_data = topology_ptr;
2963*0Sstevel@tonic-gate 
2964*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2965*0Sstevel@tonic-gate 	    " rsm_get_interconnect_topology: exit\n"));
2966*0Sstevel@tonic-gate 
2967*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
2968*0Sstevel@tonic-gate }
2969*0Sstevel@tonic-gate 
2970*0Sstevel@tonic-gate 
2971*0Sstevel@tonic-gate void
2972*0Sstevel@tonic-gate _rsm_free_interconnect_topology(rsm_topology_t *topology_ptr)
2973*0Sstevel@tonic-gate {
2974*0Sstevel@tonic-gate 
2975*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2976*0Sstevel@tonic-gate 	    "rsm_free_interconnect_topology: enter\n"));
2977*0Sstevel@tonic-gate 
2978*0Sstevel@tonic-gate 	if (topology_ptr) {
2979*0Sstevel@tonic-gate 		free((void *)topology_ptr);
2980*0Sstevel@tonic-gate 	}
2981*0Sstevel@tonic-gate 
2982*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2983*0Sstevel@tonic-gate 	    "rsm_free_interconnect_topology: exit\n"));
2984*0Sstevel@tonic-gate }
2985*0Sstevel@tonic-gate 
2986*0Sstevel@tonic-gate int
2987*0Sstevel@tonic-gate _rsm_create_localmemory_handle(rsmapi_controller_handle_t cntrl_handle,
2988*0Sstevel@tonic-gate 				rsm_localmemory_handle_t *local_hndl_p,
2989*0Sstevel@tonic-gate 				caddr_t local_vaddr, size_t len)
2990*0Sstevel@tonic-gate {
2991*0Sstevel@tonic-gate 	int e;
2992*0Sstevel@tonic-gate 	rsm_controller_t *cntrl = (rsm_controller_t *)cntrl_handle;
2993*0Sstevel@tonic-gate 
2994*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
2995*0Sstevel@tonic-gate 	    "rsm_create_localmemory_handle: enter\n"));
2996*0Sstevel@tonic-gate 
2997*0Sstevel@tonic-gate 	if ((size_t)local_vaddr & (PAGESIZE - 1)) {
2998*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
2999*0Sstevel@tonic-gate 		    "invalid arguments\n"));
3000*0Sstevel@tonic-gate 		return (RSMERR_BAD_ADDR);
3001*0Sstevel@tonic-gate 	}
3002*0Sstevel@tonic-gate 
3003*0Sstevel@tonic-gate 	if (!cntrl_handle) {
3004*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
3005*0Sstevel@tonic-gate 		    "invalid controller handle\n"));
3006*0Sstevel@tonic-gate 		return (RSMERR_BAD_CTLR_HNDL);
3007*0Sstevel@tonic-gate 	}
3008*0Sstevel@tonic-gate 	if (!local_hndl_p) {
3009*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
3010*0Sstevel@tonic-gate 		    "invalid local memory handle pointer\n"));
3011*0Sstevel@tonic-gate 		return (RSMERR_BAD_LOCALMEM_HNDL);
3012*0Sstevel@tonic-gate 	}
3013*0Sstevel@tonic-gate 	if (len == 0) {
3014*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
3015*0Sstevel@tonic-gate 		    "invalid length\n"));
3016*0Sstevel@tonic-gate 		return (RSMERR_BAD_LENGTH);
3017*0Sstevel@tonic-gate 	}
3018*0Sstevel@tonic-gate 
3019*0Sstevel@tonic-gate 	e = cntrl->cntr_segops->rsm_create_localmemory_handle(
3020*0Sstevel@tonic-gate 	    cntrl_handle,
3021*0Sstevel@tonic-gate 	    local_hndl_p,
3022*0Sstevel@tonic-gate 	    local_vaddr,
3023*0Sstevel@tonic-gate 	    len);
3024*0Sstevel@tonic-gate 
3025*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
3026*0Sstevel@tonic-gate 	    "rsm_create_localmemory_handle: exit\n"));
3027*0Sstevel@tonic-gate 
3028*0Sstevel@tonic-gate 	return (e);
3029*0Sstevel@tonic-gate }
3030*0Sstevel@tonic-gate 
3031*0Sstevel@tonic-gate int
3032*0Sstevel@tonic-gate _rsm_free_localmemory_handle(rsmapi_controller_handle_t cntrl_handle,
3033*0Sstevel@tonic-gate     rsm_localmemory_handle_t local_handle)
3034*0Sstevel@tonic-gate {
3035*0Sstevel@tonic-gate 	int e;
3036*0Sstevel@tonic-gate 
3037*0Sstevel@tonic-gate 	rsm_controller_t *cntrl = (rsm_controller_t *)cntrl_handle;
3038*0Sstevel@tonic-gate 
3039*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
3040*0Sstevel@tonic-gate 	    "rsm_free_localmemory_handle: enter\n"));
3041*0Sstevel@tonic-gate 
3042*0Sstevel@tonic-gate 
3043*0Sstevel@tonic-gate 	if (!cntrl_handle) {
3044*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
3045*0Sstevel@tonic-gate 		    "invalid controller handle\n"));
3046*0Sstevel@tonic-gate 		return (RSMERR_BAD_CTLR_HNDL);
3047*0Sstevel@tonic-gate 	}
3048*0Sstevel@tonic-gate 
3049*0Sstevel@tonic-gate 	if (!local_handle) {
3050*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
3051*0Sstevel@tonic-gate 		    "invalid localmemory handle\n"));
3052*0Sstevel@tonic-gate 		return (RSMERR_BAD_LOCALMEM_HNDL);
3053*0Sstevel@tonic-gate 	}
3054*0Sstevel@tonic-gate 
3055*0Sstevel@tonic-gate 	e = cntrl->cntr_segops->rsm_free_localmemory_handle(local_handle);
3056*0Sstevel@tonic-gate 
3057*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
3058*0Sstevel@tonic-gate 	    "rsm_free_localmemory_handle: exit\n"));
3059*0Sstevel@tonic-gate 
3060*0Sstevel@tonic-gate 	return (e);
3061*0Sstevel@tonic-gate }
3062*0Sstevel@tonic-gate 
3063*0Sstevel@tonic-gate int
3064*0Sstevel@tonic-gate _rsm_get_segmentid_range(const char *appid, rsm_memseg_id_t *baseid,
3065*0Sstevel@tonic-gate 	uint32_t *length)
3066*0Sstevel@tonic-gate {
3067*0Sstevel@tonic-gate 	char    buf[RSMFILE_BUFSIZE];
3068*0Sstevel@tonic-gate 	char	*s;
3069*0Sstevel@tonic-gate 	char	*fieldv[4];
3070*0Sstevel@tonic-gate 	int	fieldc = 0;
3071*0Sstevel@tonic-gate 	int	found = 0;
3072*0Sstevel@tonic-gate 	int	err = RSMERR_BAD_APPID;
3073*0Sstevel@tonic-gate 	FILE    *fp;
3074*0Sstevel@tonic-gate 
3075*0Sstevel@tonic-gate 	if (appid == NULL || baseid == NULL || length == NULL)
3076*0Sstevel@tonic-gate 		return (RSMERR_BAD_ADDR);
3077*0Sstevel@tonic-gate 
3078*0Sstevel@tonic-gate 	if ((fp = fopen(RSMSEGIDFILE, "r")) == NULL) {
3079*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
3080*0Sstevel@tonic-gate 		    "cannot open <%s>\n", RSMSEGIDFILE));
3081*0Sstevel@tonic-gate 		return (RSMERR_BAD_CONF);
3082*0Sstevel@tonic-gate 	}
3083*0Sstevel@tonic-gate 
3084*0Sstevel@tonic-gate 	while (s = fgets(buf, RSMFILE_BUFSIZE, fp)) {
3085*0Sstevel@tonic-gate 		fieldc = 0;
3086*0Sstevel@tonic-gate 		while (isspace(*s))	/* skip the leading spaces */
3087*0Sstevel@tonic-gate 			s++;
3088*0Sstevel@tonic-gate 
3089*0Sstevel@tonic-gate 		if (*s == '#') {	/* comment line - skip it */
3090*0Sstevel@tonic-gate 			continue;
3091*0Sstevel@tonic-gate 		}
3092*0Sstevel@tonic-gate 
3093*0Sstevel@tonic-gate 		/*
3094*0Sstevel@tonic-gate 		 * parse the reserved segid file and
3095*0Sstevel@tonic-gate 		 * set the pointers appropriately.
3096*0Sstevel@tonic-gate 		 * fieldv[0] :  keyword
3097*0Sstevel@tonic-gate 		 * fieldv[1] :  application identifier
3098*0Sstevel@tonic-gate 		 * fieldv[2] :  baseid
3099*0Sstevel@tonic-gate 		 * fieldv[3] :  length
3100*0Sstevel@tonic-gate 		 */
3101*0Sstevel@tonic-gate 		while ((*s != '\n') && (*s != '\0') && (fieldc < 4)) {
3102*0Sstevel@tonic-gate 
3103*0Sstevel@tonic-gate 			while (isspace(*s)) /* skip the leading spaces */
3104*0Sstevel@tonic-gate 				s++;
3105*0Sstevel@tonic-gate 
3106*0Sstevel@tonic-gate 			fieldv[fieldc++] = s;
3107*0Sstevel@tonic-gate 
3108*0Sstevel@tonic-gate 			if (fieldc == 4) {
3109*0Sstevel@tonic-gate 				if (fieldv[3][strlen(fieldv[3])-1] == '\n')
3110*0Sstevel@tonic-gate 					fieldv[3][strlen(fieldv[3])-1] = '\0';
3111*0Sstevel@tonic-gate 				break;
3112*0Sstevel@tonic-gate 			}
3113*0Sstevel@tonic-gate 
3114*0Sstevel@tonic-gate 			while (*s && !isspace(*s))
3115*0Sstevel@tonic-gate 				++s;	/* move to the next white space */
3116*0Sstevel@tonic-gate 
3117*0Sstevel@tonic-gate 			if (*s)
3118*0Sstevel@tonic-gate 				*s++ = '\0';
3119*0Sstevel@tonic-gate 		}
3120*0Sstevel@tonic-gate 
3121*0Sstevel@tonic-gate 		if (fieldc < 4) {	/* some fields are missing */
3122*0Sstevel@tonic-gate 			err = RSMERR_BAD_CONF;
3123*0Sstevel@tonic-gate 			break;
3124*0Sstevel@tonic-gate 		}
3125*0Sstevel@tonic-gate 
3126*0Sstevel@tonic-gate 		if (strcasecmp(fieldv[1], appid) == 0) { /* found a match */
3127*0Sstevel@tonic-gate 			if (strcasecmp(fieldv[0], RSMSEG_RESERVED) == 0) {
3128*0Sstevel@tonic-gate 				errno = 0;
3129*0Sstevel@tonic-gate 				*baseid = strtol(fieldv[2], (char **)NULL, 16);
3130*0Sstevel@tonic-gate 				if (errno != 0) {
3131*0Sstevel@tonic-gate 					err = RSMERR_BAD_CONF;
3132*0Sstevel@tonic-gate 					break;
3133*0Sstevel@tonic-gate 				}
3134*0Sstevel@tonic-gate 
3135*0Sstevel@tonic-gate 				errno = 0;
3136*0Sstevel@tonic-gate 				*length = (int)strtol(fieldv[3],
3137*0Sstevel@tonic-gate 				    (char **)NULL, 10);
3138*0Sstevel@tonic-gate 				if (errno != 0) {
3139*0Sstevel@tonic-gate 					err = RSMERR_BAD_CONF;
3140*0Sstevel@tonic-gate 					break;
3141*0Sstevel@tonic-gate 				}
3142*0Sstevel@tonic-gate 
3143*0Sstevel@tonic-gate 				found = 1;
3144*0Sstevel@tonic-gate 			} else {	/* error in format */
3145*0Sstevel@tonic-gate 				err = RSMERR_BAD_CONF;
3146*0Sstevel@tonic-gate 			}
3147*0Sstevel@tonic-gate 			break;
3148*0Sstevel@tonic-gate 		}
3149*0Sstevel@tonic-gate 	}
3150*0Sstevel@tonic-gate 
3151*0Sstevel@tonic-gate 	(void) fclose(fp);
3152*0Sstevel@tonic-gate 
3153*0Sstevel@tonic-gate 	if (found)
3154*0Sstevel@tonic-gate 		return (RSM_SUCCESS);
3155*0Sstevel@tonic-gate 
3156*0Sstevel@tonic-gate 	return (err);
3157*0Sstevel@tonic-gate }
3158*0Sstevel@tonic-gate 
3159*0Sstevel@tonic-gate static 	int
3160*0Sstevel@tonic-gate _rsm_get_hwaddr(rsmapi_controller_handle_t handle, rsm_node_id_t nodeid,
3161*0Sstevel@tonic-gate     rsm_addr_t *hwaddrp)
3162*0Sstevel@tonic-gate {
3163*0Sstevel@tonic-gate 	rsm_ioctlmsg_t	msg = {0};
3164*0Sstevel@tonic-gate 	rsm_controller_t *ctrlp;
3165*0Sstevel@tonic-gate 
3166*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
3167*0Sstevel@tonic-gate 	    "_rsm_get_hwaddr: enter\n"));
3168*0Sstevel@tonic-gate 
3169*0Sstevel@tonic-gate 	ctrlp = (rsm_controller_t *)handle;
3170*0Sstevel@tonic-gate 
3171*0Sstevel@tonic-gate 	if (ctrlp == NULL) {
3172*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
3173*0Sstevel@tonic-gate 		    "invalid controller handle\n"));
3174*0Sstevel@tonic-gate 		return (RSMERR_BAD_CTLR_HNDL);
3175*0Sstevel@tonic-gate 	}
3176*0Sstevel@tonic-gate 
3177*0Sstevel@tonic-gate 	msg.cname = ctrlp->cntr_name;
3178*0Sstevel@tonic-gate 	msg.cname_len = strlen(ctrlp->cntr_name) +1;
3179*0Sstevel@tonic-gate 	msg.cnum = ctrlp->cntr_unit;
3180*0Sstevel@tonic-gate 	msg.nodeid = nodeid;
3181*0Sstevel@tonic-gate 
3182*0Sstevel@tonic-gate 	if (ioctl(_rsm_fd, RSM_IOCTL_MAP_TO_ADDR, &msg) < 0) {
3183*0Sstevel@tonic-gate 		int error = errno;
3184*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
3185*0Sstevel@tonic-gate 		    "RSM_IOCTL_MAP_TO_ADDR failed\n"));
3186*0Sstevel@tonic-gate 		return (error);
3187*0Sstevel@tonic-gate 	}
3188*0Sstevel@tonic-gate 
3189*0Sstevel@tonic-gate 	*hwaddrp = msg.hwaddr;
3190*0Sstevel@tonic-gate 
3191*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
3192*0Sstevel@tonic-gate 	    "_rsm_get_hwaddr: exit\n"));
3193*0Sstevel@tonic-gate 
3194*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
3195*0Sstevel@tonic-gate 
3196*0Sstevel@tonic-gate }
3197*0Sstevel@tonic-gate 
3198*0Sstevel@tonic-gate static	int
3199*0Sstevel@tonic-gate _rsm_get_nodeid(rsmapi_controller_handle_t handle, rsm_addr_t hwaddr,
3200*0Sstevel@tonic-gate     rsm_node_id_t *nodeidp)
3201*0Sstevel@tonic-gate {
3202*0Sstevel@tonic-gate 
3203*0Sstevel@tonic-gate 	rsm_ioctlmsg_t	msg = {0};
3204*0Sstevel@tonic-gate 	rsm_controller_t *ctrlp;
3205*0Sstevel@tonic-gate 
3206*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
3207*0Sstevel@tonic-gate 	    "_rsm_get_nodeid: enter\n"));
3208*0Sstevel@tonic-gate 
3209*0Sstevel@tonic-gate 	ctrlp = (rsm_controller_t *)handle;
3210*0Sstevel@tonic-gate 
3211*0Sstevel@tonic-gate 	if (ctrlp == NULL) {
3212*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
3213*0Sstevel@tonic-gate 		    "invalid arguments\n"));
3214*0Sstevel@tonic-gate 		return (RSMERR_BAD_CTLR_HNDL);
3215*0Sstevel@tonic-gate 	}
3216*0Sstevel@tonic-gate 
3217*0Sstevel@tonic-gate 	msg.cname = ctrlp->cntr_name;
3218*0Sstevel@tonic-gate 	msg.cname_len = strlen(ctrlp->cntr_name) +1;
3219*0Sstevel@tonic-gate 	msg.cnum = ctrlp->cntr_unit;
3220*0Sstevel@tonic-gate 	msg.hwaddr = hwaddr;
3221*0Sstevel@tonic-gate 
3222*0Sstevel@tonic-gate 	if (ioctl(_rsm_fd, RSM_IOCTL_MAP_TO_NODEID, &msg) < 0) {
3223*0Sstevel@tonic-gate 		int error = errno;
3224*0Sstevel@tonic-gate 		DBPRINTF((RSM_LIBRARY, RSM_ERR,
3225*0Sstevel@tonic-gate 		    "RSM_IOCTL_MAP_TO_NODEID failed\n"));
3226*0Sstevel@tonic-gate 		return (error);
3227*0Sstevel@tonic-gate 	}
3228*0Sstevel@tonic-gate 
3229*0Sstevel@tonic-gate 	*nodeidp = msg.nodeid;
3230*0Sstevel@tonic-gate 
3231*0Sstevel@tonic-gate 	DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE,
3232*0Sstevel@tonic-gate 	    "_rsm_get_nodeid: exit\n"));
3233*0Sstevel@tonic-gate 
3234*0Sstevel@tonic-gate 	return (RSM_SUCCESS);
3235*0Sstevel@tonic-gate 
3236*0Sstevel@tonic-gate }
3237*0Sstevel@tonic-gate 
3238*0Sstevel@tonic-gate #ifdef DEBUG
3239*0Sstevel@tonic-gate void
3240*0Sstevel@tonic-gate dbg_printf(int msg_category, int msg_level, char *fmt, ...)
3241*0Sstevel@tonic-gate {
3242*0Sstevel@tonic-gate 	if ((msg_category & rsmlibdbg_category) &&
3243*0Sstevel@tonic-gate 	    (msg_level <= rsmlibdbg_level)) {
3244*0Sstevel@tonic-gate 		va_list arg_list;
3245*0Sstevel@tonic-gate 		va_start(arg_list, fmt);
3246*0Sstevel@tonic-gate 		mutex_lock(&rsmlog_lock);
3247*0Sstevel@tonic-gate 		fprintf(rsmlog_fd,
3248*0Sstevel@tonic-gate 			"Thread %d ", thr_self());
3249*0Sstevel@tonic-gate 		vfprintf(rsmlog_fd, fmt, arg_list);
3250*0Sstevel@tonic-gate 		fflush(rsmlog_fd);
3251*0Sstevel@tonic-gate 		mutex_unlock(&rsmlog_lock);
3252*0Sstevel@tonic-gate 		va_end(arg_list);
3253*0Sstevel@tonic-gate 	}
3254*0Sstevel@tonic-gate }
3255*0Sstevel@tonic-gate #endif /* DEBUG */
3256