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