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