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