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