10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 22*1219Sraf 230Sstevel@tonic-gate /* 24*1219Sraf * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 250Sstevel@tonic-gate * Use is subject to license terms. 260Sstevel@tonic-gate */ 270Sstevel@tonic-gate 280Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 290Sstevel@tonic-gate 30*1219Sraf #include "c_synonyms.h" 310Sstevel@tonic-gate #include <stdio.h> 320Sstevel@tonic-gate #include <stdlib.h> 330Sstevel@tonic-gate #include <unistd.h> 340Sstevel@tonic-gate #include <stdarg.h> 350Sstevel@tonic-gate #include <string.h> 360Sstevel@tonic-gate #include <strings.h> 370Sstevel@tonic-gate #include <ctype.h> 380Sstevel@tonic-gate #include <sys/types.h> 390Sstevel@tonic-gate #include <sys/stat.h> 400Sstevel@tonic-gate #include <sys/mman.h> 410Sstevel@tonic-gate #include <sys/uio.h> 420Sstevel@tonic-gate #include <sys/sysmacros.h> 430Sstevel@tonic-gate #include <sys/resource.h> 440Sstevel@tonic-gate #include <errno.h> 450Sstevel@tonic-gate #include <assert.h> 460Sstevel@tonic-gate #include <fcntl.h> 470Sstevel@tonic-gate #include <dlfcn.h> 480Sstevel@tonic-gate #include <sched.h> 490Sstevel@tonic-gate #include <stropts.h> 500Sstevel@tonic-gate #include <poll.h> 510Sstevel@tonic-gate 520Sstevel@tonic-gate #include <rsmapi.h> 530Sstevel@tonic-gate #include <sys/rsm/rsmndi.h> 540Sstevel@tonic-gate #include <rsmlib_in.h> 550Sstevel@tonic-gate #include <sys/rsm/rsm.h> 560Sstevel@tonic-gate 570Sstevel@tonic-gate #ifdef __STDC__ 580Sstevel@tonic-gate 590Sstevel@tonic-gate #pragma weak rsm_get_controller = _rsm_get_controller 600Sstevel@tonic-gate #pragma weak rsm_get_controller_attr = _rsm_get_controller_attr 610Sstevel@tonic-gate #pragma weak rsm_release_controller = _rsm_release_controller 620Sstevel@tonic-gate #pragma weak rsm_get_interconnect_topology = _rsm_get_interconnect_topology 630Sstevel@tonic-gate #pragma weak rsm_free_interconnect_topology = _rsm_free_interconnect_topology 640Sstevel@tonic-gate #pragma weak rsm_memseg_export_create = _rsm_memseg_export_create 650Sstevel@tonic-gate #pragma weak rsm_memseg_export_destroy = _rsm_memseg_export_destroy 660Sstevel@tonic-gate #pragma weak rsm_memseg_export_rebind = _rsm_memseg_export_rebind 670Sstevel@tonic-gate #pragma weak rsm_memseg_export_publish = _rsm_memseg_export_publish 680Sstevel@tonic-gate #pragma weak rsm_memseg_export_unpublish = _rsm_memseg_export_unpublish 690Sstevel@tonic-gate #pragma weak rsm_memseg_export_republish = _rsm_memseg_export_republish 700Sstevel@tonic-gate #pragma weak rsm_memseg_import_connect = _rsm_memseg_import_connect 710Sstevel@tonic-gate #pragma weak rsm_memseg_import_disconnect = _rsm_memseg_import_disconnect 720Sstevel@tonic-gate #pragma weak rsm_memseg_import_get8 = _rsm_memseg_import_get8 730Sstevel@tonic-gate #pragma weak rsm_memseg_import_get16 = _rsm_memseg_import_get16 740Sstevel@tonic-gate #pragma weak rsm_memseg_import_get32 = _rsm_memseg_import_get32 750Sstevel@tonic-gate #pragma weak rsm_memseg_import_get64 = _rsm_memseg_import_get64 760Sstevel@tonic-gate #pragma weak rsm_memseg_import_get = _rsm_memseg_import_get 770Sstevel@tonic-gate #pragma weak rsm_memseg_import_getv = _rsm_memseg_import_getv 780Sstevel@tonic-gate #pragma weak rsm_memseg_import_put8 = _rsm_memseg_import_put8 790Sstevel@tonic-gate #pragma weak rsm_memseg_import_put16 = _rsm_memseg_import_put16 800Sstevel@tonic-gate #pragma weak rsm_memseg_import_put32 = _rsm_memseg_import_put32 810Sstevel@tonic-gate #pragma weak rsm_memseg_import_put64 = _rsm_memseg_import_put64 820Sstevel@tonic-gate #pragma weak rsm_memseg_import_put = _rsm_memseg_import_put 830Sstevel@tonic-gate #pragma weak rsm_memseg_import_putv = _rsm_memseg_import_putv 840Sstevel@tonic-gate #pragma weak rsm_memseg_import_map = _rsm_memseg_import_map 850Sstevel@tonic-gate #pragma weak rsm_memseg_import_unmap = _rsm_memseg_import_unmap 860Sstevel@tonic-gate #pragma weak rsm_memseg_import_init_barrier = _rsm_memseg_import_init_barrier 870Sstevel@tonic-gate #pragma weak rsm_memseg_import_open_barrier = _rsm_memseg_import_open_barrier 880Sstevel@tonic-gate #pragma weak rsm_memseg_import_close_barrier = _rsm_memseg_import_close_barrier 890Sstevel@tonic-gate #pragma weak rsm_memseg_import_order_barrier = _rsm_memseg_import_order_barrier 900Sstevel@tonic-gate #pragma weak rsm_memseg_import_destroy_barrier = \ 910Sstevel@tonic-gate _rsm_memseg_import_destroy_barrier 920Sstevel@tonic-gate #pragma weak rsm_memseg_import_get_mode = _rsm_memseg_import_get_mode 930Sstevel@tonic-gate #pragma weak rsm_memseg_import_set_mode = _rsm_memseg_import_set_mode 940Sstevel@tonic-gate #pragma weak rsm_create_localmemory_handle = _rsm_create_localmemory_handle 950Sstevel@tonic-gate #pragma weak rsm_free_localmemory_handle = _rsm_free_localmemory_handle 960Sstevel@tonic-gate #pragma weak rsm_intr_signal_post = _rsm_intr_signal_post 970Sstevel@tonic-gate #pragma weak rsm_intr_signal_wait = _rsm_intr_signal_wait 980Sstevel@tonic-gate #pragma weak rsm_intr_signal_wait_pollfd = _rsm_intr_signal_wait_pollfd 990Sstevel@tonic-gate #pragma weak rsm_memseg_get_pollfd = _rsm_memseg_get_pollfd 1000Sstevel@tonic-gate #pragma weak rsm_memseg_release_pollfd = _rsm_memseg_release_pollfd 1010Sstevel@tonic-gate #pragma weak rsm_get_segmentid_range = _rsm_get_segmentid_range 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate #endif /* __STDC__ */ 1040Sstevel@tonic-gate 1050Sstevel@tonic-gate /* lint -w2 */ 1060Sstevel@tonic-gate extern void __rsmloopback_init_ops(rsm_segops_t *); 1070Sstevel@tonic-gate extern void __rsmdefault_setops(rsm_segops_t *); 1080Sstevel@tonic-gate 1090Sstevel@tonic-gate typedef void (*rsm_access_func_t)(void *, void *, rsm_access_size_t); 1100Sstevel@tonic-gate 1110Sstevel@tonic-gate #ifdef DEBUG 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate #define RSMLOG_BUF_SIZE 256 1140Sstevel@tonic-gate FILE *rsmlog_fd = NULL; 1150Sstevel@tonic-gate static mutex_t rsmlog_lock; 1160Sstevel@tonic-gate int rsmlibdbg_category = RSM_LIBRARY; 1170Sstevel@tonic-gate int rsmlibdbg_level = RSM_ERR; 1180Sstevel@tonic-gate void dbg_printf(int category, int level, char *fmt, ...); 1190Sstevel@tonic-gate 1200Sstevel@tonic-gate #endif /* DEBUG */ 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate rsm_node_id_t rsm_local_nodeid = 0; 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate static rsm_controller_t *controller_list = NULL; 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate static rsm_segops_t loopback_ops; 1270Sstevel@tonic-gate 1280Sstevel@tonic-gate #define MAX_STRLEN 80 1290Sstevel@tonic-gate 1300Sstevel@tonic-gate #define RSM_IOTYPE_PUTGET 1 1310Sstevel@tonic-gate #define RSM_IOTYPE_SCATGATH 2 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate #define RSMFILE_BUFSIZE 256 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate #pragma init(_rsm_librsm_init) 1360Sstevel@tonic-gate 1370Sstevel@tonic-gate static mutex_t _rsm_lock; 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate static int _rsm_fd = -1; 1400Sstevel@tonic-gate static rsm_gnum_t *bar_va, bar_fixed = 0; 1410Sstevel@tonic-gate static rsm_pollfd_table_t pollfd_table; 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate static int _rsm_get_hwaddr(rsmapi_controller_handle_t handle, 1440Sstevel@tonic-gate rsm_node_id_t, rsm_addr_t *hwaddrp); 1450Sstevel@tonic-gate static int _rsm_get_nodeid(rsmapi_controller_handle_t, 1460Sstevel@tonic-gate rsm_addr_t, rsm_node_id_t *); 1470Sstevel@tonic-gate static int __rsm_import_implicit_map(rsmseg_handle_t *, int); 1480Sstevel@tonic-gate static int __rsm_intr_signal_wait_common(struct pollfd [], minor_t [], 1490Sstevel@tonic-gate nfds_t, int, int *); 1500Sstevel@tonic-gate 1510Sstevel@tonic-gate static rsm_lib_funcs_t lib_functions = { 1520Sstevel@tonic-gate RSM_LIB_FUNCS_VERSION, 1530Sstevel@tonic-gate _rsm_get_hwaddr, 1540Sstevel@tonic-gate _rsm_get_nodeid 1550Sstevel@tonic-gate }; 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate int _rsm_get_interconnect_topology(rsm_topology_t **); 1580Sstevel@tonic-gate void _rsm_free_interconnect_topology(rsm_topology_t *); 1590Sstevel@tonic-gate int _rsm_memseg_import_open_barrier(rsmapi_barrier_t *); 1600Sstevel@tonic-gate int _rsm_memseg_import_close_barrier(rsmapi_barrier_t *); 1610Sstevel@tonic-gate int _rsm_memseg_import_unmap(rsm_memseg_import_handle_t); 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate rsm_topology_t *tp; 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate /* 1680Sstevel@tonic-gate * service module function templates: 1690Sstevel@tonic-gate */ 1700Sstevel@tonic-gate 1710Sstevel@tonic-gate /* 1720Sstevel@tonic-gate * The _rsm_librsm_init function is called the first time an application 1730Sstevel@tonic-gate * references the RSMAPI library 1740Sstevel@tonic-gate */ 1750Sstevel@tonic-gate int 1760Sstevel@tonic-gate _rsm_librsm_init() 1770Sstevel@tonic-gate { 1780Sstevel@tonic-gate rsm_ioctlmsg_t msg; 1790Sstevel@tonic-gate int e, tmpfd; 1800Sstevel@tonic-gate int i; 1810Sstevel@tonic-gate char logname[MAXNAMELEN]; 1820Sstevel@tonic-gate 1830Sstevel@tonic-gate mutex_init(&_rsm_lock, USYNC_THREAD, NULL); 1840Sstevel@tonic-gate 1850Sstevel@tonic-gate #ifdef DEBUG 1860Sstevel@tonic-gate mutex_init(&rsmlog_lock, USYNC_THREAD, NULL); 1870Sstevel@tonic-gate sprintf(logname, "%s.%d", TRACELOG, getpid()); 1880Sstevel@tonic-gate rsmlog_fd = fopen(logname, "w+"); 1890Sstevel@tonic-gate if (rsmlog_fd == NULL) { 1900Sstevel@tonic-gate fprintf(stderr, "Log file open failed\n"); 1910Sstevel@tonic-gate return (errno); 1920Sstevel@tonic-gate } 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate #endif /* DEBUG */ 1950Sstevel@tonic-gate 1960Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 1970Sstevel@tonic-gate "_rsm_librsm_init: enter\n")); 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate /* initialize the pollfd_table */ 2000Sstevel@tonic-gate mutex_init(&pollfd_table.lock, USYNC_THREAD, NULL); 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate for (i = 0; i < RSM_MAX_BUCKETS; i++) { 2030Sstevel@tonic-gate pollfd_table.buckets[i] = NULL; 2040Sstevel@tonic-gate } 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate /* open /dev/rsm and mmap barrier generation pages */ 2070Sstevel@tonic-gate mutex_lock(&_rsm_lock); 2080Sstevel@tonic-gate _rsm_fd = open(DEVRSM, O_RDONLY); 2090Sstevel@tonic-gate if (_rsm_fd < 0) { 2100Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 2110Sstevel@tonic-gate "unable to open /dev/rsm\n")); 2120Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 2130Sstevel@tonic-gate return (errno); 2140Sstevel@tonic-gate } 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate /* 2170Sstevel@tonic-gate * DUP the opened file descriptor to something greater than 2180Sstevel@tonic-gate * STDERR_FILENO so that we never use the STDIN_FILENO, 2190Sstevel@tonic-gate * STDOUT_FILENO or STDERR_FILENO. 2200Sstevel@tonic-gate */ 2210Sstevel@tonic-gate tmpfd = fcntl(_rsm_fd, F_DUPFD, 3); 2220Sstevel@tonic-gate if (tmpfd < 0) { 2230Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 2240Sstevel@tonic-gate "F_DUPFD failed\n")); 2250Sstevel@tonic-gate } else { 2260Sstevel@tonic-gate (void) close(_rsm_fd); 2270Sstevel@tonic-gate _rsm_fd = tmpfd; 2280Sstevel@tonic-gate } 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 2310Sstevel@tonic-gate "_rsm_fd is %d\n", _rsm_fd)); 2320Sstevel@tonic-gate 2330Sstevel@tonic-gate if (fcntl(_rsm_fd, F_SETFD, FD_CLOEXEC) < 0) { 2340Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 2350Sstevel@tonic-gate "F_SETFD failed\n")); 2360Sstevel@tonic-gate } 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate /* get mapping generation number page info */ 2390Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_BAR_INFO, &msg) < 0) { 2400Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 2410Sstevel@tonic-gate "RSM_IOCTL_BAR_INFO failed\n")); 2420Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 2430Sstevel@tonic-gate return (errno); 2440Sstevel@tonic-gate } 2450Sstevel@tonic-gate 2460Sstevel@tonic-gate /* 2470Sstevel@tonic-gate * bar_va is mapped to the mapping generation number page 2480Sstevel@tonic-gate * in order to support close barrier 2490Sstevel@tonic-gate */ 2500Sstevel@tonic-gate /* LINTED */ 2510Sstevel@tonic-gate bar_va = (rsm_gnum_t *)mmap(NULL, msg.len, 2520Sstevel@tonic-gate PROT_READ, MAP_SHARED, _rsm_fd, msg.off); 2530Sstevel@tonic-gate if (bar_va == (rsm_gnum_t *)MAP_FAILED) { 2540Sstevel@tonic-gate bar_va = NULL; 2550Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 2560Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 2570Sstevel@tonic-gate "unable to map barrier page\n")); 2580Sstevel@tonic-gate return (RSMERR_MAP_FAILED); 2590Sstevel@tonic-gate } 2600Sstevel@tonic-gate 2610Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 2620Sstevel@tonic-gate 2630Sstevel@tonic-gate /* get local nodeid */ 2640Sstevel@tonic-gate e = rsm_get_interconnect_topology(&tp); 2650Sstevel@tonic-gate if (e != RSM_SUCCESS) { 2660Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 2670Sstevel@tonic-gate "unable to obtain topology data\n")); 2680Sstevel@tonic-gate return (e); 2690Sstevel@tonic-gate } else 2700Sstevel@tonic-gate rsm_local_nodeid = tp->topology_hdr.local_nodeid; 2710Sstevel@tonic-gate 2720Sstevel@tonic-gate rsm_free_interconnect_topology(tp); 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 2750Sstevel@tonic-gate "_rsm_librsm_init: exit\n")); 2760Sstevel@tonic-gate 2770Sstevel@tonic-gate return (RSM_SUCCESS); 2780Sstevel@tonic-gate } 2790Sstevel@tonic-gate 2800Sstevel@tonic-gate static int 2810Sstevel@tonic-gate _rsm_loopbackload(caddr_t name, int unit, rsm_controller_t **chdl) 2820Sstevel@tonic-gate { 2830Sstevel@tonic-gate rsm_controller_t *p; 2840Sstevel@tonic-gate rsm_ioctlmsg_t msg; 2850Sstevel@tonic-gate 2860Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, 2870Sstevel@tonic-gate "_rsm_loopbackload: enter\n")); 2880Sstevel@tonic-gate /* 2890Sstevel@tonic-gate * For now do this, but we should open some file and read the 2900Sstevel@tonic-gate * list of supported controllers and there numbers. 2910Sstevel@tonic-gate */ 2920Sstevel@tonic-gate 2930Sstevel@tonic-gate p = (rsm_controller_t *)malloc(sizeof (*p) + strlen(name) + 1); 2940Sstevel@tonic-gate if (!p) { 2950Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_ERR, 2960Sstevel@tonic-gate "not enough memory\n")); 2970Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_MEM); 2980Sstevel@tonic-gate } 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate msg.cname = name; 3010Sstevel@tonic-gate msg.cname_len = strlen(name) +1; 3020Sstevel@tonic-gate msg.cnum = unit; 3030Sstevel@tonic-gate msg.arg = (caddr_t)&p->cntr_attr; 3040Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_ATTR, &msg) < 0) { 3050Sstevel@tonic-gate int error = errno; 3060Sstevel@tonic-gate free((void *)p); 3070Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_ERR, 3080Sstevel@tonic-gate "RSM_IOCTL_ATTR failed\n")); 3090Sstevel@tonic-gate return (error); 3100Sstevel@tonic-gate } 3110Sstevel@tonic-gate 3120Sstevel@tonic-gate __rsmloopback_init_ops(&loopback_ops); 3130Sstevel@tonic-gate __rsmdefault_setops(&loopback_ops); 3140Sstevel@tonic-gate p->cntr_segops = &loopback_ops; 3150Sstevel@tonic-gate 3160Sstevel@tonic-gate /* 3170Sstevel@tonic-gate * Should add this entry into list 3180Sstevel@tonic-gate */ 3190Sstevel@tonic-gate p->cntr_fd = _rsm_fd; 3200Sstevel@tonic-gate p->cntr_name = strcpy((char *)(p+1), name); 3210Sstevel@tonic-gate p->cntr_unit = unit; 3220Sstevel@tonic-gate p->cntr_refcnt = 1; 3230Sstevel@tonic-gate 3240Sstevel@tonic-gate 3250Sstevel@tonic-gate mutex_init(&p->cntr_lock, USYNC_THREAD, NULL); 3260Sstevel@tonic-gate cond_init(&p->cntr_cv, USYNC_THREAD, NULL); 3270Sstevel@tonic-gate p->cntr_rqlist = NULL; 3280Sstevel@tonic-gate p->cntr_segops->rsm_get_lib_attr(&p->cntr_lib_attr); 3290Sstevel@tonic-gate p->cntr_next = controller_list; 3300Sstevel@tonic-gate controller_list = p; 3310Sstevel@tonic-gate 3320Sstevel@tonic-gate *chdl = p; 3330Sstevel@tonic-gate 3340Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, 3350Sstevel@tonic-gate "_rsm_loopbackload: exit\n")); 3360Sstevel@tonic-gate return (RSM_SUCCESS); 3370Sstevel@tonic-gate 3380Sstevel@tonic-gate } 3390Sstevel@tonic-gate 3400Sstevel@tonic-gate static int 3410Sstevel@tonic-gate _rsm_modload(caddr_t name, int unit, rsmapi_controller_handle_t *controller) 3420Sstevel@tonic-gate { 3430Sstevel@tonic-gate int error = RSM_SUCCESS; 3440Sstevel@tonic-gate char clib[MAX_STRLEN]; 3450Sstevel@tonic-gate rsm_controller_t *p = NULL; 3460Sstevel@tonic-gate void *dlh; 3470Sstevel@tonic-gate rsm_attach_entry_t fptr; 3480Sstevel@tonic-gate rsm_ioctlmsg_t msg; 3490Sstevel@tonic-gate 3500Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 3510Sstevel@tonic-gate "_rsm_modload: enter\n")); 3520Sstevel@tonic-gate 3530Sstevel@tonic-gate (void) sprintf(clib, "%s.so", name); 3540Sstevel@tonic-gate 3550Sstevel@tonic-gate /* found entry, try to load library */ 3560Sstevel@tonic-gate dlh = dlopen(clib, RTLD_LAZY); 3570Sstevel@tonic-gate if (dlh == NULL) { 3580Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 3590Sstevel@tonic-gate "unable to find plugin library\n")); 3600Sstevel@tonic-gate error = RSMERR_CTLR_NOT_PRESENT; 3610Sstevel@tonic-gate goto skiplib; 3620Sstevel@tonic-gate } 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate (void) sprintf(clib, "%s_opendevice", name); 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate fptr = (rsm_attach_entry_t)dlsym(dlh, clib); /* lint !e611 */ 3670Sstevel@tonic-gate if (fptr != NULL) { 3680Sstevel@tonic-gate /* allocate new lib structure */ 3690Sstevel@tonic-gate /* get ops handler, attr and ops */ 3700Sstevel@tonic-gate p = (rsm_controller_t *)malloc(sizeof (*p) + strlen(name) + 1); 3710Sstevel@tonic-gate if (p != NULL) { 3720Sstevel@tonic-gate error = fptr(unit, &p->cntr_segops); 3730Sstevel@tonic-gate } else { 3740Sstevel@tonic-gate error = RSMERR_INSUFFICIENT_MEM; 3750Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 3760Sstevel@tonic-gate "not enough memory\n")); 3770Sstevel@tonic-gate } 3780Sstevel@tonic-gate } else { 3790Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 3800Sstevel@tonic-gate "can't find symbol %s\n", clib)); 3810Sstevel@tonic-gate error = RSMERR_CTLR_NOT_PRESENT; 3820Sstevel@tonic-gate (void) dlclose(dlh); 3830Sstevel@tonic-gate } 3840Sstevel@tonic-gate 3850Sstevel@tonic-gate skiplib: 3860Sstevel@tonic-gate if ((error != RSM_SUCCESS) || (p == NULL)) { 3870Sstevel@tonic-gate if (p != NULL) 3880Sstevel@tonic-gate free((void *)p); 3890Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 3900Sstevel@tonic-gate "_rsm_modload error %d\n", error)); 3910Sstevel@tonic-gate return (error); 3920Sstevel@tonic-gate } 3930Sstevel@tonic-gate 3940Sstevel@tonic-gate /* check the version number */ 3950Sstevel@tonic-gate if (p->cntr_segops->rsm_version != RSM_LIB_VERSION) { 3960Sstevel@tonic-gate /* bad version number */ 3970Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 3980Sstevel@tonic-gate "wrong version; " 3990Sstevel@tonic-gate "found %d, expected %d\n", 4000Sstevel@tonic-gate p->cntr_segops->rsm_version, RSM_LIB_VERSION)); 4010Sstevel@tonic-gate free(p); 4020Sstevel@tonic-gate return (RSMERR_BAD_LIBRARY_VERSION); 4030Sstevel@tonic-gate } else { 4040Sstevel@tonic-gate /* pass the fuctions to NDI library */ 4050Sstevel@tonic-gate if ((p->cntr_segops->rsm_register_lib_funcs == NULL) || 4060Sstevel@tonic-gate (p->cntr_segops->rsm_register_lib_funcs( 4070Sstevel@tonic-gate &lib_functions) != RSM_SUCCESS)) { 4080Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 4090Sstevel@tonic-gate "RSMNDI library not registering lib functions\n")); 4100Sstevel@tonic-gate } 4110Sstevel@tonic-gate 4120Sstevel@tonic-gate /* get controller attributes */ 4130Sstevel@tonic-gate msg.cnum = unit; 4140Sstevel@tonic-gate msg.cname = name; 4150Sstevel@tonic-gate msg.cname_len = strlen(name) +1; 4160Sstevel@tonic-gate msg.arg = (caddr_t)&p->cntr_attr; 4170Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_ATTR, &msg) < 0) { 4180Sstevel@tonic-gate error = errno; 4190Sstevel@tonic-gate free((void *)p); 4200Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 4210Sstevel@tonic-gate "RSM_IOCTL_ATTR failed\n")); 4220Sstevel@tonic-gate return (error); 4230Sstevel@tonic-gate } 4240Sstevel@tonic-gate 4250Sstevel@tonic-gate /* set controller access functions */ 4260Sstevel@tonic-gate __rsmdefault_setops(p->cntr_segops); 4270Sstevel@tonic-gate 4280Sstevel@tonic-gate mutex_init(&p->cntr_lock, USYNC_THREAD, NULL); 4290Sstevel@tonic-gate cond_init(&p->cntr_cv, USYNC_THREAD, NULL); 4300Sstevel@tonic-gate p->cntr_rqlist = NULL; 4310Sstevel@tonic-gate p->cntr_segops->rsm_get_lib_attr(&p->cntr_lib_attr); 4320Sstevel@tonic-gate /* insert into list of controllers */ 4330Sstevel@tonic-gate p->cntr_name = strcpy((char *)(p+1), name); 4340Sstevel@tonic-gate p->cntr_fd = _rsm_fd; 4350Sstevel@tonic-gate p->cntr_unit = unit; 4360Sstevel@tonic-gate p->cntr_refcnt = 1; /* first reference */ 4370Sstevel@tonic-gate p->cntr_next = controller_list; 4380Sstevel@tonic-gate controller_list = p; 4390Sstevel@tonic-gate *controller = (rsmapi_controller_handle_t)p; 4400Sstevel@tonic-gate errno = RSM_SUCCESS; 4410Sstevel@tonic-gate } 4420Sstevel@tonic-gate 4430Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 4440Sstevel@tonic-gate "_rsm_modload: exit\n")); 4450Sstevel@tonic-gate return (error); 4460Sstevel@tonic-gate } 4470Sstevel@tonic-gate 4480Sstevel@tonic-gate /* 4490Sstevel@tonic-gate * inserts a given segment handle into the pollfd table, this is called 4500Sstevel@tonic-gate * when rsm_memseg_get_pollfd() is called the first time on a segment handle. 4510Sstevel@tonic-gate * Returns RSM_SUCCESS if successful otherwise the error code is returned 4520Sstevel@tonic-gate */ 4530Sstevel@tonic-gate static int 4540Sstevel@tonic-gate _rsm_insert_pollfd_table(int segfd, minor_t segrnum) 4550Sstevel@tonic-gate { 4560Sstevel@tonic-gate int i; 4570Sstevel@tonic-gate int hash; 4580Sstevel@tonic-gate rsm_pollfd_chunk_t *chunk; 4590Sstevel@tonic-gate 4600Sstevel@tonic-gate hash = RSM_POLLFD_HASH(segfd); 4610Sstevel@tonic-gate 4620Sstevel@tonic-gate mutex_lock(&pollfd_table.lock); 4630Sstevel@tonic-gate 4640Sstevel@tonic-gate chunk = pollfd_table.buckets[hash]; 4650Sstevel@tonic-gate while (chunk) { 4660Sstevel@tonic-gate if (chunk->nfree > 0) 4670Sstevel@tonic-gate break; 4680Sstevel@tonic-gate chunk = chunk->next; 4690Sstevel@tonic-gate } 4700Sstevel@tonic-gate 4710Sstevel@tonic-gate if (!chunk) { /* couldn't find a free chunk - allocate a new one */ 4720Sstevel@tonic-gate chunk = malloc(sizeof (rsm_pollfd_chunk_t)); 4730Sstevel@tonic-gate if (!chunk) { 4740Sstevel@tonic-gate mutex_unlock(&pollfd_table.lock); 4750Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_MEM); 4760Sstevel@tonic-gate } 4770Sstevel@tonic-gate chunk->nfree = RSM_POLLFD_PER_CHUNK - 1; 4780Sstevel@tonic-gate chunk->fdarray[0].fd = segfd; 4790Sstevel@tonic-gate chunk->fdarray[0].segrnum = segrnum; 4800Sstevel@tonic-gate for (i = 1; i < RSM_POLLFD_PER_CHUNK; i++) { 4810Sstevel@tonic-gate chunk->fdarray[i].fd = -1; 4820Sstevel@tonic-gate chunk->fdarray[i].segrnum = 0; 4830Sstevel@tonic-gate } 4840Sstevel@tonic-gate /* insert this into the hash table */ 4850Sstevel@tonic-gate chunk->next = pollfd_table.buckets[hash]; 4860Sstevel@tonic-gate pollfd_table.buckets[hash] = chunk; 4870Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 4880Sstevel@tonic-gate "rsm_insert_pollfd: new chunk(%p) @ %d for %d:%d\n", 4890Sstevel@tonic-gate chunk, hash, segfd, segrnum)); 4900Sstevel@tonic-gate } else { /* a chunk with free slot was found */ 4910Sstevel@tonic-gate for (i = 0; i < RSM_POLLFD_PER_CHUNK; i++) { 4920Sstevel@tonic-gate if (chunk->fdarray[i].fd == -1) { 4930Sstevel@tonic-gate chunk->fdarray[i].fd = segfd; 4940Sstevel@tonic-gate chunk->fdarray[i].segrnum = segrnum; 4950Sstevel@tonic-gate chunk->nfree--; 4960Sstevel@tonic-gate break; 4970Sstevel@tonic-gate } 4980Sstevel@tonic-gate } 4990Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 5000Sstevel@tonic-gate "rsm_insert_pollfd: inserted @ %d for %d:%d chunk(%p)\n", 5010Sstevel@tonic-gate hash, segfd, segrnum, chunk)); 5020Sstevel@tonic-gate assert(i < RSM_POLLFD_PER_CHUNK); 5030Sstevel@tonic-gate } 5040Sstevel@tonic-gate 5050Sstevel@tonic-gate mutex_unlock(&pollfd_table.lock); 5060Sstevel@tonic-gate return (RSM_SUCCESS); 5070Sstevel@tonic-gate } 5080Sstevel@tonic-gate 5090Sstevel@tonic-gate /* 5100Sstevel@tonic-gate * Given a file descriptor returns the corresponding segment handles 5110Sstevel@tonic-gate * resource number, if the fd is not found returns 0. 0 is not a valid 5120Sstevel@tonic-gate * minor number for a rsmapi segment since it is used for the barrier 5130Sstevel@tonic-gate * resource. 5140Sstevel@tonic-gate */ 5150Sstevel@tonic-gate static minor_t 5160Sstevel@tonic-gate _rsm_lookup_pollfd_table(int segfd) 5170Sstevel@tonic-gate { 5180Sstevel@tonic-gate int i; 5190Sstevel@tonic-gate rsm_pollfd_chunk_t *chunk; 5200Sstevel@tonic-gate 5210Sstevel@tonic-gate if (segfd < 0) 5220Sstevel@tonic-gate return (0); 5230Sstevel@tonic-gate 5240Sstevel@tonic-gate mutex_lock(&pollfd_table.lock); 5250Sstevel@tonic-gate 5260Sstevel@tonic-gate chunk = pollfd_table.buckets[RSM_POLLFD_HASH(segfd)]; 5270Sstevel@tonic-gate while (chunk) { 5280Sstevel@tonic-gate assert(chunk->nfree < RSM_POLLFD_PER_CHUNK); 5290Sstevel@tonic-gate 5300Sstevel@tonic-gate for (i = 0; i < RSM_POLLFD_PER_CHUNK; i++) { 5310Sstevel@tonic-gate if (chunk->fdarray[i].fd == segfd) { 5320Sstevel@tonic-gate mutex_unlock(&pollfd_table.lock); 5330Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 5340Sstevel@tonic-gate "rsm_lookup_pollfd: found(%d) rnum(%d)\n", 5350Sstevel@tonic-gate segfd, chunk->fdarray[i].segrnum)); 5360Sstevel@tonic-gate return (chunk->fdarray[i].segrnum); 5370Sstevel@tonic-gate } 5380Sstevel@tonic-gate } 5390Sstevel@tonic-gate chunk = chunk->next; 5400Sstevel@tonic-gate } 5410Sstevel@tonic-gate 5420Sstevel@tonic-gate mutex_unlock(&pollfd_table.lock); 5430Sstevel@tonic-gate 5440Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 5450Sstevel@tonic-gate "rsm_lookup_pollfd: not found(%d)\n", segfd)); 5460Sstevel@tonic-gate 5470Sstevel@tonic-gate return (0); 5480Sstevel@tonic-gate } 5490Sstevel@tonic-gate 5500Sstevel@tonic-gate /* 5510Sstevel@tonic-gate * Remove the entry corresponding to the given file descriptor from the 5520Sstevel@tonic-gate * pollfd table. 5530Sstevel@tonic-gate */ 5540Sstevel@tonic-gate static void 5550Sstevel@tonic-gate _rsm_remove_pollfd_table(int segfd) 5560Sstevel@tonic-gate { 5570Sstevel@tonic-gate int i; 5580Sstevel@tonic-gate int hash; 5590Sstevel@tonic-gate rsm_pollfd_chunk_t *chunk; 5600Sstevel@tonic-gate rsm_pollfd_chunk_t *prev_chunk; 5610Sstevel@tonic-gate 5620Sstevel@tonic-gate if (segfd < 0) 5630Sstevel@tonic-gate return; 5640Sstevel@tonic-gate 5650Sstevel@tonic-gate hash = RSM_POLLFD_HASH(segfd); 5660Sstevel@tonic-gate 5670Sstevel@tonic-gate mutex_lock(&pollfd_table.lock); 5680Sstevel@tonic-gate 5690Sstevel@tonic-gate prev_chunk = chunk = pollfd_table.buckets[hash]; 5700Sstevel@tonic-gate while (chunk) { 5710Sstevel@tonic-gate assert(chunk->nfree < RSM_POLLFD_PER_CHUNK); 5720Sstevel@tonic-gate 5730Sstevel@tonic-gate for (i = 0; i < RSM_POLLFD_PER_CHUNK; i++) { 5740Sstevel@tonic-gate if (chunk->fdarray[i].fd == segfd) { 5750Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 5760Sstevel@tonic-gate "rsm_remove_pollfd: %d:%d\n", 5770Sstevel@tonic-gate chunk->fdarray[i].fd, 5780Sstevel@tonic-gate chunk->fdarray[i].segrnum)); 5790Sstevel@tonic-gate chunk->fdarray[i].fd = -1; 5800Sstevel@tonic-gate chunk->fdarray[i].segrnum = 0; 5810Sstevel@tonic-gate chunk->nfree++; 5820Sstevel@tonic-gate if (chunk->nfree == RSM_POLLFD_PER_CHUNK) { 5830Sstevel@tonic-gate /* chunk is empty free it */ 5840Sstevel@tonic-gate if (prev_chunk == chunk) { 5850Sstevel@tonic-gate pollfd_table.buckets[hash] = 5860Sstevel@tonic-gate chunk->next; 5870Sstevel@tonic-gate } else { 5880Sstevel@tonic-gate prev_chunk->next = chunk->next; 5890Sstevel@tonic-gate } 5900Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, 5910Sstevel@tonic-gate RSM_DEBUG_VERBOSE, 5920Sstevel@tonic-gate "rsm_remove_pollfd:free(%p)\n", 5930Sstevel@tonic-gate chunk)); 5940Sstevel@tonic-gate free(chunk); 5950Sstevel@tonic-gate mutex_unlock(&pollfd_table.lock); 5960Sstevel@tonic-gate return; 5970Sstevel@tonic-gate } 5980Sstevel@tonic-gate } 5990Sstevel@tonic-gate } 6000Sstevel@tonic-gate prev_chunk = chunk; 6010Sstevel@tonic-gate chunk = chunk->next; 6020Sstevel@tonic-gate } 6030Sstevel@tonic-gate 6040Sstevel@tonic-gate mutex_unlock(&pollfd_table.lock); 6050Sstevel@tonic-gate } 6060Sstevel@tonic-gate 6070Sstevel@tonic-gate int 6080Sstevel@tonic-gate _rsm_get_controller(char *name, rsmapi_controller_handle_t *chdl) 6090Sstevel@tonic-gate { 6100Sstevel@tonic-gate rsm_controller_t *p; 6110Sstevel@tonic-gate char cntr_name[MAXNAMELEN]; /* cntr_name=<cntr_type><unit> */ 6120Sstevel@tonic-gate char *cntr_type; 6130Sstevel@tonic-gate int unit = 0; 6140Sstevel@tonic-gate int i, e; 6150Sstevel@tonic-gate 6160Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 6170Sstevel@tonic-gate "rsm_get_controller: enter\n")); 6180Sstevel@tonic-gate /* 6190Sstevel@tonic-gate * Lookup controller name and return ops vector and controller 6200Sstevel@tonic-gate * structure 6210Sstevel@tonic-gate */ 6220Sstevel@tonic-gate 6230Sstevel@tonic-gate if (!chdl) { 6240Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 6250Sstevel@tonic-gate "Invalid controller handle\n")); 6260Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 6270Sstevel@tonic-gate } 6280Sstevel@tonic-gate if (!name) { 6290Sstevel@tonic-gate /* use loopback if null */ 6300Sstevel@tonic-gate cntr_type = LOOPBACK; 6310Sstevel@tonic-gate } else { 6320Sstevel@tonic-gate (void) strcpy(cntr_name, name); 6330Sstevel@tonic-gate /* scan from the end till a non-digit is found */ 6340Sstevel@tonic-gate for (i = strlen(cntr_name) - 1; i >= 0; i--) { 6350Sstevel@tonic-gate if (! isdigit((int)cntr_name[i])) 6360Sstevel@tonic-gate break; 6370Sstevel@tonic-gate } 6380Sstevel@tonic-gate i++; 6390Sstevel@tonic-gate unit = atoi((char *)cntr_name+i); 6400Sstevel@tonic-gate cntr_name[i] = '\0'; /* null terminate the cntr_type part */ 6410Sstevel@tonic-gate cntr_type = (char *)cntr_name; 6420Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 6430Sstevel@tonic-gate "cntr_type=%s, instance=%d\n", 6440Sstevel@tonic-gate cntr_type, unit)); 6450Sstevel@tonic-gate } 6460Sstevel@tonic-gate 6470Sstevel@tonic-gate /* protect the controller_list by locking the device/library */ 6480Sstevel@tonic-gate mutex_lock(&_rsm_lock); 6490Sstevel@tonic-gate 6500Sstevel@tonic-gate for (p = controller_list; p; p = p->cntr_next) { 6510Sstevel@tonic-gate if (!strcasecmp(p->cntr_name, cntr_type) && 6520Sstevel@tonic-gate !strcasecmp(cntr_type, LOOPBACK)) { 6530Sstevel@tonic-gate p->cntr_refcnt++; 6540Sstevel@tonic-gate *chdl = (rsmapi_controller_handle_t)p; 6550Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 6560Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 6570Sstevel@tonic-gate "rsm_get_controller: exit\n")); 6580Sstevel@tonic-gate return (RSM_SUCCESS); 6590Sstevel@tonic-gate } else if (!strcasecmp(p->cntr_name, cntr_type) && 6600Sstevel@tonic-gate (p->cntr_unit == unit)) { 6610Sstevel@tonic-gate p->cntr_refcnt++; 6620Sstevel@tonic-gate *chdl = (rsmapi_controller_handle_t)p; 6630Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 6640Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 6650Sstevel@tonic-gate "rsm_get_controller: exit\n")); 6660Sstevel@tonic-gate return (RSM_SUCCESS); 6670Sstevel@tonic-gate } 6680Sstevel@tonic-gate } 6690Sstevel@tonic-gate 6700Sstevel@tonic-gate 6710Sstevel@tonic-gate if (!strcasecmp(cntr_type, LOOPBACK)) { 6720Sstevel@tonic-gate e = _rsm_loopbackload(cntr_type, unit, 6730Sstevel@tonic-gate (rsm_controller_t **)chdl); 6740Sstevel@tonic-gate } else { 6750Sstevel@tonic-gate e = _rsm_modload(cntr_type, unit, chdl); 6760Sstevel@tonic-gate } 6770Sstevel@tonic-gate 6780Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 6790Sstevel@tonic-gate 6800Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 6810Sstevel@tonic-gate " rsm_get_controller: exit\n")); 6820Sstevel@tonic-gate return (e); 6830Sstevel@tonic-gate } 6840Sstevel@tonic-gate 6850Sstevel@tonic-gate int 6860Sstevel@tonic-gate _rsm_release_controller(rsmapi_controller_handle_t cntr_handle) 6870Sstevel@tonic-gate { 6880Sstevel@tonic-gate int e = RSM_SUCCESS; 6890Sstevel@tonic-gate rsm_controller_t *chdl = (rsm_controller_t *)cntr_handle; 6900Sstevel@tonic-gate rsm_controller_t *curr, *prev; 6910Sstevel@tonic-gate 6920Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 6930Sstevel@tonic-gate "rsm_release_controller: enter\n")); 6940Sstevel@tonic-gate 6950Sstevel@tonic-gate mutex_lock(&_rsm_lock); 6960Sstevel@tonic-gate 6970Sstevel@tonic-gate if (chdl->cntr_refcnt == 0) { 6980Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 6990Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 7000Sstevel@tonic-gate "controller reference count is zero\n")); 7010Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 7020Sstevel@tonic-gate } 7030Sstevel@tonic-gate 7040Sstevel@tonic-gate chdl->cntr_refcnt--; 7050Sstevel@tonic-gate 7060Sstevel@tonic-gate if (chdl->cntr_refcnt > 0) { 7070Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 7080Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 7090Sstevel@tonic-gate "rsm_release_controller: exit\n")); 7100Sstevel@tonic-gate return (RSM_SUCCESS); 7110Sstevel@tonic-gate } 7120Sstevel@tonic-gate 7130Sstevel@tonic-gate e = chdl->cntr_segops->rsm_closedevice(cntr_handle); 7140Sstevel@tonic-gate 7150Sstevel@tonic-gate /* 7160Sstevel@tonic-gate * remove the controller in any case from the controller list 7170Sstevel@tonic-gate */ 7180Sstevel@tonic-gate 7190Sstevel@tonic-gate prev = curr = controller_list; 7200Sstevel@tonic-gate while (curr != NULL) { 7210Sstevel@tonic-gate if (curr == chdl) { 7220Sstevel@tonic-gate if (curr == prev) { 7230Sstevel@tonic-gate controller_list = curr->cntr_next; 7240Sstevel@tonic-gate } else { 7250Sstevel@tonic-gate prev->cntr_next = curr->cntr_next; 7260Sstevel@tonic-gate } 7270Sstevel@tonic-gate free(curr); 7280Sstevel@tonic-gate break; 7290Sstevel@tonic-gate } 7300Sstevel@tonic-gate prev = curr; 7310Sstevel@tonic-gate curr = curr->cntr_next; 7320Sstevel@tonic-gate } 7330Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 7340Sstevel@tonic-gate 7350Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 7360Sstevel@tonic-gate "rsm_release_controller: exit\n")); 7370Sstevel@tonic-gate 7380Sstevel@tonic-gate return (e); 7390Sstevel@tonic-gate } 7400Sstevel@tonic-gate 7410Sstevel@tonic-gate int _rsm_get_controller_attr(rsmapi_controller_handle_t chandle, 7420Sstevel@tonic-gate rsmapi_controller_attr_t *attr) 7430Sstevel@tonic-gate { 7440Sstevel@tonic-gate rsm_controller_t *p; 7450Sstevel@tonic-gate 7460Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 7470Sstevel@tonic-gate "rsm_get_controller_attr: enter\n")); 7480Sstevel@tonic-gate 7490Sstevel@tonic-gate if (!chandle) { 7500Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 7510Sstevel@tonic-gate "invalid controller handle\n")); 7520Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 7530Sstevel@tonic-gate } 7540Sstevel@tonic-gate 7550Sstevel@tonic-gate if (!attr) { 7560Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 7570Sstevel@tonic-gate "invalid attribute pointer\n")); 7580Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 7590Sstevel@tonic-gate } 7600Sstevel@tonic-gate 7610Sstevel@tonic-gate p = (rsm_controller_t *)chandle; 7620Sstevel@tonic-gate 7630Sstevel@tonic-gate mutex_lock(&_rsm_lock); 7640Sstevel@tonic-gate if (p->cntr_refcnt == 0) { 7650Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 7660Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 7670Sstevel@tonic-gate "cntr refcnt is 0\n")); 7680Sstevel@tonic-gate return (RSMERR_CTLR_NOT_PRESENT); 7690Sstevel@tonic-gate } 7700Sstevel@tonic-gate 7710Sstevel@tonic-gate /* copy only the user part of the attr structure */ 7720Sstevel@tonic-gate attr->attr_direct_access_sizes = 7730Sstevel@tonic-gate p->cntr_attr.attr_direct_access_sizes; 7740Sstevel@tonic-gate attr->attr_atomic_sizes = 7750Sstevel@tonic-gate p->cntr_attr.attr_atomic_sizes; 7760Sstevel@tonic-gate attr->attr_page_size = 7770Sstevel@tonic-gate p->cntr_attr.attr_page_size; 7780Sstevel@tonic-gate attr->attr_max_export_segment_size = 7790Sstevel@tonic-gate p->cntr_attr.attr_max_export_segment_size; 7800Sstevel@tonic-gate attr->attr_tot_export_segment_size = 7810Sstevel@tonic-gate p->cntr_attr.attr_tot_export_segment_size; 7820Sstevel@tonic-gate attr->attr_max_export_segments = 7830Sstevel@tonic-gate p->cntr_attr.attr_max_export_segments; 7840Sstevel@tonic-gate attr->attr_max_import_map_size = 7850Sstevel@tonic-gate p->cntr_attr.attr_max_import_map_size; 7860Sstevel@tonic-gate attr->attr_tot_import_map_size = 7870Sstevel@tonic-gate p->cntr_attr.attr_tot_import_map_size; 7880Sstevel@tonic-gate attr->attr_max_import_segments = 7890Sstevel@tonic-gate p->cntr_attr.attr_max_import_segments; 7900Sstevel@tonic-gate 7910Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 7920Sstevel@tonic-gate 7930Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 7940Sstevel@tonic-gate "rsm_get_controller_attr: exit\n")); 7950Sstevel@tonic-gate 7960Sstevel@tonic-gate return (RSM_SUCCESS); 7970Sstevel@tonic-gate } 7980Sstevel@tonic-gate 7990Sstevel@tonic-gate 8000Sstevel@tonic-gate 8010Sstevel@tonic-gate /* 8020Sstevel@tonic-gate * Create a segment handle for the virtual address range specified 8030Sstevel@tonic-gate * by vaddr and size 8040Sstevel@tonic-gate */ 8050Sstevel@tonic-gate int 8060Sstevel@tonic-gate _rsm_memseg_export_create(rsmapi_controller_handle_t controller, 8070Sstevel@tonic-gate rsm_memseg_export_handle_t *memseg, 8080Sstevel@tonic-gate void *vaddr, 8090Sstevel@tonic-gate size_t length, 8100Sstevel@tonic-gate uint_t flags) 8110Sstevel@tonic-gate { 8120Sstevel@tonic-gate 8130Sstevel@tonic-gate rsm_controller_t *chdl = (rsm_controller_t *)controller; 8140Sstevel@tonic-gate rsmseg_handle_t *p; 8150Sstevel@tonic-gate rsm_ioctlmsg_t msg; 8160Sstevel@tonic-gate int e; 8170Sstevel@tonic-gate #ifndef _LP64 8180Sstevel@tonic-gate int tmpfd; 8190Sstevel@tonic-gate #endif 8200Sstevel@tonic-gate 8210Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 8220Sstevel@tonic-gate "rsm_memseg_export_create: enter\n")); 8230Sstevel@tonic-gate 8240Sstevel@tonic-gate if (!controller) { 8250Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8260Sstevel@tonic-gate "invalid controller handle\n")); 8270Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 8280Sstevel@tonic-gate } 8290Sstevel@tonic-gate if (!memseg) { 8300Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8310Sstevel@tonic-gate "invalid segment handle\n")); 8320Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 8330Sstevel@tonic-gate } 8340Sstevel@tonic-gate 8350Sstevel@tonic-gate *memseg = 0; 8360Sstevel@tonic-gate 8370Sstevel@tonic-gate /* 8380Sstevel@tonic-gate * Check vaddr and size alignment, both must be mmu page size 8390Sstevel@tonic-gate * aligned 8400Sstevel@tonic-gate */ 8410Sstevel@tonic-gate if (!vaddr) { 8420Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8430Sstevel@tonic-gate "invalid arguments\n")); 8440Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 8450Sstevel@tonic-gate } 8460Sstevel@tonic-gate 8470Sstevel@tonic-gate if (!length) { 8480Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8490Sstevel@tonic-gate "invalid arguments\n")); 8500Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 8510Sstevel@tonic-gate } 8520Sstevel@tonic-gate 8530Sstevel@tonic-gate if (((size_t)vaddr & (PAGESIZE - 1)) || 8540Sstevel@tonic-gate (length & (PAGESIZE - 1))) { 8550Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8560Sstevel@tonic-gate "invalid mem alignment for vaddr or length\n")); 8570Sstevel@tonic-gate return (RSMERR_BAD_MEM_ALIGNMENT); 8580Sstevel@tonic-gate } 8590Sstevel@tonic-gate 8600Sstevel@tonic-gate /* 8610Sstevel@tonic-gate * The following check does not apply for loopback controller 8620Sstevel@tonic-gate * since for the loopback adapter, the attr_max_export_segment_size 8630Sstevel@tonic-gate * is always 0. 8640Sstevel@tonic-gate */ 8650Sstevel@tonic-gate if (strcasecmp(chdl->cntr_name, LOOPBACK)) { 8660Sstevel@tonic-gate if (length > chdl->cntr_attr.attr_max_export_segment_size) { 8670Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8680Sstevel@tonic-gate "length exceeds controller limits\n")); 8690Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8700Sstevel@tonic-gate "controller limits %d\n", 8710Sstevel@tonic-gate chdl->cntr_attr.attr_max_export_segment_size)); 8720Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 8730Sstevel@tonic-gate } 8740Sstevel@tonic-gate } 8750Sstevel@tonic-gate 8760Sstevel@tonic-gate p = (rsmseg_handle_t *)malloc(sizeof (*p)); 8770Sstevel@tonic-gate if (p == NULL) { 8780Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8790Sstevel@tonic-gate "not enough memory\n")); 8800Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_MEM); 8810Sstevel@tonic-gate } 8820Sstevel@tonic-gate 8830Sstevel@tonic-gate p->rsmseg_fd = open(DEVRSM, O_RDWR); 8840Sstevel@tonic-gate if (p->rsmseg_fd < 0) { 8850Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 8860Sstevel@tonic-gate "unable to open device /dev/rsm\n")); 8870Sstevel@tonic-gate free((void *)p); 8880Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_RESOURCES); 8890Sstevel@tonic-gate } 8900Sstevel@tonic-gate 8910Sstevel@tonic-gate #ifndef _LP64 8920Sstevel@tonic-gate /* 8930Sstevel@tonic-gate * libc can't handle fd's greater than 255, in order to 8940Sstevel@tonic-gate * insure that these values remain available make /dev/rsm 8950Sstevel@tonic-gate * fd > 255. Note: not needed for LP64 8960Sstevel@tonic-gate */ 8970Sstevel@tonic-gate tmpfd = fcntl(p->rsmseg_fd, F_DUPFD, 256); 8980Sstevel@tonic-gate e = errno; 8990Sstevel@tonic-gate if (tmpfd < 0) { 9000Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 9010Sstevel@tonic-gate "F_DUPFD failed\n")); 9020Sstevel@tonic-gate } else { 9030Sstevel@tonic-gate (void) close(p->rsmseg_fd); 9040Sstevel@tonic-gate p->rsmseg_fd = tmpfd; 9050Sstevel@tonic-gate } 9060Sstevel@tonic-gate #endif /* _LP64 */ 9070Sstevel@tonic-gate 9080Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, "" 9090Sstevel@tonic-gate "rsmseg_fd is %d\n", p->rsmseg_fd)); 9100Sstevel@tonic-gate 9110Sstevel@tonic-gate if (fcntl(p->rsmseg_fd, F_SETFD, FD_CLOEXEC) < 0) { 9120Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 9130Sstevel@tonic-gate "F_SETFD failed\n")); 9140Sstevel@tonic-gate } 9150Sstevel@tonic-gate 9160Sstevel@tonic-gate p->rsmseg_state = EXPORT_CREATE; 9170Sstevel@tonic-gate p->rsmseg_size = length; 9180Sstevel@tonic-gate /* increment controller handle */ 9190Sstevel@tonic-gate p->rsmseg_controller = chdl; 9200Sstevel@tonic-gate 9210Sstevel@tonic-gate /* try to bind user address range */ 9220Sstevel@tonic-gate msg.cnum = chdl->cntr_unit; 9230Sstevel@tonic-gate msg.cname = chdl->cntr_name; 9240Sstevel@tonic-gate msg.cname_len = strlen(chdl->cntr_name) +1; 9250Sstevel@tonic-gate msg.vaddr = vaddr; 9260Sstevel@tonic-gate msg.len = length; 9270Sstevel@tonic-gate msg.perm = flags; 9280Sstevel@tonic-gate msg.off = 0; 9290Sstevel@tonic-gate e = RSM_IOCTL_BIND; 9300Sstevel@tonic-gate 9310Sstevel@tonic-gate /* Try to bind */ 9320Sstevel@tonic-gate if (ioctl(p->rsmseg_fd, e, &msg) < 0) { 9330Sstevel@tonic-gate e = errno; 9340Sstevel@tonic-gate (void) close(p->rsmseg_fd); 9350Sstevel@tonic-gate free((void *)p); 9360Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 9370Sstevel@tonic-gate "RSM_IOCTL_BIND failed\n")); 9380Sstevel@tonic-gate return (e); 9390Sstevel@tonic-gate } 9400Sstevel@tonic-gate /* OK */ 9410Sstevel@tonic-gate p->rsmseg_type = RSM_EXPORT_SEG; 9420Sstevel@tonic-gate p->rsmseg_vaddr = vaddr; 9430Sstevel@tonic-gate p->rsmseg_size = length; 9440Sstevel@tonic-gate p->rsmseg_state = EXPORT_BIND; 9450Sstevel@tonic-gate p->rsmseg_pollfd_refcnt = 0; 9460Sstevel@tonic-gate p->rsmseg_rnum = msg.rnum; 9470Sstevel@tonic-gate 9480Sstevel@tonic-gate mutex_init(&p->rsmseg_lock, USYNC_THREAD, NULL); 9490Sstevel@tonic-gate 9500Sstevel@tonic-gate *memseg = (rsm_memseg_export_handle_t)p; 9510Sstevel@tonic-gate 9520Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 9530Sstevel@tonic-gate "rsm_memseg_export_create: exit\n")); 9540Sstevel@tonic-gate 9550Sstevel@tonic-gate return (RSM_SUCCESS); 9560Sstevel@tonic-gate } 9570Sstevel@tonic-gate 9580Sstevel@tonic-gate int 9590Sstevel@tonic-gate _rsm_memseg_export_destroy(rsm_memseg_export_handle_t memseg) 9600Sstevel@tonic-gate { 9610Sstevel@tonic-gate rsmseg_handle_t *seg; 9620Sstevel@tonic-gate 9630Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 9640Sstevel@tonic-gate "rsm_memseg_export_destroy: enter\n")); 9650Sstevel@tonic-gate 9660Sstevel@tonic-gate if (!memseg) { 9670Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 9680Sstevel@tonic-gate "invalid segment handle\n")); 9690Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 9700Sstevel@tonic-gate } 9710Sstevel@tonic-gate 9720Sstevel@tonic-gate seg = (rsmseg_handle_t *)memseg; 9730Sstevel@tonic-gate 9740Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 9750Sstevel@tonic-gate if (seg->rsmseg_pollfd_refcnt) { 9760Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 9770Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 9780Sstevel@tonic-gate "segment reference count not zero\n")); 9790Sstevel@tonic-gate return (RSMERR_POLLFD_IN_USE); 9800Sstevel@tonic-gate } 9810Sstevel@tonic-gate else 9820Sstevel@tonic-gate seg->rsmseg_state = EXPORT_BIND; 9830Sstevel@tonic-gate 9840Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 9850Sstevel@tonic-gate 9860Sstevel@tonic-gate (void) close(seg->rsmseg_fd); 9870Sstevel@tonic-gate mutex_destroy(&seg->rsmseg_lock); 9880Sstevel@tonic-gate free((void *)seg); 9890Sstevel@tonic-gate 9900Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 9910Sstevel@tonic-gate "rsm_memseg_export_destroy: exit\n")); 9920Sstevel@tonic-gate 9930Sstevel@tonic-gate return (RSM_SUCCESS); 9940Sstevel@tonic-gate } 9950Sstevel@tonic-gate 9960Sstevel@tonic-gate int 9970Sstevel@tonic-gate _rsm_memseg_export_rebind(rsm_memseg_export_handle_t memseg, void *vaddr, 9980Sstevel@tonic-gate offset_t off, size_t length) 9990Sstevel@tonic-gate { 10000Sstevel@tonic-gate rsm_ioctlmsg_t msg; 10010Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 10020Sstevel@tonic-gate 10030Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 10040Sstevel@tonic-gate "rsm_memseg_export_rebind: enter\n")); 10050Sstevel@tonic-gate 10060Sstevel@tonic-gate off = off; 10070Sstevel@tonic-gate 10080Sstevel@tonic-gate if (!seg) { 10090Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10100Sstevel@tonic-gate "invalid segment handle\n")); 10110Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 10120Sstevel@tonic-gate } 10130Sstevel@tonic-gate if (!vaddr) { 10140Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10150Sstevel@tonic-gate "invalid vaddr\n")); 10160Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 10170Sstevel@tonic-gate } 10180Sstevel@tonic-gate 10190Sstevel@tonic-gate /* 10200Sstevel@tonic-gate * Same as bind except it's ok to have elimint in list. 10210Sstevel@tonic-gate * Call into driver to remove any existing mappings. 10220Sstevel@tonic-gate */ 10230Sstevel@tonic-gate msg.vaddr = vaddr; 10240Sstevel@tonic-gate msg.len = length; 10250Sstevel@tonic-gate msg.off = 0; 10260Sstevel@tonic-gate 10270Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 10280Sstevel@tonic-gate if (ioctl(seg->rsmseg_fd, RSM_IOCTL_REBIND, &msg) < 0) { 10290Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 10300Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10310Sstevel@tonic-gate "RSM_IOCTL_REBIND failed\n")); 10320Sstevel@tonic-gate return (errno); 10330Sstevel@tonic-gate } 10340Sstevel@tonic-gate 10350Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 10360Sstevel@tonic-gate 10370Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 10380Sstevel@tonic-gate "rsm_memseg_export_rebind: exit\n")); 10390Sstevel@tonic-gate 10400Sstevel@tonic-gate return (RSM_SUCCESS); 10410Sstevel@tonic-gate } 10420Sstevel@tonic-gate 10430Sstevel@tonic-gate int 10440Sstevel@tonic-gate _rsm_memseg_export_publish(rsm_memseg_export_handle_t memseg, 10450Sstevel@tonic-gate rsm_memseg_id_t *seg_id, 10460Sstevel@tonic-gate rsmapi_access_entry_t access_list[], 10470Sstevel@tonic-gate uint_t access_list_length) 10480Sstevel@tonic-gate 10490Sstevel@tonic-gate { 10500Sstevel@tonic-gate rsm_ioctlmsg_t msg; 10510Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 10520Sstevel@tonic-gate 10530Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 10540Sstevel@tonic-gate "rsm_memseg_export_publish: enter\n")); 10550Sstevel@tonic-gate 10560Sstevel@tonic-gate if (seg_id == NULL) { 10570Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10580Sstevel@tonic-gate "invalid segment id\n")); 10590Sstevel@tonic-gate return (RSMERR_BAD_SEGID); 10600Sstevel@tonic-gate } 10610Sstevel@tonic-gate 10620Sstevel@tonic-gate if (!seg) { 10630Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10640Sstevel@tonic-gate "invalid segment handle\n")); 10650Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 10660Sstevel@tonic-gate } 10670Sstevel@tonic-gate 10680Sstevel@tonic-gate if (access_list_length > 0 && !access_list) { 10690Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10700Sstevel@tonic-gate "invalid access control list\n")); 10710Sstevel@tonic-gate return (RSMERR_BAD_ACL); 10720Sstevel@tonic-gate } 10730Sstevel@tonic-gate 10740Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 10750Sstevel@tonic-gate if (seg->rsmseg_state != EXPORT_BIND) { 10760Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 10770Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10780Sstevel@tonic-gate "invalid segment state\n")); 10790Sstevel@tonic-gate return (RSMERR_SEG_ALREADY_PUBLISHED); 10800Sstevel@tonic-gate } 10810Sstevel@tonic-gate 10820Sstevel@tonic-gate /* 10830Sstevel@tonic-gate * seg id < RSM_DLPI_END and in the RSM_USER_APP_ID range 10840Sstevel@tonic-gate * are reserved for internal use. 10850Sstevel@tonic-gate */ 10860Sstevel@tonic-gate if ((*seg_id > 0) && 10870Sstevel@tonic-gate ((*seg_id <= RSM_DLPI_ID_END) || 10880Sstevel@tonic-gate BETWEEN (*seg_id, RSM_USER_APP_ID_BASE, RSM_USER_APP_ID_END))) { 10890Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 10900Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10910Sstevel@tonic-gate "invalid segment id\n")); 10920Sstevel@tonic-gate return (RSMERR_RESERVED_SEGID); 10930Sstevel@tonic-gate } 10940Sstevel@tonic-gate 10950Sstevel@tonic-gate msg.key = *seg_id; 10960Sstevel@tonic-gate msg.acl = access_list; 10970Sstevel@tonic-gate msg.acl_len = access_list_length; 10980Sstevel@tonic-gate 10990Sstevel@tonic-gate if (ioctl(seg->rsmseg_fd, RSM_IOCTL_PUBLISH, &msg) < 0) { 11000Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11010Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 11020Sstevel@tonic-gate "RSM_IOCTL_PUBLISH failed\n")); 11030Sstevel@tonic-gate return (errno); 11040Sstevel@tonic-gate } 11050Sstevel@tonic-gate 11060Sstevel@tonic-gate seg->rsmseg_keyid = msg.key; 11070Sstevel@tonic-gate seg->rsmseg_state = EXPORT_PUBLISH; 11080Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11090Sstevel@tonic-gate 11100Sstevel@tonic-gate if (*seg_id == 0) 11110Sstevel@tonic-gate *seg_id = msg.key; 11120Sstevel@tonic-gate 11130Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 11140Sstevel@tonic-gate "rsm_memseg_export_publish: exit\n")); 11150Sstevel@tonic-gate 11160Sstevel@tonic-gate return (RSM_SUCCESS); 11170Sstevel@tonic-gate 11180Sstevel@tonic-gate } 11190Sstevel@tonic-gate 11200Sstevel@tonic-gate int 11210Sstevel@tonic-gate _rsm_memseg_export_unpublish(rsm_memseg_export_handle_t memseg) 11220Sstevel@tonic-gate { 11230Sstevel@tonic-gate rsm_ioctlmsg_t msg; 11240Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 11250Sstevel@tonic-gate 11260Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 11270Sstevel@tonic-gate "rsm_memseg_export_unpublish: enter\n")); 11280Sstevel@tonic-gate 11290Sstevel@tonic-gate if (!seg) { 11300Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 11310Sstevel@tonic-gate "invalid arguments\n")); 11320Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 11330Sstevel@tonic-gate } 11340Sstevel@tonic-gate 11350Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 11360Sstevel@tonic-gate if (seg->rsmseg_state != EXPORT_PUBLISH) { 11370Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11380Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 11390Sstevel@tonic-gate "segment not published %d\n", 11400Sstevel@tonic-gate seg->rsmseg_keyid)); 11410Sstevel@tonic-gate return (RSMERR_SEG_NOT_PUBLISHED); 11420Sstevel@tonic-gate } 11430Sstevel@tonic-gate 11440Sstevel@tonic-gate msg.key = seg->rsmseg_keyid; 11450Sstevel@tonic-gate if (ioctl(seg->rsmseg_fd, RSM_IOCTL_UNPUBLISH, &msg) < 0) { 11460Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11470Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 11480Sstevel@tonic-gate "RSM_IOCTL_UNPUBLISH failed\n")); 11490Sstevel@tonic-gate return (errno); 11500Sstevel@tonic-gate } 11510Sstevel@tonic-gate 11520Sstevel@tonic-gate seg->rsmseg_state = EXPORT_BIND; 11530Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11540Sstevel@tonic-gate 11550Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 11560Sstevel@tonic-gate "rsm_memseg_export_unpublish: exit\n")); 11570Sstevel@tonic-gate 11580Sstevel@tonic-gate return (RSM_SUCCESS); 11590Sstevel@tonic-gate } 11600Sstevel@tonic-gate 11610Sstevel@tonic-gate 11620Sstevel@tonic-gate int 11630Sstevel@tonic-gate _rsm_memseg_export_republish(rsm_memseg_export_handle_t memseg, 11640Sstevel@tonic-gate rsmapi_access_entry_t access_list[], 11650Sstevel@tonic-gate uint_t access_list_length) 11660Sstevel@tonic-gate { 11670Sstevel@tonic-gate rsm_ioctlmsg_t msg; 11680Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 11690Sstevel@tonic-gate 11700Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 11710Sstevel@tonic-gate "rsm_memseg_export_republish: enter\n")); 11720Sstevel@tonic-gate 11730Sstevel@tonic-gate if (!seg) { 11740Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 11750Sstevel@tonic-gate "invalid segment or segment state\n")); 11760Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 11770Sstevel@tonic-gate } 11780Sstevel@tonic-gate 11790Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 11800Sstevel@tonic-gate if (seg->rsmseg_state != EXPORT_PUBLISH) { 11810Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11820Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 11830Sstevel@tonic-gate "segment not published\n")); 11840Sstevel@tonic-gate return (RSMERR_SEG_NOT_PUBLISHED); 11850Sstevel@tonic-gate } 11860Sstevel@tonic-gate 11870Sstevel@tonic-gate if (access_list_length > 0 && !access_list) { 11880Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11890Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 11900Sstevel@tonic-gate "invalid access control list\n")); 11910Sstevel@tonic-gate return (RSMERR_BAD_ACL); 11920Sstevel@tonic-gate } 11930Sstevel@tonic-gate 11940Sstevel@tonic-gate msg.key = seg->rsmseg_keyid; 11950Sstevel@tonic-gate msg.acl = access_list; 11960Sstevel@tonic-gate msg.acl_len = access_list_length; 11970Sstevel@tonic-gate 11980Sstevel@tonic-gate if (ioctl(seg->rsmseg_fd, RSM_IOCTL_REPUBLISH, &msg) < 0) { 11990Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 12000Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 12010Sstevel@tonic-gate "RSM_IOCTL_REPUBLISH failed\n")); 12020Sstevel@tonic-gate return (errno); 12030Sstevel@tonic-gate } 12040Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 12050Sstevel@tonic-gate 12060Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 12070Sstevel@tonic-gate "rsm_memseg_export_republish: exit\n")); 12080Sstevel@tonic-gate 12090Sstevel@tonic-gate return (RSM_SUCCESS); 12100Sstevel@tonic-gate } 12110Sstevel@tonic-gate 12120Sstevel@tonic-gate 12130Sstevel@tonic-gate /* 12140Sstevel@tonic-gate * import side memory segment operations: 12150Sstevel@tonic-gate */ 12160Sstevel@tonic-gate int 12170Sstevel@tonic-gate _rsm_memseg_import_connect(rsmapi_controller_handle_t controller, 12180Sstevel@tonic-gate rsm_node_id_t node_id, 12190Sstevel@tonic-gate rsm_memseg_id_t segment_id, 12200Sstevel@tonic-gate rsm_permission_t perm, 12210Sstevel@tonic-gate rsm_memseg_import_handle_t *im_memseg) 12220Sstevel@tonic-gate { 12230Sstevel@tonic-gate rsm_ioctlmsg_t msg; 12240Sstevel@tonic-gate rsmseg_handle_t *p; 12250Sstevel@tonic-gate rsm_controller_t *cntr = (rsm_controller_t *)controller; 12260Sstevel@tonic-gate #ifndef _LP64 /* added for fd > 255 fix */ 12270Sstevel@tonic-gate int tmpfd; 12280Sstevel@tonic-gate #endif 12290Sstevel@tonic-gate int e; 12300Sstevel@tonic-gate 12310Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 12320Sstevel@tonic-gate "rsm_memseg_import_connect: enter\n")); 12330Sstevel@tonic-gate 12340Sstevel@tonic-gate if (!cntr) { 12350Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 12360Sstevel@tonic-gate "invalid controller handle\n")); 12370Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 12380Sstevel@tonic-gate } 12390Sstevel@tonic-gate 12400Sstevel@tonic-gate *im_memseg = 0; 12410Sstevel@tonic-gate 12420Sstevel@tonic-gate p = (rsmseg_handle_t *)malloc(sizeof (*p)); 12430Sstevel@tonic-gate if (!p) { 12440Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 12450Sstevel@tonic-gate "not enough memory\n")); 12460Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_MEM); 12470Sstevel@tonic-gate } 12480Sstevel@tonic-gate 12490Sstevel@tonic-gate if (perm & ~RSM_PERM_RDWR) { 12500Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 12510Sstevel@tonic-gate "invalid permissions\n")); 12520Sstevel@tonic-gate return (RSMERR_PERM_DENIED); 12530Sstevel@tonic-gate } 12540Sstevel@tonic-gate 12550Sstevel@tonic-gate /* 12560Sstevel@tonic-gate * Get size, va from driver 12570Sstevel@tonic-gate */ 12580Sstevel@tonic-gate msg.cnum = cntr->cntr_unit; 12590Sstevel@tonic-gate msg.cname = cntr->cntr_name; 12600Sstevel@tonic-gate msg.cname_len = strlen(cntr->cntr_name) +1; 12610Sstevel@tonic-gate msg.nodeid = node_id; 12620Sstevel@tonic-gate msg.key = segment_id; 12630Sstevel@tonic-gate msg.perm = perm; 12640Sstevel@tonic-gate 12650Sstevel@tonic-gate p->rsmseg_fd = open(DEVRSM, O_RDWR); 12660Sstevel@tonic-gate if (p->rsmseg_fd < 0) { 12670Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 12680Sstevel@tonic-gate "unable to open /dev/rsm")); 12690Sstevel@tonic-gate free((void *)p); 12700Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_RESOURCES); 12710Sstevel@tonic-gate } 12720Sstevel@tonic-gate 12730Sstevel@tonic-gate #ifndef _LP64 12740Sstevel@tonic-gate /* 12750Sstevel@tonic-gate * libc can't handle fd's greater than 255, in order to 12760Sstevel@tonic-gate * insure that these values remain available make /dev/rsm 12770Sstevel@tonic-gate * fd > 255. Note: not needed for LP64 12780Sstevel@tonic-gate */ 12790Sstevel@tonic-gate tmpfd = fcntl(p->rsmseg_fd, F_DUPFD, 256); /* make fd > 255 */ 12800Sstevel@tonic-gate e = errno; 12810Sstevel@tonic-gate if (tmpfd < 0) { 12820Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 12830Sstevel@tonic-gate "F_DUPFD failed\n")); 12840Sstevel@tonic-gate } else { 12850Sstevel@tonic-gate (void) close(p->rsmseg_fd); 12860Sstevel@tonic-gate p->rsmseg_fd = tmpfd; 12870Sstevel@tonic-gate } 12880Sstevel@tonic-gate #endif /* _LP64 */ 12890Sstevel@tonic-gate 12900Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 12910Sstevel@tonic-gate "rsmseg_fd is %d\n", p->rsmseg_fd)); 12920Sstevel@tonic-gate 12930Sstevel@tonic-gate if (fcntl(p->rsmseg_fd, F_SETFD, FD_CLOEXEC) < 0) { 12940Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 12950Sstevel@tonic-gate "F_SETFD failed\n")); 12960Sstevel@tonic-gate } 12970Sstevel@tonic-gate if (ioctl(p->rsmseg_fd, RSM_IOCTL_CONNECT, &msg) < 0) { 12980Sstevel@tonic-gate e = errno; 12990Sstevel@tonic-gate (void) close(p->rsmseg_fd); 13000Sstevel@tonic-gate free((void *)p); 13010Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 13020Sstevel@tonic-gate "RSM_IOCTL_CONNECT failed\n")); 13030Sstevel@tonic-gate return (e); 13040Sstevel@tonic-gate } 13050Sstevel@tonic-gate 13060Sstevel@tonic-gate /* 13070Sstevel@tonic-gate * We connected ok. 13080Sstevel@tonic-gate */ 13090Sstevel@tonic-gate p->rsmseg_type = RSM_IMPORT_SEG; 13100Sstevel@tonic-gate p->rsmseg_state = IMPORT_CONNECT; 13110Sstevel@tonic-gate p->rsmseg_keyid = segment_id; 13120Sstevel@tonic-gate p->rsmseg_nodeid = node_id; 13130Sstevel@tonic-gate p->rsmseg_size = msg.len; 13140Sstevel@tonic-gate p->rsmseg_perm = perm; 13150Sstevel@tonic-gate p->rsmseg_controller = cntr; 13160Sstevel@tonic-gate p->rsmseg_barrier = NULL; 13170Sstevel@tonic-gate p->rsmseg_barmode = RSM_BARRIER_MODE_IMPLICIT; 13180Sstevel@tonic-gate p->rsmseg_bar = (bar_va ? bar_va + msg.off : &bar_fixed); 13190Sstevel@tonic-gate p->rsmseg_gnum = msg.gnum; 13200Sstevel@tonic-gate p->rsmseg_pollfd_refcnt = 0; 13210Sstevel@tonic-gate p->rsmseg_maplen = 0; /* initialized, set in import_map */ 13220Sstevel@tonic-gate p->rsmseg_mapoffset = 0; 13230Sstevel@tonic-gate p->rsmseg_flags = 0; 13240Sstevel@tonic-gate p->rsmseg_rnum = msg.rnum; 13250Sstevel@tonic-gate mutex_init(&p->rsmseg_lock, USYNC_THREAD, NULL); 13260Sstevel@tonic-gate 13270Sstevel@tonic-gate p->rsmseg_ops = cntr->cntr_segops; 13280Sstevel@tonic-gate 13290Sstevel@tonic-gate /* 13300Sstevel@tonic-gate * XXX: Based on permission and controller direct_access attribute 13310Sstevel@tonic-gate * we fix the segment ops vector 13320Sstevel@tonic-gate */ 13330Sstevel@tonic-gate 13340Sstevel@tonic-gate p->rsmseg_vaddr = 0; /* defer mapping till using maps or trys to rw */ 13350Sstevel@tonic-gate 13360Sstevel@tonic-gate *im_memseg = (rsm_memseg_import_handle_t)p; 13370Sstevel@tonic-gate 13380Sstevel@tonic-gate e = p->rsmseg_ops->rsm_memseg_import_connect(controller, 13390Sstevel@tonic-gate node_id, segment_id, perm, im_memseg); 13400Sstevel@tonic-gate 13410Sstevel@tonic-gate if (e != RSM_SUCCESS) { 13420Sstevel@tonic-gate (void) close(p->rsmseg_fd); 13430Sstevel@tonic-gate mutex_destroy(&p->rsmseg_lock); 13440Sstevel@tonic-gate free((void *)p); 13450Sstevel@tonic-gate } 13460Sstevel@tonic-gate 13470Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 13480Sstevel@tonic-gate "rsm_memseg_import_connect: exit\n")); 13490Sstevel@tonic-gate 13500Sstevel@tonic-gate return (e); 13510Sstevel@tonic-gate } 13520Sstevel@tonic-gate 13530Sstevel@tonic-gate 13540Sstevel@tonic-gate int 13550Sstevel@tonic-gate _rsm_memseg_import_disconnect(rsm_memseg_import_handle_t im_memseg) 13560Sstevel@tonic-gate { 13570Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 13580Sstevel@tonic-gate int e; 13590Sstevel@tonic-gate 13600Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 13610Sstevel@tonic-gate "rsm_memseg_import_disconnect: enter\n")); 13620Sstevel@tonic-gate 13630Sstevel@tonic-gate if (!seg) { 13640Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 13650Sstevel@tonic-gate "invalid segment handle\n")); 13660Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 13670Sstevel@tonic-gate } 13680Sstevel@tonic-gate 13690Sstevel@tonic-gate if (seg->rsmseg_state != IMPORT_CONNECT) { 13700Sstevel@tonic-gate if (seg->rsmseg_flags & RSM_IMPLICIT_MAP) { 13710Sstevel@tonic-gate e = rsm_memseg_import_unmap(im_memseg); 13720Sstevel@tonic-gate if (e != RSM_SUCCESS) { 13730Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 13740Sstevel@tonic-gate "unmap failure\n")); 13750Sstevel@tonic-gate return (e); 13760Sstevel@tonic-gate } 13770Sstevel@tonic-gate } else { 13780Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 13790Sstevel@tonic-gate "segment busy\n")); 13800Sstevel@tonic-gate return (RSMERR_SEG_STILL_MAPPED); 13810Sstevel@tonic-gate } 13820Sstevel@tonic-gate } 13830Sstevel@tonic-gate 13840Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 13850Sstevel@tonic-gate if (seg->rsmseg_pollfd_refcnt) { 13860Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 13870Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 13880Sstevel@tonic-gate "segment reference count not zero\n")); 13890Sstevel@tonic-gate return (RSMERR_POLLFD_IN_USE); 13900Sstevel@tonic-gate } 13910Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 13920Sstevel@tonic-gate 13930Sstevel@tonic-gate e = seg->rsmseg_ops->rsm_memseg_import_disconnect(im_memseg); 13940Sstevel@tonic-gate 13950Sstevel@tonic-gate if (e == RSM_SUCCESS) { 13960Sstevel@tonic-gate (void) close(seg->rsmseg_fd); 13970Sstevel@tonic-gate mutex_destroy(&seg->rsmseg_lock); 13980Sstevel@tonic-gate free((void *)seg); 13990Sstevel@tonic-gate } 14000Sstevel@tonic-gate 14010Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 14020Sstevel@tonic-gate "rsm_memseg_import_disconnect: exit\n")); 14030Sstevel@tonic-gate 14040Sstevel@tonic-gate return (e); 14050Sstevel@tonic-gate } 14060Sstevel@tonic-gate 14070Sstevel@tonic-gate /* 14080Sstevel@tonic-gate * import side memory segment operations (read access functions): 14090Sstevel@tonic-gate */ 14100Sstevel@tonic-gate 14110Sstevel@tonic-gate static int 14120Sstevel@tonic-gate __rsm_import_verify_access(rsmseg_handle_t *seg, 14130Sstevel@tonic-gate off_t offset, 14140Sstevel@tonic-gate caddr_t datap, 14150Sstevel@tonic-gate size_t len, 14160Sstevel@tonic-gate rsm_permission_t perm, 14170Sstevel@tonic-gate rsm_access_size_t das) 14180Sstevel@tonic-gate { 14190Sstevel@tonic-gate int error; 14200Sstevel@tonic-gate 14210Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 14220Sstevel@tonic-gate " __rsm_import_verify_access: enter\n")); 14230Sstevel@tonic-gate 14240Sstevel@tonic-gate if (!seg) { 14250Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14260Sstevel@tonic-gate "invalid segment handle\n")); 14270Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 14280Sstevel@tonic-gate } 14290Sstevel@tonic-gate if (!datap) { 14300Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14310Sstevel@tonic-gate "invalid data pointer\n")); 14320Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 14330Sstevel@tonic-gate } 14340Sstevel@tonic-gate 14350Sstevel@tonic-gate /* 14360Sstevel@tonic-gate * Check alignment of pointer 14370Sstevel@tonic-gate */ 14380Sstevel@tonic-gate if ((uintptr_t)datap & (das - 1)) { 14390Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14400Sstevel@tonic-gate "invalid alignment of data pointer\n")); 14410Sstevel@tonic-gate return (RSMERR_BAD_MEM_ALIGNMENT); 14420Sstevel@tonic-gate } 14430Sstevel@tonic-gate 14440Sstevel@tonic-gate if (offset & (das - 1)) { 14450Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14460Sstevel@tonic-gate "invalid offset\n")); 14470Sstevel@tonic-gate return (RSMERR_BAD_MEM_ALIGNMENT); 14480Sstevel@tonic-gate } 14490Sstevel@tonic-gate 14500Sstevel@tonic-gate /* make sure that the import seg is connected */ 14510Sstevel@tonic-gate if (seg->rsmseg_state != IMPORT_CONNECT && 14520Sstevel@tonic-gate seg->rsmseg_state != IMPORT_MAP) { 14530Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14540Sstevel@tonic-gate "incorrect segment state\n")); 14550Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 14560Sstevel@tonic-gate } 14570Sstevel@tonic-gate 14580Sstevel@tonic-gate /* do an implicit map if required */ 14590Sstevel@tonic-gate if (seg->rsmseg_state == IMPORT_CONNECT) { 14600Sstevel@tonic-gate error = __rsm_import_implicit_map(seg, RSM_IOTYPE_PUTGET); 14610Sstevel@tonic-gate if (error != RSM_SUCCESS) { 14620Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14630Sstevel@tonic-gate "implicit map failure\n")); 14640Sstevel@tonic-gate return (error); 14650Sstevel@tonic-gate } 14660Sstevel@tonic-gate } 14670Sstevel@tonic-gate 14680Sstevel@tonic-gate if ((seg->rsmseg_perm & perm) != perm) { 14690Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14700Sstevel@tonic-gate "invalid permissions\n")); 14710Sstevel@tonic-gate return (RSMERR_PERM_DENIED); 14720Sstevel@tonic-gate } 14730Sstevel@tonic-gate 14740Sstevel@tonic-gate if (seg->rsmseg_state == IMPORT_MAP) { 14750Sstevel@tonic-gate if ((offset < seg->rsmseg_mapoffset) || 14760Sstevel@tonic-gate (offset + len > seg->rsmseg_mapoffset + 14770Sstevel@tonic-gate seg->rsmseg_maplen)) { 14780Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14790Sstevel@tonic-gate "incorrect offset+length\n")); 14800Sstevel@tonic-gate return (RSMERR_BAD_OFFSET); 14810Sstevel@tonic-gate } 14820Sstevel@tonic-gate } else { /* IMPORT_CONNECT */ 14830Sstevel@tonic-gate if ((len + offset) > seg->rsmseg_size) { 14840Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14850Sstevel@tonic-gate "incorrect offset+length\n")); 14860Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 14870Sstevel@tonic-gate } 14880Sstevel@tonic-gate } 14890Sstevel@tonic-gate 14900Sstevel@tonic-gate if ((seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) && 14910Sstevel@tonic-gate (seg->rsmseg_barrier == NULL)) { 14920Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14930Sstevel@tonic-gate "invalid barrier\n")); 14940Sstevel@tonic-gate return (RSMERR_BARRIER_UNINITIALIZED); 14950Sstevel@tonic-gate } 14960Sstevel@tonic-gate 14970Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 14980Sstevel@tonic-gate " __rsm_import_verify_access: exit\n")); 14990Sstevel@tonic-gate 15000Sstevel@tonic-gate return (RSM_SUCCESS); 15010Sstevel@tonic-gate } 15020Sstevel@tonic-gate 15030Sstevel@tonic-gate static int 15040Sstevel@tonic-gate __rsm_import_implicit_map(rsmseg_handle_t *seg, int iotype) 15050Sstevel@tonic-gate { 15060Sstevel@tonic-gate caddr_t va; 15070Sstevel@tonic-gate int flag = MAP_SHARED; 15080Sstevel@tonic-gate int prot = PROT_READ|PROT_WRITE; 15090Sstevel@tonic-gate int mapping_reqd = 0; 15100Sstevel@tonic-gate 15110Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 15120Sstevel@tonic-gate " __rsm_import_implicit_map: enter\n")); 15130Sstevel@tonic-gate 15140Sstevel@tonic-gate if (iotype == RSM_IOTYPE_PUTGET) 15150Sstevel@tonic-gate mapping_reqd = seg->rsmseg_controller->cntr_lib_attr-> 15160Sstevel@tonic-gate rsm_putget_map_reqd; 15170Sstevel@tonic-gate else if (iotype == RSM_IOTYPE_SCATGATH) 15180Sstevel@tonic-gate mapping_reqd = seg->rsmseg_controller->cntr_lib_attr-> 15190Sstevel@tonic-gate rsm_scatgath_map_reqd; 15200Sstevel@tonic-gate 15210Sstevel@tonic-gate 15220Sstevel@tonic-gate if (mapping_reqd) { 15230Sstevel@tonic-gate va = mmap(NULL, seg->rsmseg_size, prot, 15240Sstevel@tonic-gate flag, seg->rsmseg_fd, 0); 15250Sstevel@tonic-gate 15260Sstevel@tonic-gate if (va == MAP_FAILED) { 15270Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 15280Sstevel@tonic-gate "implicit map failed\n")); 15290Sstevel@tonic-gate if (errno == ENOMEM || errno == ENXIO || 15300Sstevel@tonic-gate errno == EOVERFLOW) 15310Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 15320Sstevel@tonic-gate else if (errno == ENODEV) 15330Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 15340Sstevel@tonic-gate else if (errno == EAGAIN) 15350Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_RESOURCES); 15360Sstevel@tonic-gate else if (errno == ENOTSUP) 15370Sstevel@tonic-gate return (RSMERR_MAP_FAILED); 15380Sstevel@tonic-gate else if (errno == EACCES) 15390Sstevel@tonic-gate return (RSMERR_BAD_PERMS); 15400Sstevel@tonic-gate else 15410Sstevel@tonic-gate return (RSMERR_MAP_FAILED); 15420Sstevel@tonic-gate } 15430Sstevel@tonic-gate seg->rsmseg_vaddr = va; 15440Sstevel@tonic-gate seg->rsmseg_maplen = seg->rsmseg_size; 15450Sstevel@tonic-gate seg->rsmseg_mapoffset = 0; 15460Sstevel@tonic-gate seg->rsmseg_state = IMPORT_MAP; 15470Sstevel@tonic-gate seg->rsmseg_flags |= RSM_IMPLICIT_MAP; 15480Sstevel@tonic-gate } 15490Sstevel@tonic-gate 15500Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 15510Sstevel@tonic-gate " __rsm_import_implicit_map: exit\n")); 15520Sstevel@tonic-gate 15530Sstevel@tonic-gate return (RSM_SUCCESS); 15540Sstevel@tonic-gate } 15550Sstevel@tonic-gate 15560Sstevel@tonic-gate int 15570Sstevel@tonic-gate _rsm_memseg_import_get8(rsm_memseg_import_handle_t im_memseg, 15580Sstevel@tonic-gate off_t offset, 15590Sstevel@tonic-gate uint8_t *datap, 15600Sstevel@tonic-gate ulong_t rep_cnt) 15610Sstevel@tonic-gate { 15620Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 15630Sstevel@tonic-gate int e; 15640Sstevel@tonic-gate 15650Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 15660Sstevel@tonic-gate "rsm_memseg_import_get8: enter\n")); 15670Sstevel@tonic-gate 15680Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt, 15690Sstevel@tonic-gate RSM_PERM_READ, 15700Sstevel@tonic-gate RSM_DAS8); 15710Sstevel@tonic-gate if (e == RSM_SUCCESS) { 15720Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 15730Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 15740Sstevel@tonic-gate 15750Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 15760Sstevel@tonic-gate /* generation number snapshot */ 15770Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 15780Sstevel@tonic-gate } 15790Sstevel@tonic-gate 15800Sstevel@tonic-gate e = ops->rsm_memseg_import_get8(im_memseg, offset, datap, 15810Sstevel@tonic-gate rep_cnt, 0); 15820Sstevel@tonic-gate 15830Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 15840Sstevel@tonic-gate /* check the generation number for force disconnects */ 15850Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 15860Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 15870Sstevel@tonic-gate } 15880Sstevel@tonic-gate } 15890Sstevel@tonic-gate } 15900Sstevel@tonic-gate 15910Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 15920Sstevel@tonic-gate "rsm_memseg_import_get8: exit\n")); 15930Sstevel@tonic-gate 15940Sstevel@tonic-gate return (e); 15950Sstevel@tonic-gate } 15960Sstevel@tonic-gate 15970Sstevel@tonic-gate int 15980Sstevel@tonic-gate _rsm_memseg_import_get16(rsm_memseg_import_handle_t im_memseg, 15990Sstevel@tonic-gate off_t offset, 16000Sstevel@tonic-gate uint16_t *datap, 16010Sstevel@tonic-gate ulong_t rep_cnt) 16020Sstevel@tonic-gate { 16030Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 16040Sstevel@tonic-gate int e; 16050Sstevel@tonic-gate 16060Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 16070Sstevel@tonic-gate "rsm_memseg_import_get16: enter\n")); 16080Sstevel@tonic-gate 16090Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*2, 16100Sstevel@tonic-gate RSM_PERM_READ, 16110Sstevel@tonic-gate RSM_DAS16); 16120Sstevel@tonic-gate if (e == RSM_SUCCESS) { 16130Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 16140Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 16150Sstevel@tonic-gate 16160Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 16170Sstevel@tonic-gate /* generation number snapshot */ 16180Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 16190Sstevel@tonic-gate } 16200Sstevel@tonic-gate 16210Sstevel@tonic-gate e = ops->rsm_memseg_import_get16(im_memseg, offset, datap, 16220Sstevel@tonic-gate rep_cnt, 0); 16230Sstevel@tonic-gate 16240Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 16250Sstevel@tonic-gate /* check the generation number for force disconnects */ 16260Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 16270Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 16280Sstevel@tonic-gate } 16290Sstevel@tonic-gate } 16300Sstevel@tonic-gate 16310Sstevel@tonic-gate } 16320Sstevel@tonic-gate 16330Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 16340Sstevel@tonic-gate "rsm_memseg_import_get16: exit\n")); 16350Sstevel@tonic-gate 16360Sstevel@tonic-gate return (e); 16370Sstevel@tonic-gate } 16380Sstevel@tonic-gate 16390Sstevel@tonic-gate int 16400Sstevel@tonic-gate _rsm_memseg_import_get32(rsm_memseg_import_handle_t im_memseg, 16410Sstevel@tonic-gate off_t offset, 16420Sstevel@tonic-gate uint32_t *datap, 16430Sstevel@tonic-gate ulong_t rep_cnt) 16440Sstevel@tonic-gate { 16450Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 16460Sstevel@tonic-gate int e; 16470Sstevel@tonic-gate 16480Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 16490Sstevel@tonic-gate "rsm_memseg_import_get32: enter\n")); 16500Sstevel@tonic-gate 16510Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*4, 16520Sstevel@tonic-gate RSM_PERM_READ, 16530Sstevel@tonic-gate RSM_DAS32); 16540Sstevel@tonic-gate if (e == RSM_SUCCESS) { 16550Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 16560Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 16570Sstevel@tonic-gate 16580Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 16590Sstevel@tonic-gate /* generation number snapshot */ 16600Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 16610Sstevel@tonic-gate } 16620Sstevel@tonic-gate 16630Sstevel@tonic-gate e = ops->rsm_memseg_import_get32(im_memseg, offset, datap, 16640Sstevel@tonic-gate rep_cnt, 0); 16650Sstevel@tonic-gate 16660Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 16670Sstevel@tonic-gate /* check the generation number for force disconnects */ 16680Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 16690Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 16700Sstevel@tonic-gate } 16710Sstevel@tonic-gate } 16720Sstevel@tonic-gate } 16730Sstevel@tonic-gate 16740Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 16750Sstevel@tonic-gate "rsm_memseg_import_get32: exit\n")); 16760Sstevel@tonic-gate 16770Sstevel@tonic-gate return (e); 16780Sstevel@tonic-gate } 16790Sstevel@tonic-gate 16800Sstevel@tonic-gate int 16810Sstevel@tonic-gate _rsm_memseg_import_get64(rsm_memseg_import_handle_t im_memseg, 16820Sstevel@tonic-gate off_t offset, 16830Sstevel@tonic-gate uint64_t *datap, 16840Sstevel@tonic-gate ulong_t rep_cnt) 16850Sstevel@tonic-gate { 16860Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 16870Sstevel@tonic-gate int e; 16880Sstevel@tonic-gate 16890Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 16900Sstevel@tonic-gate "rsm_memseg_import_get64: enter\n")); 16910Sstevel@tonic-gate 16920Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*8, 16930Sstevel@tonic-gate RSM_PERM_READ, 16940Sstevel@tonic-gate RSM_DAS64); 16950Sstevel@tonic-gate if (e == RSM_SUCCESS) { 16960Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 16970Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 16980Sstevel@tonic-gate 16990Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 17000Sstevel@tonic-gate /* generation number snapshot */ 17010Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 17020Sstevel@tonic-gate } 17030Sstevel@tonic-gate 17040Sstevel@tonic-gate e = ops->rsm_memseg_import_get64(im_memseg, offset, datap, 17050Sstevel@tonic-gate rep_cnt, 0); 17060Sstevel@tonic-gate 17070Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 17080Sstevel@tonic-gate /* check the generation number for force disconnects */ 17090Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 17100Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 17110Sstevel@tonic-gate } 17120Sstevel@tonic-gate } 17130Sstevel@tonic-gate } 17140Sstevel@tonic-gate 17150Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 17160Sstevel@tonic-gate "rsm_memseg_import_get64: exit\n")); 17170Sstevel@tonic-gate 17180Sstevel@tonic-gate return (e); 17190Sstevel@tonic-gate } 17200Sstevel@tonic-gate 17210Sstevel@tonic-gate int 17220Sstevel@tonic-gate _rsm_memseg_import_get(rsm_memseg_import_handle_t im_memseg, 17230Sstevel@tonic-gate off_t offset, 17240Sstevel@tonic-gate void *dst_addr, 17250Sstevel@tonic-gate size_t length) 17260Sstevel@tonic-gate { 17270Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 17280Sstevel@tonic-gate int e; 17290Sstevel@tonic-gate 17300Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 17310Sstevel@tonic-gate "rsm_memseg_import_get: enter\n")); 17320Sstevel@tonic-gate 17330Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)dst_addr, length, 17340Sstevel@tonic-gate RSM_PERM_READ, 17350Sstevel@tonic-gate RSM_DAS8); 17360Sstevel@tonic-gate if (e == RSM_SUCCESS) { 17370Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 17380Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 17390Sstevel@tonic-gate 17400Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 17410Sstevel@tonic-gate /* generation number snapshot */ 17420Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 17430Sstevel@tonic-gate } 17440Sstevel@tonic-gate 17450Sstevel@tonic-gate e = ops->rsm_memseg_import_get(im_memseg, offset, dst_addr, 17460Sstevel@tonic-gate length); 17470Sstevel@tonic-gate 17480Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 17490Sstevel@tonic-gate /* check the generation number for force disconnects */ 17500Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 17510Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 17520Sstevel@tonic-gate } 17530Sstevel@tonic-gate } 17540Sstevel@tonic-gate } 17550Sstevel@tonic-gate 17560Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 17570Sstevel@tonic-gate "rsm_memseg_import_get: exit\n")); 17580Sstevel@tonic-gate 17590Sstevel@tonic-gate return (e); 17600Sstevel@tonic-gate } 17610Sstevel@tonic-gate 17620Sstevel@tonic-gate 17630Sstevel@tonic-gate int 17640Sstevel@tonic-gate _rsm_memseg_import_getv(rsm_scat_gath_t *sg_io) 17650Sstevel@tonic-gate { 17660Sstevel@tonic-gate rsm_controller_t *cntrl; 17670Sstevel@tonic-gate rsmseg_handle_t *seg; 17680Sstevel@tonic-gate uint_t save_sg_io_flags; 17690Sstevel@tonic-gate 17700Sstevel@tonic-gate int e; 17710Sstevel@tonic-gate 17720Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 17730Sstevel@tonic-gate "rsm_memseg_import_getv: enter\n")); 17740Sstevel@tonic-gate 17750Sstevel@tonic-gate if (sg_io == NULL) { 17760Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 17770Sstevel@tonic-gate "invalid sg_io structure\n")); 17780Sstevel@tonic-gate return (RSMERR_BAD_SGIO); 17790Sstevel@tonic-gate } 17800Sstevel@tonic-gate 17810Sstevel@tonic-gate seg = (rsmseg_handle_t *)sg_io->remote_handle; 17820Sstevel@tonic-gate if (seg == NULL) { 17830Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 17840Sstevel@tonic-gate "invalid remote segment handle in sg_io\n")); 17850Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 17860Sstevel@tonic-gate } 17870Sstevel@tonic-gate 17880Sstevel@tonic-gate cntrl = (rsm_controller_t *)seg->rsmseg_controller; 17890Sstevel@tonic-gate if (cntrl == NULL) { 17900Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 17910Sstevel@tonic-gate "invalid controller handle\n")); 17920Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 17930Sstevel@tonic-gate } 17940Sstevel@tonic-gate 17950Sstevel@tonic-gate if ((sg_io->io_request_count > RSM_MAX_SGIOREQS) || 17960Sstevel@tonic-gate (sg_io->io_request_count == 0)) { 17970Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 17980Sstevel@tonic-gate "io_request_count value incorrect\n")); 17990Sstevel@tonic-gate return (RSMERR_BAD_SGIO); 18000Sstevel@tonic-gate } 18010Sstevel@tonic-gate 18020Sstevel@tonic-gate if (seg->rsmseg_state == IMPORT_CONNECT) { 18030Sstevel@tonic-gate e = __rsm_import_implicit_map(seg, RSM_IOTYPE_SCATGATH); 18040Sstevel@tonic-gate if (e != RSM_SUCCESS) { 18050Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 18060Sstevel@tonic-gate "implicit map failure\n")); 18070Sstevel@tonic-gate return (e); 18080Sstevel@tonic-gate } 18090Sstevel@tonic-gate } 18100Sstevel@tonic-gate 18110Sstevel@tonic-gate /* 18120Sstevel@tonic-gate * Copy the flags field of the sg_io structure in a local 18130Sstevel@tonic-gate * variable. 18140Sstevel@tonic-gate * This is required since the flags field can be 18150Sstevel@tonic-gate * changed by the plugin library routine to indicate that 18160Sstevel@tonic-gate * the signal post was done. 18170Sstevel@tonic-gate * This change in the flags field of the sg_io structure 18180Sstevel@tonic-gate * should not be reflected to the user. Hence once the flags 18190Sstevel@tonic-gate * field has been used for the purpose of determining whether 18200Sstevel@tonic-gate * the plugin executed a signal post, it must be restored to 18210Sstevel@tonic-gate * its original value which is stored in the local variable. 18220Sstevel@tonic-gate */ 18230Sstevel@tonic-gate save_sg_io_flags = sg_io->flags; 18240Sstevel@tonic-gate 18250Sstevel@tonic-gate e = cntrl->cntr_segops->rsm_memseg_import_getv(sg_io); 18260Sstevel@tonic-gate 18270Sstevel@tonic-gate /* 18280Sstevel@tonic-gate * At this point, if an implicit signal post was requested by 18290Sstevel@tonic-gate * the user, there could be two possibilities that arise: 18300Sstevel@tonic-gate * 1. the plugin routine has already executed the implicit 18310Sstevel@tonic-gate * signal post either successfully or unsuccessfully 18320Sstevel@tonic-gate * 2. the plugin does not have the capability of doing an 18330Sstevel@tonic-gate * implicit signal post and hence the signal post needs 18340Sstevel@tonic-gate * to be done here. 18350Sstevel@tonic-gate * The above two cases can be idenfied by the flags 18360Sstevel@tonic-gate * field within the sg_io structure as follows: 18370Sstevel@tonic-gate * In case 1, the RSM_IMPLICIT_SIGPOST bit is reset to 0 by the 18380Sstevel@tonic-gate * plugin, indicating that the signal post was done. 18390Sstevel@tonic-gate * In case 2, the bit remains set to a 1 as originally given 18400Sstevel@tonic-gate * by the user, and hence a signal post needs to be done here. 18410Sstevel@tonic-gate */ 18420Sstevel@tonic-gate if (sg_io->flags & RSM_IMPLICIT_SIGPOST && 18430Sstevel@tonic-gate e == RSM_SUCCESS) { 18440Sstevel@tonic-gate /* Do the implicit signal post */ 18450Sstevel@tonic-gate 18460Sstevel@tonic-gate /* 18470Sstevel@tonic-gate * The value of the second argument to this call 18480Sstevel@tonic-gate * depends on the value of the sg_io->flags field. 18490Sstevel@tonic-gate * If the RSM_SIGPOST_NO_ACCUMULATE flag has been 18500Sstevel@tonic-gate * ored into the sg_io->flags field, this indicates 18510Sstevel@tonic-gate * that the rsm_intr_signal_post is to be done with 18520Sstevel@tonic-gate * the flags argument set to RSM_SIGPOST_NO_ACCUMULATE 18530Sstevel@tonic-gate * Else, the flags argument is set to 0. These 18540Sstevel@tonic-gate * semantics can be achieved simply by masking off 18550Sstevel@tonic-gate * all other bits in the sg_io->flags field except the 18560Sstevel@tonic-gate * RSM_SIGPOST_NO_ACCUMULATE bit and using the result 18570Sstevel@tonic-gate * as the flags argument for the rsm_intr_signal_post. 18580Sstevel@tonic-gate */ 18590Sstevel@tonic-gate 18600Sstevel@tonic-gate int sigpost_flags = sg_io->flags & RSM_SIGPOST_NO_ACCUMULATE; 18610Sstevel@tonic-gate e = rsm_intr_signal_post(seg, sigpost_flags); 18620Sstevel@tonic-gate } 18630Sstevel@tonic-gate 18640Sstevel@tonic-gate /* Restore the flags field within the users scatter gather structure */ 18650Sstevel@tonic-gate sg_io->flags = save_sg_io_flags; 18660Sstevel@tonic-gate 18670Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 18680Sstevel@tonic-gate "rsm_memseg_import_getv: exit\n")); 18690Sstevel@tonic-gate 18700Sstevel@tonic-gate return (e); 18710Sstevel@tonic-gate 18720Sstevel@tonic-gate } 18730Sstevel@tonic-gate 18740Sstevel@tonic-gate /* 18750Sstevel@tonic-gate * import side memory segment operations (write access functions): 18760Sstevel@tonic-gate */ 18770Sstevel@tonic-gate 18780Sstevel@tonic-gate int 18790Sstevel@tonic-gate _rsm_memseg_import_put8(rsm_memseg_import_handle_t im_memseg, 18800Sstevel@tonic-gate off_t offset, 18810Sstevel@tonic-gate uint8_t *datap, 18820Sstevel@tonic-gate ulong_t rep_cnt) 18830Sstevel@tonic-gate { 18840Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 18850Sstevel@tonic-gate int e; 18860Sstevel@tonic-gate 18870Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 18880Sstevel@tonic-gate "rsm_memseg_import_put8: enter\n")); 18890Sstevel@tonic-gate 18900Sstevel@tonic-gate /* addr of data will always pass the alignment check, avoids */ 18910Sstevel@tonic-gate /* need for a special case in verify_access for PUTs */ 18920Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt, 18930Sstevel@tonic-gate RSM_PERM_WRITE, 18940Sstevel@tonic-gate RSM_DAS8); 18950Sstevel@tonic-gate if (e == RSM_SUCCESS) { 18960Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 18970Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 18980Sstevel@tonic-gate 18990Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 19000Sstevel@tonic-gate /* generation number snapshot */ 19010Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 19020Sstevel@tonic-gate } 19030Sstevel@tonic-gate 19040Sstevel@tonic-gate e = ops->rsm_memseg_import_put8(im_memseg, offset, datap, 19050Sstevel@tonic-gate rep_cnt, 0); 19060Sstevel@tonic-gate 19070Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 19080Sstevel@tonic-gate /* check the generation number for force disconnects */ 19090Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 19100Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 19110Sstevel@tonic-gate } 19120Sstevel@tonic-gate } 19130Sstevel@tonic-gate } 19140Sstevel@tonic-gate 19150Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 19160Sstevel@tonic-gate "rsm_memseg_import_put8: exit\n")); 19170Sstevel@tonic-gate 19180Sstevel@tonic-gate return (e); 19190Sstevel@tonic-gate } 19200Sstevel@tonic-gate 19210Sstevel@tonic-gate int 19220Sstevel@tonic-gate _rsm_memseg_import_put16(rsm_memseg_import_handle_t im_memseg, 19230Sstevel@tonic-gate off_t offset, 19240Sstevel@tonic-gate uint16_t *datap, 19250Sstevel@tonic-gate ulong_t rep_cnt) 19260Sstevel@tonic-gate { 19270Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 19280Sstevel@tonic-gate int e; 19290Sstevel@tonic-gate 19300Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 19310Sstevel@tonic-gate "rsm_memseg_import_put16: enter\n")); 19320Sstevel@tonic-gate 19330Sstevel@tonic-gate /* addr of data will always pass the alignment check, avoids */ 19340Sstevel@tonic-gate /* need for a special case in verify_access for PUTs */ 19350Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*2, 19360Sstevel@tonic-gate RSM_PERM_WRITE, 19370Sstevel@tonic-gate RSM_DAS16); 19380Sstevel@tonic-gate if (e == RSM_SUCCESS) { 19390Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 19400Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 19410Sstevel@tonic-gate 19420Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 19430Sstevel@tonic-gate /* generation number snapshot */ 19440Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 19450Sstevel@tonic-gate } 19460Sstevel@tonic-gate 19470Sstevel@tonic-gate e = ops->rsm_memseg_import_put16(im_memseg, offset, datap, 19480Sstevel@tonic-gate rep_cnt, 0); 19490Sstevel@tonic-gate 19500Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 19510Sstevel@tonic-gate /* check the generation number for force disconnects */ 19520Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 19530Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 19540Sstevel@tonic-gate } 19550Sstevel@tonic-gate } 19560Sstevel@tonic-gate 19570Sstevel@tonic-gate } 19580Sstevel@tonic-gate 19590Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 19600Sstevel@tonic-gate "rsm_memseg_import_put16: exit\n")); 19610Sstevel@tonic-gate 19620Sstevel@tonic-gate return (e); 19630Sstevel@tonic-gate } 19640Sstevel@tonic-gate 19650Sstevel@tonic-gate int 19660Sstevel@tonic-gate _rsm_memseg_import_put32(rsm_memseg_import_handle_t im_memseg, 19670Sstevel@tonic-gate off_t offset, 19680Sstevel@tonic-gate uint32_t *datap, 19690Sstevel@tonic-gate ulong_t rep_cnt) 19700Sstevel@tonic-gate { 19710Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 19720Sstevel@tonic-gate int e; 19730Sstevel@tonic-gate 19740Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 19750Sstevel@tonic-gate "rsm_memseg_import_put32: enter\n")); 19760Sstevel@tonic-gate 19770Sstevel@tonic-gate /* addr of data will always pass the alignment check, avoids */ 19780Sstevel@tonic-gate /* need for a special case in verify_access for PUTs */ 19790Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*4, 19800Sstevel@tonic-gate RSM_PERM_WRITE, 19810Sstevel@tonic-gate RSM_DAS32); 19820Sstevel@tonic-gate if (e == RSM_SUCCESS) { 19830Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 19840Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 19850Sstevel@tonic-gate 19860Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 19870Sstevel@tonic-gate /* generation number snapshot */ 19880Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 19890Sstevel@tonic-gate } 19900Sstevel@tonic-gate 19910Sstevel@tonic-gate e = ops->rsm_memseg_import_put32(im_memseg, offset, datap, 19920Sstevel@tonic-gate rep_cnt, 0); 19930Sstevel@tonic-gate 19940Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 19950Sstevel@tonic-gate /* check the generation number for force disconnects */ 19960Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 19970Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 19980Sstevel@tonic-gate } 19990Sstevel@tonic-gate } 20000Sstevel@tonic-gate } 20010Sstevel@tonic-gate 20020Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 20030Sstevel@tonic-gate "rsm_memseg_import_put32: exit\n")); 20040Sstevel@tonic-gate 20050Sstevel@tonic-gate return (e); 20060Sstevel@tonic-gate } 20070Sstevel@tonic-gate 20080Sstevel@tonic-gate int 20090Sstevel@tonic-gate _rsm_memseg_import_put64(rsm_memseg_import_handle_t im_memseg, 20100Sstevel@tonic-gate off_t offset, 20110Sstevel@tonic-gate uint64_t *datap, 20120Sstevel@tonic-gate ulong_t rep_cnt) 20130Sstevel@tonic-gate { 20140Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 20150Sstevel@tonic-gate int e; 20160Sstevel@tonic-gate 20170Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 20180Sstevel@tonic-gate "rsm_memseg_import_put64: enter\n")); 20190Sstevel@tonic-gate 20200Sstevel@tonic-gate /* addr of data will always pass the alignment check, avoids */ 20210Sstevel@tonic-gate /* need for a special case in verify_access for PUTs */ 20220Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*8, 20230Sstevel@tonic-gate RSM_PERM_WRITE, 20240Sstevel@tonic-gate RSM_DAS64); 20250Sstevel@tonic-gate if (e == RSM_SUCCESS) { 20260Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 20270Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 20280Sstevel@tonic-gate 20290Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 20300Sstevel@tonic-gate /* generation number snapshot */ 20310Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 20320Sstevel@tonic-gate } 20330Sstevel@tonic-gate 20340Sstevel@tonic-gate e = ops->rsm_memseg_import_put64(im_memseg, offset, datap, 20350Sstevel@tonic-gate rep_cnt, 0); 20360Sstevel@tonic-gate 20370Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 20380Sstevel@tonic-gate /* check the generation number for force disconnects */ 20390Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 20400Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 20410Sstevel@tonic-gate } 20420Sstevel@tonic-gate } 20430Sstevel@tonic-gate } 20440Sstevel@tonic-gate 20450Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 20460Sstevel@tonic-gate "rsm_memseg_import_put64: exit\n")); 20470Sstevel@tonic-gate 20480Sstevel@tonic-gate return (e); 20490Sstevel@tonic-gate } 20500Sstevel@tonic-gate 20510Sstevel@tonic-gate int 20520Sstevel@tonic-gate _rsm_memseg_import_put(rsm_memseg_import_handle_t im_memseg, 20530Sstevel@tonic-gate off_t offset, 20540Sstevel@tonic-gate void *src_addr, 20550Sstevel@tonic-gate size_t length) 20560Sstevel@tonic-gate { 20570Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 20580Sstevel@tonic-gate int e; 20590Sstevel@tonic-gate 20600Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 20610Sstevel@tonic-gate "rsm_memseg_import_put: enter\n")); 20620Sstevel@tonic-gate 20630Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)src_addr, length, 20640Sstevel@tonic-gate RSM_PERM_WRITE, 20650Sstevel@tonic-gate RSM_DAS8); 20660Sstevel@tonic-gate if (e == RSM_SUCCESS) { 20670Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 20680Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 20690Sstevel@tonic-gate 20700Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 20710Sstevel@tonic-gate /* generation number snapshot */ 20720Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 20730Sstevel@tonic-gate } 20740Sstevel@tonic-gate 20750Sstevel@tonic-gate e = ops->rsm_memseg_import_put(im_memseg, offset, src_addr, 20760Sstevel@tonic-gate length); 20770Sstevel@tonic-gate 20780Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 20790Sstevel@tonic-gate /* check the generation number for force disconnects */ 20800Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 20810Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 20820Sstevel@tonic-gate } 20830Sstevel@tonic-gate } 20840Sstevel@tonic-gate 20850Sstevel@tonic-gate } 20860Sstevel@tonic-gate 20870Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 20880Sstevel@tonic-gate "rsm_memseg_import_put: exit\n")); 20890Sstevel@tonic-gate return (e); 20900Sstevel@tonic-gate } 20910Sstevel@tonic-gate 20920Sstevel@tonic-gate 20930Sstevel@tonic-gate int 20940Sstevel@tonic-gate _rsm_memseg_import_putv(rsm_scat_gath_t *sg_io) 20950Sstevel@tonic-gate { 20960Sstevel@tonic-gate rsm_controller_t *cntrl; 20970Sstevel@tonic-gate rsmseg_handle_t *seg; 20980Sstevel@tonic-gate uint_t save_sg_io_flags; 20990Sstevel@tonic-gate 21000Sstevel@tonic-gate int e; 21010Sstevel@tonic-gate 21020Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 21030Sstevel@tonic-gate "rsm_memseg_import_putv: enter\n")); 21040Sstevel@tonic-gate 21050Sstevel@tonic-gate 21060Sstevel@tonic-gate if (sg_io == NULL) { 21070Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 21080Sstevel@tonic-gate "invalid sg_io structure\n")); 21090Sstevel@tonic-gate return (RSMERR_BAD_SGIO); 21100Sstevel@tonic-gate } 21110Sstevel@tonic-gate 21120Sstevel@tonic-gate seg = (rsmseg_handle_t *)sg_io->remote_handle; 21130Sstevel@tonic-gate if (seg == NULL) { 21140Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 21150Sstevel@tonic-gate "invalid remote segment handle in sg_io\n")); 21160Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 21170Sstevel@tonic-gate } 21180Sstevel@tonic-gate 21190Sstevel@tonic-gate cntrl = (rsm_controller_t *)seg->rsmseg_controller; 21200Sstevel@tonic-gate if (cntrl == NULL) { 21210Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 21220Sstevel@tonic-gate "invalid controller handle\n")); 21230Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 21240Sstevel@tonic-gate } 21250Sstevel@tonic-gate 21260Sstevel@tonic-gate if ((sg_io->io_request_count > RSM_MAX_SGIOREQS) || 21270Sstevel@tonic-gate (sg_io->io_request_count == 0)) { 21280Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 21290Sstevel@tonic-gate "io_request_count value incorrect\n")); 21300Sstevel@tonic-gate return (RSMERR_BAD_SGIO); 21310Sstevel@tonic-gate } 21320Sstevel@tonic-gate 21330Sstevel@tonic-gate /* do an implicit map if required */ 21340Sstevel@tonic-gate if (seg->rsmseg_state == IMPORT_CONNECT) { 21350Sstevel@tonic-gate e = __rsm_import_implicit_map(seg, RSM_IOTYPE_SCATGATH); 21360Sstevel@tonic-gate if (e != RSM_SUCCESS) { 21370Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 21380Sstevel@tonic-gate "implicit map failed\n")); 21390Sstevel@tonic-gate return (e); 21400Sstevel@tonic-gate } 21410Sstevel@tonic-gate } 21420Sstevel@tonic-gate 21430Sstevel@tonic-gate /* 21440Sstevel@tonic-gate * Copy the flags field of the sg_io structure in a local 21450Sstevel@tonic-gate * variable. 21460Sstevel@tonic-gate * This is required since the flags field can be 21470Sstevel@tonic-gate * changed by the plugin library routine to indicate that 21480Sstevel@tonic-gate * the signal post was done. 21490Sstevel@tonic-gate * This change in the flags field of the sg_io structure 21500Sstevel@tonic-gate * should not be reflected to the user. Hence once the flags 21510Sstevel@tonic-gate * field has been used for the purpose of determining whether 21520Sstevel@tonic-gate * the plugin executed a signal post, it must be restored to 21530Sstevel@tonic-gate * its original value which is stored in the local variable. 21540Sstevel@tonic-gate */ 21550Sstevel@tonic-gate save_sg_io_flags = sg_io->flags; 21560Sstevel@tonic-gate 21570Sstevel@tonic-gate e = cntrl->cntr_segops->rsm_memseg_import_putv(sg_io); 21580Sstevel@tonic-gate 21590Sstevel@tonic-gate /* 21600Sstevel@tonic-gate * At this point, if an implicit signal post was requested by 21610Sstevel@tonic-gate * the user, there could be two possibilities that arise: 21620Sstevel@tonic-gate * 1. the plugin routine has already executed the implicit 21630Sstevel@tonic-gate * signal post either successfully or unsuccessfully 21640Sstevel@tonic-gate * 2. the plugin does not have the capability of doing an 21650Sstevel@tonic-gate * implicit signal post and hence the signal post needs 21660Sstevel@tonic-gate * to be done here. 21670Sstevel@tonic-gate * The above two cases can be idenfied by the flags 21680Sstevel@tonic-gate * field within the sg_io structure as follows: 21690Sstevel@tonic-gate * In case 1, the RSM_IMPLICIT_SIGPOST bit is reset to 0 by the 21700Sstevel@tonic-gate * plugin, indicating that the signal post was done. 21710Sstevel@tonic-gate * In case 2, the bit remains set to a 1 as originally given 21720Sstevel@tonic-gate * by the user, and hence a signal post needs to be done here. 21730Sstevel@tonic-gate */ 21740Sstevel@tonic-gate if (sg_io->flags & RSM_IMPLICIT_SIGPOST && 21750Sstevel@tonic-gate e == RSM_SUCCESS) { 21760Sstevel@tonic-gate /* Do the implicit signal post */ 21770Sstevel@tonic-gate 21780Sstevel@tonic-gate /* 21790Sstevel@tonic-gate * The value of the second argument to this call 21800Sstevel@tonic-gate * depends on the value of the sg_io->flags field. 21810Sstevel@tonic-gate * If the RSM_SIGPOST_NO_ACCUMULATE flag has been 21820Sstevel@tonic-gate * ored into the sg_io->flags field, this indicates 21830Sstevel@tonic-gate * that the rsm_intr_signal_post is to be done with 21840Sstevel@tonic-gate * the flags argument set to RSM_SIGPOST_NO_ACCUMULATE 21850Sstevel@tonic-gate * Else, the flags argument is set to 0. These 21860Sstevel@tonic-gate * semantics can be achieved simply by masking off 21870Sstevel@tonic-gate * all other bits in the sg_io->flags field except the 21880Sstevel@tonic-gate * RSM_SIGPOST_NO_ACCUMULATE bit and using the result 21890Sstevel@tonic-gate * as the flags argument for the rsm_intr_signal_post. 21900Sstevel@tonic-gate */ 21910Sstevel@tonic-gate 21920Sstevel@tonic-gate int sigpost_flags = sg_io->flags & RSM_SIGPOST_NO_ACCUMULATE; 21930Sstevel@tonic-gate e = rsm_intr_signal_post(seg, sigpost_flags); 21940Sstevel@tonic-gate 21950Sstevel@tonic-gate } 21960Sstevel@tonic-gate 21970Sstevel@tonic-gate /* Restore the flags field within the users scatter gather structure */ 21980Sstevel@tonic-gate sg_io->flags = save_sg_io_flags; 21990Sstevel@tonic-gate 22000Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 22010Sstevel@tonic-gate "rsm_memseg_import_putv: exit\n")); 22020Sstevel@tonic-gate 22030Sstevel@tonic-gate return (e); 22040Sstevel@tonic-gate } 22050Sstevel@tonic-gate 22060Sstevel@tonic-gate 22070Sstevel@tonic-gate /* 22080Sstevel@tonic-gate * import side memory segment operations (mapping): 22090Sstevel@tonic-gate */ 22100Sstevel@tonic-gate int 22110Sstevel@tonic-gate _rsm_memseg_import_map(rsm_memseg_import_handle_t im_memseg, 22120Sstevel@tonic-gate void **address, 22130Sstevel@tonic-gate rsm_attribute_t attr, 22140Sstevel@tonic-gate rsm_permission_t perm, 22150Sstevel@tonic-gate off_t offset, 22160Sstevel@tonic-gate size_t length) 22170Sstevel@tonic-gate { 22180Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 22190Sstevel@tonic-gate int flag = MAP_SHARED; 22200Sstevel@tonic-gate int prot; 22210Sstevel@tonic-gate caddr_t va; 22220Sstevel@tonic-gate 22230Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 22240Sstevel@tonic-gate "rsm_memseg_import_map: enter\n")); 22250Sstevel@tonic-gate 22260Sstevel@tonic-gate if (!seg) { 22270Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 22280Sstevel@tonic-gate "invalid segment\n")); 22290Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 22300Sstevel@tonic-gate } 22310Sstevel@tonic-gate if (!address) { 22320Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 22330Sstevel@tonic-gate "invalid address\n")); 22340Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 22350Sstevel@tonic-gate } 22360Sstevel@tonic-gate 22370Sstevel@tonic-gate /* 22380Sstevel@tonic-gate * Only one map per segment handle! 22390Sstevel@tonic-gate * XXX need to take a lock here 22400Sstevel@tonic-gate */ 22410Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 22420Sstevel@tonic-gate 22430Sstevel@tonic-gate if (seg->rsmseg_state == IMPORT_MAP) { 22440Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 22450Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 22460Sstevel@tonic-gate "segment already mapped\n")); 22470Sstevel@tonic-gate return (RSMERR_SEG_ALREADY_MAPPED); 22480Sstevel@tonic-gate } 22490Sstevel@tonic-gate 22500Sstevel@tonic-gate /* Only import segments allowed to map */ 22510Sstevel@tonic-gate if (seg->rsmseg_state != IMPORT_CONNECT) { 22520Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 22530Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 22540Sstevel@tonic-gate } 22550Sstevel@tonic-gate 22560Sstevel@tonic-gate /* check for permissions */ 22570Sstevel@tonic-gate if (perm > RSM_PERM_RDWR) { 22580Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 22590Sstevel@tonic-gate "bad permissions when mapping\n")); 22600Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 22610Sstevel@tonic-gate return (RSMERR_BAD_PERMS); 22620Sstevel@tonic-gate } 22630Sstevel@tonic-gate 22640Sstevel@tonic-gate if (length == 0) { 22650Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 22660Sstevel@tonic-gate "mapping with length 0\n")); 22670Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 22680Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 22690Sstevel@tonic-gate } 22700Sstevel@tonic-gate 22710Sstevel@tonic-gate if (offset + length > seg->rsmseg_size) { 22720Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 22730Sstevel@tonic-gate "map length + offset exceed segment size\n")); 22740Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 22750Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 22760Sstevel@tonic-gate } 22770Sstevel@tonic-gate 22780Sstevel@tonic-gate if ((size_t)offset & (PAGESIZE - 1)) { 22790Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 22800Sstevel@tonic-gate "bad mem alignment\n")); 22810Sstevel@tonic-gate return (RSMERR_BAD_MEM_ALIGNMENT); 22820Sstevel@tonic-gate } 22830Sstevel@tonic-gate 22840Sstevel@tonic-gate if (attr & RSM_MAP_FIXED) { 22850Sstevel@tonic-gate if ((uintptr_t)(*address) & (PAGESIZE - 1)) { 22860Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 22870Sstevel@tonic-gate "bad mem alignment\n")); 22880Sstevel@tonic-gate return (RSMERR_BAD_MEM_ALIGNMENT); 22890Sstevel@tonic-gate } 22900Sstevel@tonic-gate flag |= MAP_FIXED; 22910Sstevel@tonic-gate } 22920Sstevel@tonic-gate 22930Sstevel@tonic-gate prot = PROT_NONE; 22940Sstevel@tonic-gate if (perm & RSM_PERM_READ) 22950Sstevel@tonic-gate prot |= PROT_READ; 22960Sstevel@tonic-gate if (perm & RSM_PERM_WRITE) 22970Sstevel@tonic-gate prot |= PROT_WRITE; 22980Sstevel@tonic-gate 22990Sstevel@tonic-gate va = mmap(*address, length, prot, flag, seg->rsmseg_fd, offset); 23000Sstevel@tonic-gate if (va == MAP_FAILED) { 23010Sstevel@tonic-gate int e = errno; 23020Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 23030Sstevel@tonic-gate "error %d during map\n", e)); 23040Sstevel@tonic-gate 23050Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 23060Sstevel@tonic-gate if (e == ENXIO || e == EOVERFLOW || 23070Sstevel@tonic-gate e == ENOMEM) 23080Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 23090Sstevel@tonic-gate else if (e == ENODEV) 23100Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 23110Sstevel@tonic-gate else if (e == EAGAIN) 23120Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_RESOURCES); 23130Sstevel@tonic-gate else if (e == ENOTSUP) 23140Sstevel@tonic-gate return (RSMERR_MAP_FAILED); 23150Sstevel@tonic-gate else if (e == EACCES) 23160Sstevel@tonic-gate return (RSMERR_BAD_PERMS); 23170Sstevel@tonic-gate else 23180Sstevel@tonic-gate return (RSMERR_MAP_FAILED); 23190Sstevel@tonic-gate } 23200Sstevel@tonic-gate *address = va; 23210Sstevel@tonic-gate 23220Sstevel@tonic-gate /* 23230Sstevel@tonic-gate * Fix segment ops vector to handle direct access. 23240Sstevel@tonic-gate */ 23250Sstevel@tonic-gate /* 23260Sstevel@tonic-gate * XXX: Set this only for full segment mapping. Keep a list 23270Sstevel@tonic-gate * of mappings to use for access functions 23280Sstevel@tonic-gate */ 23290Sstevel@tonic-gate seg->rsmseg_vaddr = va; 23300Sstevel@tonic-gate seg->rsmseg_maplen = length; 23310Sstevel@tonic-gate seg->rsmseg_mapoffset = offset; 23320Sstevel@tonic-gate seg->rsmseg_state = IMPORT_MAP; 23330Sstevel@tonic-gate 23340Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 23350Sstevel@tonic-gate 23360Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 23370Sstevel@tonic-gate "rsm_memseg_import_map: exit\n")); 23380Sstevel@tonic-gate 23390Sstevel@tonic-gate return (RSM_SUCCESS); 23400Sstevel@tonic-gate } 23410Sstevel@tonic-gate 23420Sstevel@tonic-gate int 23430Sstevel@tonic-gate _rsm_memseg_import_unmap(rsm_memseg_import_handle_t im_memseg) 23440Sstevel@tonic-gate { 23450Sstevel@tonic-gate /* 23460Sstevel@tonic-gate * Until we fix the rsm driver to catch unload, we unload 23470Sstevel@tonic-gate * the whole segment. 23480Sstevel@tonic-gate */ 23490Sstevel@tonic-gate 23500Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 23510Sstevel@tonic-gate 23520Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 23530Sstevel@tonic-gate "rsm_memseg_import_unmap: enter\n")); 23540Sstevel@tonic-gate 23550Sstevel@tonic-gate if (!seg) { 23560Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 23570Sstevel@tonic-gate "invalid segment or segment state\n")); 23580Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 23590Sstevel@tonic-gate } 23600Sstevel@tonic-gate 23610Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 23620Sstevel@tonic-gate if (seg->rsmseg_state != IMPORT_MAP) { 23630Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 23640Sstevel@tonic-gate return (RSMERR_SEG_NOT_MAPPED); 23650Sstevel@tonic-gate } 23660Sstevel@tonic-gate 23670Sstevel@tonic-gate seg->rsmseg_mapoffset = 0; /* reset the offset */ 23680Sstevel@tonic-gate seg->rsmseg_state = IMPORT_CONNECT; 23690Sstevel@tonic-gate seg->rsmseg_flags &= ~RSM_IMPLICIT_MAP; 23700Sstevel@tonic-gate (void) munmap(seg->rsmseg_vaddr, seg->rsmseg_maplen); 23710Sstevel@tonic-gate 23720Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 23730Sstevel@tonic-gate 23740Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 23750Sstevel@tonic-gate "rsm_memseg_import_unmap: exit\n")); 23760Sstevel@tonic-gate 23770Sstevel@tonic-gate return (RSM_SUCCESS); 23780Sstevel@tonic-gate } 23790Sstevel@tonic-gate 23800Sstevel@tonic-gate 23810Sstevel@tonic-gate /* 23820Sstevel@tonic-gate * import side memory segment operations (barriers): 23830Sstevel@tonic-gate */ 23840Sstevel@tonic-gate int 23850Sstevel@tonic-gate _rsm_memseg_import_init_barrier(rsm_memseg_import_handle_t im_memseg, 23860Sstevel@tonic-gate rsm_barrier_type_t type, 23870Sstevel@tonic-gate rsmapi_barrier_t *barrier) 23880Sstevel@tonic-gate { 23890Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 23900Sstevel@tonic-gate rsmbar_handle_t *bar; 23910Sstevel@tonic-gate 23920Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 23930Sstevel@tonic-gate "rsm_memseg_import_init_barrier: enter\n")); 23940Sstevel@tonic-gate 23950Sstevel@tonic-gate if (!seg) { 23960Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 23970Sstevel@tonic-gate "invalid segment or barrier\n")); 23980Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 23990Sstevel@tonic-gate } 24000Sstevel@tonic-gate if (!barrier) { 24010Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 24020Sstevel@tonic-gate "invalid barrier pointer\n")); 24030Sstevel@tonic-gate return (RSMERR_BAD_BARRIER_PTR); 24040Sstevel@tonic-gate } 24050Sstevel@tonic-gate 24060Sstevel@tonic-gate bar = (rsmbar_handle_t *)barrier; 24070Sstevel@tonic-gate bar->rsmbar_seg = seg; 24080Sstevel@tonic-gate 24090Sstevel@tonic-gate seg->rsmseg_barrier = barrier; /* used in put/get fns */ 24100Sstevel@tonic-gate 24110Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 24120Sstevel@tonic-gate "rsm_memseg_import_init_barrier: exit\n")); 24130Sstevel@tonic-gate 24140Sstevel@tonic-gate return (seg->rsmseg_ops->rsm_memseg_import_init_barrier(im_memseg, 24150Sstevel@tonic-gate type, (rsm_barrier_handle_t)barrier)); 24160Sstevel@tonic-gate } 24170Sstevel@tonic-gate 24180Sstevel@tonic-gate int 24190Sstevel@tonic-gate _rsm_memseg_import_open_barrier(rsmapi_barrier_t *barrier) 24200Sstevel@tonic-gate { 24210Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)barrier; 24220Sstevel@tonic-gate rsm_segops_t *ops; 24230Sstevel@tonic-gate 24240Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 24250Sstevel@tonic-gate "rsm_memseg_import_open_barrier: enter\n")); 24260Sstevel@tonic-gate 24270Sstevel@tonic-gate if (!bar) { 24280Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 24290Sstevel@tonic-gate "invalid barrier\n")); 24300Sstevel@tonic-gate return (RSMERR_BAD_BARRIER_PTR); 24310Sstevel@tonic-gate } 24320Sstevel@tonic-gate if (!bar->rsmbar_seg) { 24330Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 24340Sstevel@tonic-gate "uninitialized barrier\n")); 24350Sstevel@tonic-gate return (RSMERR_BARRIER_UNINITIALIZED); 24360Sstevel@tonic-gate } 24370Sstevel@tonic-gate 24380Sstevel@tonic-gate /* generation number snapshot */ 24390Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; /* bar[0] */ 24400Sstevel@tonic-gate 24410Sstevel@tonic-gate ops = bar->rsmbar_seg->rsmseg_ops; 24420Sstevel@tonic-gate 24430Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 24440Sstevel@tonic-gate "rsm_memseg_import_open_barrier: exit\n")); 24450Sstevel@tonic-gate 24460Sstevel@tonic-gate return (ops->rsm_memseg_import_open_barrier( 24470Sstevel@tonic-gate (rsm_barrier_handle_t)barrier)); 24480Sstevel@tonic-gate } 24490Sstevel@tonic-gate 24500Sstevel@tonic-gate int 24510Sstevel@tonic-gate _rsm_memseg_import_order_barrier(rsmapi_barrier_t *barrier) 24520Sstevel@tonic-gate { 24530Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)barrier; 24540Sstevel@tonic-gate rsm_segops_t *ops; 24550Sstevel@tonic-gate 24560Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 24570Sstevel@tonic-gate "rsm_memseg_import_order_barrier: enter\n")); 24580Sstevel@tonic-gate 24590Sstevel@tonic-gate if (!bar) { 24600Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 24610Sstevel@tonic-gate "invalid barrier\n")); 24620Sstevel@tonic-gate return (RSMERR_BAD_BARRIER_PTR); 24630Sstevel@tonic-gate } 24640Sstevel@tonic-gate if (!bar->rsmbar_seg) { 24650Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 24660Sstevel@tonic-gate "uninitialized barrier\n")); 24670Sstevel@tonic-gate return (RSMERR_BARRIER_UNINITIALIZED); 24680Sstevel@tonic-gate } 24690Sstevel@tonic-gate 24700Sstevel@tonic-gate ops = bar->rsmbar_seg->rsmseg_ops; 24710Sstevel@tonic-gate 24720Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 24730Sstevel@tonic-gate "rsm_memseg_import_order_barrier: exit\n")); 24740Sstevel@tonic-gate 24750Sstevel@tonic-gate return (ops->rsm_memseg_import_order_barrier( 24760Sstevel@tonic-gate (rsm_barrier_handle_t)barrier)); 24770Sstevel@tonic-gate } 24780Sstevel@tonic-gate 24790Sstevel@tonic-gate int 24800Sstevel@tonic-gate _rsm_memseg_import_close_barrier(rsmapi_barrier_t *barrier) 24810Sstevel@tonic-gate { 24820Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)barrier; 24830Sstevel@tonic-gate rsm_segops_t *ops; 24840Sstevel@tonic-gate 24850Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 24860Sstevel@tonic-gate "rsm_memseg_import_close_barrier: enter\n")); 24870Sstevel@tonic-gate 24880Sstevel@tonic-gate if (!bar) { 24890Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 24900Sstevel@tonic-gate "invalid barrier\n")); 24910Sstevel@tonic-gate return (RSMERR_BAD_BARRIER_PTR); 24920Sstevel@tonic-gate } 24930Sstevel@tonic-gate if (!bar->rsmbar_seg) { 24940Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 24950Sstevel@tonic-gate "uninitialized barrier\n")); 24960Sstevel@tonic-gate return (RSMERR_BARRIER_UNINITIALIZED); 24970Sstevel@tonic-gate } 24980Sstevel@tonic-gate 24990Sstevel@tonic-gate /* generation number snapshot */ 25000Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 25010Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 25020Sstevel@tonic-gate } 25030Sstevel@tonic-gate 25040Sstevel@tonic-gate ops = bar->rsmbar_seg->rsmseg_ops; 25050Sstevel@tonic-gate 25060Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25070Sstevel@tonic-gate "rsm_memseg_import_close_barrier: exit\n")); 25080Sstevel@tonic-gate 25090Sstevel@tonic-gate return (ops->rsm_memseg_import_close_barrier( 25100Sstevel@tonic-gate (rsm_barrier_handle_t)barrier)); 25110Sstevel@tonic-gate } 25120Sstevel@tonic-gate 25130Sstevel@tonic-gate int 25140Sstevel@tonic-gate _rsm_memseg_import_destroy_barrier(rsmapi_barrier_t *barrier) 25150Sstevel@tonic-gate { 25160Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)barrier; 25170Sstevel@tonic-gate rsm_segops_t *ops; 25180Sstevel@tonic-gate 25190Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25200Sstevel@tonic-gate "rsm_memseg_import_destroy_barrier: enter\n")); 25210Sstevel@tonic-gate 25220Sstevel@tonic-gate if (!bar) { 25230Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 25240Sstevel@tonic-gate "invalid barrier\n")); 25250Sstevel@tonic-gate return (RSMERR_BAD_BARRIER_PTR); 25260Sstevel@tonic-gate } 25270Sstevel@tonic-gate if (!bar->rsmbar_seg) { 25280Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 25290Sstevel@tonic-gate "uninitialized barrier\n")); 25300Sstevel@tonic-gate return (RSMERR_BARRIER_UNINITIALIZED); 25310Sstevel@tonic-gate } 25320Sstevel@tonic-gate 25330Sstevel@tonic-gate bar->rsmbar_seg->rsmseg_barrier = NULL; 25340Sstevel@tonic-gate 25350Sstevel@tonic-gate ops = bar->rsmbar_seg->rsmseg_ops; 25360Sstevel@tonic-gate 25370Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25380Sstevel@tonic-gate "rsm_memseg_import_destroy_barrier: exit\n")); 25390Sstevel@tonic-gate 25400Sstevel@tonic-gate return (ops->rsm_memseg_import_destroy_barrier 25410Sstevel@tonic-gate ((rsm_barrier_handle_t)barrier)); 25420Sstevel@tonic-gate } 25430Sstevel@tonic-gate 25440Sstevel@tonic-gate int 25450Sstevel@tonic-gate _rsm_memseg_import_get_mode(rsm_memseg_import_handle_t im_memseg, 25460Sstevel@tonic-gate rsm_barrier_mode_t *mode) 25470Sstevel@tonic-gate { 25480Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 25490Sstevel@tonic-gate 25500Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25510Sstevel@tonic-gate "rsm_memseg_import_get_mode: enter\n")); 25520Sstevel@tonic-gate 25530Sstevel@tonic-gate if (seg) { 25540Sstevel@tonic-gate *mode = seg->rsmseg_barmode; 25550Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25560Sstevel@tonic-gate "rsm_memseg_import_get_mode: exit\n")); 25570Sstevel@tonic-gate 25580Sstevel@tonic-gate return (seg->rsmseg_ops->rsm_memseg_import_get_mode(im_memseg, 25590Sstevel@tonic-gate mode)); 25600Sstevel@tonic-gate } 25610Sstevel@tonic-gate 25620Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 25630Sstevel@tonic-gate "invalid arguments \n")); 25640Sstevel@tonic-gate 25650Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 25660Sstevel@tonic-gate 25670Sstevel@tonic-gate } 25680Sstevel@tonic-gate 25690Sstevel@tonic-gate int 25700Sstevel@tonic-gate _rsm_memseg_import_set_mode(rsm_memseg_import_handle_t im_memseg, 25710Sstevel@tonic-gate rsm_barrier_mode_t mode) 25720Sstevel@tonic-gate { 25730Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 25740Sstevel@tonic-gate 25750Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25760Sstevel@tonic-gate "rsm_memseg_import_set_mode: enter\n")); 25770Sstevel@tonic-gate if (seg) { 25780Sstevel@tonic-gate if ((mode == RSM_BARRIER_MODE_IMPLICIT || 25790Sstevel@tonic-gate mode == RSM_BARRIER_MODE_EXPLICIT)) { 25800Sstevel@tonic-gate seg->rsmseg_barmode = mode; 25810Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25820Sstevel@tonic-gate "rsm_memseg_import_set_mode: exit\n")); 25830Sstevel@tonic-gate 25840Sstevel@tonic-gate return (seg->rsmseg_ops->rsm_memseg_import_set_mode( 25850Sstevel@tonic-gate im_memseg, 25860Sstevel@tonic-gate mode)); 25870Sstevel@tonic-gate } else { 25880Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25890Sstevel@tonic-gate "bad barrier mode\n")); 25900Sstevel@tonic-gate return (RSMERR_BAD_MODE); 25910Sstevel@tonic-gate } 25920Sstevel@tonic-gate } 25930Sstevel@tonic-gate 25940Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 25950Sstevel@tonic-gate "invalid arguments\n")); 25960Sstevel@tonic-gate 25970Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 25980Sstevel@tonic-gate } 25990Sstevel@tonic-gate 26000Sstevel@tonic-gate int 26010Sstevel@tonic-gate _rsm_intr_signal_post(void *memseg, uint_t flags) 26020Sstevel@tonic-gate { 26030Sstevel@tonic-gate rsm_ioctlmsg_t msg; 26040Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 26050Sstevel@tonic-gate 26060Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 26070Sstevel@tonic-gate "rsm_intr_signal_post: enter\n")); 26080Sstevel@tonic-gate 26090Sstevel@tonic-gate flags = flags; 26100Sstevel@tonic-gate 26110Sstevel@tonic-gate if (!seg) { 26120Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 26130Sstevel@tonic-gate "invalid segment handle\n")); 26140Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 26150Sstevel@tonic-gate } 26160Sstevel@tonic-gate 26170Sstevel@tonic-gate if (ioctl(seg->rsmseg_fd, RSM_IOCTL_RING_BELL, &msg) < 0) { 26180Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 26190Sstevel@tonic-gate "RSM_IOCTL_RING_BELL failed\n")); 26200Sstevel@tonic-gate return (errno); 26210Sstevel@tonic-gate } 26220Sstevel@tonic-gate 26230Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 26240Sstevel@tonic-gate "rsm_intr_signal_post: exit\n")); 26250Sstevel@tonic-gate 26260Sstevel@tonic-gate return (RSM_SUCCESS); 26270Sstevel@tonic-gate } 26280Sstevel@tonic-gate 26290Sstevel@tonic-gate int 26300Sstevel@tonic-gate _rsm_intr_signal_wait(void *memseg, int timeout) 26310Sstevel@tonic-gate { 26320Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 26330Sstevel@tonic-gate struct pollfd fds; 26340Sstevel@tonic-gate minor_t rnum; 26350Sstevel@tonic-gate 26360Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 26370Sstevel@tonic-gate "rsm_intr_signal_wait: enter\n")); 26380Sstevel@tonic-gate 26390Sstevel@tonic-gate if (!seg) { 26400Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 26410Sstevel@tonic-gate "invalid segment\n")); 26420Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 26430Sstevel@tonic-gate } 26440Sstevel@tonic-gate 26450Sstevel@tonic-gate fds.fd = seg->rsmseg_fd; 26460Sstevel@tonic-gate fds.events = POLLRDNORM; 26470Sstevel@tonic-gate 26480Sstevel@tonic-gate rnum = seg->rsmseg_rnum; 26490Sstevel@tonic-gate 26500Sstevel@tonic-gate return (__rsm_intr_signal_wait_common(&fds, &rnum, 1, timeout, NULL)); 26510Sstevel@tonic-gate } 26520Sstevel@tonic-gate 26530Sstevel@tonic-gate int 26540Sstevel@tonic-gate _rsm_intr_signal_wait_pollfd(struct pollfd fds[], nfds_t nfds, int timeout, 26550Sstevel@tonic-gate int *numfdsp) 26560Sstevel@tonic-gate { 26570Sstevel@tonic-gate return (__rsm_intr_signal_wait_common(fds, NULL, nfds, timeout, 26580Sstevel@tonic-gate numfdsp)); 26590Sstevel@tonic-gate } 26600Sstevel@tonic-gate 26610Sstevel@tonic-gate /* 26620Sstevel@tonic-gate * This is the generic wait routine, it takes the following arguments 26630Sstevel@tonic-gate * - pollfd array 26640Sstevel@tonic-gate * - rnums array corresponding to the pollfd if known, if this is 26650Sstevel@tonic-gate * NULL then the fds are looked up from the pollfd_table. 26660Sstevel@tonic-gate * - number of fds in pollfd array, 26670Sstevel@tonic-gate * - timeout 26680Sstevel@tonic-gate * - pointer to a location where the number of fds with successful 26690Sstevel@tonic-gate * events is returned. 26700Sstevel@tonic-gate */ 26710Sstevel@tonic-gate static int 26720Sstevel@tonic-gate __rsm_intr_signal_wait_common(struct pollfd fds[], minor_t rnums[], 26730Sstevel@tonic-gate nfds_t nfds, int timeout, int *numfdsp) 26740Sstevel@tonic-gate { 26750Sstevel@tonic-gate int i; 26760Sstevel@tonic-gate int numsegs = 0; 26770Sstevel@tonic-gate int numfd; 26780Sstevel@tonic-gate int fds_processed = 0; 26790Sstevel@tonic-gate minor_t segrnum; 26800Sstevel@tonic-gate rsm_poll_event_t event_arr[RSM_MAX_POLLFDS]; 26810Sstevel@tonic-gate rsm_poll_event_t *event_list = NULL; 26820Sstevel@tonic-gate rsm_poll_event_t *events; 26830Sstevel@tonic-gate rsm_consume_event_msg_t msg; 26840Sstevel@tonic-gate 26850Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, "wait_common enter\n")); 26860Sstevel@tonic-gate 26870Sstevel@tonic-gate if (numfdsp) { 26880Sstevel@tonic-gate *numfdsp = 0; 26890Sstevel@tonic-gate } 26900Sstevel@tonic-gate 26910Sstevel@tonic-gate numfd = poll(fds, nfds, timeout); 26920Sstevel@tonic-gate 26930Sstevel@tonic-gate switch (numfd) { 26940Sstevel@tonic-gate case -1: /* poll returned error - map to RSMERR_... */ 26950Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, "signal wait pollfd err\n")); 26960Sstevel@tonic-gate switch (errno) { 26970Sstevel@tonic-gate case EAGAIN: 26980Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_RESOURCES); 26990Sstevel@tonic-gate case EFAULT: 27000Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 27010Sstevel@tonic-gate case EINTR: 27020Sstevel@tonic-gate return (RSMERR_INTERRUPTED); 27030Sstevel@tonic-gate case EINVAL: 27040Sstevel@tonic-gate default: 27050Sstevel@tonic-gate return (RSMERR_BAD_ARGS_ERRORS); 27060Sstevel@tonic-gate } 27070Sstevel@tonic-gate case 0: /* timedout - return from here */ 27080Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 27090Sstevel@tonic-gate "signal wait timed out\n")); 27100Sstevel@tonic-gate return (RSMERR_TIMEOUT); 27110Sstevel@tonic-gate default: 27120Sstevel@tonic-gate break; 27130Sstevel@tonic-gate } 27140Sstevel@tonic-gate 27150Sstevel@tonic-gate if (numfd <= RSM_MAX_POLLFDS) { 27160Sstevel@tonic-gate /* use the event array on the stack */ 27170Sstevel@tonic-gate events = (rsm_poll_event_t *)event_arr; 27180Sstevel@tonic-gate } else { 27190Sstevel@tonic-gate /* 27200Sstevel@tonic-gate * actual number of fds corresponding to rsmapi segments might 27210Sstevel@tonic-gate * be < numfd, don't want to scan the list to figure that out 27220Sstevel@tonic-gate * lets just allocate on the heap 27230Sstevel@tonic-gate */ 27240Sstevel@tonic-gate event_list = (rsm_poll_event_t *)malloc( 27250Sstevel@tonic-gate sizeof (rsm_poll_event_t)*numfd); 27260Sstevel@tonic-gate if (!event_list) { 27270Sstevel@tonic-gate /* 27280Sstevel@tonic-gate * return with error even if poll might have succeeded 27290Sstevel@tonic-gate * since the application can retry and the events will 27300Sstevel@tonic-gate * still be available. 27310Sstevel@tonic-gate */ 27320Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_MEM); 27330Sstevel@tonic-gate } 27340Sstevel@tonic-gate events = event_list; 27350Sstevel@tonic-gate } 27360Sstevel@tonic-gate 27370Sstevel@tonic-gate /* 27380Sstevel@tonic-gate * process the fds for events and if it corresponds to an rsmapi 27390Sstevel@tonic-gate * segment consume the event 27400Sstevel@tonic-gate */ 27410Sstevel@tonic-gate for (i = 0; i < nfds; i++) { 27420Sstevel@tonic-gate if (fds[i].revents == POLLRDNORM) { 27430Sstevel@tonic-gate /* 27440Sstevel@tonic-gate * poll returned an event and if its POLLRDNORM, it 27450Sstevel@tonic-gate * might correspond to an rsmapi segment 27460Sstevel@tonic-gate */ 27470Sstevel@tonic-gate if (rnums) { /* resource num is passed in */ 27480Sstevel@tonic-gate segrnum = rnums[i]; 27490Sstevel@tonic-gate } else { /* lookup pollfd table to get resource num */ 27500Sstevel@tonic-gate segrnum = _rsm_lookup_pollfd_table(fds[i].fd); 27510Sstevel@tonic-gate } 27520Sstevel@tonic-gate if (segrnum) { 27530Sstevel@tonic-gate events[numsegs].rnum = segrnum; 27540Sstevel@tonic-gate events[numsegs].revent = 0; 27550Sstevel@tonic-gate events[numsegs].fdsidx = i; /* fdlist index */ 27560Sstevel@tonic-gate numsegs++; 27570Sstevel@tonic-gate } 27580Sstevel@tonic-gate } 27590Sstevel@tonic-gate 27600Sstevel@tonic-gate if ((fds[i].revents) && (++fds_processed == numfd)) { 27610Sstevel@tonic-gate /* 27620Sstevel@tonic-gate * only "numfd" events have revents field set, once we 27630Sstevel@tonic-gate * process that many break out of the loop 27640Sstevel@tonic-gate */ 27650Sstevel@tonic-gate break; 27660Sstevel@tonic-gate } 27670Sstevel@tonic-gate } 27680Sstevel@tonic-gate 27690Sstevel@tonic-gate if (numsegs == 0) { /* No events for rsmapi segs in the fdlist */ 27700Sstevel@tonic-gate if (event_list) { 27710Sstevel@tonic-gate free(event_list); 27720Sstevel@tonic-gate } 27730Sstevel@tonic-gate if (numfdsp) { 27740Sstevel@tonic-gate *numfdsp = numfd; 27750Sstevel@tonic-gate } 27760Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 27770Sstevel@tonic-gate "wait_common exit: no rsmapi segs\n")); 27780Sstevel@tonic-gate return (RSM_SUCCESS); 27790Sstevel@tonic-gate } 27800Sstevel@tonic-gate 27810Sstevel@tonic-gate msg.seglist = (caddr_t)events; 27820Sstevel@tonic-gate msg.numents = numsegs; 27830Sstevel@tonic-gate 27840Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_CONSUMEEVENT, &msg) < 0) { 27850Sstevel@tonic-gate int error = errno; 27860Sstevel@tonic-gate if (event_list) { 27870Sstevel@tonic-gate free(event_list); 27880Sstevel@tonic-gate } 27890Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_ERR, 27900Sstevel@tonic-gate "RSM_IOCTL_CONSUMEEVENT failed(%d)\n", error)); 27910Sstevel@tonic-gate return (error); 27920Sstevel@tonic-gate } 27930Sstevel@tonic-gate 27940Sstevel@tonic-gate /* count the number of segs for which consumeevent was successful */ 27950Sstevel@tonic-gate numfd -= numsegs; 27960Sstevel@tonic-gate 27970Sstevel@tonic-gate for (i = 0; i < numsegs; i++) { 27980Sstevel@tonic-gate if (events[i].revent != 0) { 27990Sstevel@tonic-gate fds[events[i].fdsidx].revents = POLLRDNORM; 28000Sstevel@tonic-gate numfd++; 28010Sstevel@tonic-gate } else { /* failed to consume event so set revents to 0 */ 28020Sstevel@tonic-gate fds[events[i].fdsidx].revents = 0; 28030Sstevel@tonic-gate } 28040Sstevel@tonic-gate } 28050Sstevel@tonic-gate 28060Sstevel@tonic-gate if (event_list) { 28070Sstevel@tonic-gate free(event_list); 28080Sstevel@tonic-gate } 28090Sstevel@tonic-gate 28100Sstevel@tonic-gate if (numfd > 0) { 28110Sstevel@tonic-gate if (numfdsp) { 28120Sstevel@tonic-gate *numfdsp = numfd; 28130Sstevel@tonic-gate } 28140Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 28150Sstevel@tonic-gate "wait_common exit\n")); 28160Sstevel@tonic-gate return (RSM_SUCCESS); 28170Sstevel@tonic-gate } else { 28180Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 28190Sstevel@tonic-gate "wait_common exit\n")); 28200Sstevel@tonic-gate return (RSMERR_TIMEOUT); 28210Sstevel@tonic-gate } 28220Sstevel@tonic-gate } 28230Sstevel@tonic-gate 28240Sstevel@tonic-gate /* 28250Sstevel@tonic-gate * This function provides the data (file descriptor and event) for 28260Sstevel@tonic-gate * the specified pollfd struct. The pollfd struct may then be 28270Sstevel@tonic-gate * subsequently used with the poll system call to wait for an event 28280Sstevel@tonic-gate * signalled by rsm_intr_signal_post. The memory segment must be 28290Sstevel@tonic-gate * currently published for a successful return with a valid pollfd. 28300Sstevel@tonic-gate * A reference count for the descriptor is incremented. 28310Sstevel@tonic-gate */ 28320Sstevel@tonic-gate int 28330Sstevel@tonic-gate _rsm_memseg_get_pollfd(void *memseg, 28340Sstevel@tonic-gate struct pollfd *poll_fd) 28350Sstevel@tonic-gate { 28360Sstevel@tonic-gate int i; 28370Sstevel@tonic-gate int err = RSM_SUCCESS; 28380Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 28390Sstevel@tonic-gate 28400Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 28410Sstevel@tonic-gate "rsm_memseg_get_pollfd: enter\n")); 28420Sstevel@tonic-gate 28430Sstevel@tonic-gate if (!seg) { 28440Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 28450Sstevel@tonic-gate "invalid segment\n")); 28460Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 28470Sstevel@tonic-gate } 28480Sstevel@tonic-gate 28490Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 28500Sstevel@tonic-gate 28510Sstevel@tonic-gate poll_fd->fd = seg->rsmseg_fd; 28520Sstevel@tonic-gate poll_fd->events = POLLRDNORM; 28530Sstevel@tonic-gate seg->rsmseg_pollfd_refcnt++; 28540Sstevel@tonic-gate if (seg->rsmseg_pollfd_refcnt == 1) { 28550Sstevel@tonic-gate /* insert the segment into the pollfd table */ 28560Sstevel@tonic-gate err = _rsm_insert_pollfd_table(seg->rsmseg_fd, 28570Sstevel@tonic-gate seg->rsmseg_rnum); 28580Sstevel@tonic-gate } 28590Sstevel@tonic-gate 28600Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 28610Sstevel@tonic-gate 28620Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 28630Sstevel@tonic-gate "rsm_memseg_get_pollfd: exit(%d)\n", err)); 28640Sstevel@tonic-gate 28650Sstevel@tonic-gate return (err); 28660Sstevel@tonic-gate } 28670Sstevel@tonic-gate 28680Sstevel@tonic-gate /* 28690Sstevel@tonic-gate * This function decrements the segment pollfd reference count. 28700Sstevel@tonic-gate * A segment unpublish or destroy operation will fail if the reference count is 28710Sstevel@tonic-gate * non zero. 28720Sstevel@tonic-gate */ 28730Sstevel@tonic-gate int 28740Sstevel@tonic-gate _rsm_memseg_release_pollfd(void * memseg) 28750Sstevel@tonic-gate { 28760Sstevel@tonic-gate int i; 28770Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 28780Sstevel@tonic-gate 28790Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 28800Sstevel@tonic-gate "rsm_memseg_release_pollfd: enter\n")); 28810Sstevel@tonic-gate 28820Sstevel@tonic-gate if (!seg) { 28830Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 28840Sstevel@tonic-gate "invalid segment handle\n")); 28850Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 28860Sstevel@tonic-gate } 28870Sstevel@tonic-gate 28880Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 28890Sstevel@tonic-gate 28900Sstevel@tonic-gate if (seg->rsmseg_pollfd_refcnt) { 28910Sstevel@tonic-gate seg->rsmseg_pollfd_refcnt--; 28920Sstevel@tonic-gate if (seg->rsmseg_pollfd_refcnt == 0) { 28930Sstevel@tonic-gate /* last reference removed - update the pollfd_table */ 28940Sstevel@tonic-gate _rsm_remove_pollfd_table(seg->rsmseg_fd); 28950Sstevel@tonic-gate } 28960Sstevel@tonic-gate } 28970Sstevel@tonic-gate 28980Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 28990Sstevel@tonic-gate 29000Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 29010Sstevel@tonic-gate "rsm_memseg_release_pollfd: exit\n")); 29020Sstevel@tonic-gate 29030Sstevel@tonic-gate return (RSM_SUCCESS); 29040Sstevel@tonic-gate } 29050Sstevel@tonic-gate 29060Sstevel@tonic-gate /* 29070Sstevel@tonic-gate * The interconnect topology data is obtained from the Kernel Agent 29080Sstevel@tonic-gate * and stored in a memory buffer allocated by this function. A pointer 29090Sstevel@tonic-gate * to the buffer is stored in the location specified by the caller in 29100Sstevel@tonic-gate * the function argument. It is the callers responsibility to 29110Sstevel@tonic-gate * call rsm_free_interconnect_topolgy() to free the allocated memory. 29120Sstevel@tonic-gate */ 29130Sstevel@tonic-gate int 29140Sstevel@tonic-gate _rsm_get_interconnect_topology(rsm_topology_t **topology_data) 29150Sstevel@tonic-gate { 29160Sstevel@tonic-gate uint32_t topology_data_size; 29170Sstevel@tonic-gate rsm_topology_t *topology_ptr; 29180Sstevel@tonic-gate int error; 29190Sstevel@tonic-gate 29200Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 29210Sstevel@tonic-gate "rsm_get_interconnect_topology: enter\n")); 29220Sstevel@tonic-gate 29230Sstevel@tonic-gate if (topology_data == NULL) 29240Sstevel@tonic-gate return (RSMERR_BAD_TOPOLOGY_PTR); 29250Sstevel@tonic-gate 29260Sstevel@tonic-gate *topology_data = NULL; 29270Sstevel@tonic-gate 29280Sstevel@tonic-gate again: 29290Sstevel@tonic-gate /* obtain the size of the topology data */ 29300Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_TOPOLOGY_SIZE, &topology_data_size) < 0) { 29310Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 29320Sstevel@tonic-gate "RSM_IOCTL_TOPOLOGY_SIZE failed\n")); 29330Sstevel@tonic-gate return (errno); 29340Sstevel@tonic-gate } 29350Sstevel@tonic-gate 29360Sstevel@tonic-gate /* allocate double-word aligned memory to hold the topology data */ 29370Sstevel@tonic-gate topology_ptr = (rsm_topology_t *)memalign(8, topology_data_size); 29380Sstevel@tonic-gate if (topology_ptr == NULL) { 29390Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 29400Sstevel@tonic-gate "not enough memory\n")); 29410Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_MEM); 29420Sstevel@tonic-gate } 29430Sstevel@tonic-gate 29440Sstevel@tonic-gate /* 29450Sstevel@tonic-gate * Request the topology data. 29460Sstevel@tonic-gate * Pass in the size to be used as a check in case 29470Sstevel@tonic-gate * the data has grown since the size was obtained - if 29480Sstevel@tonic-gate * it has, the errno value will be E2BIG. 29490Sstevel@tonic-gate */ 29500Sstevel@tonic-gate topology_ptr->topology_hdr.local_nodeid = 29510Sstevel@tonic-gate (rsm_node_id_t)topology_data_size; 29520Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_TOPOLOGY_DATA, topology_ptr) < 0) { 29530Sstevel@tonic-gate error = errno; 29540Sstevel@tonic-gate free((void *)topology_ptr); 29550Sstevel@tonic-gate if (error == E2BIG) 29560Sstevel@tonic-gate goto again; 29570Sstevel@tonic-gate else { 29580Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 29590Sstevel@tonic-gate "RSM_IOCTL_TOPOLOGY_DATA failed\n")); 29600Sstevel@tonic-gate return (error); 29610Sstevel@tonic-gate } 29620Sstevel@tonic-gate } else 29630Sstevel@tonic-gate *topology_data = topology_ptr; 29640Sstevel@tonic-gate 29650Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 29660Sstevel@tonic-gate " rsm_get_interconnect_topology: exit\n")); 29670Sstevel@tonic-gate 29680Sstevel@tonic-gate return (RSM_SUCCESS); 29690Sstevel@tonic-gate } 29700Sstevel@tonic-gate 29710Sstevel@tonic-gate 29720Sstevel@tonic-gate void 29730Sstevel@tonic-gate _rsm_free_interconnect_topology(rsm_topology_t *topology_ptr) 29740Sstevel@tonic-gate { 29750Sstevel@tonic-gate 29760Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 29770Sstevel@tonic-gate "rsm_free_interconnect_topology: enter\n")); 29780Sstevel@tonic-gate 29790Sstevel@tonic-gate if (topology_ptr) { 29800Sstevel@tonic-gate free((void *)topology_ptr); 29810Sstevel@tonic-gate } 29820Sstevel@tonic-gate 29830Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 29840Sstevel@tonic-gate "rsm_free_interconnect_topology: exit\n")); 29850Sstevel@tonic-gate } 29860Sstevel@tonic-gate 29870Sstevel@tonic-gate int 29880Sstevel@tonic-gate _rsm_create_localmemory_handle(rsmapi_controller_handle_t cntrl_handle, 29890Sstevel@tonic-gate rsm_localmemory_handle_t *local_hndl_p, 29900Sstevel@tonic-gate caddr_t local_vaddr, size_t len) 29910Sstevel@tonic-gate { 29920Sstevel@tonic-gate int e; 29930Sstevel@tonic-gate rsm_controller_t *cntrl = (rsm_controller_t *)cntrl_handle; 29940Sstevel@tonic-gate 29950Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 29960Sstevel@tonic-gate "rsm_create_localmemory_handle: enter\n")); 29970Sstevel@tonic-gate 29980Sstevel@tonic-gate if ((size_t)local_vaddr & (PAGESIZE - 1)) { 29990Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 30000Sstevel@tonic-gate "invalid arguments\n")); 30010Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 30020Sstevel@tonic-gate } 30030Sstevel@tonic-gate 30040Sstevel@tonic-gate if (!cntrl_handle) { 30050Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 30060Sstevel@tonic-gate "invalid controller handle\n")); 30070Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 30080Sstevel@tonic-gate } 30090Sstevel@tonic-gate if (!local_hndl_p) { 30100Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 30110Sstevel@tonic-gate "invalid local memory handle pointer\n")); 30120Sstevel@tonic-gate return (RSMERR_BAD_LOCALMEM_HNDL); 30130Sstevel@tonic-gate } 30140Sstevel@tonic-gate if (len == 0) { 30150Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 30160Sstevel@tonic-gate "invalid length\n")); 30170Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 30180Sstevel@tonic-gate } 30190Sstevel@tonic-gate 30200Sstevel@tonic-gate e = cntrl->cntr_segops->rsm_create_localmemory_handle( 30210Sstevel@tonic-gate cntrl_handle, 30220Sstevel@tonic-gate local_hndl_p, 30230Sstevel@tonic-gate local_vaddr, 30240Sstevel@tonic-gate len); 30250Sstevel@tonic-gate 30260Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 30270Sstevel@tonic-gate "rsm_create_localmemory_handle: exit\n")); 30280Sstevel@tonic-gate 30290Sstevel@tonic-gate return (e); 30300Sstevel@tonic-gate } 30310Sstevel@tonic-gate 30320Sstevel@tonic-gate int 30330Sstevel@tonic-gate _rsm_free_localmemory_handle(rsmapi_controller_handle_t cntrl_handle, 30340Sstevel@tonic-gate rsm_localmemory_handle_t local_handle) 30350Sstevel@tonic-gate { 30360Sstevel@tonic-gate int e; 30370Sstevel@tonic-gate 30380Sstevel@tonic-gate rsm_controller_t *cntrl = (rsm_controller_t *)cntrl_handle; 30390Sstevel@tonic-gate 30400Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 30410Sstevel@tonic-gate "rsm_free_localmemory_handle: enter\n")); 30420Sstevel@tonic-gate 30430Sstevel@tonic-gate 30440Sstevel@tonic-gate if (!cntrl_handle) { 30450Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 30460Sstevel@tonic-gate "invalid controller handle\n")); 30470Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 30480Sstevel@tonic-gate } 30490Sstevel@tonic-gate 30500Sstevel@tonic-gate if (!local_handle) { 30510Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 30520Sstevel@tonic-gate "invalid localmemory handle\n")); 30530Sstevel@tonic-gate return (RSMERR_BAD_LOCALMEM_HNDL); 30540Sstevel@tonic-gate } 30550Sstevel@tonic-gate 30560Sstevel@tonic-gate e = cntrl->cntr_segops->rsm_free_localmemory_handle(local_handle); 30570Sstevel@tonic-gate 30580Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 30590Sstevel@tonic-gate "rsm_free_localmemory_handle: exit\n")); 30600Sstevel@tonic-gate 30610Sstevel@tonic-gate return (e); 30620Sstevel@tonic-gate } 30630Sstevel@tonic-gate 30640Sstevel@tonic-gate int 30650Sstevel@tonic-gate _rsm_get_segmentid_range(const char *appid, rsm_memseg_id_t *baseid, 30660Sstevel@tonic-gate uint32_t *length) 30670Sstevel@tonic-gate { 30680Sstevel@tonic-gate char buf[RSMFILE_BUFSIZE]; 30690Sstevel@tonic-gate char *s; 30700Sstevel@tonic-gate char *fieldv[4]; 30710Sstevel@tonic-gate int fieldc = 0; 30720Sstevel@tonic-gate int found = 0; 30730Sstevel@tonic-gate int err = RSMERR_BAD_APPID; 30740Sstevel@tonic-gate FILE *fp; 30750Sstevel@tonic-gate 30760Sstevel@tonic-gate if (appid == NULL || baseid == NULL || length == NULL) 30770Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 30780Sstevel@tonic-gate 30790Sstevel@tonic-gate if ((fp = fopen(RSMSEGIDFILE, "r")) == NULL) { 30800Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 30810Sstevel@tonic-gate "cannot open <%s>\n", RSMSEGIDFILE)); 30820Sstevel@tonic-gate return (RSMERR_BAD_CONF); 30830Sstevel@tonic-gate } 30840Sstevel@tonic-gate 30850Sstevel@tonic-gate while (s = fgets(buf, RSMFILE_BUFSIZE, fp)) { 30860Sstevel@tonic-gate fieldc = 0; 30870Sstevel@tonic-gate while (isspace(*s)) /* skip the leading spaces */ 30880Sstevel@tonic-gate s++; 30890Sstevel@tonic-gate 30900Sstevel@tonic-gate if (*s == '#') { /* comment line - skip it */ 30910Sstevel@tonic-gate continue; 30920Sstevel@tonic-gate } 30930Sstevel@tonic-gate 30940Sstevel@tonic-gate /* 30950Sstevel@tonic-gate * parse the reserved segid file and 30960Sstevel@tonic-gate * set the pointers appropriately. 30970Sstevel@tonic-gate * fieldv[0] : keyword 30980Sstevel@tonic-gate * fieldv[1] : application identifier 30990Sstevel@tonic-gate * fieldv[2] : baseid 31000Sstevel@tonic-gate * fieldv[3] : length 31010Sstevel@tonic-gate */ 31020Sstevel@tonic-gate while ((*s != '\n') && (*s != '\0') && (fieldc < 4)) { 31030Sstevel@tonic-gate 31040Sstevel@tonic-gate while (isspace(*s)) /* skip the leading spaces */ 31050Sstevel@tonic-gate s++; 31060Sstevel@tonic-gate 31070Sstevel@tonic-gate fieldv[fieldc++] = s; 31080Sstevel@tonic-gate 31090Sstevel@tonic-gate if (fieldc == 4) { 31100Sstevel@tonic-gate if (fieldv[3][strlen(fieldv[3])-1] == '\n') 31110Sstevel@tonic-gate fieldv[3][strlen(fieldv[3])-1] = '\0'; 31120Sstevel@tonic-gate break; 31130Sstevel@tonic-gate } 31140Sstevel@tonic-gate 31150Sstevel@tonic-gate while (*s && !isspace(*s)) 31160Sstevel@tonic-gate ++s; /* move to the next white space */ 31170Sstevel@tonic-gate 31180Sstevel@tonic-gate if (*s) 31190Sstevel@tonic-gate *s++ = '\0'; 31200Sstevel@tonic-gate } 31210Sstevel@tonic-gate 31220Sstevel@tonic-gate if (fieldc < 4) { /* some fields are missing */ 31230Sstevel@tonic-gate err = RSMERR_BAD_CONF; 31240Sstevel@tonic-gate break; 31250Sstevel@tonic-gate } 31260Sstevel@tonic-gate 31270Sstevel@tonic-gate if (strcasecmp(fieldv[1], appid) == 0) { /* found a match */ 31280Sstevel@tonic-gate if (strcasecmp(fieldv[0], RSMSEG_RESERVED) == 0) { 31290Sstevel@tonic-gate errno = 0; 31300Sstevel@tonic-gate *baseid = strtol(fieldv[2], (char **)NULL, 16); 31310Sstevel@tonic-gate if (errno != 0) { 31320Sstevel@tonic-gate err = RSMERR_BAD_CONF; 31330Sstevel@tonic-gate break; 31340Sstevel@tonic-gate } 31350Sstevel@tonic-gate 31360Sstevel@tonic-gate errno = 0; 31370Sstevel@tonic-gate *length = (int)strtol(fieldv[3], 31380Sstevel@tonic-gate (char **)NULL, 10); 31390Sstevel@tonic-gate if (errno != 0) { 31400Sstevel@tonic-gate err = RSMERR_BAD_CONF; 31410Sstevel@tonic-gate break; 31420Sstevel@tonic-gate } 31430Sstevel@tonic-gate 31440Sstevel@tonic-gate found = 1; 31450Sstevel@tonic-gate } else { /* error in format */ 31460Sstevel@tonic-gate err = RSMERR_BAD_CONF; 31470Sstevel@tonic-gate } 31480Sstevel@tonic-gate break; 31490Sstevel@tonic-gate } 31500Sstevel@tonic-gate } 31510Sstevel@tonic-gate 31520Sstevel@tonic-gate (void) fclose(fp); 31530Sstevel@tonic-gate 31540Sstevel@tonic-gate if (found) 31550Sstevel@tonic-gate return (RSM_SUCCESS); 31560Sstevel@tonic-gate 31570Sstevel@tonic-gate return (err); 31580Sstevel@tonic-gate } 31590Sstevel@tonic-gate 31600Sstevel@tonic-gate static int 31610Sstevel@tonic-gate _rsm_get_hwaddr(rsmapi_controller_handle_t handle, rsm_node_id_t nodeid, 31620Sstevel@tonic-gate rsm_addr_t *hwaddrp) 31630Sstevel@tonic-gate { 31640Sstevel@tonic-gate rsm_ioctlmsg_t msg = {0}; 31650Sstevel@tonic-gate rsm_controller_t *ctrlp; 31660Sstevel@tonic-gate 31670Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 31680Sstevel@tonic-gate "_rsm_get_hwaddr: enter\n")); 31690Sstevel@tonic-gate 31700Sstevel@tonic-gate ctrlp = (rsm_controller_t *)handle; 31710Sstevel@tonic-gate 31720Sstevel@tonic-gate if (ctrlp == NULL) { 31730Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 31740Sstevel@tonic-gate "invalid controller handle\n")); 31750Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 31760Sstevel@tonic-gate } 31770Sstevel@tonic-gate 31780Sstevel@tonic-gate msg.cname = ctrlp->cntr_name; 31790Sstevel@tonic-gate msg.cname_len = strlen(ctrlp->cntr_name) +1; 31800Sstevel@tonic-gate msg.cnum = ctrlp->cntr_unit; 31810Sstevel@tonic-gate msg.nodeid = nodeid; 31820Sstevel@tonic-gate 31830Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_MAP_TO_ADDR, &msg) < 0) { 31840Sstevel@tonic-gate int error = errno; 31850Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 31860Sstevel@tonic-gate "RSM_IOCTL_MAP_TO_ADDR failed\n")); 31870Sstevel@tonic-gate return (error); 31880Sstevel@tonic-gate } 31890Sstevel@tonic-gate 31900Sstevel@tonic-gate *hwaddrp = msg.hwaddr; 31910Sstevel@tonic-gate 31920Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 31930Sstevel@tonic-gate "_rsm_get_hwaddr: exit\n")); 31940Sstevel@tonic-gate 31950Sstevel@tonic-gate return (RSM_SUCCESS); 31960Sstevel@tonic-gate 31970Sstevel@tonic-gate } 31980Sstevel@tonic-gate 31990Sstevel@tonic-gate static int 32000Sstevel@tonic-gate _rsm_get_nodeid(rsmapi_controller_handle_t handle, rsm_addr_t hwaddr, 32010Sstevel@tonic-gate rsm_node_id_t *nodeidp) 32020Sstevel@tonic-gate { 32030Sstevel@tonic-gate 32040Sstevel@tonic-gate rsm_ioctlmsg_t msg = {0}; 32050Sstevel@tonic-gate rsm_controller_t *ctrlp; 32060Sstevel@tonic-gate 32070Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 32080Sstevel@tonic-gate "_rsm_get_nodeid: enter\n")); 32090Sstevel@tonic-gate 32100Sstevel@tonic-gate ctrlp = (rsm_controller_t *)handle; 32110Sstevel@tonic-gate 32120Sstevel@tonic-gate if (ctrlp == NULL) { 32130Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 32140Sstevel@tonic-gate "invalid arguments\n")); 32150Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 32160Sstevel@tonic-gate } 32170Sstevel@tonic-gate 32180Sstevel@tonic-gate msg.cname = ctrlp->cntr_name; 32190Sstevel@tonic-gate msg.cname_len = strlen(ctrlp->cntr_name) +1; 32200Sstevel@tonic-gate msg.cnum = ctrlp->cntr_unit; 32210Sstevel@tonic-gate msg.hwaddr = hwaddr; 32220Sstevel@tonic-gate 32230Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_MAP_TO_NODEID, &msg) < 0) { 32240Sstevel@tonic-gate int error = errno; 32250Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 32260Sstevel@tonic-gate "RSM_IOCTL_MAP_TO_NODEID failed\n")); 32270Sstevel@tonic-gate return (error); 32280Sstevel@tonic-gate } 32290Sstevel@tonic-gate 32300Sstevel@tonic-gate *nodeidp = msg.nodeid; 32310Sstevel@tonic-gate 32320Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 32330Sstevel@tonic-gate "_rsm_get_nodeid: exit\n")); 32340Sstevel@tonic-gate 32350Sstevel@tonic-gate return (RSM_SUCCESS); 32360Sstevel@tonic-gate 32370Sstevel@tonic-gate } 32380Sstevel@tonic-gate 32390Sstevel@tonic-gate #ifdef DEBUG 32400Sstevel@tonic-gate void 32410Sstevel@tonic-gate dbg_printf(int msg_category, int msg_level, char *fmt, ...) 32420Sstevel@tonic-gate { 32430Sstevel@tonic-gate if ((msg_category & rsmlibdbg_category) && 32440Sstevel@tonic-gate (msg_level <= rsmlibdbg_level)) { 32450Sstevel@tonic-gate va_list arg_list; 32460Sstevel@tonic-gate va_start(arg_list, fmt); 32470Sstevel@tonic-gate mutex_lock(&rsmlog_lock); 32480Sstevel@tonic-gate fprintf(rsmlog_fd, 32490Sstevel@tonic-gate "Thread %d ", thr_self()); 32500Sstevel@tonic-gate vfprintf(rsmlog_fd, fmt, arg_list); 32510Sstevel@tonic-gate fflush(rsmlog_fd); 32520Sstevel@tonic-gate mutex_unlock(&rsmlog_lock); 32530Sstevel@tonic-gate va_end(arg_list); 32540Sstevel@tonic-gate } 32550Sstevel@tonic-gate } 32560Sstevel@tonic-gate #endif /* DEBUG */ 3257