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