17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*004388ebScasper * Common Development and Distribution License (the "License"). 6*004388ebScasper * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21e8031f0aSraf 227c478bd9Sstevel@tonic-gate /* 23e8031f0aSraf * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 29e8031f0aSraf #include "c_synonyms.h" 307c478bd9Sstevel@tonic-gate #include <stdio.h> 317c478bd9Sstevel@tonic-gate #include <stdlib.h> 327c478bd9Sstevel@tonic-gate #include <unistd.h> 337c478bd9Sstevel@tonic-gate #include <stdarg.h> 347c478bd9Sstevel@tonic-gate #include <string.h> 357c478bd9Sstevel@tonic-gate #include <strings.h> 367c478bd9Sstevel@tonic-gate #include <ctype.h> 377c478bd9Sstevel@tonic-gate #include <sys/types.h> 387c478bd9Sstevel@tonic-gate #include <sys/stat.h> 397c478bd9Sstevel@tonic-gate #include <sys/mman.h> 407c478bd9Sstevel@tonic-gate #include <sys/uio.h> 417c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 427c478bd9Sstevel@tonic-gate #include <sys/resource.h> 437c478bd9Sstevel@tonic-gate #include <errno.h> 447c478bd9Sstevel@tonic-gate #include <assert.h> 457c478bd9Sstevel@tonic-gate #include <fcntl.h> 467c478bd9Sstevel@tonic-gate #include <dlfcn.h> 477c478bd9Sstevel@tonic-gate #include <sched.h> 487c478bd9Sstevel@tonic-gate #include <stropts.h> 497c478bd9Sstevel@tonic-gate #include <poll.h> 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate #include <rsmapi.h> 527c478bd9Sstevel@tonic-gate #include <sys/rsm/rsmndi.h> 537c478bd9Sstevel@tonic-gate #include <rsmlib_in.h> 547c478bd9Sstevel@tonic-gate #include <sys/rsm/rsm.h> 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate #ifdef __STDC__ 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate #pragma weak rsm_get_controller = _rsm_get_controller 597c478bd9Sstevel@tonic-gate #pragma weak rsm_get_controller_attr = _rsm_get_controller_attr 607c478bd9Sstevel@tonic-gate #pragma weak rsm_release_controller = _rsm_release_controller 617c478bd9Sstevel@tonic-gate #pragma weak rsm_get_interconnect_topology = _rsm_get_interconnect_topology 627c478bd9Sstevel@tonic-gate #pragma weak rsm_free_interconnect_topology = _rsm_free_interconnect_topology 637c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_export_create = _rsm_memseg_export_create 647c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_export_destroy = _rsm_memseg_export_destroy 657c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_export_rebind = _rsm_memseg_export_rebind 667c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_export_publish = _rsm_memseg_export_publish 677c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_export_unpublish = _rsm_memseg_export_unpublish 687c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_export_republish = _rsm_memseg_export_republish 697c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_connect = _rsm_memseg_import_connect 707c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_disconnect = _rsm_memseg_import_disconnect 717c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_get8 = _rsm_memseg_import_get8 727c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_get16 = _rsm_memseg_import_get16 737c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_get32 = _rsm_memseg_import_get32 747c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_get64 = _rsm_memseg_import_get64 757c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_get = _rsm_memseg_import_get 767c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_getv = _rsm_memseg_import_getv 777c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_put8 = _rsm_memseg_import_put8 787c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_put16 = _rsm_memseg_import_put16 797c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_put32 = _rsm_memseg_import_put32 807c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_put64 = _rsm_memseg_import_put64 817c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_put = _rsm_memseg_import_put 827c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_putv = _rsm_memseg_import_putv 837c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_map = _rsm_memseg_import_map 847c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_unmap = _rsm_memseg_import_unmap 857c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_init_barrier = _rsm_memseg_import_init_barrier 867c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_open_barrier = _rsm_memseg_import_open_barrier 877c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_close_barrier = _rsm_memseg_import_close_barrier 887c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_order_barrier = _rsm_memseg_import_order_barrier 897c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_destroy_barrier = \ 907c478bd9Sstevel@tonic-gate _rsm_memseg_import_destroy_barrier 917c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_get_mode = _rsm_memseg_import_get_mode 927c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_import_set_mode = _rsm_memseg_import_set_mode 937c478bd9Sstevel@tonic-gate #pragma weak rsm_create_localmemory_handle = _rsm_create_localmemory_handle 947c478bd9Sstevel@tonic-gate #pragma weak rsm_free_localmemory_handle = _rsm_free_localmemory_handle 957c478bd9Sstevel@tonic-gate #pragma weak rsm_intr_signal_post = _rsm_intr_signal_post 967c478bd9Sstevel@tonic-gate #pragma weak rsm_intr_signal_wait = _rsm_intr_signal_wait 977c478bd9Sstevel@tonic-gate #pragma weak rsm_intr_signal_wait_pollfd = _rsm_intr_signal_wait_pollfd 987c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_get_pollfd = _rsm_memseg_get_pollfd 997c478bd9Sstevel@tonic-gate #pragma weak rsm_memseg_release_pollfd = _rsm_memseg_release_pollfd 1007c478bd9Sstevel@tonic-gate #pragma weak rsm_get_segmentid_range = _rsm_get_segmentid_range 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate #endif /* __STDC__ */ 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate /* lint -w2 */ 1057c478bd9Sstevel@tonic-gate extern void __rsmloopback_init_ops(rsm_segops_t *); 1067c478bd9Sstevel@tonic-gate extern void __rsmdefault_setops(rsm_segops_t *); 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate typedef void (*rsm_access_func_t)(void *, void *, rsm_access_size_t); 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate #ifdef DEBUG 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate #define RSMLOG_BUF_SIZE 256 1137c478bd9Sstevel@tonic-gate FILE *rsmlog_fd = NULL; 1147c478bd9Sstevel@tonic-gate static mutex_t rsmlog_lock; 1157c478bd9Sstevel@tonic-gate int rsmlibdbg_category = RSM_LIBRARY; 1167c478bd9Sstevel@tonic-gate int rsmlibdbg_level = RSM_ERR; 1177c478bd9Sstevel@tonic-gate void dbg_printf(int category, int level, char *fmt, ...); 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate rsm_node_id_t rsm_local_nodeid = 0; 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate static rsm_controller_t *controller_list = NULL; 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate static rsm_segops_t loopback_ops; 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate #define MAX_STRLEN 80 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate #define RSM_IOTYPE_PUTGET 1 1307c478bd9Sstevel@tonic-gate #define RSM_IOTYPE_SCATGATH 2 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate #define RSMFILE_BUFSIZE 256 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate #pragma init(_rsm_librsm_init) 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate static mutex_t _rsm_lock; 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate static int _rsm_fd = -1; 1397c478bd9Sstevel@tonic-gate static rsm_gnum_t *bar_va, bar_fixed = 0; 1407c478bd9Sstevel@tonic-gate static rsm_pollfd_table_t pollfd_table; 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate static int _rsm_get_hwaddr(rsmapi_controller_handle_t handle, 1437c478bd9Sstevel@tonic-gate rsm_node_id_t, rsm_addr_t *hwaddrp); 1447c478bd9Sstevel@tonic-gate static int _rsm_get_nodeid(rsmapi_controller_handle_t, 1457c478bd9Sstevel@tonic-gate rsm_addr_t, rsm_node_id_t *); 1467c478bd9Sstevel@tonic-gate static int __rsm_import_implicit_map(rsmseg_handle_t *, int); 1477c478bd9Sstevel@tonic-gate static int __rsm_intr_signal_wait_common(struct pollfd [], minor_t [], 1487c478bd9Sstevel@tonic-gate nfds_t, int, int *); 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate static rsm_lib_funcs_t lib_functions = { 1517c478bd9Sstevel@tonic-gate RSM_LIB_FUNCS_VERSION, 1527c478bd9Sstevel@tonic-gate _rsm_get_hwaddr, 1537c478bd9Sstevel@tonic-gate _rsm_get_nodeid 1547c478bd9Sstevel@tonic-gate }; 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate int _rsm_get_interconnect_topology(rsm_topology_t **); 1577c478bd9Sstevel@tonic-gate void _rsm_free_interconnect_topology(rsm_topology_t *); 1587c478bd9Sstevel@tonic-gate int _rsm_memseg_import_open_barrier(rsmapi_barrier_t *); 1597c478bd9Sstevel@tonic-gate int _rsm_memseg_import_close_barrier(rsmapi_barrier_t *); 1607c478bd9Sstevel@tonic-gate int _rsm_memseg_import_unmap(rsm_memseg_import_handle_t); 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate rsm_topology_t *tp; 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate /* 1677c478bd9Sstevel@tonic-gate * service module function templates: 1687c478bd9Sstevel@tonic-gate */ 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate /* 1717c478bd9Sstevel@tonic-gate * The _rsm_librsm_init function is called the first time an application 1727c478bd9Sstevel@tonic-gate * references the RSMAPI library 1737c478bd9Sstevel@tonic-gate */ 1747c478bd9Sstevel@tonic-gate int 1757c478bd9Sstevel@tonic-gate _rsm_librsm_init() 1767c478bd9Sstevel@tonic-gate { 1777c478bd9Sstevel@tonic-gate rsm_ioctlmsg_t msg; 1787c478bd9Sstevel@tonic-gate int e, tmpfd; 1797c478bd9Sstevel@tonic-gate int i; 1807c478bd9Sstevel@tonic-gate char logname[MAXNAMELEN]; 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate mutex_init(&_rsm_lock, USYNC_THREAD, NULL); 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate #ifdef DEBUG 1857c478bd9Sstevel@tonic-gate mutex_init(&rsmlog_lock, USYNC_THREAD, NULL); 1867c478bd9Sstevel@tonic-gate sprintf(logname, "%s.%d", TRACELOG, getpid()); 187*004388ebScasper rsmlog_fd = fopen(logname, "w+F"); 1887c478bd9Sstevel@tonic-gate if (rsmlog_fd == NULL) { 1897c478bd9Sstevel@tonic-gate fprintf(stderr, "Log file open failed\n"); 1907c478bd9Sstevel@tonic-gate return (errno); 1917c478bd9Sstevel@tonic-gate } 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 1967c478bd9Sstevel@tonic-gate "_rsm_librsm_init: enter\n")); 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate /* initialize the pollfd_table */ 1997c478bd9Sstevel@tonic-gate mutex_init(&pollfd_table.lock, USYNC_THREAD, NULL); 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate for (i = 0; i < RSM_MAX_BUCKETS; i++) { 2027c478bd9Sstevel@tonic-gate pollfd_table.buckets[i] = NULL; 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate /* open /dev/rsm and mmap barrier generation pages */ 2067c478bd9Sstevel@tonic-gate mutex_lock(&_rsm_lock); 2077c478bd9Sstevel@tonic-gate _rsm_fd = open(DEVRSM, O_RDONLY); 2087c478bd9Sstevel@tonic-gate if (_rsm_fd < 0) { 2097c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 2107c478bd9Sstevel@tonic-gate "unable to open /dev/rsm\n")); 2117c478bd9Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 2127c478bd9Sstevel@tonic-gate return (errno); 2137c478bd9Sstevel@tonic-gate } 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate /* 2167c478bd9Sstevel@tonic-gate * DUP the opened file descriptor to something greater than 2177c478bd9Sstevel@tonic-gate * STDERR_FILENO so that we never use the STDIN_FILENO, 2187c478bd9Sstevel@tonic-gate * STDOUT_FILENO or STDERR_FILENO. 2197c478bd9Sstevel@tonic-gate */ 2207c478bd9Sstevel@tonic-gate tmpfd = fcntl(_rsm_fd, F_DUPFD, 3); 2217c478bd9Sstevel@tonic-gate if (tmpfd < 0) { 2227c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 2237c478bd9Sstevel@tonic-gate "F_DUPFD failed\n")); 2247c478bd9Sstevel@tonic-gate } else { 2257c478bd9Sstevel@tonic-gate (void) close(_rsm_fd); 2267c478bd9Sstevel@tonic-gate _rsm_fd = tmpfd; 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 2307c478bd9Sstevel@tonic-gate "_rsm_fd is %d\n", _rsm_fd)); 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate if (fcntl(_rsm_fd, F_SETFD, FD_CLOEXEC) < 0) { 2337c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 2347c478bd9Sstevel@tonic-gate "F_SETFD failed\n")); 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate /* get mapping generation number page info */ 2387c478bd9Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_BAR_INFO, &msg) < 0) { 2397c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 2407c478bd9Sstevel@tonic-gate "RSM_IOCTL_BAR_INFO failed\n")); 2417c478bd9Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 2427c478bd9Sstevel@tonic-gate return (errno); 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate /* 2467c478bd9Sstevel@tonic-gate * bar_va is mapped to the mapping generation number page 2477c478bd9Sstevel@tonic-gate * in order to support close barrier 2487c478bd9Sstevel@tonic-gate */ 2497c478bd9Sstevel@tonic-gate /* LINTED */ 2507c478bd9Sstevel@tonic-gate bar_va = (rsm_gnum_t *)mmap(NULL, msg.len, 2517c478bd9Sstevel@tonic-gate PROT_READ, MAP_SHARED, _rsm_fd, msg.off); 2527c478bd9Sstevel@tonic-gate if (bar_va == (rsm_gnum_t *)MAP_FAILED) { 2537c478bd9Sstevel@tonic-gate bar_va = NULL; 2547c478bd9Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 2557c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 2567c478bd9Sstevel@tonic-gate "unable to map barrier page\n")); 2577c478bd9Sstevel@tonic-gate return (RSMERR_MAP_FAILED); 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate /* get local nodeid */ 2637c478bd9Sstevel@tonic-gate e = rsm_get_interconnect_topology(&tp); 2647c478bd9Sstevel@tonic-gate if (e != RSM_SUCCESS) { 2657c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 2667c478bd9Sstevel@tonic-gate "unable to obtain topology data\n")); 2677c478bd9Sstevel@tonic-gate return (e); 2687c478bd9Sstevel@tonic-gate } else 2697c478bd9Sstevel@tonic-gate rsm_local_nodeid = tp->topology_hdr.local_nodeid; 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate rsm_free_interconnect_topology(tp); 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 2747c478bd9Sstevel@tonic-gate "_rsm_librsm_init: exit\n")); 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate static int 2807c478bd9Sstevel@tonic-gate _rsm_loopbackload(caddr_t name, int unit, rsm_controller_t **chdl) 2817c478bd9Sstevel@tonic-gate { 2827c478bd9Sstevel@tonic-gate rsm_controller_t *p; 2837c478bd9Sstevel@tonic-gate rsm_ioctlmsg_t msg; 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, 2867c478bd9Sstevel@tonic-gate "_rsm_loopbackload: enter\n")); 2877c478bd9Sstevel@tonic-gate /* 2887c478bd9Sstevel@tonic-gate * For now do this, but we should open some file and read the 2897c478bd9Sstevel@tonic-gate * list of supported controllers and there numbers. 2907c478bd9Sstevel@tonic-gate */ 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate p = (rsm_controller_t *)malloc(sizeof (*p) + strlen(name) + 1); 2937c478bd9Sstevel@tonic-gate if (!p) { 2947c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_ERR, 2957c478bd9Sstevel@tonic-gate "not enough memory\n")); 2967c478bd9Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_MEM); 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate msg.cname = name; 3007c478bd9Sstevel@tonic-gate msg.cname_len = strlen(name) +1; 3017c478bd9Sstevel@tonic-gate msg.cnum = unit; 3027c478bd9Sstevel@tonic-gate msg.arg = (caddr_t)&p->cntr_attr; 3037c478bd9Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_ATTR, &msg) < 0) { 3047c478bd9Sstevel@tonic-gate int error = errno; 3057c478bd9Sstevel@tonic-gate free((void *)p); 3067c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_ERR, 3077c478bd9Sstevel@tonic-gate "RSM_IOCTL_ATTR failed\n")); 3087c478bd9Sstevel@tonic-gate return (error); 3097c478bd9Sstevel@tonic-gate } 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate __rsmloopback_init_ops(&loopback_ops); 3127c478bd9Sstevel@tonic-gate __rsmdefault_setops(&loopback_ops); 3137c478bd9Sstevel@tonic-gate p->cntr_segops = &loopback_ops; 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate /* 3167c478bd9Sstevel@tonic-gate * Should add this entry into list 3177c478bd9Sstevel@tonic-gate */ 3187c478bd9Sstevel@tonic-gate p->cntr_fd = _rsm_fd; 3197c478bd9Sstevel@tonic-gate p->cntr_name = strcpy((char *)(p+1), name); 3207c478bd9Sstevel@tonic-gate p->cntr_unit = unit; 3217c478bd9Sstevel@tonic-gate p->cntr_refcnt = 1; 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate mutex_init(&p->cntr_lock, USYNC_THREAD, NULL); 3257c478bd9Sstevel@tonic-gate cond_init(&p->cntr_cv, USYNC_THREAD, NULL); 3267c478bd9Sstevel@tonic-gate p->cntr_rqlist = NULL; 3277c478bd9Sstevel@tonic-gate p->cntr_segops->rsm_get_lib_attr(&p->cntr_lib_attr); 3287c478bd9Sstevel@tonic-gate p->cntr_next = controller_list; 3297c478bd9Sstevel@tonic-gate controller_list = p; 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate *chdl = p; 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_DEBUG_VERBOSE, 3347c478bd9Sstevel@tonic-gate "_rsm_loopbackload: exit\n")); 3357c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate static int 3407c478bd9Sstevel@tonic-gate _rsm_modload(caddr_t name, int unit, rsmapi_controller_handle_t *controller) 3417c478bd9Sstevel@tonic-gate { 3427c478bd9Sstevel@tonic-gate int error = RSM_SUCCESS; 3437c478bd9Sstevel@tonic-gate char clib[MAX_STRLEN]; 3447c478bd9Sstevel@tonic-gate rsm_controller_t *p = NULL; 3457c478bd9Sstevel@tonic-gate void *dlh; 3467c478bd9Sstevel@tonic-gate rsm_attach_entry_t fptr; 3477c478bd9Sstevel@tonic-gate rsm_ioctlmsg_t msg; 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 3507c478bd9Sstevel@tonic-gate "_rsm_modload: enter\n")); 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate (void) sprintf(clib, "%s.so", name); 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate /* found entry, try to load library */ 3557c478bd9Sstevel@tonic-gate dlh = dlopen(clib, RTLD_LAZY); 3567c478bd9Sstevel@tonic-gate if (dlh == NULL) { 3577c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 3587c478bd9Sstevel@tonic-gate "unable to find plugin library\n")); 3597c478bd9Sstevel@tonic-gate error = RSMERR_CTLR_NOT_PRESENT; 3607c478bd9Sstevel@tonic-gate goto skiplib; 3617c478bd9Sstevel@tonic-gate } 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate (void) sprintf(clib, "%s_opendevice", name); 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate fptr = (rsm_attach_entry_t)dlsym(dlh, clib); /* lint !e611 */ 3667c478bd9Sstevel@tonic-gate if (fptr != NULL) { 3677c478bd9Sstevel@tonic-gate /* allocate new lib structure */ 3687c478bd9Sstevel@tonic-gate /* get ops handler, attr and ops */ 3697c478bd9Sstevel@tonic-gate p = (rsm_controller_t *)malloc(sizeof (*p) + strlen(name) + 1); 3707c478bd9Sstevel@tonic-gate if (p != NULL) { 3717c478bd9Sstevel@tonic-gate error = fptr(unit, &p->cntr_segops); 3727c478bd9Sstevel@tonic-gate } else { 3737c478bd9Sstevel@tonic-gate error = RSMERR_INSUFFICIENT_MEM; 3747c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 3757c478bd9Sstevel@tonic-gate "not enough memory\n")); 3767c478bd9Sstevel@tonic-gate } 3777c478bd9Sstevel@tonic-gate } else { 3787c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 3797c478bd9Sstevel@tonic-gate "can't find symbol %s\n", clib)); 3807c478bd9Sstevel@tonic-gate error = RSMERR_CTLR_NOT_PRESENT; 3817c478bd9Sstevel@tonic-gate (void) dlclose(dlh); 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate skiplib: 3857c478bd9Sstevel@tonic-gate if ((error != RSM_SUCCESS) || (p == NULL)) { 3867c478bd9Sstevel@tonic-gate if (p != NULL) 3877c478bd9Sstevel@tonic-gate free((void *)p); 3887c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 3897c478bd9Sstevel@tonic-gate "_rsm_modload error %d\n", error)); 3907c478bd9Sstevel@tonic-gate return (error); 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate /* check the version number */ 3947c478bd9Sstevel@tonic-gate if (p->cntr_segops->rsm_version != RSM_LIB_VERSION) { 3957c478bd9Sstevel@tonic-gate /* bad version number */ 3967c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 3977c478bd9Sstevel@tonic-gate "wrong version; " 3987c478bd9Sstevel@tonic-gate "found %d, expected %d\n", 3997c478bd9Sstevel@tonic-gate p->cntr_segops->rsm_version, RSM_LIB_VERSION)); 4007c478bd9Sstevel@tonic-gate free(p); 4017c478bd9Sstevel@tonic-gate return (RSMERR_BAD_LIBRARY_VERSION); 4027c478bd9Sstevel@tonic-gate } else { 4037c478bd9Sstevel@tonic-gate /* pass the fuctions to NDI library */ 4047c478bd9Sstevel@tonic-gate if ((p->cntr_segops->rsm_register_lib_funcs == NULL) || 4057c478bd9Sstevel@tonic-gate (p->cntr_segops->rsm_register_lib_funcs( 4067c478bd9Sstevel@tonic-gate &lib_functions) != RSM_SUCCESS)) { 4077c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 4087c478bd9Sstevel@tonic-gate "RSMNDI library not registering lib functions\n")); 4097c478bd9Sstevel@tonic-gate } 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate /* get controller attributes */ 4127c478bd9Sstevel@tonic-gate msg.cnum = unit; 4137c478bd9Sstevel@tonic-gate msg.cname = name; 4147c478bd9Sstevel@tonic-gate msg.cname_len = strlen(name) +1; 4157c478bd9Sstevel@tonic-gate msg.arg = (caddr_t)&p->cntr_attr; 4167c478bd9Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_ATTR, &msg) < 0) { 4177c478bd9Sstevel@tonic-gate error = errno; 4187c478bd9Sstevel@tonic-gate free((void *)p); 4197c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 4207c478bd9Sstevel@tonic-gate "RSM_IOCTL_ATTR failed\n")); 4217c478bd9Sstevel@tonic-gate return (error); 4227c478bd9Sstevel@tonic-gate } 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate /* set controller access functions */ 4257c478bd9Sstevel@tonic-gate __rsmdefault_setops(p->cntr_segops); 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate mutex_init(&p->cntr_lock, USYNC_THREAD, NULL); 4287c478bd9Sstevel@tonic-gate cond_init(&p->cntr_cv, USYNC_THREAD, NULL); 4297c478bd9Sstevel@tonic-gate p->cntr_rqlist = NULL; 4307c478bd9Sstevel@tonic-gate p->cntr_segops->rsm_get_lib_attr(&p->cntr_lib_attr); 4317c478bd9Sstevel@tonic-gate /* insert into list of controllers */ 4327c478bd9Sstevel@tonic-gate p->cntr_name = strcpy((char *)(p+1), name); 4337c478bd9Sstevel@tonic-gate p->cntr_fd = _rsm_fd; 4347c478bd9Sstevel@tonic-gate p->cntr_unit = unit; 4357c478bd9Sstevel@tonic-gate p->cntr_refcnt = 1; /* first reference */ 4367c478bd9Sstevel@tonic-gate p->cntr_next = controller_list; 4377c478bd9Sstevel@tonic-gate controller_list = p; 4387c478bd9Sstevel@tonic-gate *controller = (rsmapi_controller_handle_t)p; 4397c478bd9Sstevel@tonic-gate errno = RSM_SUCCESS; 4407c478bd9Sstevel@tonic-gate } 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 4437c478bd9Sstevel@tonic-gate "_rsm_modload: exit\n")); 4447c478bd9Sstevel@tonic-gate return (error); 4457c478bd9Sstevel@tonic-gate } 4467c478bd9Sstevel@tonic-gate 4477c478bd9Sstevel@tonic-gate /* 4487c478bd9Sstevel@tonic-gate * inserts a given segment handle into the pollfd table, this is called 4497c478bd9Sstevel@tonic-gate * when rsm_memseg_get_pollfd() is called the first time on a segment handle. 4507c478bd9Sstevel@tonic-gate * Returns RSM_SUCCESS if successful otherwise the error code is returned 4517c478bd9Sstevel@tonic-gate */ 4527c478bd9Sstevel@tonic-gate static int 4537c478bd9Sstevel@tonic-gate _rsm_insert_pollfd_table(int segfd, minor_t segrnum) 4547c478bd9Sstevel@tonic-gate { 4557c478bd9Sstevel@tonic-gate int i; 4567c478bd9Sstevel@tonic-gate int hash; 4577c478bd9Sstevel@tonic-gate rsm_pollfd_chunk_t *chunk; 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate hash = RSM_POLLFD_HASH(segfd); 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate mutex_lock(&pollfd_table.lock); 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate chunk = pollfd_table.buckets[hash]; 4647c478bd9Sstevel@tonic-gate while (chunk) { 4657c478bd9Sstevel@tonic-gate if (chunk->nfree > 0) 4667c478bd9Sstevel@tonic-gate break; 4677c478bd9Sstevel@tonic-gate chunk = chunk->next; 4687c478bd9Sstevel@tonic-gate } 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate if (!chunk) { /* couldn't find a free chunk - allocate a new one */ 4717c478bd9Sstevel@tonic-gate chunk = malloc(sizeof (rsm_pollfd_chunk_t)); 4727c478bd9Sstevel@tonic-gate if (!chunk) { 4737c478bd9Sstevel@tonic-gate mutex_unlock(&pollfd_table.lock); 4747c478bd9Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_MEM); 4757c478bd9Sstevel@tonic-gate } 4767c478bd9Sstevel@tonic-gate chunk->nfree = RSM_POLLFD_PER_CHUNK - 1; 4777c478bd9Sstevel@tonic-gate chunk->fdarray[0].fd = segfd; 4787c478bd9Sstevel@tonic-gate chunk->fdarray[0].segrnum = segrnum; 4797c478bd9Sstevel@tonic-gate for (i = 1; i < RSM_POLLFD_PER_CHUNK; i++) { 4807c478bd9Sstevel@tonic-gate chunk->fdarray[i].fd = -1; 4817c478bd9Sstevel@tonic-gate chunk->fdarray[i].segrnum = 0; 4827c478bd9Sstevel@tonic-gate } 4837c478bd9Sstevel@tonic-gate /* insert this into the hash table */ 4847c478bd9Sstevel@tonic-gate chunk->next = pollfd_table.buckets[hash]; 4857c478bd9Sstevel@tonic-gate pollfd_table.buckets[hash] = chunk; 4867c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 4877c478bd9Sstevel@tonic-gate "rsm_insert_pollfd: new chunk(%p) @ %d for %d:%d\n", 4887c478bd9Sstevel@tonic-gate chunk, hash, segfd, segrnum)); 4897c478bd9Sstevel@tonic-gate } else { /* a chunk with free slot was found */ 4907c478bd9Sstevel@tonic-gate for (i = 0; i < RSM_POLLFD_PER_CHUNK; i++) { 4917c478bd9Sstevel@tonic-gate if (chunk->fdarray[i].fd == -1) { 4927c478bd9Sstevel@tonic-gate chunk->fdarray[i].fd = segfd; 4937c478bd9Sstevel@tonic-gate chunk->fdarray[i].segrnum = segrnum; 4947c478bd9Sstevel@tonic-gate chunk->nfree--; 4957c478bd9Sstevel@tonic-gate break; 4967c478bd9Sstevel@tonic-gate } 4977c478bd9Sstevel@tonic-gate } 4987c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 4997c478bd9Sstevel@tonic-gate "rsm_insert_pollfd: inserted @ %d for %d:%d chunk(%p)\n", 5007c478bd9Sstevel@tonic-gate hash, segfd, segrnum, chunk)); 5017c478bd9Sstevel@tonic-gate assert(i < RSM_POLLFD_PER_CHUNK); 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate mutex_unlock(&pollfd_table.lock); 5057c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 5067c478bd9Sstevel@tonic-gate } 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate /* 5097c478bd9Sstevel@tonic-gate * Given a file descriptor returns the corresponding segment handles 5107c478bd9Sstevel@tonic-gate * resource number, if the fd is not found returns 0. 0 is not a valid 5117c478bd9Sstevel@tonic-gate * minor number for a rsmapi segment since it is used for the barrier 5127c478bd9Sstevel@tonic-gate * resource. 5137c478bd9Sstevel@tonic-gate */ 5147c478bd9Sstevel@tonic-gate static minor_t 5157c478bd9Sstevel@tonic-gate _rsm_lookup_pollfd_table(int segfd) 5167c478bd9Sstevel@tonic-gate { 5177c478bd9Sstevel@tonic-gate int i; 5187c478bd9Sstevel@tonic-gate rsm_pollfd_chunk_t *chunk; 5197c478bd9Sstevel@tonic-gate 5207c478bd9Sstevel@tonic-gate if (segfd < 0) 5217c478bd9Sstevel@tonic-gate return (0); 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate mutex_lock(&pollfd_table.lock); 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate chunk = pollfd_table.buckets[RSM_POLLFD_HASH(segfd)]; 5267c478bd9Sstevel@tonic-gate while (chunk) { 5277c478bd9Sstevel@tonic-gate assert(chunk->nfree < RSM_POLLFD_PER_CHUNK); 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate for (i = 0; i < RSM_POLLFD_PER_CHUNK; i++) { 5307c478bd9Sstevel@tonic-gate if (chunk->fdarray[i].fd == segfd) { 5317c478bd9Sstevel@tonic-gate mutex_unlock(&pollfd_table.lock); 5327c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 5337c478bd9Sstevel@tonic-gate "rsm_lookup_pollfd: found(%d) rnum(%d)\n", 5347c478bd9Sstevel@tonic-gate segfd, chunk->fdarray[i].segrnum)); 5357c478bd9Sstevel@tonic-gate return (chunk->fdarray[i].segrnum); 5367c478bd9Sstevel@tonic-gate } 5377c478bd9Sstevel@tonic-gate } 5387c478bd9Sstevel@tonic-gate chunk = chunk->next; 5397c478bd9Sstevel@tonic-gate } 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate mutex_unlock(&pollfd_table.lock); 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 5447c478bd9Sstevel@tonic-gate "rsm_lookup_pollfd: not found(%d)\n", segfd)); 5457c478bd9Sstevel@tonic-gate 5467c478bd9Sstevel@tonic-gate return (0); 5477c478bd9Sstevel@tonic-gate } 5487c478bd9Sstevel@tonic-gate 5497c478bd9Sstevel@tonic-gate /* 5507c478bd9Sstevel@tonic-gate * Remove the entry corresponding to the given file descriptor from the 5517c478bd9Sstevel@tonic-gate * pollfd table. 5527c478bd9Sstevel@tonic-gate */ 5537c478bd9Sstevel@tonic-gate static void 5547c478bd9Sstevel@tonic-gate _rsm_remove_pollfd_table(int segfd) 5557c478bd9Sstevel@tonic-gate { 5567c478bd9Sstevel@tonic-gate int i; 5577c478bd9Sstevel@tonic-gate int hash; 5587c478bd9Sstevel@tonic-gate rsm_pollfd_chunk_t *chunk; 5597c478bd9Sstevel@tonic-gate rsm_pollfd_chunk_t *prev_chunk; 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate if (segfd < 0) 5627c478bd9Sstevel@tonic-gate return; 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate hash = RSM_POLLFD_HASH(segfd); 5657c478bd9Sstevel@tonic-gate 5667c478bd9Sstevel@tonic-gate mutex_lock(&pollfd_table.lock); 5677c478bd9Sstevel@tonic-gate 5687c478bd9Sstevel@tonic-gate prev_chunk = chunk = pollfd_table.buckets[hash]; 5697c478bd9Sstevel@tonic-gate while (chunk) { 5707c478bd9Sstevel@tonic-gate assert(chunk->nfree < RSM_POLLFD_PER_CHUNK); 5717c478bd9Sstevel@tonic-gate 5727c478bd9Sstevel@tonic-gate for (i = 0; i < RSM_POLLFD_PER_CHUNK; i++) { 5737c478bd9Sstevel@tonic-gate if (chunk->fdarray[i].fd == segfd) { 5747c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 5757c478bd9Sstevel@tonic-gate "rsm_remove_pollfd: %d:%d\n", 5767c478bd9Sstevel@tonic-gate chunk->fdarray[i].fd, 5777c478bd9Sstevel@tonic-gate chunk->fdarray[i].segrnum)); 5787c478bd9Sstevel@tonic-gate chunk->fdarray[i].fd = -1; 5797c478bd9Sstevel@tonic-gate chunk->fdarray[i].segrnum = 0; 5807c478bd9Sstevel@tonic-gate chunk->nfree++; 5817c478bd9Sstevel@tonic-gate if (chunk->nfree == RSM_POLLFD_PER_CHUNK) { 5827c478bd9Sstevel@tonic-gate /* chunk is empty free it */ 5837c478bd9Sstevel@tonic-gate if (prev_chunk == chunk) { 5847c478bd9Sstevel@tonic-gate pollfd_table.buckets[hash] = 5857c478bd9Sstevel@tonic-gate chunk->next; 5867c478bd9Sstevel@tonic-gate } else { 5877c478bd9Sstevel@tonic-gate prev_chunk->next = chunk->next; 5887c478bd9Sstevel@tonic-gate } 5897c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, 5907c478bd9Sstevel@tonic-gate RSM_DEBUG_VERBOSE, 5917c478bd9Sstevel@tonic-gate "rsm_remove_pollfd:free(%p)\n", 5927c478bd9Sstevel@tonic-gate chunk)); 5937c478bd9Sstevel@tonic-gate free(chunk); 5947c478bd9Sstevel@tonic-gate mutex_unlock(&pollfd_table.lock); 5957c478bd9Sstevel@tonic-gate return; 5967c478bd9Sstevel@tonic-gate } 5977c478bd9Sstevel@tonic-gate } 5987c478bd9Sstevel@tonic-gate } 5997c478bd9Sstevel@tonic-gate prev_chunk = chunk; 6007c478bd9Sstevel@tonic-gate chunk = chunk->next; 6017c478bd9Sstevel@tonic-gate } 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate mutex_unlock(&pollfd_table.lock); 6047c478bd9Sstevel@tonic-gate } 6057c478bd9Sstevel@tonic-gate 6067c478bd9Sstevel@tonic-gate int 6077c478bd9Sstevel@tonic-gate _rsm_get_controller(char *name, rsmapi_controller_handle_t *chdl) 6087c478bd9Sstevel@tonic-gate { 6097c478bd9Sstevel@tonic-gate rsm_controller_t *p; 6107c478bd9Sstevel@tonic-gate char cntr_name[MAXNAMELEN]; /* cntr_name=<cntr_type><unit> */ 6117c478bd9Sstevel@tonic-gate char *cntr_type; 6127c478bd9Sstevel@tonic-gate int unit = 0; 6137c478bd9Sstevel@tonic-gate int i, e; 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 6167c478bd9Sstevel@tonic-gate "rsm_get_controller: enter\n")); 6177c478bd9Sstevel@tonic-gate /* 6187c478bd9Sstevel@tonic-gate * Lookup controller name and return ops vector and controller 6197c478bd9Sstevel@tonic-gate * structure 6207c478bd9Sstevel@tonic-gate */ 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate if (!chdl) { 6237c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 6247c478bd9Sstevel@tonic-gate "Invalid controller handle\n")); 6257c478bd9Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 6267c478bd9Sstevel@tonic-gate } 6277c478bd9Sstevel@tonic-gate if (!name) { 6287c478bd9Sstevel@tonic-gate /* use loopback if null */ 6297c478bd9Sstevel@tonic-gate cntr_type = LOOPBACK; 6307c478bd9Sstevel@tonic-gate } else { 6317c478bd9Sstevel@tonic-gate (void) strcpy(cntr_name, name); 6327c478bd9Sstevel@tonic-gate /* scan from the end till a non-digit is found */ 6337c478bd9Sstevel@tonic-gate for (i = strlen(cntr_name) - 1; i >= 0; i--) { 6347c478bd9Sstevel@tonic-gate if (! isdigit((int)cntr_name[i])) 6357c478bd9Sstevel@tonic-gate break; 6367c478bd9Sstevel@tonic-gate } 6377c478bd9Sstevel@tonic-gate i++; 6387c478bd9Sstevel@tonic-gate unit = atoi((char *)cntr_name+i); 6397c478bd9Sstevel@tonic-gate cntr_name[i] = '\0'; /* null terminate the cntr_type part */ 6407c478bd9Sstevel@tonic-gate cntr_type = (char *)cntr_name; 6417c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 6427c478bd9Sstevel@tonic-gate "cntr_type=%s, instance=%d\n", 6437c478bd9Sstevel@tonic-gate cntr_type, unit)); 6447c478bd9Sstevel@tonic-gate } 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate /* protect the controller_list by locking the device/library */ 6477c478bd9Sstevel@tonic-gate mutex_lock(&_rsm_lock); 6487c478bd9Sstevel@tonic-gate 6497c478bd9Sstevel@tonic-gate for (p = controller_list; p; p = p->cntr_next) { 6507c478bd9Sstevel@tonic-gate if (!strcasecmp(p->cntr_name, cntr_type) && 6517c478bd9Sstevel@tonic-gate !strcasecmp(cntr_type, LOOPBACK)) { 6527c478bd9Sstevel@tonic-gate p->cntr_refcnt++; 6537c478bd9Sstevel@tonic-gate *chdl = (rsmapi_controller_handle_t)p; 6547c478bd9Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 6557c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 6567c478bd9Sstevel@tonic-gate "rsm_get_controller: exit\n")); 6577c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 6587c478bd9Sstevel@tonic-gate } else if (!strcasecmp(p->cntr_name, cntr_type) && 6597c478bd9Sstevel@tonic-gate (p->cntr_unit == unit)) { 6607c478bd9Sstevel@tonic-gate p->cntr_refcnt++; 6617c478bd9Sstevel@tonic-gate *chdl = (rsmapi_controller_handle_t)p; 6627c478bd9Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 6637c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 6647c478bd9Sstevel@tonic-gate "rsm_get_controller: exit\n")); 6657c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 6667c478bd9Sstevel@tonic-gate } 6677c478bd9Sstevel@tonic-gate } 6687c478bd9Sstevel@tonic-gate 6697c478bd9Sstevel@tonic-gate 6707c478bd9Sstevel@tonic-gate if (!strcasecmp(cntr_type, LOOPBACK)) { 6717c478bd9Sstevel@tonic-gate e = _rsm_loopbackload(cntr_type, unit, 6727c478bd9Sstevel@tonic-gate (rsm_controller_t **)chdl); 6737c478bd9Sstevel@tonic-gate } else { 6747c478bd9Sstevel@tonic-gate e = _rsm_modload(cntr_type, unit, chdl); 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate 6777c478bd9Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 6807c478bd9Sstevel@tonic-gate " rsm_get_controller: exit\n")); 6817c478bd9Sstevel@tonic-gate return (e); 6827c478bd9Sstevel@tonic-gate } 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate int 6857c478bd9Sstevel@tonic-gate _rsm_release_controller(rsmapi_controller_handle_t cntr_handle) 6867c478bd9Sstevel@tonic-gate { 6877c478bd9Sstevel@tonic-gate int e = RSM_SUCCESS; 6887c478bd9Sstevel@tonic-gate rsm_controller_t *chdl = (rsm_controller_t *)cntr_handle; 6897c478bd9Sstevel@tonic-gate rsm_controller_t *curr, *prev; 6907c478bd9Sstevel@tonic-gate 6917c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 6927c478bd9Sstevel@tonic-gate "rsm_release_controller: enter\n")); 6937c478bd9Sstevel@tonic-gate 6947c478bd9Sstevel@tonic-gate mutex_lock(&_rsm_lock); 6957c478bd9Sstevel@tonic-gate 6967c478bd9Sstevel@tonic-gate if (chdl->cntr_refcnt == 0) { 6977c478bd9Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 6987c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 6997c478bd9Sstevel@tonic-gate "controller reference count is zero\n")); 7007c478bd9Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 7017c478bd9Sstevel@tonic-gate } 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate chdl->cntr_refcnt--; 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate if (chdl->cntr_refcnt > 0) { 7067c478bd9Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 7077c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 7087c478bd9Sstevel@tonic-gate "rsm_release_controller: exit\n")); 7097c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 7107c478bd9Sstevel@tonic-gate } 7117c478bd9Sstevel@tonic-gate 7127c478bd9Sstevel@tonic-gate e = chdl->cntr_segops->rsm_closedevice(cntr_handle); 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate /* 7157c478bd9Sstevel@tonic-gate * remove the controller in any case from the controller list 7167c478bd9Sstevel@tonic-gate */ 7177c478bd9Sstevel@tonic-gate 7187c478bd9Sstevel@tonic-gate prev = curr = controller_list; 7197c478bd9Sstevel@tonic-gate while (curr != NULL) { 7207c478bd9Sstevel@tonic-gate if (curr == chdl) { 7217c478bd9Sstevel@tonic-gate if (curr == prev) { 7227c478bd9Sstevel@tonic-gate controller_list = curr->cntr_next; 7237c478bd9Sstevel@tonic-gate } else { 7247c478bd9Sstevel@tonic-gate prev->cntr_next = curr->cntr_next; 7257c478bd9Sstevel@tonic-gate } 7267c478bd9Sstevel@tonic-gate free(curr); 7277c478bd9Sstevel@tonic-gate break; 7287c478bd9Sstevel@tonic-gate } 7297c478bd9Sstevel@tonic-gate prev = curr; 7307c478bd9Sstevel@tonic-gate curr = curr->cntr_next; 7317c478bd9Sstevel@tonic-gate } 7327c478bd9Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 7337c478bd9Sstevel@tonic-gate 7347c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 7357c478bd9Sstevel@tonic-gate "rsm_release_controller: exit\n")); 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate return (e); 7387c478bd9Sstevel@tonic-gate } 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate int _rsm_get_controller_attr(rsmapi_controller_handle_t chandle, 7417c478bd9Sstevel@tonic-gate rsmapi_controller_attr_t *attr) 7427c478bd9Sstevel@tonic-gate { 7437c478bd9Sstevel@tonic-gate rsm_controller_t *p; 7447c478bd9Sstevel@tonic-gate 7457c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 7467c478bd9Sstevel@tonic-gate "rsm_get_controller_attr: enter\n")); 7477c478bd9Sstevel@tonic-gate 7487c478bd9Sstevel@tonic-gate if (!chandle) { 7497c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 7507c478bd9Sstevel@tonic-gate "invalid controller handle\n")); 7517c478bd9Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 7527c478bd9Sstevel@tonic-gate } 7537c478bd9Sstevel@tonic-gate 7547c478bd9Sstevel@tonic-gate if (!attr) { 7557c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 7567c478bd9Sstevel@tonic-gate "invalid attribute pointer\n")); 7577c478bd9Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 7587c478bd9Sstevel@tonic-gate } 7597c478bd9Sstevel@tonic-gate 7607c478bd9Sstevel@tonic-gate p = (rsm_controller_t *)chandle; 7617c478bd9Sstevel@tonic-gate 7627c478bd9Sstevel@tonic-gate mutex_lock(&_rsm_lock); 7637c478bd9Sstevel@tonic-gate if (p->cntr_refcnt == 0) { 7647c478bd9Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 7657c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 7667c478bd9Sstevel@tonic-gate "cntr refcnt is 0\n")); 7677c478bd9Sstevel@tonic-gate return (RSMERR_CTLR_NOT_PRESENT); 7687c478bd9Sstevel@tonic-gate } 7697c478bd9Sstevel@tonic-gate 7707c478bd9Sstevel@tonic-gate /* copy only the user part of the attr structure */ 7717c478bd9Sstevel@tonic-gate attr->attr_direct_access_sizes = 7727c478bd9Sstevel@tonic-gate p->cntr_attr.attr_direct_access_sizes; 7737c478bd9Sstevel@tonic-gate attr->attr_atomic_sizes = 7747c478bd9Sstevel@tonic-gate p->cntr_attr.attr_atomic_sizes; 7757c478bd9Sstevel@tonic-gate attr->attr_page_size = 7767c478bd9Sstevel@tonic-gate p->cntr_attr.attr_page_size; 7777c478bd9Sstevel@tonic-gate attr->attr_max_export_segment_size = 7787c478bd9Sstevel@tonic-gate p->cntr_attr.attr_max_export_segment_size; 7797c478bd9Sstevel@tonic-gate attr->attr_tot_export_segment_size = 7807c478bd9Sstevel@tonic-gate p->cntr_attr.attr_tot_export_segment_size; 7817c478bd9Sstevel@tonic-gate attr->attr_max_export_segments = 7827c478bd9Sstevel@tonic-gate p->cntr_attr.attr_max_export_segments; 7837c478bd9Sstevel@tonic-gate attr->attr_max_import_map_size = 7847c478bd9Sstevel@tonic-gate p->cntr_attr.attr_max_import_map_size; 7857c478bd9Sstevel@tonic-gate attr->attr_tot_import_map_size = 7867c478bd9Sstevel@tonic-gate p->cntr_attr.attr_tot_import_map_size; 7877c478bd9Sstevel@tonic-gate attr->attr_max_import_segments = 7887c478bd9Sstevel@tonic-gate p->cntr_attr.attr_max_import_segments; 7897c478bd9Sstevel@tonic-gate 7907c478bd9Sstevel@tonic-gate mutex_unlock(&_rsm_lock); 7917c478bd9Sstevel@tonic-gate 7927c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 7937c478bd9Sstevel@tonic-gate "rsm_get_controller_attr: exit\n")); 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 7967c478bd9Sstevel@tonic-gate } 7977c478bd9Sstevel@tonic-gate 7987c478bd9Sstevel@tonic-gate 7997c478bd9Sstevel@tonic-gate 8007c478bd9Sstevel@tonic-gate /* 8017c478bd9Sstevel@tonic-gate * Create a segment handle for the virtual address range specified 8027c478bd9Sstevel@tonic-gate * by vaddr and size 8037c478bd9Sstevel@tonic-gate */ 8047c478bd9Sstevel@tonic-gate int 8057c478bd9Sstevel@tonic-gate _rsm_memseg_export_create(rsmapi_controller_handle_t controller, 8067c478bd9Sstevel@tonic-gate rsm_memseg_export_handle_t *memseg, 8077c478bd9Sstevel@tonic-gate void *vaddr, 8087c478bd9Sstevel@tonic-gate size_t length, 8097c478bd9Sstevel@tonic-gate uint_t flags) 8107c478bd9Sstevel@tonic-gate { 8117c478bd9Sstevel@tonic-gate 8127c478bd9Sstevel@tonic-gate rsm_controller_t *chdl = (rsm_controller_t *)controller; 8137c478bd9Sstevel@tonic-gate rsmseg_handle_t *p; 8147c478bd9Sstevel@tonic-gate rsm_ioctlmsg_t msg; 8157c478bd9Sstevel@tonic-gate int e; 8167c478bd9Sstevel@tonic-gate #ifndef _LP64 8177c478bd9Sstevel@tonic-gate int tmpfd; 8187c478bd9Sstevel@tonic-gate #endif 8197c478bd9Sstevel@tonic-gate 8207c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 8217c478bd9Sstevel@tonic-gate "rsm_memseg_export_create: enter\n")); 8227c478bd9Sstevel@tonic-gate 8237c478bd9Sstevel@tonic-gate if (!controller) { 8247c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8257c478bd9Sstevel@tonic-gate "invalid controller handle\n")); 8267c478bd9Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 8277c478bd9Sstevel@tonic-gate } 8287c478bd9Sstevel@tonic-gate if (!memseg) { 8297c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8307c478bd9Sstevel@tonic-gate "invalid segment handle\n")); 8317c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 8327c478bd9Sstevel@tonic-gate } 8337c478bd9Sstevel@tonic-gate 8347c478bd9Sstevel@tonic-gate *memseg = 0; 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate /* 8377c478bd9Sstevel@tonic-gate * Check vaddr and size alignment, both must be mmu page size 8387c478bd9Sstevel@tonic-gate * aligned 8397c478bd9Sstevel@tonic-gate */ 8407c478bd9Sstevel@tonic-gate if (!vaddr) { 8417c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8427c478bd9Sstevel@tonic-gate "invalid arguments\n")); 8437c478bd9Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 8447c478bd9Sstevel@tonic-gate } 8457c478bd9Sstevel@tonic-gate 8467c478bd9Sstevel@tonic-gate if (!length) { 8477c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8487c478bd9Sstevel@tonic-gate "invalid arguments\n")); 8497c478bd9Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 8507c478bd9Sstevel@tonic-gate } 8517c478bd9Sstevel@tonic-gate 8527c478bd9Sstevel@tonic-gate if (((size_t)vaddr & (PAGESIZE - 1)) || 8537c478bd9Sstevel@tonic-gate (length & (PAGESIZE - 1))) { 8547c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8557c478bd9Sstevel@tonic-gate "invalid mem alignment for vaddr or length\n")); 8567c478bd9Sstevel@tonic-gate return (RSMERR_BAD_MEM_ALIGNMENT); 8577c478bd9Sstevel@tonic-gate } 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gate /* 8607c478bd9Sstevel@tonic-gate * The following check does not apply for loopback controller 8617c478bd9Sstevel@tonic-gate * since for the loopback adapter, the attr_max_export_segment_size 8627c478bd9Sstevel@tonic-gate * is always 0. 8637c478bd9Sstevel@tonic-gate */ 8647c478bd9Sstevel@tonic-gate if (strcasecmp(chdl->cntr_name, LOOPBACK)) { 8657c478bd9Sstevel@tonic-gate if (length > chdl->cntr_attr.attr_max_export_segment_size) { 8667c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8677c478bd9Sstevel@tonic-gate "length exceeds controller limits\n")); 8687c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8697c478bd9Sstevel@tonic-gate "controller limits %d\n", 8707c478bd9Sstevel@tonic-gate chdl->cntr_attr.attr_max_export_segment_size)); 8717c478bd9Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 8727c478bd9Sstevel@tonic-gate } 8737c478bd9Sstevel@tonic-gate } 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate p = (rsmseg_handle_t *)malloc(sizeof (*p)); 8767c478bd9Sstevel@tonic-gate if (p == NULL) { 8777c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 8787c478bd9Sstevel@tonic-gate "not enough memory\n")); 8797c478bd9Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_MEM); 8807c478bd9Sstevel@tonic-gate } 8817c478bd9Sstevel@tonic-gate 8827c478bd9Sstevel@tonic-gate p->rsmseg_fd = open(DEVRSM, O_RDWR); 8837c478bd9Sstevel@tonic-gate if (p->rsmseg_fd < 0) { 8847c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 8857c478bd9Sstevel@tonic-gate "unable to open device /dev/rsm\n")); 8867c478bd9Sstevel@tonic-gate free((void *)p); 8877c478bd9Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_RESOURCES); 8887c478bd9Sstevel@tonic-gate } 8897c478bd9Sstevel@tonic-gate 8907c478bd9Sstevel@tonic-gate #ifndef _LP64 8917c478bd9Sstevel@tonic-gate /* 8927c478bd9Sstevel@tonic-gate * libc can't handle fd's greater than 255, in order to 8937c478bd9Sstevel@tonic-gate * insure that these values remain available make /dev/rsm 8947c478bd9Sstevel@tonic-gate * fd > 255. Note: not needed for LP64 8957c478bd9Sstevel@tonic-gate */ 8967c478bd9Sstevel@tonic-gate tmpfd = fcntl(p->rsmseg_fd, F_DUPFD, 256); 8977c478bd9Sstevel@tonic-gate e = errno; 8987c478bd9Sstevel@tonic-gate if (tmpfd < 0) { 8997c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 9007c478bd9Sstevel@tonic-gate "F_DUPFD failed\n")); 9017c478bd9Sstevel@tonic-gate } else { 9027c478bd9Sstevel@tonic-gate (void) close(p->rsmseg_fd); 9037c478bd9Sstevel@tonic-gate p->rsmseg_fd = tmpfd; 9047c478bd9Sstevel@tonic-gate } 9057c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 9067c478bd9Sstevel@tonic-gate 9077c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, "" 9087c478bd9Sstevel@tonic-gate "rsmseg_fd is %d\n", p->rsmseg_fd)); 9097c478bd9Sstevel@tonic-gate 9107c478bd9Sstevel@tonic-gate if (fcntl(p->rsmseg_fd, F_SETFD, FD_CLOEXEC) < 0) { 9117c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 9127c478bd9Sstevel@tonic-gate "F_SETFD failed\n")); 9137c478bd9Sstevel@tonic-gate } 9147c478bd9Sstevel@tonic-gate 9157c478bd9Sstevel@tonic-gate p->rsmseg_state = EXPORT_CREATE; 9167c478bd9Sstevel@tonic-gate p->rsmseg_size = length; 9177c478bd9Sstevel@tonic-gate /* increment controller handle */ 9187c478bd9Sstevel@tonic-gate p->rsmseg_controller = chdl; 9197c478bd9Sstevel@tonic-gate 9207c478bd9Sstevel@tonic-gate /* try to bind user address range */ 9217c478bd9Sstevel@tonic-gate msg.cnum = chdl->cntr_unit; 9227c478bd9Sstevel@tonic-gate msg.cname = chdl->cntr_name; 9237c478bd9Sstevel@tonic-gate msg.cname_len = strlen(chdl->cntr_name) +1; 9247c478bd9Sstevel@tonic-gate msg.vaddr = vaddr; 9257c478bd9Sstevel@tonic-gate msg.len = length; 9267c478bd9Sstevel@tonic-gate msg.perm = flags; 9277c478bd9Sstevel@tonic-gate msg.off = 0; 9287c478bd9Sstevel@tonic-gate e = RSM_IOCTL_BIND; 9297c478bd9Sstevel@tonic-gate 9307c478bd9Sstevel@tonic-gate /* Try to bind */ 9317c478bd9Sstevel@tonic-gate if (ioctl(p->rsmseg_fd, e, &msg) < 0) { 9327c478bd9Sstevel@tonic-gate e = errno; 9337c478bd9Sstevel@tonic-gate (void) close(p->rsmseg_fd); 9347c478bd9Sstevel@tonic-gate free((void *)p); 9357c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 9367c478bd9Sstevel@tonic-gate "RSM_IOCTL_BIND failed\n")); 9377c478bd9Sstevel@tonic-gate return (e); 9387c478bd9Sstevel@tonic-gate } 9397c478bd9Sstevel@tonic-gate /* OK */ 9407c478bd9Sstevel@tonic-gate p->rsmseg_type = RSM_EXPORT_SEG; 9417c478bd9Sstevel@tonic-gate p->rsmseg_vaddr = vaddr; 9427c478bd9Sstevel@tonic-gate p->rsmseg_size = length; 9437c478bd9Sstevel@tonic-gate p->rsmseg_state = EXPORT_BIND; 9447c478bd9Sstevel@tonic-gate p->rsmseg_pollfd_refcnt = 0; 9457c478bd9Sstevel@tonic-gate p->rsmseg_rnum = msg.rnum; 9467c478bd9Sstevel@tonic-gate 9477c478bd9Sstevel@tonic-gate mutex_init(&p->rsmseg_lock, USYNC_THREAD, NULL); 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate *memseg = (rsm_memseg_export_handle_t)p; 9507c478bd9Sstevel@tonic-gate 9517c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 9527c478bd9Sstevel@tonic-gate "rsm_memseg_export_create: exit\n")); 9537c478bd9Sstevel@tonic-gate 9547c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 9557c478bd9Sstevel@tonic-gate } 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate int 9587c478bd9Sstevel@tonic-gate _rsm_memseg_export_destroy(rsm_memseg_export_handle_t memseg) 9597c478bd9Sstevel@tonic-gate { 9607c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg; 9617c478bd9Sstevel@tonic-gate 9627c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 9637c478bd9Sstevel@tonic-gate "rsm_memseg_export_destroy: enter\n")); 9647c478bd9Sstevel@tonic-gate 9657c478bd9Sstevel@tonic-gate if (!memseg) { 9667c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 9677c478bd9Sstevel@tonic-gate "invalid segment handle\n")); 9687c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 9697c478bd9Sstevel@tonic-gate } 9707c478bd9Sstevel@tonic-gate 9717c478bd9Sstevel@tonic-gate seg = (rsmseg_handle_t *)memseg; 9727c478bd9Sstevel@tonic-gate 9737c478bd9Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 9747c478bd9Sstevel@tonic-gate if (seg->rsmseg_pollfd_refcnt) { 9757c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 9767c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 9777c478bd9Sstevel@tonic-gate "segment reference count not zero\n")); 9787c478bd9Sstevel@tonic-gate return (RSMERR_POLLFD_IN_USE); 9797c478bd9Sstevel@tonic-gate } 9807c478bd9Sstevel@tonic-gate else 9817c478bd9Sstevel@tonic-gate seg->rsmseg_state = EXPORT_BIND; 9827c478bd9Sstevel@tonic-gate 9837c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 9847c478bd9Sstevel@tonic-gate 9857c478bd9Sstevel@tonic-gate (void) close(seg->rsmseg_fd); 9867c478bd9Sstevel@tonic-gate mutex_destroy(&seg->rsmseg_lock); 9877c478bd9Sstevel@tonic-gate free((void *)seg); 9887c478bd9Sstevel@tonic-gate 9897c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 9907c478bd9Sstevel@tonic-gate "rsm_memseg_export_destroy: exit\n")); 9917c478bd9Sstevel@tonic-gate 9927c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 9937c478bd9Sstevel@tonic-gate } 9947c478bd9Sstevel@tonic-gate 9957c478bd9Sstevel@tonic-gate int 9967c478bd9Sstevel@tonic-gate _rsm_memseg_export_rebind(rsm_memseg_export_handle_t memseg, void *vaddr, 9977c478bd9Sstevel@tonic-gate offset_t off, size_t length) 9987c478bd9Sstevel@tonic-gate { 9997c478bd9Sstevel@tonic-gate rsm_ioctlmsg_t msg; 10007c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 10017c478bd9Sstevel@tonic-gate 10027c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 10037c478bd9Sstevel@tonic-gate "rsm_memseg_export_rebind: enter\n")); 10047c478bd9Sstevel@tonic-gate 10057c478bd9Sstevel@tonic-gate off = off; 10067c478bd9Sstevel@tonic-gate 10077c478bd9Sstevel@tonic-gate if (!seg) { 10087c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10097c478bd9Sstevel@tonic-gate "invalid segment handle\n")); 10107c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 10117c478bd9Sstevel@tonic-gate } 10127c478bd9Sstevel@tonic-gate if (!vaddr) { 10137c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10147c478bd9Sstevel@tonic-gate "invalid vaddr\n")); 10157c478bd9Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 10167c478bd9Sstevel@tonic-gate } 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate /* 10197c478bd9Sstevel@tonic-gate * Same as bind except it's ok to have elimint in list. 10207c478bd9Sstevel@tonic-gate * Call into driver to remove any existing mappings. 10217c478bd9Sstevel@tonic-gate */ 10227c478bd9Sstevel@tonic-gate msg.vaddr = vaddr; 10237c478bd9Sstevel@tonic-gate msg.len = length; 10247c478bd9Sstevel@tonic-gate msg.off = 0; 10257c478bd9Sstevel@tonic-gate 10267c478bd9Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 10277c478bd9Sstevel@tonic-gate if (ioctl(seg->rsmseg_fd, RSM_IOCTL_REBIND, &msg) < 0) { 10287c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 10297c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10307c478bd9Sstevel@tonic-gate "RSM_IOCTL_REBIND failed\n")); 10317c478bd9Sstevel@tonic-gate return (errno); 10327c478bd9Sstevel@tonic-gate } 10337c478bd9Sstevel@tonic-gate 10347c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 10357c478bd9Sstevel@tonic-gate 10367c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 10377c478bd9Sstevel@tonic-gate "rsm_memseg_export_rebind: exit\n")); 10387c478bd9Sstevel@tonic-gate 10397c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 10407c478bd9Sstevel@tonic-gate } 10417c478bd9Sstevel@tonic-gate 10427c478bd9Sstevel@tonic-gate int 10437c478bd9Sstevel@tonic-gate _rsm_memseg_export_publish(rsm_memseg_export_handle_t memseg, 10447c478bd9Sstevel@tonic-gate rsm_memseg_id_t *seg_id, 10457c478bd9Sstevel@tonic-gate rsmapi_access_entry_t access_list[], 10467c478bd9Sstevel@tonic-gate uint_t access_list_length) 10477c478bd9Sstevel@tonic-gate 10487c478bd9Sstevel@tonic-gate { 10497c478bd9Sstevel@tonic-gate rsm_ioctlmsg_t msg; 10507c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 10517c478bd9Sstevel@tonic-gate 10527c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 10537c478bd9Sstevel@tonic-gate "rsm_memseg_export_publish: enter\n")); 10547c478bd9Sstevel@tonic-gate 10557c478bd9Sstevel@tonic-gate if (seg_id == NULL) { 10567c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10577c478bd9Sstevel@tonic-gate "invalid segment id\n")); 10587c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEGID); 10597c478bd9Sstevel@tonic-gate } 10607c478bd9Sstevel@tonic-gate 10617c478bd9Sstevel@tonic-gate if (!seg) { 10627c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10637c478bd9Sstevel@tonic-gate "invalid segment handle\n")); 10647c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 10657c478bd9Sstevel@tonic-gate } 10667c478bd9Sstevel@tonic-gate 10677c478bd9Sstevel@tonic-gate if (access_list_length > 0 && !access_list) { 10687c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10697c478bd9Sstevel@tonic-gate "invalid access control list\n")); 10707c478bd9Sstevel@tonic-gate return (RSMERR_BAD_ACL); 10717c478bd9Sstevel@tonic-gate } 10727c478bd9Sstevel@tonic-gate 10737c478bd9Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 10747c478bd9Sstevel@tonic-gate if (seg->rsmseg_state != EXPORT_BIND) { 10757c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 10767c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10777c478bd9Sstevel@tonic-gate "invalid segment state\n")); 10787c478bd9Sstevel@tonic-gate return (RSMERR_SEG_ALREADY_PUBLISHED); 10797c478bd9Sstevel@tonic-gate } 10807c478bd9Sstevel@tonic-gate 10817c478bd9Sstevel@tonic-gate /* 10827c478bd9Sstevel@tonic-gate * seg id < RSM_DLPI_END and in the RSM_USER_APP_ID range 10837c478bd9Sstevel@tonic-gate * are reserved for internal use. 10847c478bd9Sstevel@tonic-gate */ 10857c478bd9Sstevel@tonic-gate if ((*seg_id > 0) && 10867c478bd9Sstevel@tonic-gate ((*seg_id <= RSM_DLPI_ID_END) || 10877c478bd9Sstevel@tonic-gate BETWEEN (*seg_id, RSM_USER_APP_ID_BASE, RSM_USER_APP_ID_END))) { 10887c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 10897c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 10907c478bd9Sstevel@tonic-gate "invalid segment id\n")); 10917c478bd9Sstevel@tonic-gate return (RSMERR_RESERVED_SEGID); 10927c478bd9Sstevel@tonic-gate } 10937c478bd9Sstevel@tonic-gate 10947c478bd9Sstevel@tonic-gate msg.key = *seg_id; 10957c478bd9Sstevel@tonic-gate msg.acl = access_list; 10967c478bd9Sstevel@tonic-gate msg.acl_len = access_list_length; 10977c478bd9Sstevel@tonic-gate 10987c478bd9Sstevel@tonic-gate if (ioctl(seg->rsmseg_fd, RSM_IOCTL_PUBLISH, &msg) < 0) { 10997c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11007c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 11017c478bd9Sstevel@tonic-gate "RSM_IOCTL_PUBLISH failed\n")); 11027c478bd9Sstevel@tonic-gate return (errno); 11037c478bd9Sstevel@tonic-gate } 11047c478bd9Sstevel@tonic-gate 11057c478bd9Sstevel@tonic-gate seg->rsmseg_keyid = msg.key; 11067c478bd9Sstevel@tonic-gate seg->rsmseg_state = EXPORT_PUBLISH; 11077c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11087c478bd9Sstevel@tonic-gate 11097c478bd9Sstevel@tonic-gate if (*seg_id == 0) 11107c478bd9Sstevel@tonic-gate *seg_id = msg.key; 11117c478bd9Sstevel@tonic-gate 11127c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 11137c478bd9Sstevel@tonic-gate "rsm_memseg_export_publish: exit\n")); 11147c478bd9Sstevel@tonic-gate 11157c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 11167c478bd9Sstevel@tonic-gate 11177c478bd9Sstevel@tonic-gate } 11187c478bd9Sstevel@tonic-gate 11197c478bd9Sstevel@tonic-gate int 11207c478bd9Sstevel@tonic-gate _rsm_memseg_export_unpublish(rsm_memseg_export_handle_t memseg) 11217c478bd9Sstevel@tonic-gate { 11227c478bd9Sstevel@tonic-gate rsm_ioctlmsg_t msg; 11237c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 11247c478bd9Sstevel@tonic-gate 11257c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 11267c478bd9Sstevel@tonic-gate "rsm_memseg_export_unpublish: enter\n")); 11277c478bd9Sstevel@tonic-gate 11287c478bd9Sstevel@tonic-gate if (!seg) { 11297c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 11307c478bd9Sstevel@tonic-gate "invalid arguments\n")); 11317c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 11327c478bd9Sstevel@tonic-gate } 11337c478bd9Sstevel@tonic-gate 11347c478bd9Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 11357c478bd9Sstevel@tonic-gate if (seg->rsmseg_state != EXPORT_PUBLISH) { 11367c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11377c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 11387c478bd9Sstevel@tonic-gate "segment not published %d\n", 11397c478bd9Sstevel@tonic-gate seg->rsmseg_keyid)); 11407c478bd9Sstevel@tonic-gate return (RSMERR_SEG_NOT_PUBLISHED); 11417c478bd9Sstevel@tonic-gate } 11427c478bd9Sstevel@tonic-gate 11437c478bd9Sstevel@tonic-gate msg.key = seg->rsmseg_keyid; 11447c478bd9Sstevel@tonic-gate if (ioctl(seg->rsmseg_fd, RSM_IOCTL_UNPUBLISH, &msg) < 0) { 11457c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11467c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 11477c478bd9Sstevel@tonic-gate "RSM_IOCTL_UNPUBLISH failed\n")); 11487c478bd9Sstevel@tonic-gate return (errno); 11497c478bd9Sstevel@tonic-gate } 11507c478bd9Sstevel@tonic-gate 11517c478bd9Sstevel@tonic-gate seg->rsmseg_state = EXPORT_BIND; 11527c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11537c478bd9Sstevel@tonic-gate 11547c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 11557c478bd9Sstevel@tonic-gate "rsm_memseg_export_unpublish: exit\n")); 11567c478bd9Sstevel@tonic-gate 11577c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 11587c478bd9Sstevel@tonic-gate } 11597c478bd9Sstevel@tonic-gate 11607c478bd9Sstevel@tonic-gate 11617c478bd9Sstevel@tonic-gate int 11627c478bd9Sstevel@tonic-gate _rsm_memseg_export_republish(rsm_memseg_export_handle_t memseg, 11637c478bd9Sstevel@tonic-gate rsmapi_access_entry_t access_list[], 11647c478bd9Sstevel@tonic-gate uint_t access_list_length) 11657c478bd9Sstevel@tonic-gate { 11667c478bd9Sstevel@tonic-gate rsm_ioctlmsg_t msg; 11677c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 11687c478bd9Sstevel@tonic-gate 11697c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 11707c478bd9Sstevel@tonic-gate "rsm_memseg_export_republish: enter\n")); 11717c478bd9Sstevel@tonic-gate 11727c478bd9Sstevel@tonic-gate if (!seg) { 11737c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 11747c478bd9Sstevel@tonic-gate "invalid segment or segment state\n")); 11757c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 11767c478bd9Sstevel@tonic-gate } 11777c478bd9Sstevel@tonic-gate 11787c478bd9Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 11797c478bd9Sstevel@tonic-gate if (seg->rsmseg_state != EXPORT_PUBLISH) { 11807c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11817c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 11827c478bd9Sstevel@tonic-gate "segment not published\n")); 11837c478bd9Sstevel@tonic-gate return (RSMERR_SEG_NOT_PUBLISHED); 11847c478bd9Sstevel@tonic-gate } 11857c478bd9Sstevel@tonic-gate 11867c478bd9Sstevel@tonic-gate if (access_list_length > 0 && !access_list) { 11877c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11887c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 11897c478bd9Sstevel@tonic-gate "invalid access control list\n")); 11907c478bd9Sstevel@tonic-gate return (RSMERR_BAD_ACL); 11917c478bd9Sstevel@tonic-gate } 11927c478bd9Sstevel@tonic-gate 11937c478bd9Sstevel@tonic-gate msg.key = seg->rsmseg_keyid; 11947c478bd9Sstevel@tonic-gate msg.acl = access_list; 11957c478bd9Sstevel@tonic-gate msg.acl_len = access_list_length; 11967c478bd9Sstevel@tonic-gate 11977c478bd9Sstevel@tonic-gate if (ioctl(seg->rsmseg_fd, RSM_IOCTL_REPUBLISH, &msg) < 0) { 11987c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 11997c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 12007c478bd9Sstevel@tonic-gate "RSM_IOCTL_REPUBLISH failed\n")); 12017c478bd9Sstevel@tonic-gate return (errno); 12027c478bd9Sstevel@tonic-gate } 12037c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 12047c478bd9Sstevel@tonic-gate 12057c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_DEBUG_VERBOSE, 12067c478bd9Sstevel@tonic-gate "rsm_memseg_export_republish: exit\n")); 12077c478bd9Sstevel@tonic-gate 12087c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 12097c478bd9Sstevel@tonic-gate } 12107c478bd9Sstevel@tonic-gate 12117c478bd9Sstevel@tonic-gate 12127c478bd9Sstevel@tonic-gate /* 12137c478bd9Sstevel@tonic-gate * import side memory segment operations: 12147c478bd9Sstevel@tonic-gate */ 12157c478bd9Sstevel@tonic-gate int 12167c478bd9Sstevel@tonic-gate _rsm_memseg_import_connect(rsmapi_controller_handle_t controller, 12177c478bd9Sstevel@tonic-gate rsm_node_id_t node_id, 12187c478bd9Sstevel@tonic-gate rsm_memseg_id_t segment_id, 12197c478bd9Sstevel@tonic-gate rsm_permission_t perm, 12207c478bd9Sstevel@tonic-gate rsm_memseg_import_handle_t *im_memseg) 12217c478bd9Sstevel@tonic-gate { 12227c478bd9Sstevel@tonic-gate rsm_ioctlmsg_t msg; 12237c478bd9Sstevel@tonic-gate rsmseg_handle_t *p; 12247c478bd9Sstevel@tonic-gate rsm_controller_t *cntr = (rsm_controller_t *)controller; 12257c478bd9Sstevel@tonic-gate #ifndef _LP64 /* added for fd > 255 fix */ 12267c478bd9Sstevel@tonic-gate int tmpfd; 12277c478bd9Sstevel@tonic-gate #endif 12287c478bd9Sstevel@tonic-gate int e; 12297c478bd9Sstevel@tonic-gate 12307c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 12317c478bd9Sstevel@tonic-gate "rsm_memseg_import_connect: enter\n")); 12327c478bd9Sstevel@tonic-gate 12337c478bd9Sstevel@tonic-gate if (!cntr) { 12347c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 12357c478bd9Sstevel@tonic-gate "invalid controller handle\n")); 12367c478bd9Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 12377c478bd9Sstevel@tonic-gate } 12387c478bd9Sstevel@tonic-gate 12397c478bd9Sstevel@tonic-gate *im_memseg = 0; 12407c478bd9Sstevel@tonic-gate 12417c478bd9Sstevel@tonic-gate p = (rsmseg_handle_t *)malloc(sizeof (*p)); 12427c478bd9Sstevel@tonic-gate if (!p) { 12437c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 12447c478bd9Sstevel@tonic-gate "not enough memory\n")); 12457c478bd9Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_MEM); 12467c478bd9Sstevel@tonic-gate } 12477c478bd9Sstevel@tonic-gate 12487c478bd9Sstevel@tonic-gate if (perm & ~RSM_PERM_RDWR) { 12497c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 12507c478bd9Sstevel@tonic-gate "invalid permissions\n")); 12517c478bd9Sstevel@tonic-gate return (RSMERR_PERM_DENIED); 12527c478bd9Sstevel@tonic-gate } 12537c478bd9Sstevel@tonic-gate 12547c478bd9Sstevel@tonic-gate /* 12557c478bd9Sstevel@tonic-gate * Get size, va from driver 12567c478bd9Sstevel@tonic-gate */ 12577c478bd9Sstevel@tonic-gate msg.cnum = cntr->cntr_unit; 12587c478bd9Sstevel@tonic-gate msg.cname = cntr->cntr_name; 12597c478bd9Sstevel@tonic-gate msg.cname_len = strlen(cntr->cntr_name) +1; 12607c478bd9Sstevel@tonic-gate msg.nodeid = node_id; 12617c478bd9Sstevel@tonic-gate msg.key = segment_id; 12627c478bd9Sstevel@tonic-gate msg.perm = perm; 12637c478bd9Sstevel@tonic-gate 12647c478bd9Sstevel@tonic-gate p->rsmseg_fd = open(DEVRSM, O_RDWR); 12657c478bd9Sstevel@tonic-gate if (p->rsmseg_fd < 0) { 12667c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 12677c478bd9Sstevel@tonic-gate "unable to open /dev/rsm")); 12687c478bd9Sstevel@tonic-gate free((void *)p); 12697c478bd9Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_RESOURCES); 12707c478bd9Sstevel@tonic-gate } 12717c478bd9Sstevel@tonic-gate 12727c478bd9Sstevel@tonic-gate #ifndef _LP64 12737c478bd9Sstevel@tonic-gate /* 12747c478bd9Sstevel@tonic-gate * libc can't handle fd's greater than 255, in order to 12757c478bd9Sstevel@tonic-gate * insure that these values remain available make /dev/rsm 12767c478bd9Sstevel@tonic-gate * fd > 255. Note: not needed for LP64 12777c478bd9Sstevel@tonic-gate */ 12787c478bd9Sstevel@tonic-gate tmpfd = fcntl(p->rsmseg_fd, F_DUPFD, 256); /* make fd > 255 */ 12797c478bd9Sstevel@tonic-gate e = errno; 12807c478bd9Sstevel@tonic-gate if (tmpfd < 0) { 12817c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 12827c478bd9Sstevel@tonic-gate "F_DUPFD failed\n")); 12837c478bd9Sstevel@tonic-gate } else { 12847c478bd9Sstevel@tonic-gate (void) close(p->rsmseg_fd); 12857c478bd9Sstevel@tonic-gate p->rsmseg_fd = tmpfd; 12867c478bd9Sstevel@tonic-gate } 12877c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 12887c478bd9Sstevel@tonic-gate 12897c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 12907c478bd9Sstevel@tonic-gate "rsmseg_fd is %d\n", p->rsmseg_fd)); 12917c478bd9Sstevel@tonic-gate 12927c478bd9Sstevel@tonic-gate if (fcntl(p->rsmseg_fd, F_SETFD, FD_CLOEXEC) < 0) { 12937c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 12947c478bd9Sstevel@tonic-gate "F_SETFD failed\n")); 12957c478bd9Sstevel@tonic-gate } 12967c478bd9Sstevel@tonic-gate if (ioctl(p->rsmseg_fd, RSM_IOCTL_CONNECT, &msg) < 0) { 12977c478bd9Sstevel@tonic-gate e = errno; 12987c478bd9Sstevel@tonic-gate (void) close(p->rsmseg_fd); 12997c478bd9Sstevel@tonic-gate free((void *)p); 13007c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 13017c478bd9Sstevel@tonic-gate "RSM_IOCTL_CONNECT failed\n")); 13027c478bd9Sstevel@tonic-gate return (e); 13037c478bd9Sstevel@tonic-gate } 13047c478bd9Sstevel@tonic-gate 13057c478bd9Sstevel@tonic-gate /* 13067c478bd9Sstevel@tonic-gate * We connected ok. 13077c478bd9Sstevel@tonic-gate */ 13087c478bd9Sstevel@tonic-gate p->rsmseg_type = RSM_IMPORT_SEG; 13097c478bd9Sstevel@tonic-gate p->rsmseg_state = IMPORT_CONNECT; 13107c478bd9Sstevel@tonic-gate p->rsmseg_keyid = segment_id; 13117c478bd9Sstevel@tonic-gate p->rsmseg_nodeid = node_id; 13127c478bd9Sstevel@tonic-gate p->rsmseg_size = msg.len; 13137c478bd9Sstevel@tonic-gate p->rsmseg_perm = perm; 13147c478bd9Sstevel@tonic-gate p->rsmseg_controller = cntr; 13157c478bd9Sstevel@tonic-gate p->rsmseg_barrier = NULL; 13167c478bd9Sstevel@tonic-gate p->rsmseg_barmode = RSM_BARRIER_MODE_IMPLICIT; 13177c478bd9Sstevel@tonic-gate p->rsmseg_bar = (bar_va ? bar_va + msg.off : &bar_fixed); 13187c478bd9Sstevel@tonic-gate p->rsmseg_gnum = msg.gnum; 13197c478bd9Sstevel@tonic-gate p->rsmseg_pollfd_refcnt = 0; 13207c478bd9Sstevel@tonic-gate p->rsmseg_maplen = 0; /* initialized, set in import_map */ 13217c478bd9Sstevel@tonic-gate p->rsmseg_mapoffset = 0; 13227c478bd9Sstevel@tonic-gate p->rsmseg_flags = 0; 13237c478bd9Sstevel@tonic-gate p->rsmseg_rnum = msg.rnum; 13247c478bd9Sstevel@tonic-gate mutex_init(&p->rsmseg_lock, USYNC_THREAD, NULL); 13257c478bd9Sstevel@tonic-gate 13267c478bd9Sstevel@tonic-gate p->rsmseg_ops = cntr->cntr_segops; 13277c478bd9Sstevel@tonic-gate 13287c478bd9Sstevel@tonic-gate /* 13297c478bd9Sstevel@tonic-gate * XXX: Based on permission and controller direct_access attribute 13307c478bd9Sstevel@tonic-gate * we fix the segment ops vector 13317c478bd9Sstevel@tonic-gate */ 13327c478bd9Sstevel@tonic-gate 13337c478bd9Sstevel@tonic-gate p->rsmseg_vaddr = 0; /* defer mapping till using maps or trys to rw */ 13347c478bd9Sstevel@tonic-gate 13357c478bd9Sstevel@tonic-gate *im_memseg = (rsm_memseg_import_handle_t)p; 13367c478bd9Sstevel@tonic-gate 13377c478bd9Sstevel@tonic-gate e = p->rsmseg_ops->rsm_memseg_import_connect(controller, 13387c478bd9Sstevel@tonic-gate node_id, segment_id, perm, im_memseg); 13397c478bd9Sstevel@tonic-gate 13407c478bd9Sstevel@tonic-gate if (e != RSM_SUCCESS) { 13417c478bd9Sstevel@tonic-gate (void) close(p->rsmseg_fd); 13427c478bd9Sstevel@tonic-gate mutex_destroy(&p->rsmseg_lock); 13437c478bd9Sstevel@tonic-gate free((void *)p); 13447c478bd9Sstevel@tonic-gate } 13457c478bd9Sstevel@tonic-gate 13467c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 13477c478bd9Sstevel@tonic-gate "rsm_memseg_import_connect: exit\n")); 13487c478bd9Sstevel@tonic-gate 13497c478bd9Sstevel@tonic-gate return (e); 13507c478bd9Sstevel@tonic-gate } 13517c478bd9Sstevel@tonic-gate 13527c478bd9Sstevel@tonic-gate 13537c478bd9Sstevel@tonic-gate int 13547c478bd9Sstevel@tonic-gate _rsm_memseg_import_disconnect(rsm_memseg_import_handle_t im_memseg) 13557c478bd9Sstevel@tonic-gate { 13567c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 13577c478bd9Sstevel@tonic-gate int e; 13587c478bd9Sstevel@tonic-gate 13597c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 13607c478bd9Sstevel@tonic-gate "rsm_memseg_import_disconnect: enter\n")); 13617c478bd9Sstevel@tonic-gate 13627c478bd9Sstevel@tonic-gate if (!seg) { 13637c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 13647c478bd9Sstevel@tonic-gate "invalid segment handle\n")); 13657c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 13667c478bd9Sstevel@tonic-gate } 13677c478bd9Sstevel@tonic-gate 13687c478bd9Sstevel@tonic-gate if (seg->rsmseg_state != IMPORT_CONNECT) { 13697c478bd9Sstevel@tonic-gate if (seg->rsmseg_flags & RSM_IMPLICIT_MAP) { 13707c478bd9Sstevel@tonic-gate e = rsm_memseg_import_unmap(im_memseg); 13717c478bd9Sstevel@tonic-gate if (e != RSM_SUCCESS) { 13727c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 13737c478bd9Sstevel@tonic-gate "unmap failure\n")); 13747c478bd9Sstevel@tonic-gate return (e); 13757c478bd9Sstevel@tonic-gate } 13767c478bd9Sstevel@tonic-gate } else { 13777c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 13787c478bd9Sstevel@tonic-gate "segment busy\n")); 13797c478bd9Sstevel@tonic-gate return (RSMERR_SEG_STILL_MAPPED); 13807c478bd9Sstevel@tonic-gate } 13817c478bd9Sstevel@tonic-gate } 13827c478bd9Sstevel@tonic-gate 13837c478bd9Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 13847c478bd9Sstevel@tonic-gate if (seg->rsmseg_pollfd_refcnt) { 13857c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 13867c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_EXPORT, RSM_ERR, 13877c478bd9Sstevel@tonic-gate "segment reference count not zero\n")); 13887c478bd9Sstevel@tonic-gate return (RSMERR_POLLFD_IN_USE); 13897c478bd9Sstevel@tonic-gate } 13907c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 13917c478bd9Sstevel@tonic-gate 13927c478bd9Sstevel@tonic-gate e = seg->rsmseg_ops->rsm_memseg_import_disconnect(im_memseg); 13937c478bd9Sstevel@tonic-gate 13947c478bd9Sstevel@tonic-gate if (e == RSM_SUCCESS) { 13957c478bd9Sstevel@tonic-gate (void) close(seg->rsmseg_fd); 13967c478bd9Sstevel@tonic-gate mutex_destroy(&seg->rsmseg_lock); 13977c478bd9Sstevel@tonic-gate free((void *)seg); 13987c478bd9Sstevel@tonic-gate } 13997c478bd9Sstevel@tonic-gate 14007c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 14017c478bd9Sstevel@tonic-gate "rsm_memseg_import_disconnect: exit\n")); 14027c478bd9Sstevel@tonic-gate 14037c478bd9Sstevel@tonic-gate return (e); 14047c478bd9Sstevel@tonic-gate } 14057c478bd9Sstevel@tonic-gate 14067c478bd9Sstevel@tonic-gate /* 14077c478bd9Sstevel@tonic-gate * import side memory segment operations (read access functions): 14087c478bd9Sstevel@tonic-gate */ 14097c478bd9Sstevel@tonic-gate 14107c478bd9Sstevel@tonic-gate static int 14117c478bd9Sstevel@tonic-gate __rsm_import_verify_access(rsmseg_handle_t *seg, 14127c478bd9Sstevel@tonic-gate off_t offset, 14137c478bd9Sstevel@tonic-gate caddr_t datap, 14147c478bd9Sstevel@tonic-gate size_t len, 14157c478bd9Sstevel@tonic-gate rsm_permission_t perm, 14167c478bd9Sstevel@tonic-gate rsm_access_size_t das) 14177c478bd9Sstevel@tonic-gate { 14187c478bd9Sstevel@tonic-gate int error; 14197c478bd9Sstevel@tonic-gate 14207c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 14217c478bd9Sstevel@tonic-gate " __rsm_import_verify_access: enter\n")); 14227c478bd9Sstevel@tonic-gate 14237c478bd9Sstevel@tonic-gate if (!seg) { 14247c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14257c478bd9Sstevel@tonic-gate "invalid segment handle\n")); 14267c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 14277c478bd9Sstevel@tonic-gate } 14287c478bd9Sstevel@tonic-gate if (!datap) { 14297c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14307c478bd9Sstevel@tonic-gate "invalid data pointer\n")); 14317c478bd9Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 14327c478bd9Sstevel@tonic-gate } 14337c478bd9Sstevel@tonic-gate 14347c478bd9Sstevel@tonic-gate /* 14357c478bd9Sstevel@tonic-gate * Check alignment of pointer 14367c478bd9Sstevel@tonic-gate */ 14377c478bd9Sstevel@tonic-gate if ((uintptr_t)datap & (das - 1)) { 14387c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14397c478bd9Sstevel@tonic-gate "invalid alignment of data pointer\n")); 14407c478bd9Sstevel@tonic-gate return (RSMERR_BAD_MEM_ALIGNMENT); 14417c478bd9Sstevel@tonic-gate } 14427c478bd9Sstevel@tonic-gate 14437c478bd9Sstevel@tonic-gate if (offset & (das - 1)) { 14447c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14457c478bd9Sstevel@tonic-gate "invalid offset\n")); 14467c478bd9Sstevel@tonic-gate return (RSMERR_BAD_MEM_ALIGNMENT); 14477c478bd9Sstevel@tonic-gate } 14487c478bd9Sstevel@tonic-gate 14497c478bd9Sstevel@tonic-gate /* make sure that the import seg is connected */ 14507c478bd9Sstevel@tonic-gate if (seg->rsmseg_state != IMPORT_CONNECT && 14517c478bd9Sstevel@tonic-gate seg->rsmseg_state != IMPORT_MAP) { 14527c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14537c478bd9Sstevel@tonic-gate "incorrect segment state\n")); 14547c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 14557c478bd9Sstevel@tonic-gate } 14567c478bd9Sstevel@tonic-gate 14577c478bd9Sstevel@tonic-gate /* do an implicit map if required */ 14587c478bd9Sstevel@tonic-gate if (seg->rsmseg_state == IMPORT_CONNECT) { 14597c478bd9Sstevel@tonic-gate error = __rsm_import_implicit_map(seg, RSM_IOTYPE_PUTGET); 14607c478bd9Sstevel@tonic-gate if (error != RSM_SUCCESS) { 14617c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14627c478bd9Sstevel@tonic-gate "implicit map failure\n")); 14637c478bd9Sstevel@tonic-gate return (error); 14647c478bd9Sstevel@tonic-gate } 14657c478bd9Sstevel@tonic-gate } 14667c478bd9Sstevel@tonic-gate 14677c478bd9Sstevel@tonic-gate if ((seg->rsmseg_perm & perm) != perm) { 14687c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14697c478bd9Sstevel@tonic-gate "invalid permissions\n")); 14707c478bd9Sstevel@tonic-gate return (RSMERR_PERM_DENIED); 14717c478bd9Sstevel@tonic-gate } 14727c478bd9Sstevel@tonic-gate 14737c478bd9Sstevel@tonic-gate if (seg->rsmseg_state == IMPORT_MAP) { 14747c478bd9Sstevel@tonic-gate if ((offset < seg->rsmseg_mapoffset) || 14757c478bd9Sstevel@tonic-gate (offset + len > seg->rsmseg_mapoffset + 14767c478bd9Sstevel@tonic-gate seg->rsmseg_maplen)) { 14777c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14787c478bd9Sstevel@tonic-gate "incorrect offset+length\n")); 14797c478bd9Sstevel@tonic-gate return (RSMERR_BAD_OFFSET); 14807c478bd9Sstevel@tonic-gate } 14817c478bd9Sstevel@tonic-gate } else { /* IMPORT_CONNECT */ 14827c478bd9Sstevel@tonic-gate if ((len + offset) > seg->rsmseg_size) { 14837c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14847c478bd9Sstevel@tonic-gate "incorrect offset+length\n")); 14857c478bd9Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 14867c478bd9Sstevel@tonic-gate } 14877c478bd9Sstevel@tonic-gate } 14887c478bd9Sstevel@tonic-gate 14897c478bd9Sstevel@tonic-gate if ((seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) && 14907c478bd9Sstevel@tonic-gate (seg->rsmseg_barrier == NULL)) { 14917c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 14927c478bd9Sstevel@tonic-gate "invalid barrier\n")); 14937c478bd9Sstevel@tonic-gate return (RSMERR_BARRIER_UNINITIALIZED); 14947c478bd9Sstevel@tonic-gate } 14957c478bd9Sstevel@tonic-gate 14967c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 14977c478bd9Sstevel@tonic-gate " __rsm_import_verify_access: exit\n")); 14987c478bd9Sstevel@tonic-gate 14997c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 15007c478bd9Sstevel@tonic-gate } 15017c478bd9Sstevel@tonic-gate 15027c478bd9Sstevel@tonic-gate static int 15037c478bd9Sstevel@tonic-gate __rsm_import_implicit_map(rsmseg_handle_t *seg, int iotype) 15047c478bd9Sstevel@tonic-gate { 15057c478bd9Sstevel@tonic-gate caddr_t va; 15067c478bd9Sstevel@tonic-gate int flag = MAP_SHARED; 15077c478bd9Sstevel@tonic-gate int prot = PROT_READ|PROT_WRITE; 15087c478bd9Sstevel@tonic-gate int mapping_reqd = 0; 15097c478bd9Sstevel@tonic-gate 15107c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 15117c478bd9Sstevel@tonic-gate " __rsm_import_implicit_map: enter\n")); 15127c478bd9Sstevel@tonic-gate 15137c478bd9Sstevel@tonic-gate if (iotype == RSM_IOTYPE_PUTGET) 15147c478bd9Sstevel@tonic-gate mapping_reqd = seg->rsmseg_controller->cntr_lib_attr-> 15157c478bd9Sstevel@tonic-gate rsm_putget_map_reqd; 15167c478bd9Sstevel@tonic-gate else if (iotype == RSM_IOTYPE_SCATGATH) 15177c478bd9Sstevel@tonic-gate mapping_reqd = seg->rsmseg_controller->cntr_lib_attr-> 15187c478bd9Sstevel@tonic-gate rsm_scatgath_map_reqd; 15197c478bd9Sstevel@tonic-gate 15207c478bd9Sstevel@tonic-gate 15217c478bd9Sstevel@tonic-gate if (mapping_reqd) { 15227c478bd9Sstevel@tonic-gate va = mmap(NULL, seg->rsmseg_size, prot, 15237c478bd9Sstevel@tonic-gate flag, seg->rsmseg_fd, 0); 15247c478bd9Sstevel@tonic-gate 15257c478bd9Sstevel@tonic-gate if (va == MAP_FAILED) { 15267c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 15277c478bd9Sstevel@tonic-gate "implicit map failed\n")); 15287c478bd9Sstevel@tonic-gate if (errno == ENOMEM || errno == ENXIO || 15297c478bd9Sstevel@tonic-gate errno == EOVERFLOW) 15307c478bd9Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 15317c478bd9Sstevel@tonic-gate else if (errno == ENODEV) 15327c478bd9Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 15337c478bd9Sstevel@tonic-gate else if (errno == EAGAIN) 15347c478bd9Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_RESOURCES); 15357c478bd9Sstevel@tonic-gate else if (errno == ENOTSUP) 15367c478bd9Sstevel@tonic-gate return (RSMERR_MAP_FAILED); 15377c478bd9Sstevel@tonic-gate else if (errno == EACCES) 15387c478bd9Sstevel@tonic-gate return (RSMERR_BAD_PERMS); 15397c478bd9Sstevel@tonic-gate else 15407c478bd9Sstevel@tonic-gate return (RSMERR_MAP_FAILED); 15417c478bd9Sstevel@tonic-gate } 15427c478bd9Sstevel@tonic-gate seg->rsmseg_vaddr = va; 15437c478bd9Sstevel@tonic-gate seg->rsmseg_maplen = seg->rsmseg_size; 15447c478bd9Sstevel@tonic-gate seg->rsmseg_mapoffset = 0; 15457c478bd9Sstevel@tonic-gate seg->rsmseg_state = IMPORT_MAP; 15467c478bd9Sstevel@tonic-gate seg->rsmseg_flags |= RSM_IMPLICIT_MAP; 15477c478bd9Sstevel@tonic-gate } 15487c478bd9Sstevel@tonic-gate 15497c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 15507c478bd9Sstevel@tonic-gate " __rsm_import_implicit_map: exit\n")); 15517c478bd9Sstevel@tonic-gate 15527c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 15537c478bd9Sstevel@tonic-gate } 15547c478bd9Sstevel@tonic-gate 15557c478bd9Sstevel@tonic-gate int 15567c478bd9Sstevel@tonic-gate _rsm_memseg_import_get8(rsm_memseg_import_handle_t im_memseg, 15577c478bd9Sstevel@tonic-gate off_t offset, 15587c478bd9Sstevel@tonic-gate uint8_t *datap, 15597c478bd9Sstevel@tonic-gate ulong_t rep_cnt) 15607c478bd9Sstevel@tonic-gate { 15617c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 15627c478bd9Sstevel@tonic-gate int e; 15637c478bd9Sstevel@tonic-gate 15647c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 15657c478bd9Sstevel@tonic-gate "rsm_memseg_import_get8: enter\n")); 15667c478bd9Sstevel@tonic-gate 15677c478bd9Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt, 15687c478bd9Sstevel@tonic-gate RSM_PERM_READ, 15697c478bd9Sstevel@tonic-gate RSM_DAS8); 15707c478bd9Sstevel@tonic-gate if (e == RSM_SUCCESS) { 15717c478bd9Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 15727c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 15737c478bd9Sstevel@tonic-gate 15747c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 15757c478bd9Sstevel@tonic-gate /* generation number snapshot */ 15767c478bd9Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 15777c478bd9Sstevel@tonic-gate } 15787c478bd9Sstevel@tonic-gate 15797c478bd9Sstevel@tonic-gate e = ops->rsm_memseg_import_get8(im_memseg, offset, datap, 15807c478bd9Sstevel@tonic-gate rep_cnt, 0); 15817c478bd9Sstevel@tonic-gate 15827c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 15837c478bd9Sstevel@tonic-gate /* check the generation number for force disconnects */ 15847c478bd9Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 15857c478bd9Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 15867c478bd9Sstevel@tonic-gate } 15877c478bd9Sstevel@tonic-gate } 15887c478bd9Sstevel@tonic-gate } 15897c478bd9Sstevel@tonic-gate 15907c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 15917c478bd9Sstevel@tonic-gate "rsm_memseg_import_get8: exit\n")); 15927c478bd9Sstevel@tonic-gate 15937c478bd9Sstevel@tonic-gate return (e); 15947c478bd9Sstevel@tonic-gate } 15957c478bd9Sstevel@tonic-gate 15967c478bd9Sstevel@tonic-gate int 15977c478bd9Sstevel@tonic-gate _rsm_memseg_import_get16(rsm_memseg_import_handle_t im_memseg, 15987c478bd9Sstevel@tonic-gate off_t offset, 15997c478bd9Sstevel@tonic-gate uint16_t *datap, 16007c478bd9Sstevel@tonic-gate ulong_t rep_cnt) 16017c478bd9Sstevel@tonic-gate { 16027c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 16037c478bd9Sstevel@tonic-gate int e; 16047c478bd9Sstevel@tonic-gate 16057c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 16067c478bd9Sstevel@tonic-gate "rsm_memseg_import_get16: enter\n")); 16077c478bd9Sstevel@tonic-gate 16087c478bd9Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*2, 16097c478bd9Sstevel@tonic-gate RSM_PERM_READ, 16107c478bd9Sstevel@tonic-gate RSM_DAS16); 16117c478bd9Sstevel@tonic-gate if (e == RSM_SUCCESS) { 16127c478bd9Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 16137c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 16147c478bd9Sstevel@tonic-gate 16157c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 16167c478bd9Sstevel@tonic-gate /* generation number snapshot */ 16177c478bd9Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 16187c478bd9Sstevel@tonic-gate } 16197c478bd9Sstevel@tonic-gate 16207c478bd9Sstevel@tonic-gate e = ops->rsm_memseg_import_get16(im_memseg, offset, datap, 16217c478bd9Sstevel@tonic-gate rep_cnt, 0); 16227c478bd9Sstevel@tonic-gate 16237c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 16247c478bd9Sstevel@tonic-gate /* check the generation number for force disconnects */ 16257c478bd9Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 16267c478bd9Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 16277c478bd9Sstevel@tonic-gate } 16287c478bd9Sstevel@tonic-gate } 16297c478bd9Sstevel@tonic-gate 16307c478bd9Sstevel@tonic-gate } 16317c478bd9Sstevel@tonic-gate 16327c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 16337c478bd9Sstevel@tonic-gate "rsm_memseg_import_get16: exit\n")); 16347c478bd9Sstevel@tonic-gate 16357c478bd9Sstevel@tonic-gate return (e); 16367c478bd9Sstevel@tonic-gate } 16377c478bd9Sstevel@tonic-gate 16387c478bd9Sstevel@tonic-gate int 16397c478bd9Sstevel@tonic-gate _rsm_memseg_import_get32(rsm_memseg_import_handle_t im_memseg, 16407c478bd9Sstevel@tonic-gate off_t offset, 16417c478bd9Sstevel@tonic-gate uint32_t *datap, 16427c478bd9Sstevel@tonic-gate ulong_t rep_cnt) 16437c478bd9Sstevel@tonic-gate { 16447c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 16457c478bd9Sstevel@tonic-gate int e; 16467c478bd9Sstevel@tonic-gate 16477c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 16487c478bd9Sstevel@tonic-gate "rsm_memseg_import_get32: enter\n")); 16497c478bd9Sstevel@tonic-gate 16507c478bd9Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*4, 16517c478bd9Sstevel@tonic-gate RSM_PERM_READ, 16527c478bd9Sstevel@tonic-gate RSM_DAS32); 16537c478bd9Sstevel@tonic-gate if (e == RSM_SUCCESS) { 16547c478bd9Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 16557c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 16567c478bd9Sstevel@tonic-gate 16577c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 16587c478bd9Sstevel@tonic-gate /* generation number snapshot */ 16597c478bd9Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 16607c478bd9Sstevel@tonic-gate } 16617c478bd9Sstevel@tonic-gate 16627c478bd9Sstevel@tonic-gate e = ops->rsm_memseg_import_get32(im_memseg, offset, datap, 16637c478bd9Sstevel@tonic-gate rep_cnt, 0); 16647c478bd9Sstevel@tonic-gate 16657c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 16667c478bd9Sstevel@tonic-gate /* check the generation number for force disconnects */ 16677c478bd9Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 16687c478bd9Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 16697c478bd9Sstevel@tonic-gate } 16707c478bd9Sstevel@tonic-gate } 16717c478bd9Sstevel@tonic-gate } 16727c478bd9Sstevel@tonic-gate 16737c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 16747c478bd9Sstevel@tonic-gate "rsm_memseg_import_get32: exit\n")); 16757c478bd9Sstevel@tonic-gate 16767c478bd9Sstevel@tonic-gate return (e); 16777c478bd9Sstevel@tonic-gate } 16787c478bd9Sstevel@tonic-gate 16797c478bd9Sstevel@tonic-gate int 16807c478bd9Sstevel@tonic-gate _rsm_memseg_import_get64(rsm_memseg_import_handle_t im_memseg, 16817c478bd9Sstevel@tonic-gate off_t offset, 16827c478bd9Sstevel@tonic-gate uint64_t *datap, 16837c478bd9Sstevel@tonic-gate ulong_t rep_cnt) 16847c478bd9Sstevel@tonic-gate { 16857c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 16867c478bd9Sstevel@tonic-gate int e; 16877c478bd9Sstevel@tonic-gate 16887c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 16897c478bd9Sstevel@tonic-gate "rsm_memseg_import_get64: enter\n")); 16907c478bd9Sstevel@tonic-gate 16917c478bd9Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*8, 16927c478bd9Sstevel@tonic-gate RSM_PERM_READ, 16937c478bd9Sstevel@tonic-gate RSM_DAS64); 16947c478bd9Sstevel@tonic-gate if (e == RSM_SUCCESS) { 16957c478bd9Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 16967c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 16977c478bd9Sstevel@tonic-gate 16987c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 16997c478bd9Sstevel@tonic-gate /* generation number snapshot */ 17007c478bd9Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 17017c478bd9Sstevel@tonic-gate } 17027c478bd9Sstevel@tonic-gate 17037c478bd9Sstevel@tonic-gate e = ops->rsm_memseg_import_get64(im_memseg, offset, datap, 17047c478bd9Sstevel@tonic-gate rep_cnt, 0); 17057c478bd9Sstevel@tonic-gate 17067c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 17077c478bd9Sstevel@tonic-gate /* check the generation number for force disconnects */ 17087c478bd9Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 17097c478bd9Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 17107c478bd9Sstevel@tonic-gate } 17117c478bd9Sstevel@tonic-gate } 17127c478bd9Sstevel@tonic-gate } 17137c478bd9Sstevel@tonic-gate 17147c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 17157c478bd9Sstevel@tonic-gate "rsm_memseg_import_get64: exit\n")); 17167c478bd9Sstevel@tonic-gate 17177c478bd9Sstevel@tonic-gate return (e); 17187c478bd9Sstevel@tonic-gate } 17197c478bd9Sstevel@tonic-gate 17207c478bd9Sstevel@tonic-gate int 17217c478bd9Sstevel@tonic-gate _rsm_memseg_import_get(rsm_memseg_import_handle_t im_memseg, 17227c478bd9Sstevel@tonic-gate off_t offset, 17237c478bd9Sstevel@tonic-gate void *dst_addr, 17247c478bd9Sstevel@tonic-gate size_t length) 17257c478bd9Sstevel@tonic-gate { 17267c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 17277c478bd9Sstevel@tonic-gate int e; 17287c478bd9Sstevel@tonic-gate 17297c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 17307c478bd9Sstevel@tonic-gate "rsm_memseg_import_get: enter\n")); 17317c478bd9Sstevel@tonic-gate 17327c478bd9Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)dst_addr, length, 17337c478bd9Sstevel@tonic-gate RSM_PERM_READ, 17347c478bd9Sstevel@tonic-gate RSM_DAS8); 17357c478bd9Sstevel@tonic-gate if (e == RSM_SUCCESS) { 17367c478bd9Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 17377c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 17387c478bd9Sstevel@tonic-gate 17397c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 17407c478bd9Sstevel@tonic-gate /* generation number snapshot */ 17417c478bd9Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 17427c478bd9Sstevel@tonic-gate } 17437c478bd9Sstevel@tonic-gate 17447c478bd9Sstevel@tonic-gate e = ops->rsm_memseg_import_get(im_memseg, offset, dst_addr, 17457c478bd9Sstevel@tonic-gate length); 17467c478bd9Sstevel@tonic-gate 17477c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 17487c478bd9Sstevel@tonic-gate /* check the generation number for force disconnects */ 17497c478bd9Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 17507c478bd9Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 17517c478bd9Sstevel@tonic-gate } 17527c478bd9Sstevel@tonic-gate } 17537c478bd9Sstevel@tonic-gate } 17547c478bd9Sstevel@tonic-gate 17557c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 17567c478bd9Sstevel@tonic-gate "rsm_memseg_import_get: exit\n")); 17577c478bd9Sstevel@tonic-gate 17587c478bd9Sstevel@tonic-gate return (e); 17597c478bd9Sstevel@tonic-gate } 17607c478bd9Sstevel@tonic-gate 17617c478bd9Sstevel@tonic-gate 17627c478bd9Sstevel@tonic-gate int 17637c478bd9Sstevel@tonic-gate _rsm_memseg_import_getv(rsm_scat_gath_t *sg_io) 17647c478bd9Sstevel@tonic-gate { 17657c478bd9Sstevel@tonic-gate rsm_controller_t *cntrl; 17667c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg; 17677c478bd9Sstevel@tonic-gate uint_t save_sg_io_flags; 17687c478bd9Sstevel@tonic-gate 17697c478bd9Sstevel@tonic-gate int e; 17707c478bd9Sstevel@tonic-gate 17717c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 17727c478bd9Sstevel@tonic-gate "rsm_memseg_import_getv: enter\n")); 17737c478bd9Sstevel@tonic-gate 17747c478bd9Sstevel@tonic-gate if (sg_io == NULL) { 17757c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 17767c478bd9Sstevel@tonic-gate "invalid sg_io structure\n")); 17777c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SGIO); 17787c478bd9Sstevel@tonic-gate } 17797c478bd9Sstevel@tonic-gate 17807c478bd9Sstevel@tonic-gate seg = (rsmseg_handle_t *)sg_io->remote_handle; 17817c478bd9Sstevel@tonic-gate if (seg == NULL) { 17827c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 17837c478bd9Sstevel@tonic-gate "invalid remote segment handle in sg_io\n")); 17847c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 17857c478bd9Sstevel@tonic-gate } 17867c478bd9Sstevel@tonic-gate 17877c478bd9Sstevel@tonic-gate cntrl = (rsm_controller_t *)seg->rsmseg_controller; 17887c478bd9Sstevel@tonic-gate if (cntrl == NULL) { 17897c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 17907c478bd9Sstevel@tonic-gate "invalid controller handle\n")); 17917c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 17927c478bd9Sstevel@tonic-gate } 17937c478bd9Sstevel@tonic-gate 17947c478bd9Sstevel@tonic-gate if ((sg_io->io_request_count > RSM_MAX_SGIOREQS) || 17957c478bd9Sstevel@tonic-gate (sg_io->io_request_count == 0)) { 17967c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 17977c478bd9Sstevel@tonic-gate "io_request_count value incorrect\n")); 17987c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SGIO); 17997c478bd9Sstevel@tonic-gate } 18007c478bd9Sstevel@tonic-gate 18017c478bd9Sstevel@tonic-gate if (seg->rsmseg_state == IMPORT_CONNECT) { 18027c478bd9Sstevel@tonic-gate e = __rsm_import_implicit_map(seg, RSM_IOTYPE_SCATGATH); 18037c478bd9Sstevel@tonic-gate if (e != RSM_SUCCESS) { 18047c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 18057c478bd9Sstevel@tonic-gate "implicit map failure\n")); 18067c478bd9Sstevel@tonic-gate return (e); 18077c478bd9Sstevel@tonic-gate } 18087c478bd9Sstevel@tonic-gate } 18097c478bd9Sstevel@tonic-gate 18107c478bd9Sstevel@tonic-gate /* 18117c478bd9Sstevel@tonic-gate * Copy the flags field of the sg_io structure in a local 18127c478bd9Sstevel@tonic-gate * variable. 18137c478bd9Sstevel@tonic-gate * This is required since the flags field can be 18147c478bd9Sstevel@tonic-gate * changed by the plugin library routine to indicate that 18157c478bd9Sstevel@tonic-gate * the signal post was done. 18167c478bd9Sstevel@tonic-gate * This change in the flags field of the sg_io structure 18177c478bd9Sstevel@tonic-gate * should not be reflected to the user. Hence once the flags 18187c478bd9Sstevel@tonic-gate * field has been used for the purpose of determining whether 18197c478bd9Sstevel@tonic-gate * the plugin executed a signal post, it must be restored to 18207c478bd9Sstevel@tonic-gate * its original value which is stored in the local variable. 18217c478bd9Sstevel@tonic-gate */ 18227c478bd9Sstevel@tonic-gate save_sg_io_flags = sg_io->flags; 18237c478bd9Sstevel@tonic-gate 18247c478bd9Sstevel@tonic-gate e = cntrl->cntr_segops->rsm_memseg_import_getv(sg_io); 18257c478bd9Sstevel@tonic-gate 18267c478bd9Sstevel@tonic-gate /* 18277c478bd9Sstevel@tonic-gate * At this point, if an implicit signal post was requested by 18287c478bd9Sstevel@tonic-gate * the user, there could be two possibilities that arise: 18297c478bd9Sstevel@tonic-gate * 1. the plugin routine has already executed the implicit 18307c478bd9Sstevel@tonic-gate * signal post either successfully or unsuccessfully 18317c478bd9Sstevel@tonic-gate * 2. the plugin does not have the capability of doing an 18327c478bd9Sstevel@tonic-gate * implicit signal post and hence the signal post needs 18337c478bd9Sstevel@tonic-gate * to be done here. 18347c478bd9Sstevel@tonic-gate * The above two cases can be idenfied by the flags 18357c478bd9Sstevel@tonic-gate * field within the sg_io structure as follows: 18367c478bd9Sstevel@tonic-gate * In case 1, the RSM_IMPLICIT_SIGPOST bit is reset to 0 by the 18377c478bd9Sstevel@tonic-gate * plugin, indicating that the signal post was done. 18387c478bd9Sstevel@tonic-gate * In case 2, the bit remains set to a 1 as originally given 18397c478bd9Sstevel@tonic-gate * by the user, and hence a signal post needs to be done here. 18407c478bd9Sstevel@tonic-gate */ 18417c478bd9Sstevel@tonic-gate if (sg_io->flags & RSM_IMPLICIT_SIGPOST && 18427c478bd9Sstevel@tonic-gate e == RSM_SUCCESS) { 18437c478bd9Sstevel@tonic-gate /* Do the implicit signal post */ 18447c478bd9Sstevel@tonic-gate 18457c478bd9Sstevel@tonic-gate /* 18467c478bd9Sstevel@tonic-gate * The value of the second argument to this call 18477c478bd9Sstevel@tonic-gate * depends on the value of the sg_io->flags field. 18487c478bd9Sstevel@tonic-gate * If the RSM_SIGPOST_NO_ACCUMULATE flag has been 18497c478bd9Sstevel@tonic-gate * ored into the sg_io->flags field, this indicates 18507c478bd9Sstevel@tonic-gate * that the rsm_intr_signal_post is to be done with 18517c478bd9Sstevel@tonic-gate * the flags argument set to RSM_SIGPOST_NO_ACCUMULATE 18527c478bd9Sstevel@tonic-gate * Else, the flags argument is set to 0. These 18537c478bd9Sstevel@tonic-gate * semantics can be achieved simply by masking off 18547c478bd9Sstevel@tonic-gate * all other bits in the sg_io->flags field except the 18557c478bd9Sstevel@tonic-gate * RSM_SIGPOST_NO_ACCUMULATE bit and using the result 18567c478bd9Sstevel@tonic-gate * as the flags argument for the rsm_intr_signal_post. 18577c478bd9Sstevel@tonic-gate */ 18587c478bd9Sstevel@tonic-gate 18597c478bd9Sstevel@tonic-gate int sigpost_flags = sg_io->flags & RSM_SIGPOST_NO_ACCUMULATE; 18607c478bd9Sstevel@tonic-gate e = rsm_intr_signal_post(seg, sigpost_flags); 18617c478bd9Sstevel@tonic-gate } 18627c478bd9Sstevel@tonic-gate 18637c478bd9Sstevel@tonic-gate /* Restore the flags field within the users scatter gather structure */ 18647c478bd9Sstevel@tonic-gate sg_io->flags = save_sg_io_flags; 18657c478bd9Sstevel@tonic-gate 18667c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 18677c478bd9Sstevel@tonic-gate "rsm_memseg_import_getv: exit\n")); 18687c478bd9Sstevel@tonic-gate 18697c478bd9Sstevel@tonic-gate return (e); 18707c478bd9Sstevel@tonic-gate 18717c478bd9Sstevel@tonic-gate } 18727c478bd9Sstevel@tonic-gate 18737c478bd9Sstevel@tonic-gate /* 18747c478bd9Sstevel@tonic-gate * import side memory segment operations (write access functions): 18757c478bd9Sstevel@tonic-gate */ 18767c478bd9Sstevel@tonic-gate 18777c478bd9Sstevel@tonic-gate int 18787c478bd9Sstevel@tonic-gate _rsm_memseg_import_put8(rsm_memseg_import_handle_t im_memseg, 18797c478bd9Sstevel@tonic-gate off_t offset, 18807c478bd9Sstevel@tonic-gate uint8_t *datap, 18817c478bd9Sstevel@tonic-gate ulong_t rep_cnt) 18827c478bd9Sstevel@tonic-gate { 18837c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 18847c478bd9Sstevel@tonic-gate int e; 18857c478bd9Sstevel@tonic-gate 18867c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 18877c478bd9Sstevel@tonic-gate "rsm_memseg_import_put8: enter\n")); 18887c478bd9Sstevel@tonic-gate 18897c478bd9Sstevel@tonic-gate /* addr of data will always pass the alignment check, avoids */ 18907c478bd9Sstevel@tonic-gate /* need for a special case in verify_access for PUTs */ 18917c478bd9Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt, 18927c478bd9Sstevel@tonic-gate RSM_PERM_WRITE, 18937c478bd9Sstevel@tonic-gate RSM_DAS8); 18947c478bd9Sstevel@tonic-gate if (e == RSM_SUCCESS) { 18957c478bd9Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 18967c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 18977c478bd9Sstevel@tonic-gate 18987c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 18997c478bd9Sstevel@tonic-gate /* generation number snapshot */ 19007c478bd9Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 19017c478bd9Sstevel@tonic-gate } 19027c478bd9Sstevel@tonic-gate 19037c478bd9Sstevel@tonic-gate e = ops->rsm_memseg_import_put8(im_memseg, offset, datap, 19047c478bd9Sstevel@tonic-gate rep_cnt, 0); 19057c478bd9Sstevel@tonic-gate 19067c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 19077c478bd9Sstevel@tonic-gate /* check the generation number for force disconnects */ 19087c478bd9Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 19097c478bd9Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 19107c478bd9Sstevel@tonic-gate } 19117c478bd9Sstevel@tonic-gate } 19127c478bd9Sstevel@tonic-gate } 19137c478bd9Sstevel@tonic-gate 19147c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 19157c478bd9Sstevel@tonic-gate "rsm_memseg_import_put8: exit\n")); 19167c478bd9Sstevel@tonic-gate 19177c478bd9Sstevel@tonic-gate return (e); 19187c478bd9Sstevel@tonic-gate } 19197c478bd9Sstevel@tonic-gate 19207c478bd9Sstevel@tonic-gate int 19217c478bd9Sstevel@tonic-gate _rsm_memseg_import_put16(rsm_memseg_import_handle_t im_memseg, 19227c478bd9Sstevel@tonic-gate off_t offset, 19237c478bd9Sstevel@tonic-gate uint16_t *datap, 19247c478bd9Sstevel@tonic-gate ulong_t rep_cnt) 19257c478bd9Sstevel@tonic-gate { 19267c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 19277c478bd9Sstevel@tonic-gate int e; 19287c478bd9Sstevel@tonic-gate 19297c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 19307c478bd9Sstevel@tonic-gate "rsm_memseg_import_put16: enter\n")); 19317c478bd9Sstevel@tonic-gate 19327c478bd9Sstevel@tonic-gate /* addr of data will always pass the alignment check, avoids */ 19337c478bd9Sstevel@tonic-gate /* need for a special case in verify_access for PUTs */ 19347c478bd9Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*2, 19357c478bd9Sstevel@tonic-gate RSM_PERM_WRITE, 19367c478bd9Sstevel@tonic-gate RSM_DAS16); 19377c478bd9Sstevel@tonic-gate if (e == RSM_SUCCESS) { 19387c478bd9Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 19397c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 19407c478bd9Sstevel@tonic-gate 19417c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 19427c478bd9Sstevel@tonic-gate /* generation number snapshot */ 19437c478bd9Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 19447c478bd9Sstevel@tonic-gate } 19457c478bd9Sstevel@tonic-gate 19467c478bd9Sstevel@tonic-gate e = ops->rsm_memseg_import_put16(im_memseg, offset, datap, 19477c478bd9Sstevel@tonic-gate rep_cnt, 0); 19487c478bd9Sstevel@tonic-gate 19497c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 19507c478bd9Sstevel@tonic-gate /* check the generation number for force disconnects */ 19517c478bd9Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 19527c478bd9Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 19537c478bd9Sstevel@tonic-gate } 19547c478bd9Sstevel@tonic-gate } 19557c478bd9Sstevel@tonic-gate 19567c478bd9Sstevel@tonic-gate } 19577c478bd9Sstevel@tonic-gate 19587c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 19597c478bd9Sstevel@tonic-gate "rsm_memseg_import_put16: exit\n")); 19607c478bd9Sstevel@tonic-gate 19617c478bd9Sstevel@tonic-gate return (e); 19627c478bd9Sstevel@tonic-gate } 19637c478bd9Sstevel@tonic-gate 19647c478bd9Sstevel@tonic-gate int 19657c478bd9Sstevel@tonic-gate _rsm_memseg_import_put32(rsm_memseg_import_handle_t im_memseg, 19667c478bd9Sstevel@tonic-gate off_t offset, 19677c478bd9Sstevel@tonic-gate uint32_t *datap, 19687c478bd9Sstevel@tonic-gate ulong_t rep_cnt) 19697c478bd9Sstevel@tonic-gate { 19707c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 19717c478bd9Sstevel@tonic-gate int e; 19727c478bd9Sstevel@tonic-gate 19737c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 19747c478bd9Sstevel@tonic-gate "rsm_memseg_import_put32: enter\n")); 19757c478bd9Sstevel@tonic-gate 19767c478bd9Sstevel@tonic-gate /* addr of data will always pass the alignment check, avoids */ 19777c478bd9Sstevel@tonic-gate /* need for a special case in verify_access for PUTs */ 19787c478bd9Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*4, 19797c478bd9Sstevel@tonic-gate RSM_PERM_WRITE, 19807c478bd9Sstevel@tonic-gate RSM_DAS32); 19817c478bd9Sstevel@tonic-gate if (e == RSM_SUCCESS) { 19827c478bd9Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 19837c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 19847c478bd9Sstevel@tonic-gate 19857c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 19867c478bd9Sstevel@tonic-gate /* generation number snapshot */ 19877c478bd9Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 19887c478bd9Sstevel@tonic-gate } 19897c478bd9Sstevel@tonic-gate 19907c478bd9Sstevel@tonic-gate e = ops->rsm_memseg_import_put32(im_memseg, offset, datap, 19917c478bd9Sstevel@tonic-gate rep_cnt, 0); 19927c478bd9Sstevel@tonic-gate 19937c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 19947c478bd9Sstevel@tonic-gate /* check the generation number for force disconnects */ 19957c478bd9Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 19967c478bd9Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 19977c478bd9Sstevel@tonic-gate } 19987c478bd9Sstevel@tonic-gate } 19997c478bd9Sstevel@tonic-gate } 20007c478bd9Sstevel@tonic-gate 20017c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 20027c478bd9Sstevel@tonic-gate "rsm_memseg_import_put32: exit\n")); 20037c478bd9Sstevel@tonic-gate 20047c478bd9Sstevel@tonic-gate return (e); 20057c478bd9Sstevel@tonic-gate } 20067c478bd9Sstevel@tonic-gate 20077c478bd9Sstevel@tonic-gate int 20087c478bd9Sstevel@tonic-gate _rsm_memseg_import_put64(rsm_memseg_import_handle_t im_memseg, 20097c478bd9Sstevel@tonic-gate off_t offset, 20107c478bd9Sstevel@tonic-gate uint64_t *datap, 20117c478bd9Sstevel@tonic-gate ulong_t rep_cnt) 20127c478bd9Sstevel@tonic-gate { 20137c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 20147c478bd9Sstevel@tonic-gate int e; 20157c478bd9Sstevel@tonic-gate 20167c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 20177c478bd9Sstevel@tonic-gate "rsm_memseg_import_put64: enter\n")); 20187c478bd9Sstevel@tonic-gate 20197c478bd9Sstevel@tonic-gate /* addr of data will always pass the alignment check, avoids */ 20207c478bd9Sstevel@tonic-gate /* need for a special case in verify_access for PUTs */ 20217c478bd9Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)datap, rep_cnt*8, 20227c478bd9Sstevel@tonic-gate RSM_PERM_WRITE, 20237c478bd9Sstevel@tonic-gate RSM_DAS64); 20247c478bd9Sstevel@tonic-gate if (e == RSM_SUCCESS) { 20257c478bd9Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 20267c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 20277c478bd9Sstevel@tonic-gate 20287c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 20297c478bd9Sstevel@tonic-gate /* generation number snapshot */ 20307c478bd9Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 20317c478bd9Sstevel@tonic-gate } 20327c478bd9Sstevel@tonic-gate 20337c478bd9Sstevel@tonic-gate e = ops->rsm_memseg_import_put64(im_memseg, offset, datap, 20347c478bd9Sstevel@tonic-gate rep_cnt, 0); 20357c478bd9Sstevel@tonic-gate 20367c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 20377c478bd9Sstevel@tonic-gate /* check the generation number for force disconnects */ 20387c478bd9Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 20397c478bd9Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 20407c478bd9Sstevel@tonic-gate } 20417c478bd9Sstevel@tonic-gate } 20427c478bd9Sstevel@tonic-gate } 20437c478bd9Sstevel@tonic-gate 20447c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 20457c478bd9Sstevel@tonic-gate "rsm_memseg_import_put64: exit\n")); 20467c478bd9Sstevel@tonic-gate 20477c478bd9Sstevel@tonic-gate return (e); 20487c478bd9Sstevel@tonic-gate } 20497c478bd9Sstevel@tonic-gate 20507c478bd9Sstevel@tonic-gate int 20517c478bd9Sstevel@tonic-gate _rsm_memseg_import_put(rsm_memseg_import_handle_t im_memseg, 20527c478bd9Sstevel@tonic-gate off_t offset, 20537c478bd9Sstevel@tonic-gate void *src_addr, 20547c478bd9Sstevel@tonic-gate size_t length) 20557c478bd9Sstevel@tonic-gate { 20567c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 20577c478bd9Sstevel@tonic-gate int e; 20587c478bd9Sstevel@tonic-gate 20597c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 20607c478bd9Sstevel@tonic-gate "rsm_memseg_import_put: enter\n")); 20617c478bd9Sstevel@tonic-gate 20627c478bd9Sstevel@tonic-gate e = __rsm_import_verify_access(seg, offset, (caddr_t)src_addr, length, 20637c478bd9Sstevel@tonic-gate RSM_PERM_WRITE, 20647c478bd9Sstevel@tonic-gate RSM_DAS8); 20657c478bd9Sstevel@tonic-gate if (e == RSM_SUCCESS) { 20667c478bd9Sstevel@tonic-gate rsm_segops_t *ops = seg->rsmseg_ops; 20677c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)seg->rsmseg_barrier; 20687c478bd9Sstevel@tonic-gate 20697c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 20707c478bd9Sstevel@tonic-gate /* generation number snapshot */ 20717c478bd9Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; 20727c478bd9Sstevel@tonic-gate } 20737c478bd9Sstevel@tonic-gate 20747c478bd9Sstevel@tonic-gate e = ops->rsm_memseg_import_put(im_memseg, offset, src_addr, 20757c478bd9Sstevel@tonic-gate length); 20767c478bd9Sstevel@tonic-gate 20777c478bd9Sstevel@tonic-gate if (seg->rsmseg_barmode == RSM_BARRIER_MODE_IMPLICIT) { 20787c478bd9Sstevel@tonic-gate /* check the generation number for force disconnects */ 20797c478bd9Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 20807c478bd9Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 20817c478bd9Sstevel@tonic-gate } 20827c478bd9Sstevel@tonic-gate } 20837c478bd9Sstevel@tonic-gate 20847c478bd9Sstevel@tonic-gate } 20857c478bd9Sstevel@tonic-gate 20867c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 20877c478bd9Sstevel@tonic-gate "rsm_memseg_import_put: exit\n")); 20887c478bd9Sstevel@tonic-gate return (e); 20897c478bd9Sstevel@tonic-gate } 20907c478bd9Sstevel@tonic-gate 20917c478bd9Sstevel@tonic-gate 20927c478bd9Sstevel@tonic-gate int 20937c478bd9Sstevel@tonic-gate _rsm_memseg_import_putv(rsm_scat_gath_t *sg_io) 20947c478bd9Sstevel@tonic-gate { 20957c478bd9Sstevel@tonic-gate rsm_controller_t *cntrl; 20967c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg; 20977c478bd9Sstevel@tonic-gate uint_t save_sg_io_flags; 20987c478bd9Sstevel@tonic-gate 20997c478bd9Sstevel@tonic-gate int e; 21007c478bd9Sstevel@tonic-gate 21017c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 21027c478bd9Sstevel@tonic-gate "rsm_memseg_import_putv: enter\n")); 21037c478bd9Sstevel@tonic-gate 21047c478bd9Sstevel@tonic-gate 21057c478bd9Sstevel@tonic-gate if (sg_io == NULL) { 21067c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 21077c478bd9Sstevel@tonic-gate "invalid sg_io structure\n")); 21087c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SGIO); 21097c478bd9Sstevel@tonic-gate } 21107c478bd9Sstevel@tonic-gate 21117c478bd9Sstevel@tonic-gate seg = (rsmseg_handle_t *)sg_io->remote_handle; 21127c478bd9Sstevel@tonic-gate if (seg == NULL) { 21137c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 21147c478bd9Sstevel@tonic-gate "invalid remote segment handle in sg_io\n")); 21157c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 21167c478bd9Sstevel@tonic-gate } 21177c478bd9Sstevel@tonic-gate 21187c478bd9Sstevel@tonic-gate cntrl = (rsm_controller_t *)seg->rsmseg_controller; 21197c478bd9Sstevel@tonic-gate if (cntrl == NULL) { 21207c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 21217c478bd9Sstevel@tonic-gate "invalid controller handle\n")); 21227c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 21237c478bd9Sstevel@tonic-gate } 21247c478bd9Sstevel@tonic-gate 21257c478bd9Sstevel@tonic-gate if ((sg_io->io_request_count > RSM_MAX_SGIOREQS) || 21267c478bd9Sstevel@tonic-gate (sg_io->io_request_count == 0)) { 21277c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 21287c478bd9Sstevel@tonic-gate "io_request_count value incorrect\n")); 21297c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SGIO); 21307c478bd9Sstevel@tonic-gate } 21317c478bd9Sstevel@tonic-gate 21327c478bd9Sstevel@tonic-gate /* do an implicit map if required */ 21337c478bd9Sstevel@tonic-gate if (seg->rsmseg_state == IMPORT_CONNECT) { 21347c478bd9Sstevel@tonic-gate e = __rsm_import_implicit_map(seg, RSM_IOTYPE_SCATGATH); 21357c478bd9Sstevel@tonic-gate if (e != RSM_SUCCESS) { 21367c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 21377c478bd9Sstevel@tonic-gate "implicit map failed\n")); 21387c478bd9Sstevel@tonic-gate return (e); 21397c478bd9Sstevel@tonic-gate } 21407c478bd9Sstevel@tonic-gate } 21417c478bd9Sstevel@tonic-gate 21427c478bd9Sstevel@tonic-gate /* 21437c478bd9Sstevel@tonic-gate * Copy the flags field of the sg_io structure in a local 21447c478bd9Sstevel@tonic-gate * variable. 21457c478bd9Sstevel@tonic-gate * This is required since the flags field can be 21467c478bd9Sstevel@tonic-gate * changed by the plugin library routine to indicate that 21477c478bd9Sstevel@tonic-gate * the signal post was done. 21487c478bd9Sstevel@tonic-gate * This change in the flags field of the sg_io structure 21497c478bd9Sstevel@tonic-gate * should not be reflected to the user. Hence once the flags 21507c478bd9Sstevel@tonic-gate * field has been used for the purpose of determining whether 21517c478bd9Sstevel@tonic-gate * the plugin executed a signal post, it must be restored to 21527c478bd9Sstevel@tonic-gate * its original value which is stored in the local variable. 21537c478bd9Sstevel@tonic-gate */ 21547c478bd9Sstevel@tonic-gate save_sg_io_flags = sg_io->flags; 21557c478bd9Sstevel@tonic-gate 21567c478bd9Sstevel@tonic-gate e = cntrl->cntr_segops->rsm_memseg_import_putv(sg_io); 21577c478bd9Sstevel@tonic-gate 21587c478bd9Sstevel@tonic-gate /* 21597c478bd9Sstevel@tonic-gate * At this point, if an implicit signal post was requested by 21607c478bd9Sstevel@tonic-gate * the user, there could be two possibilities that arise: 21617c478bd9Sstevel@tonic-gate * 1. the plugin routine has already executed the implicit 21627c478bd9Sstevel@tonic-gate * signal post either successfully or unsuccessfully 21637c478bd9Sstevel@tonic-gate * 2. the plugin does not have the capability of doing an 21647c478bd9Sstevel@tonic-gate * implicit signal post and hence the signal post needs 21657c478bd9Sstevel@tonic-gate * to be done here. 21667c478bd9Sstevel@tonic-gate * The above two cases can be idenfied by the flags 21677c478bd9Sstevel@tonic-gate * field within the sg_io structure as follows: 21687c478bd9Sstevel@tonic-gate * In case 1, the RSM_IMPLICIT_SIGPOST bit is reset to 0 by the 21697c478bd9Sstevel@tonic-gate * plugin, indicating that the signal post was done. 21707c478bd9Sstevel@tonic-gate * In case 2, the bit remains set to a 1 as originally given 21717c478bd9Sstevel@tonic-gate * by the user, and hence a signal post needs to be done here. 21727c478bd9Sstevel@tonic-gate */ 21737c478bd9Sstevel@tonic-gate if (sg_io->flags & RSM_IMPLICIT_SIGPOST && 21747c478bd9Sstevel@tonic-gate e == RSM_SUCCESS) { 21757c478bd9Sstevel@tonic-gate /* Do the implicit signal post */ 21767c478bd9Sstevel@tonic-gate 21777c478bd9Sstevel@tonic-gate /* 21787c478bd9Sstevel@tonic-gate * The value of the second argument to this call 21797c478bd9Sstevel@tonic-gate * depends on the value of the sg_io->flags field. 21807c478bd9Sstevel@tonic-gate * If the RSM_SIGPOST_NO_ACCUMULATE flag has been 21817c478bd9Sstevel@tonic-gate * ored into the sg_io->flags field, this indicates 21827c478bd9Sstevel@tonic-gate * that the rsm_intr_signal_post is to be done with 21837c478bd9Sstevel@tonic-gate * the flags argument set to RSM_SIGPOST_NO_ACCUMULATE 21847c478bd9Sstevel@tonic-gate * Else, the flags argument is set to 0. These 21857c478bd9Sstevel@tonic-gate * semantics can be achieved simply by masking off 21867c478bd9Sstevel@tonic-gate * all other bits in the sg_io->flags field except the 21877c478bd9Sstevel@tonic-gate * RSM_SIGPOST_NO_ACCUMULATE bit and using the result 21887c478bd9Sstevel@tonic-gate * as the flags argument for the rsm_intr_signal_post. 21897c478bd9Sstevel@tonic-gate */ 21907c478bd9Sstevel@tonic-gate 21917c478bd9Sstevel@tonic-gate int sigpost_flags = sg_io->flags & RSM_SIGPOST_NO_ACCUMULATE; 21927c478bd9Sstevel@tonic-gate e = rsm_intr_signal_post(seg, sigpost_flags); 21937c478bd9Sstevel@tonic-gate 21947c478bd9Sstevel@tonic-gate } 21957c478bd9Sstevel@tonic-gate 21967c478bd9Sstevel@tonic-gate /* Restore the flags field within the users scatter gather structure */ 21977c478bd9Sstevel@tonic-gate sg_io->flags = save_sg_io_flags; 21987c478bd9Sstevel@tonic-gate 21997c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 22007c478bd9Sstevel@tonic-gate "rsm_memseg_import_putv: exit\n")); 22017c478bd9Sstevel@tonic-gate 22027c478bd9Sstevel@tonic-gate return (e); 22037c478bd9Sstevel@tonic-gate } 22047c478bd9Sstevel@tonic-gate 22057c478bd9Sstevel@tonic-gate 22067c478bd9Sstevel@tonic-gate /* 22077c478bd9Sstevel@tonic-gate * import side memory segment operations (mapping): 22087c478bd9Sstevel@tonic-gate */ 22097c478bd9Sstevel@tonic-gate int 22107c478bd9Sstevel@tonic-gate _rsm_memseg_import_map(rsm_memseg_import_handle_t im_memseg, 22117c478bd9Sstevel@tonic-gate void **address, 22127c478bd9Sstevel@tonic-gate rsm_attribute_t attr, 22137c478bd9Sstevel@tonic-gate rsm_permission_t perm, 22147c478bd9Sstevel@tonic-gate off_t offset, 22157c478bd9Sstevel@tonic-gate size_t length) 22167c478bd9Sstevel@tonic-gate { 22177c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 22187c478bd9Sstevel@tonic-gate int flag = MAP_SHARED; 22197c478bd9Sstevel@tonic-gate int prot; 22207c478bd9Sstevel@tonic-gate caddr_t va; 22217c478bd9Sstevel@tonic-gate 22227c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 22237c478bd9Sstevel@tonic-gate "rsm_memseg_import_map: enter\n")); 22247c478bd9Sstevel@tonic-gate 22257c478bd9Sstevel@tonic-gate if (!seg) { 22267c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 22277c478bd9Sstevel@tonic-gate "invalid segment\n")); 22287c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 22297c478bd9Sstevel@tonic-gate } 22307c478bd9Sstevel@tonic-gate if (!address) { 22317c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 22327c478bd9Sstevel@tonic-gate "invalid address\n")); 22337c478bd9Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 22347c478bd9Sstevel@tonic-gate } 22357c478bd9Sstevel@tonic-gate 22367c478bd9Sstevel@tonic-gate /* 22377c478bd9Sstevel@tonic-gate * Only one map per segment handle! 22387c478bd9Sstevel@tonic-gate * XXX need to take a lock here 22397c478bd9Sstevel@tonic-gate */ 22407c478bd9Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 22417c478bd9Sstevel@tonic-gate 22427c478bd9Sstevel@tonic-gate if (seg->rsmseg_state == IMPORT_MAP) { 22437c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 22447c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 22457c478bd9Sstevel@tonic-gate "segment already mapped\n")); 22467c478bd9Sstevel@tonic-gate return (RSMERR_SEG_ALREADY_MAPPED); 22477c478bd9Sstevel@tonic-gate } 22487c478bd9Sstevel@tonic-gate 22497c478bd9Sstevel@tonic-gate /* Only import segments allowed to map */ 22507c478bd9Sstevel@tonic-gate if (seg->rsmseg_state != IMPORT_CONNECT) { 22517c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 22527c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 22537c478bd9Sstevel@tonic-gate } 22547c478bd9Sstevel@tonic-gate 22557c478bd9Sstevel@tonic-gate /* check for permissions */ 22567c478bd9Sstevel@tonic-gate if (perm > RSM_PERM_RDWR) { 22577c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 22587c478bd9Sstevel@tonic-gate "bad permissions when mapping\n")); 22597c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 22607c478bd9Sstevel@tonic-gate return (RSMERR_BAD_PERMS); 22617c478bd9Sstevel@tonic-gate } 22627c478bd9Sstevel@tonic-gate 22637c478bd9Sstevel@tonic-gate if (length == 0) { 22647c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 22657c478bd9Sstevel@tonic-gate "mapping with length 0\n")); 22667c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 22677c478bd9Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 22687c478bd9Sstevel@tonic-gate } 22697c478bd9Sstevel@tonic-gate 22707c478bd9Sstevel@tonic-gate if (offset + length > seg->rsmseg_size) { 22717c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 22727c478bd9Sstevel@tonic-gate "map length + offset exceed segment size\n")); 22737c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 22747c478bd9Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 22757c478bd9Sstevel@tonic-gate } 22767c478bd9Sstevel@tonic-gate 22777c478bd9Sstevel@tonic-gate if ((size_t)offset & (PAGESIZE - 1)) { 22787c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 22797c478bd9Sstevel@tonic-gate "bad mem alignment\n")); 22807c478bd9Sstevel@tonic-gate return (RSMERR_BAD_MEM_ALIGNMENT); 22817c478bd9Sstevel@tonic-gate } 22827c478bd9Sstevel@tonic-gate 22837c478bd9Sstevel@tonic-gate if (attr & RSM_MAP_FIXED) { 22847c478bd9Sstevel@tonic-gate if ((uintptr_t)(*address) & (PAGESIZE - 1)) { 22857c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 22867c478bd9Sstevel@tonic-gate "bad mem alignment\n")); 22877c478bd9Sstevel@tonic-gate return (RSMERR_BAD_MEM_ALIGNMENT); 22887c478bd9Sstevel@tonic-gate } 22897c478bd9Sstevel@tonic-gate flag |= MAP_FIXED; 22907c478bd9Sstevel@tonic-gate } 22917c478bd9Sstevel@tonic-gate 22927c478bd9Sstevel@tonic-gate prot = PROT_NONE; 22937c478bd9Sstevel@tonic-gate if (perm & RSM_PERM_READ) 22947c478bd9Sstevel@tonic-gate prot |= PROT_READ; 22957c478bd9Sstevel@tonic-gate if (perm & RSM_PERM_WRITE) 22967c478bd9Sstevel@tonic-gate prot |= PROT_WRITE; 22977c478bd9Sstevel@tonic-gate 22987c478bd9Sstevel@tonic-gate va = mmap(*address, length, prot, flag, seg->rsmseg_fd, offset); 22997c478bd9Sstevel@tonic-gate if (va == MAP_FAILED) { 23007c478bd9Sstevel@tonic-gate int e = errno; 23017c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 23027c478bd9Sstevel@tonic-gate "error %d during map\n", e)); 23037c478bd9Sstevel@tonic-gate 23047c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 23057c478bd9Sstevel@tonic-gate if (e == ENXIO || e == EOVERFLOW || 23067c478bd9Sstevel@tonic-gate e == ENOMEM) 23077c478bd9Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 23087c478bd9Sstevel@tonic-gate else if (e == ENODEV) 23097c478bd9Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 23107c478bd9Sstevel@tonic-gate else if (e == EAGAIN) 23117c478bd9Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_RESOURCES); 23127c478bd9Sstevel@tonic-gate else if (e == ENOTSUP) 23137c478bd9Sstevel@tonic-gate return (RSMERR_MAP_FAILED); 23147c478bd9Sstevel@tonic-gate else if (e == EACCES) 23157c478bd9Sstevel@tonic-gate return (RSMERR_BAD_PERMS); 23167c478bd9Sstevel@tonic-gate else 23177c478bd9Sstevel@tonic-gate return (RSMERR_MAP_FAILED); 23187c478bd9Sstevel@tonic-gate } 23197c478bd9Sstevel@tonic-gate *address = va; 23207c478bd9Sstevel@tonic-gate 23217c478bd9Sstevel@tonic-gate /* 23227c478bd9Sstevel@tonic-gate * Fix segment ops vector to handle direct access. 23237c478bd9Sstevel@tonic-gate */ 23247c478bd9Sstevel@tonic-gate /* 23257c478bd9Sstevel@tonic-gate * XXX: Set this only for full segment mapping. Keep a list 23267c478bd9Sstevel@tonic-gate * of mappings to use for access functions 23277c478bd9Sstevel@tonic-gate */ 23287c478bd9Sstevel@tonic-gate seg->rsmseg_vaddr = va; 23297c478bd9Sstevel@tonic-gate seg->rsmseg_maplen = length; 23307c478bd9Sstevel@tonic-gate seg->rsmseg_mapoffset = offset; 23317c478bd9Sstevel@tonic-gate seg->rsmseg_state = IMPORT_MAP; 23327c478bd9Sstevel@tonic-gate 23337c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 23347c478bd9Sstevel@tonic-gate 23357c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 23367c478bd9Sstevel@tonic-gate "rsm_memseg_import_map: exit\n")); 23377c478bd9Sstevel@tonic-gate 23387c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 23397c478bd9Sstevel@tonic-gate } 23407c478bd9Sstevel@tonic-gate 23417c478bd9Sstevel@tonic-gate int 23427c478bd9Sstevel@tonic-gate _rsm_memseg_import_unmap(rsm_memseg_import_handle_t im_memseg) 23437c478bd9Sstevel@tonic-gate { 23447c478bd9Sstevel@tonic-gate /* 23457c478bd9Sstevel@tonic-gate * Until we fix the rsm driver to catch unload, we unload 23467c478bd9Sstevel@tonic-gate * the whole segment. 23477c478bd9Sstevel@tonic-gate */ 23487c478bd9Sstevel@tonic-gate 23497c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 23507c478bd9Sstevel@tonic-gate 23517c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 23527c478bd9Sstevel@tonic-gate "rsm_memseg_import_unmap: enter\n")); 23537c478bd9Sstevel@tonic-gate 23547c478bd9Sstevel@tonic-gate if (!seg) { 23557c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 23567c478bd9Sstevel@tonic-gate "invalid segment or segment state\n")); 23577c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 23587c478bd9Sstevel@tonic-gate } 23597c478bd9Sstevel@tonic-gate 23607c478bd9Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 23617c478bd9Sstevel@tonic-gate if (seg->rsmseg_state != IMPORT_MAP) { 23627c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 23637c478bd9Sstevel@tonic-gate return (RSMERR_SEG_NOT_MAPPED); 23647c478bd9Sstevel@tonic-gate } 23657c478bd9Sstevel@tonic-gate 23667c478bd9Sstevel@tonic-gate seg->rsmseg_mapoffset = 0; /* reset the offset */ 23677c478bd9Sstevel@tonic-gate seg->rsmseg_state = IMPORT_CONNECT; 23687c478bd9Sstevel@tonic-gate seg->rsmseg_flags &= ~RSM_IMPLICIT_MAP; 23697c478bd9Sstevel@tonic-gate (void) munmap(seg->rsmseg_vaddr, seg->rsmseg_maplen); 23707c478bd9Sstevel@tonic-gate 23717c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 23727c478bd9Sstevel@tonic-gate 23737c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 23747c478bd9Sstevel@tonic-gate "rsm_memseg_import_unmap: exit\n")); 23757c478bd9Sstevel@tonic-gate 23767c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 23777c478bd9Sstevel@tonic-gate } 23787c478bd9Sstevel@tonic-gate 23797c478bd9Sstevel@tonic-gate 23807c478bd9Sstevel@tonic-gate /* 23817c478bd9Sstevel@tonic-gate * import side memory segment operations (barriers): 23827c478bd9Sstevel@tonic-gate */ 23837c478bd9Sstevel@tonic-gate int 23847c478bd9Sstevel@tonic-gate _rsm_memseg_import_init_barrier(rsm_memseg_import_handle_t im_memseg, 23857c478bd9Sstevel@tonic-gate rsm_barrier_type_t type, 23867c478bd9Sstevel@tonic-gate rsmapi_barrier_t *barrier) 23877c478bd9Sstevel@tonic-gate { 23887c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 23897c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar; 23907c478bd9Sstevel@tonic-gate 23917c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 23927c478bd9Sstevel@tonic-gate "rsm_memseg_import_init_barrier: enter\n")); 23937c478bd9Sstevel@tonic-gate 23947c478bd9Sstevel@tonic-gate if (!seg) { 23957c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 23967c478bd9Sstevel@tonic-gate "invalid segment or barrier\n")); 23977c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 23987c478bd9Sstevel@tonic-gate } 23997c478bd9Sstevel@tonic-gate if (!barrier) { 24007c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 24017c478bd9Sstevel@tonic-gate "invalid barrier pointer\n")); 24027c478bd9Sstevel@tonic-gate return (RSMERR_BAD_BARRIER_PTR); 24037c478bd9Sstevel@tonic-gate } 24047c478bd9Sstevel@tonic-gate 24057c478bd9Sstevel@tonic-gate bar = (rsmbar_handle_t *)barrier; 24067c478bd9Sstevel@tonic-gate bar->rsmbar_seg = seg; 24077c478bd9Sstevel@tonic-gate 24087c478bd9Sstevel@tonic-gate seg->rsmseg_barrier = barrier; /* used in put/get fns */ 24097c478bd9Sstevel@tonic-gate 24107c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 24117c478bd9Sstevel@tonic-gate "rsm_memseg_import_init_barrier: exit\n")); 24127c478bd9Sstevel@tonic-gate 24137c478bd9Sstevel@tonic-gate return (seg->rsmseg_ops->rsm_memseg_import_init_barrier(im_memseg, 24147c478bd9Sstevel@tonic-gate type, (rsm_barrier_handle_t)barrier)); 24157c478bd9Sstevel@tonic-gate } 24167c478bd9Sstevel@tonic-gate 24177c478bd9Sstevel@tonic-gate int 24187c478bd9Sstevel@tonic-gate _rsm_memseg_import_open_barrier(rsmapi_barrier_t *barrier) 24197c478bd9Sstevel@tonic-gate { 24207c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)barrier; 24217c478bd9Sstevel@tonic-gate rsm_segops_t *ops; 24227c478bd9Sstevel@tonic-gate 24237c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 24247c478bd9Sstevel@tonic-gate "rsm_memseg_import_open_barrier: enter\n")); 24257c478bd9Sstevel@tonic-gate 24267c478bd9Sstevel@tonic-gate if (!bar) { 24277c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 24287c478bd9Sstevel@tonic-gate "invalid barrier\n")); 24297c478bd9Sstevel@tonic-gate return (RSMERR_BAD_BARRIER_PTR); 24307c478bd9Sstevel@tonic-gate } 24317c478bd9Sstevel@tonic-gate if (!bar->rsmbar_seg) { 24327c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 24337c478bd9Sstevel@tonic-gate "uninitialized barrier\n")); 24347c478bd9Sstevel@tonic-gate return (RSMERR_BARRIER_UNINITIALIZED); 24357c478bd9Sstevel@tonic-gate } 24367c478bd9Sstevel@tonic-gate 24377c478bd9Sstevel@tonic-gate /* generation number snapshot */ 24387c478bd9Sstevel@tonic-gate bar->rsmbar_gen = bar->rsmbar_seg->rsmseg_gnum; /* bar[0] */ 24397c478bd9Sstevel@tonic-gate 24407c478bd9Sstevel@tonic-gate ops = bar->rsmbar_seg->rsmseg_ops; 24417c478bd9Sstevel@tonic-gate 24427c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 24437c478bd9Sstevel@tonic-gate "rsm_memseg_import_open_barrier: exit\n")); 24447c478bd9Sstevel@tonic-gate 24457c478bd9Sstevel@tonic-gate return (ops->rsm_memseg_import_open_barrier( 24467c478bd9Sstevel@tonic-gate (rsm_barrier_handle_t)barrier)); 24477c478bd9Sstevel@tonic-gate } 24487c478bd9Sstevel@tonic-gate 24497c478bd9Sstevel@tonic-gate int 24507c478bd9Sstevel@tonic-gate _rsm_memseg_import_order_barrier(rsmapi_barrier_t *barrier) 24517c478bd9Sstevel@tonic-gate { 24527c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)barrier; 24537c478bd9Sstevel@tonic-gate rsm_segops_t *ops; 24547c478bd9Sstevel@tonic-gate 24557c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 24567c478bd9Sstevel@tonic-gate "rsm_memseg_import_order_barrier: enter\n")); 24577c478bd9Sstevel@tonic-gate 24587c478bd9Sstevel@tonic-gate if (!bar) { 24597c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 24607c478bd9Sstevel@tonic-gate "invalid barrier\n")); 24617c478bd9Sstevel@tonic-gate return (RSMERR_BAD_BARRIER_PTR); 24627c478bd9Sstevel@tonic-gate } 24637c478bd9Sstevel@tonic-gate if (!bar->rsmbar_seg) { 24647c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 24657c478bd9Sstevel@tonic-gate "uninitialized barrier\n")); 24667c478bd9Sstevel@tonic-gate return (RSMERR_BARRIER_UNINITIALIZED); 24677c478bd9Sstevel@tonic-gate } 24687c478bd9Sstevel@tonic-gate 24697c478bd9Sstevel@tonic-gate ops = bar->rsmbar_seg->rsmseg_ops; 24707c478bd9Sstevel@tonic-gate 24717c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 24727c478bd9Sstevel@tonic-gate "rsm_memseg_import_order_barrier: exit\n")); 24737c478bd9Sstevel@tonic-gate 24747c478bd9Sstevel@tonic-gate return (ops->rsm_memseg_import_order_barrier( 24757c478bd9Sstevel@tonic-gate (rsm_barrier_handle_t)barrier)); 24767c478bd9Sstevel@tonic-gate } 24777c478bd9Sstevel@tonic-gate 24787c478bd9Sstevel@tonic-gate int 24797c478bd9Sstevel@tonic-gate _rsm_memseg_import_close_barrier(rsmapi_barrier_t *barrier) 24807c478bd9Sstevel@tonic-gate { 24817c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)barrier; 24827c478bd9Sstevel@tonic-gate rsm_segops_t *ops; 24837c478bd9Sstevel@tonic-gate 24847c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 24857c478bd9Sstevel@tonic-gate "rsm_memseg_import_close_barrier: enter\n")); 24867c478bd9Sstevel@tonic-gate 24877c478bd9Sstevel@tonic-gate if (!bar) { 24887c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 24897c478bd9Sstevel@tonic-gate "invalid barrier\n")); 24907c478bd9Sstevel@tonic-gate return (RSMERR_BAD_BARRIER_PTR); 24917c478bd9Sstevel@tonic-gate } 24927c478bd9Sstevel@tonic-gate if (!bar->rsmbar_seg) { 24937c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 24947c478bd9Sstevel@tonic-gate "uninitialized barrier\n")); 24957c478bd9Sstevel@tonic-gate return (RSMERR_BARRIER_UNINITIALIZED); 24967c478bd9Sstevel@tonic-gate } 24977c478bd9Sstevel@tonic-gate 24987c478bd9Sstevel@tonic-gate /* generation number snapshot */ 24997c478bd9Sstevel@tonic-gate if (bar->rsmbar_gen != bar->rsmbar_seg->rsmseg_bar[0]) { 25007c478bd9Sstevel@tonic-gate return (RSMERR_CONN_ABORTED); 25017c478bd9Sstevel@tonic-gate } 25027c478bd9Sstevel@tonic-gate 25037c478bd9Sstevel@tonic-gate ops = bar->rsmbar_seg->rsmseg_ops; 25047c478bd9Sstevel@tonic-gate 25057c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25067c478bd9Sstevel@tonic-gate "rsm_memseg_import_close_barrier: exit\n")); 25077c478bd9Sstevel@tonic-gate 25087c478bd9Sstevel@tonic-gate return (ops->rsm_memseg_import_close_barrier( 25097c478bd9Sstevel@tonic-gate (rsm_barrier_handle_t)barrier)); 25107c478bd9Sstevel@tonic-gate } 25117c478bd9Sstevel@tonic-gate 25127c478bd9Sstevel@tonic-gate int 25137c478bd9Sstevel@tonic-gate _rsm_memseg_import_destroy_barrier(rsmapi_barrier_t *barrier) 25147c478bd9Sstevel@tonic-gate { 25157c478bd9Sstevel@tonic-gate rsmbar_handle_t *bar = (rsmbar_handle_t *)barrier; 25167c478bd9Sstevel@tonic-gate rsm_segops_t *ops; 25177c478bd9Sstevel@tonic-gate 25187c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25197c478bd9Sstevel@tonic-gate "rsm_memseg_import_destroy_barrier: enter\n")); 25207c478bd9Sstevel@tonic-gate 25217c478bd9Sstevel@tonic-gate if (!bar) { 25227c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 25237c478bd9Sstevel@tonic-gate "invalid barrier\n")); 25247c478bd9Sstevel@tonic-gate return (RSMERR_BAD_BARRIER_PTR); 25257c478bd9Sstevel@tonic-gate } 25267c478bd9Sstevel@tonic-gate if (!bar->rsmbar_seg) { 25277c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 25287c478bd9Sstevel@tonic-gate "uninitialized barrier\n")); 25297c478bd9Sstevel@tonic-gate return (RSMERR_BARRIER_UNINITIALIZED); 25307c478bd9Sstevel@tonic-gate } 25317c478bd9Sstevel@tonic-gate 25327c478bd9Sstevel@tonic-gate bar->rsmbar_seg->rsmseg_barrier = NULL; 25337c478bd9Sstevel@tonic-gate 25347c478bd9Sstevel@tonic-gate ops = bar->rsmbar_seg->rsmseg_ops; 25357c478bd9Sstevel@tonic-gate 25367c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25377c478bd9Sstevel@tonic-gate "rsm_memseg_import_destroy_barrier: exit\n")); 25387c478bd9Sstevel@tonic-gate 25397c478bd9Sstevel@tonic-gate return (ops->rsm_memseg_import_destroy_barrier 25407c478bd9Sstevel@tonic-gate ((rsm_barrier_handle_t)barrier)); 25417c478bd9Sstevel@tonic-gate } 25427c478bd9Sstevel@tonic-gate 25437c478bd9Sstevel@tonic-gate int 25447c478bd9Sstevel@tonic-gate _rsm_memseg_import_get_mode(rsm_memseg_import_handle_t im_memseg, 25457c478bd9Sstevel@tonic-gate rsm_barrier_mode_t *mode) 25467c478bd9Sstevel@tonic-gate { 25477c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 25487c478bd9Sstevel@tonic-gate 25497c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25507c478bd9Sstevel@tonic-gate "rsm_memseg_import_get_mode: enter\n")); 25517c478bd9Sstevel@tonic-gate 25527c478bd9Sstevel@tonic-gate if (seg) { 25537c478bd9Sstevel@tonic-gate *mode = seg->rsmseg_barmode; 25547c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25557c478bd9Sstevel@tonic-gate "rsm_memseg_import_get_mode: exit\n")); 25567c478bd9Sstevel@tonic-gate 25577c478bd9Sstevel@tonic-gate return (seg->rsmseg_ops->rsm_memseg_import_get_mode(im_memseg, 25587c478bd9Sstevel@tonic-gate mode)); 25597c478bd9Sstevel@tonic-gate } 25607c478bd9Sstevel@tonic-gate 25617c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 25627c478bd9Sstevel@tonic-gate "invalid arguments \n")); 25637c478bd9Sstevel@tonic-gate 25647c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 25657c478bd9Sstevel@tonic-gate 25667c478bd9Sstevel@tonic-gate } 25677c478bd9Sstevel@tonic-gate 25687c478bd9Sstevel@tonic-gate int 25697c478bd9Sstevel@tonic-gate _rsm_memseg_import_set_mode(rsm_memseg_import_handle_t im_memseg, 25707c478bd9Sstevel@tonic-gate rsm_barrier_mode_t mode) 25717c478bd9Sstevel@tonic-gate { 25727c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)im_memseg; 25737c478bd9Sstevel@tonic-gate 25747c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25757c478bd9Sstevel@tonic-gate "rsm_memseg_import_set_mode: enter\n")); 25767c478bd9Sstevel@tonic-gate if (seg) { 25777c478bd9Sstevel@tonic-gate if ((mode == RSM_BARRIER_MODE_IMPLICIT || 25787c478bd9Sstevel@tonic-gate mode == RSM_BARRIER_MODE_EXPLICIT)) { 25797c478bd9Sstevel@tonic-gate seg->rsmseg_barmode = mode; 25807c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25817c478bd9Sstevel@tonic-gate "rsm_memseg_import_set_mode: exit\n")); 25827c478bd9Sstevel@tonic-gate 25837c478bd9Sstevel@tonic-gate return (seg->rsmseg_ops->rsm_memseg_import_set_mode( 25847c478bd9Sstevel@tonic-gate im_memseg, 25857c478bd9Sstevel@tonic-gate mode)); 25867c478bd9Sstevel@tonic-gate } else { 25877c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_DEBUG_VERBOSE, 25887c478bd9Sstevel@tonic-gate "bad barrier mode\n")); 25897c478bd9Sstevel@tonic-gate return (RSMERR_BAD_MODE); 25907c478bd9Sstevel@tonic-gate } 25917c478bd9Sstevel@tonic-gate } 25927c478bd9Sstevel@tonic-gate 25937c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_IMPORT, RSM_ERR, 25947c478bd9Sstevel@tonic-gate "invalid arguments\n")); 25957c478bd9Sstevel@tonic-gate 25967c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 25977c478bd9Sstevel@tonic-gate } 25987c478bd9Sstevel@tonic-gate 25997c478bd9Sstevel@tonic-gate int 26007c478bd9Sstevel@tonic-gate _rsm_intr_signal_post(void *memseg, uint_t flags) 26017c478bd9Sstevel@tonic-gate { 26027c478bd9Sstevel@tonic-gate rsm_ioctlmsg_t msg; 26037c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 26047c478bd9Sstevel@tonic-gate 26057c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 26067c478bd9Sstevel@tonic-gate "rsm_intr_signal_post: enter\n")); 26077c478bd9Sstevel@tonic-gate 26087c478bd9Sstevel@tonic-gate flags = flags; 26097c478bd9Sstevel@tonic-gate 26107c478bd9Sstevel@tonic-gate if (!seg) { 26117c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 26127c478bd9Sstevel@tonic-gate "invalid segment handle\n")); 26137c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 26147c478bd9Sstevel@tonic-gate } 26157c478bd9Sstevel@tonic-gate 26167c478bd9Sstevel@tonic-gate if (ioctl(seg->rsmseg_fd, RSM_IOCTL_RING_BELL, &msg) < 0) { 26177c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 26187c478bd9Sstevel@tonic-gate "RSM_IOCTL_RING_BELL failed\n")); 26197c478bd9Sstevel@tonic-gate return (errno); 26207c478bd9Sstevel@tonic-gate } 26217c478bd9Sstevel@tonic-gate 26227c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 26237c478bd9Sstevel@tonic-gate "rsm_intr_signal_post: exit\n")); 26247c478bd9Sstevel@tonic-gate 26257c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 26267c478bd9Sstevel@tonic-gate } 26277c478bd9Sstevel@tonic-gate 26287c478bd9Sstevel@tonic-gate int 26297c478bd9Sstevel@tonic-gate _rsm_intr_signal_wait(void *memseg, int timeout) 26307c478bd9Sstevel@tonic-gate { 26317c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 26327c478bd9Sstevel@tonic-gate struct pollfd fds; 26337c478bd9Sstevel@tonic-gate minor_t rnum; 26347c478bd9Sstevel@tonic-gate 26357c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 26367c478bd9Sstevel@tonic-gate "rsm_intr_signal_wait: enter\n")); 26377c478bd9Sstevel@tonic-gate 26387c478bd9Sstevel@tonic-gate if (!seg) { 26397c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 26407c478bd9Sstevel@tonic-gate "invalid segment\n")); 26417c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 26427c478bd9Sstevel@tonic-gate } 26437c478bd9Sstevel@tonic-gate 26447c478bd9Sstevel@tonic-gate fds.fd = seg->rsmseg_fd; 26457c478bd9Sstevel@tonic-gate fds.events = POLLRDNORM; 26467c478bd9Sstevel@tonic-gate 26477c478bd9Sstevel@tonic-gate rnum = seg->rsmseg_rnum; 26487c478bd9Sstevel@tonic-gate 26497c478bd9Sstevel@tonic-gate return (__rsm_intr_signal_wait_common(&fds, &rnum, 1, timeout, NULL)); 26507c478bd9Sstevel@tonic-gate } 26517c478bd9Sstevel@tonic-gate 26527c478bd9Sstevel@tonic-gate int 26537c478bd9Sstevel@tonic-gate _rsm_intr_signal_wait_pollfd(struct pollfd fds[], nfds_t nfds, int timeout, 26547c478bd9Sstevel@tonic-gate int *numfdsp) 26557c478bd9Sstevel@tonic-gate { 26567c478bd9Sstevel@tonic-gate return (__rsm_intr_signal_wait_common(fds, NULL, nfds, timeout, 26577c478bd9Sstevel@tonic-gate numfdsp)); 26587c478bd9Sstevel@tonic-gate } 26597c478bd9Sstevel@tonic-gate 26607c478bd9Sstevel@tonic-gate /* 26617c478bd9Sstevel@tonic-gate * This is the generic wait routine, it takes the following arguments 26627c478bd9Sstevel@tonic-gate * - pollfd array 26637c478bd9Sstevel@tonic-gate * - rnums array corresponding to the pollfd if known, if this is 26647c478bd9Sstevel@tonic-gate * NULL then the fds are looked up from the pollfd_table. 26657c478bd9Sstevel@tonic-gate * - number of fds in pollfd array, 26667c478bd9Sstevel@tonic-gate * - timeout 26677c478bd9Sstevel@tonic-gate * - pointer to a location where the number of fds with successful 26687c478bd9Sstevel@tonic-gate * events is returned. 26697c478bd9Sstevel@tonic-gate */ 26707c478bd9Sstevel@tonic-gate static int 26717c478bd9Sstevel@tonic-gate __rsm_intr_signal_wait_common(struct pollfd fds[], minor_t rnums[], 26727c478bd9Sstevel@tonic-gate nfds_t nfds, int timeout, int *numfdsp) 26737c478bd9Sstevel@tonic-gate { 26747c478bd9Sstevel@tonic-gate int i; 26757c478bd9Sstevel@tonic-gate int numsegs = 0; 26767c478bd9Sstevel@tonic-gate int numfd; 26777c478bd9Sstevel@tonic-gate int fds_processed = 0; 26787c478bd9Sstevel@tonic-gate minor_t segrnum; 26797c478bd9Sstevel@tonic-gate rsm_poll_event_t event_arr[RSM_MAX_POLLFDS]; 26807c478bd9Sstevel@tonic-gate rsm_poll_event_t *event_list = NULL; 26817c478bd9Sstevel@tonic-gate rsm_poll_event_t *events; 26827c478bd9Sstevel@tonic-gate rsm_consume_event_msg_t msg; 26837c478bd9Sstevel@tonic-gate 26847c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, "wait_common enter\n")); 26857c478bd9Sstevel@tonic-gate 26867c478bd9Sstevel@tonic-gate if (numfdsp) { 26877c478bd9Sstevel@tonic-gate *numfdsp = 0; 26887c478bd9Sstevel@tonic-gate } 26897c478bd9Sstevel@tonic-gate 26907c478bd9Sstevel@tonic-gate numfd = poll(fds, nfds, timeout); 26917c478bd9Sstevel@tonic-gate 26927c478bd9Sstevel@tonic-gate switch (numfd) { 26937c478bd9Sstevel@tonic-gate case -1: /* poll returned error - map to RSMERR_... */ 26947c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, "signal wait pollfd err\n")); 26957c478bd9Sstevel@tonic-gate switch (errno) { 26967c478bd9Sstevel@tonic-gate case EAGAIN: 26977c478bd9Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_RESOURCES); 26987c478bd9Sstevel@tonic-gate case EFAULT: 26997c478bd9Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 27007c478bd9Sstevel@tonic-gate case EINTR: 27017c478bd9Sstevel@tonic-gate return (RSMERR_INTERRUPTED); 27027c478bd9Sstevel@tonic-gate case EINVAL: 27037c478bd9Sstevel@tonic-gate default: 27047c478bd9Sstevel@tonic-gate return (RSMERR_BAD_ARGS_ERRORS); 27057c478bd9Sstevel@tonic-gate } 27067c478bd9Sstevel@tonic-gate case 0: /* timedout - return from here */ 27077c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 27087c478bd9Sstevel@tonic-gate "signal wait timed out\n")); 27097c478bd9Sstevel@tonic-gate return (RSMERR_TIMEOUT); 27107c478bd9Sstevel@tonic-gate default: 27117c478bd9Sstevel@tonic-gate break; 27127c478bd9Sstevel@tonic-gate } 27137c478bd9Sstevel@tonic-gate 27147c478bd9Sstevel@tonic-gate if (numfd <= RSM_MAX_POLLFDS) { 27157c478bd9Sstevel@tonic-gate /* use the event array on the stack */ 27167c478bd9Sstevel@tonic-gate events = (rsm_poll_event_t *)event_arr; 27177c478bd9Sstevel@tonic-gate } else { 27187c478bd9Sstevel@tonic-gate /* 27197c478bd9Sstevel@tonic-gate * actual number of fds corresponding to rsmapi segments might 27207c478bd9Sstevel@tonic-gate * be < numfd, don't want to scan the list to figure that out 27217c478bd9Sstevel@tonic-gate * lets just allocate on the heap 27227c478bd9Sstevel@tonic-gate */ 27237c478bd9Sstevel@tonic-gate event_list = (rsm_poll_event_t *)malloc( 27247c478bd9Sstevel@tonic-gate sizeof (rsm_poll_event_t)*numfd); 27257c478bd9Sstevel@tonic-gate if (!event_list) { 27267c478bd9Sstevel@tonic-gate /* 27277c478bd9Sstevel@tonic-gate * return with error even if poll might have succeeded 27287c478bd9Sstevel@tonic-gate * since the application can retry and the events will 27297c478bd9Sstevel@tonic-gate * still be available. 27307c478bd9Sstevel@tonic-gate */ 27317c478bd9Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_MEM); 27327c478bd9Sstevel@tonic-gate } 27337c478bd9Sstevel@tonic-gate events = event_list; 27347c478bd9Sstevel@tonic-gate } 27357c478bd9Sstevel@tonic-gate 27367c478bd9Sstevel@tonic-gate /* 27377c478bd9Sstevel@tonic-gate * process the fds for events and if it corresponds to an rsmapi 27387c478bd9Sstevel@tonic-gate * segment consume the event 27397c478bd9Sstevel@tonic-gate */ 27407c478bd9Sstevel@tonic-gate for (i = 0; i < nfds; i++) { 27417c478bd9Sstevel@tonic-gate if (fds[i].revents == POLLRDNORM) { 27427c478bd9Sstevel@tonic-gate /* 27437c478bd9Sstevel@tonic-gate * poll returned an event and if its POLLRDNORM, it 27447c478bd9Sstevel@tonic-gate * might correspond to an rsmapi segment 27457c478bd9Sstevel@tonic-gate */ 27467c478bd9Sstevel@tonic-gate if (rnums) { /* resource num is passed in */ 27477c478bd9Sstevel@tonic-gate segrnum = rnums[i]; 27487c478bd9Sstevel@tonic-gate } else { /* lookup pollfd table to get resource num */ 27497c478bd9Sstevel@tonic-gate segrnum = _rsm_lookup_pollfd_table(fds[i].fd); 27507c478bd9Sstevel@tonic-gate } 27517c478bd9Sstevel@tonic-gate if (segrnum) { 27527c478bd9Sstevel@tonic-gate events[numsegs].rnum = segrnum; 27537c478bd9Sstevel@tonic-gate events[numsegs].revent = 0; 27547c478bd9Sstevel@tonic-gate events[numsegs].fdsidx = i; /* fdlist index */ 27557c478bd9Sstevel@tonic-gate numsegs++; 27567c478bd9Sstevel@tonic-gate } 27577c478bd9Sstevel@tonic-gate } 27587c478bd9Sstevel@tonic-gate 27597c478bd9Sstevel@tonic-gate if ((fds[i].revents) && (++fds_processed == numfd)) { 27607c478bd9Sstevel@tonic-gate /* 27617c478bd9Sstevel@tonic-gate * only "numfd" events have revents field set, once we 27627c478bd9Sstevel@tonic-gate * process that many break out of the loop 27637c478bd9Sstevel@tonic-gate */ 27647c478bd9Sstevel@tonic-gate break; 27657c478bd9Sstevel@tonic-gate } 27667c478bd9Sstevel@tonic-gate } 27677c478bd9Sstevel@tonic-gate 27687c478bd9Sstevel@tonic-gate if (numsegs == 0) { /* No events for rsmapi segs in the fdlist */ 27697c478bd9Sstevel@tonic-gate if (event_list) { 27707c478bd9Sstevel@tonic-gate free(event_list); 27717c478bd9Sstevel@tonic-gate } 27727c478bd9Sstevel@tonic-gate if (numfdsp) { 27737c478bd9Sstevel@tonic-gate *numfdsp = numfd; 27747c478bd9Sstevel@tonic-gate } 27757c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 27767c478bd9Sstevel@tonic-gate "wait_common exit: no rsmapi segs\n")); 27777c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 27787c478bd9Sstevel@tonic-gate } 27797c478bd9Sstevel@tonic-gate 27807c478bd9Sstevel@tonic-gate msg.seglist = (caddr_t)events; 27817c478bd9Sstevel@tonic-gate msg.numents = numsegs; 27827c478bd9Sstevel@tonic-gate 27837c478bd9Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_CONSUMEEVENT, &msg) < 0) { 27847c478bd9Sstevel@tonic-gate int error = errno; 27857c478bd9Sstevel@tonic-gate if (event_list) { 27867c478bd9Sstevel@tonic-gate free(event_list); 27877c478bd9Sstevel@tonic-gate } 27887c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY|RSM_LOOPBACK, RSM_ERR, 27897c478bd9Sstevel@tonic-gate "RSM_IOCTL_CONSUMEEVENT failed(%d)\n", error)); 27907c478bd9Sstevel@tonic-gate return (error); 27917c478bd9Sstevel@tonic-gate } 27927c478bd9Sstevel@tonic-gate 27937c478bd9Sstevel@tonic-gate /* count the number of segs for which consumeevent was successful */ 27947c478bd9Sstevel@tonic-gate numfd -= numsegs; 27957c478bd9Sstevel@tonic-gate 27967c478bd9Sstevel@tonic-gate for (i = 0; i < numsegs; i++) { 27977c478bd9Sstevel@tonic-gate if (events[i].revent != 0) { 27987c478bd9Sstevel@tonic-gate fds[events[i].fdsidx].revents = POLLRDNORM; 27997c478bd9Sstevel@tonic-gate numfd++; 28007c478bd9Sstevel@tonic-gate } else { /* failed to consume event so set revents to 0 */ 28017c478bd9Sstevel@tonic-gate fds[events[i].fdsidx].revents = 0; 28027c478bd9Sstevel@tonic-gate } 28037c478bd9Sstevel@tonic-gate } 28047c478bd9Sstevel@tonic-gate 28057c478bd9Sstevel@tonic-gate if (event_list) { 28067c478bd9Sstevel@tonic-gate free(event_list); 28077c478bd9Sstevel@tonic-gate } 28087c478bd9Sstevel@tonic-gate 28097c478bd9Sstevel@tonic-gate if (numfd > 0) { 28107c478bd9Sstevel@tonic-gate if (numfdsp) { 28117c478bd9Sstevel@tonic-gate *numfdsp = numfd; 28127c478bd9Sstevel@tonic-gate } 28137c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 28147c478bd9Sstevel@tonic-gate "wait_common exit\n")); 28157c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 28167c478bd9Sstevel@tonic-gate } else { 28177c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 28187c478bd9Sstevel@tonic-gate "wait_common exit\n")); 28197c478bd9Sstevel@tonic-gate return (RSMERR_TIMEOUT); 28207c478bd9Sstevel@tonic-gate } 28217c478bd9Sstevel@tonic-gate } 28227c478bd9Sstevel@tonic-gate 28237c478bd9Sstevel@tonic-gate /* 28247c478bd9Sstevel@tonic-gate * This function provides the data (file descriptor and event) for 28257c478bd9Sstevel@tonic-gate * the specified pollfd struct. The pollfd struct may then be 28267c478bd9Sstevel@tonic-gate * subsequently used with the poll system call to wait for an event 28277c478bd9Sstevel@tonic-gate * signalled by rsm_intr_signal_post. The memory segment must be 28287c478bd9Sstevel@tonic-gate * currently published for a successful return with a valid pollfd. 28297c478bd9Sstevel@tonic-gate * A reference count for the descriptor is incremented. 28307c478bd9Sstevel@tonic-gate */ 28317c478bd9Sstevel@tonic-gate int 28327c478bd9Sstevel@tonic-gate _rsm_memseg_get_pollfd(void *memseg, 28337c478bd9Sstevel@tonic-gate struct pollfd *poll_fd) 28347c478bd9Sstevel@tonic-gate { 28357c478bd9Sstevel@tonic-gate int i; 28367c478bd9Sstevel@tonic-gate int err = RSM_SUCCESS; 28377c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 28387c478bd9Sstevel@tonic-gate 28397c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 28407c478bd9Sstevel@tonic-gate "rsm_memseg_get_pollfd: enter\n")); 28417c478bd9Sstevel@tonic-gate 28427c478bd9Sstevel@tonic-gate if (!seg) { 28437c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 28447c478bd9Sstevel@tonic-gate "invalid segment\n")); 28457c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 28467c478bd9Sstevel@tonic-gate } 28477c478bd9Sstevel@tonic-gate 28487c478bd9Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 28497c478bd9Sstevel@tonic-gate 28507c478bd9Sstevel@tonic-gate poll_fd->fd = seg->rsmseg_fd; 28517c478bd9Sstevel@tonic-gate poll_fd->events = POLLRDNORM; 28527c478bd9Sstevel@tonic-gate seg->rsmseg_pollfd_refcnt++; 28537c478bd9Sstevel@tonic-gate if (seg->rsmseg_pollfd_refcnt == 1) { 28547c478bd9Sstevel@tonic-gate /* insert the segment into the pollfd table */ 28557c478bd9Sstevel@tonic-gate err = _rsm_insert_pollfd_table(seg->rsmseg_fd, 28567c478bd9Sstevel@tonic-gate seg->rsmseg_rnum); 28577c478bd9Sstevel@tonic-gate } 28587c478bd9Sstevel@tonic-gate 28597c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 28607c478bd9Sstevel@tonic-gate 28617c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 28627c478bd9Sstevel@tonic-gate "rsm_memseg_get_pollfd: exit(%d)\n", err)); 28637c478bd9Sstevel@tonic-gate 28647c478bd9Sstevel@tonic-gate return (err); 28657c478bd9Sstevel@tonic-gate } 28667c478bd9Sstevel@tonic-gate 28677c478bd9Sstevel@tonic-gate /* 28687c478bd9Sstevel@tonic-gate * This function decrements the segment pollfd reference count. 28697c478bd9Sstevel@tonic-gate * A segment unpublish or destroy operation will fail if the reference count is 28707c478bd9Sstevel@tonic-gate * non zero. 28717c478bd9Sstevel@tonic-gate */ 28727c478bd9Sstevel@tonic-gate int 28737c478bd9Sstevel@tonic-gate _rsm_memseg_release_pollfd(void * memseg) 28747c478bd9Sstevel@tonic-gate { 28757c478bd9Sstevel@tonic-gate int i; 28767c478bd9Sstevel@tonic-gate rsmseg_handle_t *seg = (rsmseg_handle_t *)memseg; 28777c478bd9Sstevel@tonic-gate 28787c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 28797c478bd9Sstevel@tonic-gate "rsm_memseg_release_pollfd: enter\n")); 28807c478bd9Sstevel@tonic-gate 28817c478bd9Sstevel@tonic-gate if (!seg) { 28827c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 28837c478bd9Sstevel@tonic-gate "invalid segment handle\n")); 28847c478bd9Sstevel@tonic-gate return (RSMERR_BAD_SEG_HNDL); 28857c478bd9Sstevel@tonic-gate } 28867c478bd9Sstevel@tonic-gate 28877c478bd9Sstevel@tonic-gate mutex_lock(&seg->rsmseg_lock); 28887c478bd9Sstevel@tonic-gate 28897c478bd9Sstevel@tonic-gate if (seg->rsmseg_pollfd_refcnt) { 28907c478bd9Sstevel@tonic-gate seg->rsmseg_pollfd_refcnt--; 28917c478bd9Sstevel@tonic-gate if (seg->rsmseg_pollfd_refcnt == 0) { 28927c478bd9Sstevel@tonic-gate /* last reference removed - update the pollfd_table */ 28937c478bd9Sstevel@tonic-gate _rsm_remove_pollfd_table(seg->rsmseg_fd); 28947c478bd9Sstevel@tonic-gate } 28957c478bd9Sstevel@tonic-gate } 28967c478bd9Sstevel@tonic-gate 28977c478bd9Sstevel@tonic-gate mutex_unlock(&seg->rsmseg_lock); 28987c478bd9Sstevel@tonic-gate 28997c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 29007c478bd9Sstevel@tonic-gate "rsm_memseg_release_pollfd: exit\n")); 29017c478bd9Sstevel@tonic-gate 29027c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 29037c478bd9Sstevel@tonic-gate } 29047c478bd9Sstevel@tonic-gate 29057c478bd9Sstevel@tonic-gate /* 29067c478bd9Sstevel@tonic-gate * The interconnect topology data is obtained from the Kernel Agent 29077c478bd9Sstevel@tonic-gate * and stored in a memory buffer allocated by this function. A pointer 29087c478bd9Sstevel@tonic-gate * to the buffer is stored in the location specified by the caller in 29097c478bd9Sstevel@tonic-gate * the function argument. It is the callers responsibility to 29107c478bd9Sstevel@tonic-gate * call rsm_free_interconnect_topolgy() to free the allocated memory. 29117c478bd9Sstevel@tonic-gate */ 29127c478bd9Sstevel@tonic-gate int 29137c478bd9Sstevel@tonic-gate _rsm_get_interconnect_topology(rsm_topology_t **topology_data) 29147c478bd9Sstevel@tonic-gate { 29157c478bd9Sstevel@tonic-gate uint32_t topology_data_size; 29167c478bd9Sstevel@tonic-gate rsm_topology_t *topology_ptr; 29177c478bd9Sstevel@tonic-gate int error; 29187c478bd9Sstevel@tonic-gate 29197c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 29207c478bd9Sstevel@tonic-gate "rsm_get_interconnect_topology: enter\n")); 29217c478bd9Sstevel@tonic-gate 29227c478bd9Sstevel@tonic-gate if (topology_data == NULL) 29237c478bd9Sstevel@tonic-gate return (RSMERR_BAD_TOPOLOGY_PTR); 29247c478bd9Sstevel@tonic-gate 29257c478bd9Sstevel@tonic-gate *topology_data = NULL; 29267c478bd9Sstevel@tonic-gate 29277c478bd9Sstevel@tonic-gate again: 29287c478bd9Sstevel@tonic-gate /* obtain the size of the topology data */ 29297c478bd9Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_TOPOLOGY_SIZE, &topology_data_size) < 0) { 29307c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 29317c478bd9Sstevel@tonic-gate "RSM_IOCTL_TOPOLOGY_SIZE failed\n")); 29327c478bd9Sstevel@tonic-gate return (errno); 29337c478bd9Sstevel@tonic-gate } 29347c478bd9Sstevel@tonic-gate 29357c478bd9Sstevel@tonic-gate /* allocate double-word aligned memory to hold the topology data */ 29367c478bd9Sstevel@tonic-gate topology_ptr = (rsm_topology_t *)memalign(8, topology_data_size); 29377c478bd9Sstevel@tonic-gate if (topology_ptr == NULL) { 29387c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 29397c478bd9Sstevel@tonic-gate "not enough memory\n")); 29407c478bd9Sstevel@tonic-gate return (RSMERR_INSUFFICIENT_MEM); 29417c478bd9Sstevel@tonic-gate } 29427c478bd9Sstevel@tonic-gate 29437c478bd9Sstevel@tonic-gate /* 29447c478bd9Sstevel@tonic-gate * Request the topology data. 29457c478bd9Sstevel@tonic-gate * Pass in the size to be used as a check in case 29467c478bd9Sstevel@tonic-gate * the data has grown since the size was obtained - if 29477c478bd9Sstevel@tonic-gate * it has, the errno value will be E2BIG. 29487c478bd9Sstevel@tonic-gate */ 29497c478bd9Sstevel@tonic-gate topology_ptr->topology_hdr.local_nodeid = 29507c478bd9Sstevel@tonic-gate (rsm_node_id_t)topology_data_size; 29517c478bd9Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_TOPOLOGY_DATA, topology_ptr) < 0) { 29527c478bd9Sstevel@tonic-gate error = errno; 29537c478bd9Sstevel@tonic-gate free((void *)topology_ptr); 29547c478bd9Sstevel@tonic-gate if (error == E2BIG) 29557c478bd9Sstevel@tonic-gate goto again; 29567c478bd9Sstevel@tonic-gate else { 29577c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 29587c478bd9Sstevel@tonic-gate "RSM_IOCTL_TOPOLOGY_DATA failed\n")); 29597c478bd9Sstevel@tonic-gate return (error); 29607c478bd9Sstevel@tonic-gate } 29617c478bd9Sstevel@tonic-gate } else 29627c478bd9Sstevel@tonic-gate *topology_data = topology_ptr; 29637c478bd9Sstevel@tonic-gate 29647c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 29657c478bd9Sstevel@tonic-gate " rsm_get_interconnect_topology: exit\n")); 29667c478bd9Sstevel@tonic-gate 29677c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 29687c478bd9Sstevel@tonic-gate } 29697c478bd9Sstevel@tonic-gate 29707c478bd9Sstevel@tonic-gate 29717c478bd9Sstevel@tonic-gate void 29727c478bd9Sstevel@tonic-gate _rsm_free_interconnect_topology(rsm_topology_t *topology_ptr) 29737c478bd9Sstevel@tonic-gate { 29747c478bd9Sstevel@tonic-gate 29757c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 29767c478bd9Sstevel@tonic-gate "rsm_free_interconnect_topology: enter\n")); 29777c478bd9Sstevel@tonic-gate 29787c478bd9Sstevel@tonic-gate if (topology_ptr) { 29797c478bd9Sstevel@tonic-gate free((void *)topology_ptr); 29807c478bd9Sstevel@tonic-gate } 29817c478bd9Sstevel@tonic-gate 29827c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 29837c478bd9Sstevel@tonic-gate "rsm_free_interconnect_topology: exit\n")); 29847c478bd9Sstevel@tonic-gate } 29857c478bd9Sstevel@tonic-gate 29867c478bd9Sstevel@tonic-gate int 29877c478bd9Sstevel@tonic-gate _rsm_create_localmemory_handle(rsmapi_controller_handle_t cntrl_handle, 29887c478bd9Sstevel@tonic-gate rsm_localmemory_handle_t *local_hndl_p, 29897c478bd9Sstevel@tonic-gate caddr_t local_vaddr, size_t len) 29907c478bd9Sstevel@tonic-gate { 29917c478bd9Sstevel@tonic-gate int e; 29927c478bd9Sstevel@tonic-gate rsm_controller_t *cntrl = (rsm_controller_t *)cntrl_handle; 29937c478bd9Sstevel@tonic-gate 29947c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 29957c478bd9Sstevel@tonic-gate "rsm_create_localmemory_handle: enter\n")); 29967c478bd9Sstevel@tonic-gate 29977c478bd9Sstevel@tonic-gate if ((size_t)local_vaddr & (PAGESIZE - 1)) { 29987c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 29997c478bd9Sstevel@tonic-gate "invalid arguments\n")); 30007c478bd9Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 30017c478bd9Sstevel@tonic-gate } 30027c478bd9Sstevel@tonic-gate 30037c478bd9Sstevel@tonic-gate if (!cntrl_handle) { 30047c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 30057c478bd9Sstevel@tonic-gate "invalid controller handle\n")); 30067c478bd9Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 30077c478bd9Sstevel@tonic-gate } 30087c478bd9Sstevel@tonic-gate if (!local_hndl_p) { 30097c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 30107c478bd9Sstevel@tonic-gate "invalid local memory handle pointer\n")); 30117c478bd9Sstevel@tonic-gate return (RSMERR_BAD_LOCALMEM_HNDL); 30127c478bd9Sstevel@tonic-gate } 30137c478bd9Sstevel@tonic-gate if (len == 0) { 30147c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 30157c478bd9Sstevel@tonic-gate "invalid length\n")); 30167c478bd9Sstevel@tonic-gate return (RSMERR_BAD_LENGTH); 30177c478bd9Sstevel@tonic-gate } 30187c478bd9Sstevel@tonic-gate 30197c478bd9Sstevel@tonic-gate e = cntrl->cntr_segops->rsm_create_localmemory_handle( 30207c478bd9Sstevel@tonic-gate cntrl_handle, 30217c478bd9Sstevel@tonic-gate local_hndl_p, 30227c478bd9Sstevel@tonic-gate local_vaddr, 30237c478bd9Sstevel@tonic-gate len); 30247c478bd9Sstevel@tonic-gate 30257c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 30267c478bd9Sstevel@tonic-gate "rsm_create_localmemory_handle: exit\n")); 30277c478bd9Sstevel@tonic-gate 30287c478bd9Sstevel@tonic-gate return (e); 30297c478bd9Sstevel@tonic-gate } 30307c478bd9Sstevel@tonic-gate 30317c478bd9Sstevel@tonic-gate int 30327c478bd9Sstevel@tonic-gate _rsm_free_localmemory_handle(rsmapi_controller_handle_t cntrl_handle, 30337c478bd9Sstevel@tonic-gate rsm_localmemory_handle_t local_handle) 30347c478bd9Sstevel@tonic-gate { 30357c478bd9Sstevel@tonic-gate int e; 30367c478bd9Sstevel@tonic-gate 30377c478bd9Sstevel@tonic-gate rsm_controller_t *cntrl = (rsm_controller_t *)cntrl_handle; 30387c478bd9Sstevel@tonic-gate 30397c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 30407c478bd9Sstevel@tonic-gate "rsm_free_localmemory_handle: enter\n")); 30417c478bd9Sstevel@tonic-gate 30427c478bd9Sstevel@tonic-gate 30437c478bd9Sstevel@tonic-gate if (!cntrl_handle) { 30447c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 30457c478bd9Sstevel@tonic-gate "invalid controller handle\n")); 30467c478bd9Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 30477c478bd9Sstevel@tonic-gate } 30487c478bd9Sstevel@tonic-gate 30497c478bd9Sstevel@tonic-gate if (!local_handle) { 30507c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 30517c478bd9Sstevel@tonic-gate "invalid localmemory handle\n")); 30527c478bd9Sstevel@tonic-gate return (RSMERR_BAD_LOCALMEM_HNDL); 30537c478bd9Sstevel@tonic-gate } 30547c478bd9Sstevel@tonic-gate 30557c478bd9Sstevel@tonic-gate e = cntrl->cntr_segops->rsm_free_localmemory_handle(local_handle); 30567c478bd9Sstevel@tonic-gate 30577c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 30587c478bd9Sstevel@tonic-gate "rsm_free_localmemory_handle: exit\n")); 30597c478bd9Sstevel@tonic-gate 30607c478bd9Sstevel@tonic-gate return (e); 30617c478bd9Sstevel@tonic-gate } 30627c478bd9Sstevel@tonic-gate 30637c478bd9Sstevel@tonic-gate int 30647c478bd9Sstevel@tonic-gate _rsm_get_segmentid_range(const char *appid, rsm_memseg_id_t *baseid, 30657c478bd9Sstevel@tonic-gate uint32_t *length) 30667c478bd9Sstevel@tonic-gate { 30677c478bd9Sstevel@tonic-gate char buf[RSMFILE_BUFSIZE]; 30687c478bd9Sstevel@tonic-gate char *s; 30697c478bd9Sstevel@tonic-gate char *fieldv[4]; 30707c478bd9Sstevel@tonic-gate int fieldc = 0; 30717c478bd9Sstevel@tonic-gate int found = 0; 30727c478bd9Sstevel@tonic-gate int err = RSMERR_BAD_APPID; 30737c478bd9Sstevel@tonic-gate FILE *fp; 30747c478bd9Sstevel@tonic-gate 30757c478bd9Sstevel@tonic-gate if (appid == NULL || baseid == NULL || length == NULL) 30767c478bd9Sstevel@tonic-gate return (RSMERR_BAD_ADDR); 30777c478bd9Sstevel@tonic-gate 3078*004388ebScasper if ((fp = fopen(RSMSEGIDFILE, "rF")) == NULL) { 30797c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 30807c478bd9Sstevel@tonic-gate "cannot open <%s>\n", RSMSEGIDFILE)); 30817c478bd9Sstevel@tonic-gate return (RSMERR_BAD_CONF); 30827c478bd9Sstevel@tonic-gate } 30837c478bd9Sstevel@tonic-gate 30847c478bd9Sstevel@tonic-gate while (s = fgets(buf, RSMFILE_BUFSIZE, fp)) { 30857c478bd9Sstevel@tonic-gate fieldc = 0; 30867c478bd9Sstevel@tonic-gate while (isspace(*s)) /* skip the leading spaces */ 30877c478bd9Sstevel@tonic-gate s++; 30887c478bd9Sstevel@tonic-gate 30897c478bd9Sstevel@tonic-gate if (*s == '#') { /* comment line - skip it */ 30907c478bd9Sstevel@tonic-gate continue; 30917c478bd9Sstevel@tonic-gate } 30927c478bd9Sstevel@tonic-gate 30937c478bd9Sstevel@tonic-gate /* 30947c478bd9Sstevel@tonic-gate * parse the reserved segid file and 30957c478bd9Sstevel@tonic-gate * set the pointers appropriately. 30967c478bd9Sstevel@tonic-gate * fieldv[0] : keyword 30977c478bd9Sstevel@tonic-gate * fieldv[1] : application identifier 30987c478bd9Sstevel@tonic-gate * fieldv[2] : baseid 30997c478bd9Sstevel@tonic-gate * fieldv[3] : length 31007c478bd9Sstevel@tonic-gate */ 31017c478bd9Sstevel@tonic-gate while ((*s != '\n') && (*s != '\0') && (fieldc < 4)) { 31027c478bd9Sstevel@tonic-gate 31037c478bd9Sstevel@tonic-gate while (isspace(*s)) /* skip the leading spaces */ 31047c478bd9Sstevel@tonic-gate s++; 31057c478bd9Sstevel@tonic-gate 31067c478bd9Sstevel@tonic-gate fieldv[fieldc++] = s; 31077c478bd9Sstevel@tonic-gate 31087c478bd9Sstevel@tonic-gate if (fieldc == 4) { 31097c478bd9Sstevel@tonic-gate if (fieldv[3][strlen(fieldv[3])-1] == '\n') 31107c478bd9Sstevel@tonic-gate fieldv[3][strlen(fieldv[3])-1] = '\0'; 31117c478bd9Sstevel@tonic-gate break; 31127c478bd9Sstevel@tonic-gate } 31137c478bd9Sstevel@tonic-gate 31147c478bd9Sstevel@tonic-gate while (*s && !isspace(*s)) 31157c478bd9Sstevel@tonic-gate ++s; /* move to the next white space */ 31167c478bd9Sstevel@tonic-gate 31177c478bd9Sstevel@tonic-gate if (*s) 31187c478bd9Sstevel@tonic-gate *s++ = '\0'; 31197c478bd9Sstevel@tonic-gate } 31207c478bd9Sstevel@tonic-gate 31217c478bd9Sstevel@tonic-gate if (fieldc < 4) { /* some fields are missing */ 31227c478bd9Sstevel@tonic-gate err = RSMERR_BAD_CONF; 31237c478bd9Sstevel@tonic-gate break; 31247c478bd9Sstevel@tonic-gate } 31257c478bd9Sstevel@tonic-gate 31267c478bd9Sstevel@tonic-gate if (strcasecmp(fieldv[1], appid) == 0) { /* found a match */ 31277c478bd9Sstevel@tonic-gate if (strcasecmp(fieldv[0], RSMSEG_RESERVED) == 0) { 31287c478bd9Sstevel@tonic-gate errno = 0; 31297c478bd9Sstevel@tonic-gate *baseid = strtol(fieldv[2], (char **)NULL, 16); 31307c478bd9Sstevel@tonic-gate if (errno != 0) { 31317c478bd9Sstevel@tonic-gate err = RSMERR_BAD_CONF; 31327c478bd9Sstevel@tonic-gate break; 31337c478bd9Sstevel@tonic-gate } 31347c478bd9Sstevel@tonic-gate 31357c478bd9Sstevel@tonic-gate errno = 0; 31367c478bd9Sstevel@tonic-gate *length = (int)strtol(fieldv[3], 31377c478bd9Sstevel@tonic-gate (char **)NULL, 10); 31387c478bd9Sstevel@tonic-gate if (errno != 0) { 31397c478bd9Sstevel@tonic-gate err = RSMERR_BAD_CONF; 31407c478bd9Sstevel@tonic-gate break; 31417c478bd9Sstevel@tonic-gate } 31427c478bd9Sstevel@tonic-gate 31437c478bd9Sstevel@tonic-gate found = 1; 31447c478bd9Sstevel@tonic-gate } else { /* error in format */ 31457c478bd9Sstevel@tonic-gate err = RSMERR_BAD_CONF; 31467c478bd9Sstevel@tonic-gate } 31477c478bd9Sstevel@tonic-gate break; 31487c478bd9Sstevel@tonic-gate } 31497c478bd9Sstevel@tonic-gate } 31507c478bd9Sstevel@tonic-gate 31517c478bd9Sstevel@tonic-gate (void) fclose(fp); 31527c478bd9Sstevel@tonic-gate 31537c478bd9Sstevel@tonic-gate if (found) 31547c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 31557c478bd9Sstevel@tonic-gate 31567c478bd9Sstevel@tonic-gate return (err); 31577c478bd9Sstevel@tonic-gate } 31587c478bd9Sstevel@tonic-gate 31597c478bd9Sstevel@tonic-gate static int 31607c478bd9Sstevel@tonic-gate _rsm_get_hwaddr(rsmapi_controller_handle_t handle, rsm_node_id_t nodeid, 31617c478bd9Sstevel@tonic-gate rsm_addr_t *hwaddrp) 31627c478bd9Sstevel@tonic-gate { 31637c478bd9Sstevel@tonic-gate rsm_ioctlmsg_t msg = {0}; 31647c478bd9Sstevel@tonic-gate rsm_controller_t *ctrlp; 31657c478bd9Sstevel@tonic-gate 31667c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 31677c478bd9Sstevel@tonic-gate "_rsm_get_hwaddr: enter\n")); 31687c478bd9Sstevel@tonic-gate 31697c478bd9Sstevel@tonic-gate ctrlp = (rsm_controller_t *)handle; 31707c478bd9Sstevel@tonic-gate 31717c478bd9Sstevel@tonic-gate if (ctrlp == NULL) { 31727c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 31737c478bd9Sstevel@tonic-gate "invalid controller handle\n")); 31747c478bd9Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 31757c478bd9Sstevel@tonic-gate } 31767c478bd9Sstevel@tonic-gate 31777c478bd9Sstevel@tonic-gate msg.cname = ctrlp->cntr_name; 31787c478bd9Sstevel@tonic-gate msg.cname_len = strlen(ctrlp->cntr_name) +1; 31797c478bd9Sstevel@tonic-gate msg.cnum = ctrlp->cntr_unit; 31807c478bd9Sstevel@tonic-gate msg.nodeid = nodeid; 31817c478bd9Sstevel@tonic-gate 31827c478bd9Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_MAP_TO_ADDR, &msg) < 0) { 31837c478bd9Sstevel@tonic-gate int error = errno; 31847c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 31857c478bd9Sstevel@tonic-gate "RSM_IOCTL_MAP_TO_ADDR failed\n")); 31867c478bd9Sstevel@tonic-gate return (error); 31877c478bd9Sstevel@tonic-gate } 31887c478bd9Sstevel@tonic-gate 31897c478bd9Sstevel@tonic-gate *hwaddrp = msg.hwaddr; 31907c478bd9Sstevel@tonic-gate 31917c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 31927c478bd9Sstevel@tonic-gate "_rsm_get_hwaddr: exit\n")); 31937c478bd9Sstevel@tonic-gate 31947c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 31957c478bd9Sstevel@tonic-gate 31967c478bd9Sstevel@tonic-gate } 31977c478bd9Sstevel@tonic-gate 31987c478bd9Sstevel@tonic-gate static int 31997c478bd9Sstevel@tonic-gate _rsm_get_nodeid(rsmapi_controller_handle_t handle, rsm_addr_t hwaddr, 32007c478bd9Sstevel@tonic-gate rsm_node_id_t *nodeidp) 32017c478bd9Sstevel@tonic-gate { 32027c478bd9Sstevel@tonic-gate 32037c478bd9Sstevel@tonic-gate rsm_ioctlmsg_t msg = {0}; 32047c478bd9Sstevel@tonic-gate rsm_controller_t *ctrlp; 32057c478bd9Sstevel@tonic-gate 32067c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 32077c478bd9Sstevel@tonic-gate "_rsm_get_nodeid: enter\n")); 32087c478bd9Sstevel@tonic-gate 32097c478bd9Sstevel@tonic-gate ctrlp = (rsm_controller_t *)handle; 32107c478bd9Sstevel@tonic-gate 32117c478bd9Sstevel@tonic-gate if (ctrlp == NULL) { 32127c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 32137c478bd9Sstevel@tonic-gate "invalid arguments\n")); 32147c478bd9Sstevel@tonic-gate return (RSMERR_BAD_CTLR_HNDL); 32157c478bd9Sstevel@tonic-gate } 32167c478bd9Sstevel@tonic-gate 32177c478bd9Sstevel@tonic-gate msg.cname = ctrlp->cntr_name; 32187c478bd9Sstevel@tonic-gate msg.cname_len = strlen(ctrlp->cntr_name) +1; 32197c478bd9Sstevel@tonic-gate msg.cnum = ctrlp->cntr_unit; 32207c478bd9Sstevel@tonic-gate msg.hwaddr = hwaddr; 32217c478bd9Sstevel@tonic-gate 32227c478bd9Sstevel@tonic-gate if (ioctl(_rsm_fd, RSM_IOCTL_MAP_TO_NODEID, &msg) < 0) { 32237c478bd9Sstevel@tonic-gate int error = errno; 32247c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_ERR, 32257c478bd9Sstevel@tonic-gate "RSM_IOCTL_MAP_TO_NODEID failed\n")); 32267c478bd9Sstevel@tonic-gate return (error); 32277c478bd9Sstevel@tonic-gate } 32287c478bd9Sstevel@tonic-gate 32297c478bd9Sstevel@tonic-gate *nodeidp = msg.nodeid; 32307c478bd9Sstevel@tonic-gate 32317c478bd9Sstevel@tonic-gate DBPRINTF((RSM_LIBRARY, RSM_DEBUG_VERBOSE, 32327c478bd9Sstevel@tonic-gate "_rsm_get_nodeid: exit\n")); 32337c478bd9Sstevel@tonic-gate 32347c478bd9Sstevel@tonic-gate return (RSM_SUCCESS); 32357c478bd9Sstevel@tonic-gate 32367c478bd9Sstevel@tonic-gate } 32377c478bd9Sstevel@tonic-gate 32387c478bd9Sstevel@tonic-gate #ifdef DEBUG 32397c478bd9Sstevel@tonic-gate void 32407c478bd9Sstevel@tonic-gate dbg_printf(int msg_category, int msg_level, char *fmt, ...) 32417c478bd9Sstevel@tonic-gate { 32427c478bd9Sstevel@tonic-gate if ((msg_category & rsmlibdbg_category) && 32437c478bd9Sstevel@tonic-gate (msg_level <= rsmlibdbg_level)) { 32447c478bd9Sstevel@tonic-gate va_list arg_list; 32457c478bd9Sstevel@tonic-gate va_start(arg_list, fmt); 32467c478bd9Sstevel@tonic-gate mutex_lock(&rsmlog_lock); 32477c478bd9Sstevel@tonic-gate fprintf(rsmlog_fd, 32487c478bd9Sstevel@tonic-gate "Thread %d ", thr_self()); 32497c478bd9Sstevel@tonic-gate vfprintf(rsmlog_fd, fmt, arg_list); 32507c478bd9Sstevel@tonic-gate fflush(rsmlog_fd); 32517c478bd9Sstevel@tonic-gate mutex_unlock(&rsmlog_lock); 32527c478bd9Sstevel@tonic-gate va_end(arg_list); 32537c478bd9Sstevel@tonic-gate } 32547c478bd9Sstevel@tonic-gate } 32557c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 3256