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 <sys/types.h> 28 #include <sys/socket.h> 29 #include <sys/sockio.h> 30 #include <sys/param.h> 31 #include <sys/stat.h> 32 #include <netinet/in.h> 33 #include <arpa/inet.h> 34 #include <net/if.h> 35 #include <unistd.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <errno.h> 39 #include <libdevinfo.h> 40 41 #include "dapl.h" 42 #include "dapl_adapter_util.h" 43 #include "dapl_tavor_ibtf_impl.h" 44 #include "dapl_hca_util.h" 45 #include "dapl_name_service.h" 46 #define IF_NAME "ibd" 47 #define MAX_HCAS 64 48 #define PROP_HCA_GUID "hca-guid" 49 #define PROP_PORT_NUM "port-number" 50 #define PROP_PORT_PKEY "port-pkey" 51 52 #define DEVDAPLT "/dev/daplt" 53 54 /* function prototypes */ 55 static DAT_RETURN dapli_process_tavor_node(di_node_t node, int *hca_idx, 56 int try_blueflame); 57 static DAT_RETURN dapli_process_ibd_node(di_node_t node, DAPL_HCA *hca_ptr, 58 int hca_idx); 59 60 #if defined(IBHOSTS_NAMING) 61 #include <stdio.h> 62 static int dapli_process_fake_ibds(DAPL_HCA **hca_list, int hca_idx); 63 #endif /* IBHOSTS_NAMING */ 64 65 static DAPL_OS_LOCK g_tavor_state_lock; 66 static struct dapls_ib_hca_state g_tavor_state[MAX_HCAS]; 67 DAPL_OS_LOCK g_tavor_uar_lock; 68 69 DAT_RETURN 70 dapli_init_hca( 71 IN DAPL_HCA *hca_ptr) 72 { 73 di_node_t root_node; 74 di_node_t hca_node; 75 di_node_t ibd_node; 76 DAT_RETURN dat_status = DAT_SUCCESS; 77 int hca_idx = 0; 78 int ia_instance; 79 int check_for_bf = 0; 80 81 ia_instance = (int)dapl_os_strtol(hca_ptr->name + strlen(IF_NAME), 82 NULL, 0); 83 84 root_node = di_init("/", DINFOCPYALL); 85 if (root_node == DI_NODE_NIL) { 86 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 87 "init_hca: di_init failed %s\n", strerror(errno)); 88 return (DAT_INTERNAL_ERROR); 89 } 90 91 ibd_node = di_drv_first_node(IF_NAME, root_node); 92 while (ibd_node != DI_NODE_NIL) { 93 /* find the ibd node matching our ianame */ 94 if (di_instance(ibd_node) == ia_instance) { 95 break; 96 } 97 ibd_node = di_drv_next_node(ibd_node); 98 } 99 100 if (ibd_node == DI_NODE_NIL) { 101 dat_status = DAT_ERROR(DAT_NAME_NOT_FOUND, 0); 102 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 103 "init_hcas: ibd%d di_node not found\n", ia_instance); 104 goto bail; 105 } 106 107 hca_node = di_parent_node(ibd_node); 108 if ((hca_node != DI_NODE_NIL) && (strncmp(di_driver_name(hca_node), 109 "tavor", strlen("tavor")) == 0)) 110 dapls_init_funcs_tavor(hca_ptr); 111 else if ((hca_node != DI_NODE_NIL) && (strncmp(di_driver_name 112 (hca_node), "arbel", strlen("arbel")) == 0)) 113 dapls_init_funcs_arbel(hca_ptr); 114 else if ((hca_node != DI_NODE_NIL) && (strncmp(di_driver_name 115 (hca_node), "hermon", strlen("hermon")) == 0)) { 116 dapls_init_funcs_hermon(hca_ptr); 117 check_for_bf = 1; 118 } else { 119 dat_status = DAT_ERROR(DAT_NAME_NOT_FOUND, 0); 120 dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 121 "init_hcas: ibd%d hca_node not found\n", ia_instance); 122 goto bail; 123 } 124 125 dat_status = dapli_process_tavor_node(hca_node, &hca_idx, check_for_bf); 126 if (dat_status != DAT_SUCCESS) { 127 dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 128 "init_hcas: ibd%d process_tavor_node failed(0x%x)\n", 129 ia_instance, dat_status); 130 goto bail; 131 } 132 133 #if defined(IBHOSTS_NAMING) 134 if (dapli_process_fake_ibds(hca_ptr, hca_idx) == 0) { 135 /* no entries were found */ 136 dat_status = DAT_ERROR(DAT_NAME_NOT_FOUND, 0); 137 } 138 #else 139 dat_status = dapli_process_ibd_node(ibd_node, hca_ptr, hca_idx); 140 #endif 141 if (dat_status != DAT_SUCCESS) { 142 dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 143 "init_hcas: ibd%d process_ibd_node failed(0x%x)\n", 144 ia_instance, dat_status); 145 goto bail; 146 } 147 148 dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 149 "init_hcas: done ibd%d\n", ia_instance); 150 151 bail: 152 di_fini(root_node); 153 return (dat_status); 154 } 155 156 static DAT_RETURN 157 dapli_process_tavor_node(di_node_t node, int *hca_idx, int try_blueflame) 158 { 159 char *dev_path; 160 char path_buf[MAXPATHLEN]; 161 int idx, fd; 162 #ifndef _LP64 163 int tmpfd; 164 #endif 165 size_t pagesize; 166 void *mapaddr; 167 pid_t cur_pid; 168 off64_t uarpg_offset; 169 170 dapl_os_lock(&g_tavor_state_lock); 171 172 for (idx = 0; idx < MAX_HCAS; idx++) { 173 /* 174 * page size == 0 means this entry is not occupied 175 */ 176 if (g_tavor_state[idx].uarpg_size == 0) { 177 break; 178 } 179 } 180 if (idx == MAX_HCAS) { 181 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 182 "process_tavor: all hcas are being used!\n"); 183 dapl_os_unlock(&g_tavor_state_lock); 184 return (DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 0)); 185 } 186 dev_path = di_devfs_path(node); 187 188 /* Add 16 to accomodate the prefix "/devices" and suffix ":devctl" */ 189 if (strlen("/devices") + strlen(dev_path) + strlen(":devctl") + 1 > 190 MAXPATHLEN) { 191 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 192 "process_tavor: devfs path %s is too long\n", 193 dev_path); 194 di_devfs_path_free(dev_path); 195 dapl_os_unlock(&g_tavor_state_lock); 196 return (DAT_ERROR(DAT_INTERNAL_ERROR, 0)); 197 } 198 (void) dapl_os_strcpy(path_buf, "/devices"); 199 (void) dapl_os_strcat(path_buf, dev_path); 200 (void) dapl_os_strcat(path_buf, ":devctl"); 201 di_devfs_path_free(dev_path); 202 203 pagesize = (size_t)sysconf(_SC_PAGESIZE); 204 if (pagesize == 0) { 205 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 206 "process_tavor: page_size == 0\n"); 207 dapl_os_unlock(&g_tavor_state_lock); 208 return (DAT_ERROR(DAT_INTERNAL_ERROR, 0)); 209 } 210 cur_pid = getpid(); 211 212 fd = open(path_buf, O_RDWR); 213 if (fd < 0) { 214 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 215 "process_tavor: cannot open %s: %s\n", 216 path_buf, strerror(errno)); 217 dapl_os_unlock(&g_tavor_state_lock); 218 return (DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 0)); 219 } 220 #ifndef _LP64 221 /* 222 * libc can't handle fd's greater than 255, in order to 223 * ensure that these values remain available make fd > 255. 224 * Note: not needed for LP64 225 */ 226 tmpfd = fcntl(fd, F_DUPFD, 256); 227 if (tmpfd < 0) { 228 dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 229 "process_tavor: cannot F_DUPFD: %s\n", strerror(errno)); 230 } else { 231 (void) close(fd); 232 fd = tmpfd; 233 } 234 #endif /* _LP64 */ 235 236 if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) { 237 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 238 "process_tavor: cannot F_SETFD: %s\n", strerror(errno)); 239 (void) close(fd); 240 dapl_os_unlock(&g_tavor_state_lock); 241 return (DAT_ERROR(DAT_INTERNAL_ERROR, 0)); 242 } 243 244 uarpg_offset = (((off64_t)cur_pid << MLNX_UMAP_RSRC_TYPE_SHIFT) | 245 MLNX_UMAP_UARPG_RSRC) * pagesize; 246 247 mapaddr = mmap64((void *)0, pagesize, PROT_READ | PROT_WRITE, 248 MAP_SHARED, fd, uarpg_offset); 249 if (mapaddr == MAP_FAILED) { 250 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 251 "process_tavor: mmap failed %s\n", strerror(errno)); 252 (void) close(fd); 253 dapl_os_unlock(&g_tavor_state_lock); 254 return (DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 0)); 255 } 256 257 g_tavor_state[idx].hca_fd = fd; 258 g_tavor_state[idx].uarpg_baseaddr = mapaddr; 259 g_tavor_state[idx].uarpg_size = pagesize; 260 261 if (try_blueflame == 0) 262 goto done; 263 264 /* Try to do the Hermon Blueflame page mapping */ 265 uarpg_offset = (((off64_t)cur_pid << MLNX_UMAP_RSRC_TYPE_SHIFT) | 266 MLNX_UMAP_BLUEFLAMEPG_RSRC) * pagesize; 267 268 mapaddr = mmap64((void *)0, pagesize, PROT_READ | PROT_WRITE, 269 MAP_SHARED, fd, uarpg_offset); 270 if (mapaddr == MAP_FAILED) { 271 /* This is not considered to be fatal. Charge on! */ 272 dapl_dbg_log(DAPL_DBG_TYPE_WARN, 273 "process_tavor: mmap of blueflame page failed %s\n", 274 strerror(errno)); 275 } else { 276 g_tavor_state[idx].bf_pg_baseaddr = mapaddr; 277 } 278 done: 279 dapl_os_unlock(&g_tavor_state_lock); 280 281 *hca_idx = idx; 282 283 return (DAT_SUCCESS); 284 } 285 286 static DAT_RETURN 287 dapli_process_ibd_node(di_node_t node, DAPL_HCA *hca_ptr, int hca_idx) 288 { 289 di_prop_t prop; 290 ib_guid_t hca_guid = 0; 291 struct lifreq lifreq; 292 uint32_t port_num = 0; 293 uint32_t partition_key = 0; 294 int instance, sfd, retval, af; 295 int tmp; 296 int digits; 297 char *drv_name; 298 char addr_buf[64]; 299 300 prop = di_prop_next(node, DI_PROP_NIL); 301 while (prop != DI_PROP_NIL) { 302 char *prop_name; 303 uchar_t *bytep; 304 int *intp, count; 305 306 prop_name = di_prop_name(prop); 307 count = 0; 308 309 if (strcmp(prop_name, PROP_HCA_GUID) == 0) { 310 count = di_prop_bytes(prop, &bytep); 311 dapl_os_assert(count == sizeof (ib_guid_t)); 312 (void) dapl_os_memcpy((void *)&hca_guid, (void *)bytep, 313 sizeof (ib_guid_t)); 314 } else if (strcmp(prop_name, PROP_PORT_NUM) == 0) { 315 count = di_prop_ints(prop, &intp); 316 dapl_os_assert(count == 1); 317 port_num = (uint32_t)intp[0]; 318 } else if (strcmp(prop_name, PROP_PORT_PKEY) == 0) { 319 count = di_prop_ints(prop, &intp); 320 dapl_os_assert(count == 1); 321 partition_key = (uint32_t)intp[0]; 322 } 323 prop = di_prop_next(node, prop); 324 } 325 if (hca_guid == 0 || port_num == 0 || partition_key == 0) { 326 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 327 "process_ibd: invalid properties: guid 0x%016llx, " 328 "port %d, pkey 0x%08x\n", hca_guid, port_num, 329 partition_key); 330 return (DAT_ERROR(DAT_INVALID_PARAMETER, 0)); 331 } 332 333 /* 334 * if an interface has both v4 and v6 addresses plumbed, 335 * we'll take the v4 address. 336 */ 337 af = AF_INET; 338 again: 339 sfd = socket(af, SOCK_DGRAM, 0); 340 if (sfd < 0) { 341 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 342 "process_ibd: socket failed: %s\n", strerror(errno)); 343 return (DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 0)); 344 } 345 instance = di_instance(node); 346 drv_name = di_driver_name(node); 347 348 /* calculate the number of digits in instance */ 349 tmp = instance; 350 digits = 0; 351 do { 352 tmp = tmp / 10; 353 digits++; 354 } while (tmp > 0); 355 /* check if name will fit in lifr_name */ 356 if (dapl_os_strlen(drv_name) + digits + 1 > LIFNAMSIZ) { 357 (void) close(sfd); 358 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 359 "process_ibd: if name overflow %s:%d\n", 360 drv_name, instance); 361 return (DAT_ERROR(DAT_INVALID_PARAMETER, 0)); 362 } 363 364 (void) dapl_os_strcpy(lifreq.lifr_name, drv_name); 365 (void) sprintf(&lifreq.lifr_name[dapl_os_strlen(drv_name)], "%d", 366 instance); 367 retval = ioctl(sfd, SIOCGLIFADDR, (caddr_t)&lifreq); 368 if (retval < 0) { 369 (void) close(sfd); 370 if (af == AF_INET6) { 371 /* 372 * the interface is not plumbed. 373 */ 374 dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 375 "process_ibd: %s: ip address not found\n", 376 lifreq.lifr_name); 377 return (DAT_ERROR(DAT_INSUFFICIENT_RESOURCES, 0)); 378 } else { 379 /* 380 * we've failed to find a v4 address. now 381 * let's try v6. 382 */ 383 af = AF_INET6; 384 goto again; 385 } 386 } 387 (void) close(sfd); 388 389 hca_ptr->hca_ibd_inst = instance; 390 hca_ptr->tavor_idx = hca_idx; 391 hca_ptr->node_GUID = hca_guid; 392 hca_ptr->port_num = port_num; 393 hca_ptr->partition_key = partition_key; 394 (void) dapl_os_memcpy((void *)&hca_ptr->hca_address, 395 (void *)&lifreq.lifr_addr, sizeof (hca_ptr->hca_address)); 396 hca_ptr->max_inline_send = dapls_tavor_max_inline(); 397 398 dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 399 "process_ibd: interface %s, hca guid 0x%016llx, port %d, " 400 "pkey 0x%08x, ip addr %s\n", lifreq.lifr_name, hca_guid, 401 port_num, partition_key, dapls_inet_ntop( 402 (struct sockaddr *)&hca_ptr->hca_address, addr_buf, 64)); 403 return (DAT_SUCCESS); 404 } 405 406 void 407 dapls_ib_state_init(void) 408 { 409 int i; 410 411 (void) dapl_os_lock_init(&g_tavor_state_lock); 412 (void) dapl_os_lock_init(&g_tavor_uar_lock); 413 (void) dapl_os_lock_init(&dapls_ib_dbp_lock); 414 415 for (i = 0; i < MAX_HCAS; i++) { 416 g_tavor_state[i].hca_fd = 0; 417 g_tavor_state[i].uarpg_baseaddr = NULL; 418 g_tavor_state[i].uarpg_size = 0; 419 g_tavor_state[i].bf_pg_baseaddr = NULL; 420 } 421 } 422 423 void 424 dapls_ib_state_fini(void) 425 { 426 int i, count = 0; 427 428 /* 429 * Uinitialize the per hca instance state 430 */ 431 dapl_os_lock(&g_tavor_state_lock); 432 for (i = 0; i < MAX_HCAS; i++) { 433 if (g_tavor_state[i].uarpg_size == 0) { 434 dapl_os_assert(g_tavor_state[i].uarpg_baseaddr == 435 NULL); 436 continue; 437 } 438 if (munmap(g_tavor_state[i].uarpg_baseaddr, 439 g_tavor_state[i].uarpg_size) < 0) { 440 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 441 "ib_state_fini: " 442 "munmap(0x%p, 0x%llx) failed(%d)\n", 443 g_tavor_state[i].uarpg_baseaddr, 444 g_tavor_state[i].uarpg_size, errno); 445 } 446 if ((g_tavor_state[i].bf_pg_baseaddr != NULL) && 447 (munmap(g_tavor_state[i].bf_pg_baseaddr, 448 g_tavor_state[i].uarpg_size) < 0)) { 449 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 450 "ib_state_fini: " 451 "munmap(0x%p, 0x%llx) of blueflame failed(%d)\n", 452 g_tavor_state[i].bf_pg_baseaddr, 453 g_tavor_state[i].uarpg_size, errno); 454 } 455 456 (void) close(g_tavor_state[i].hca_fd); 457 count++; 458 } 459 dapl_os_unlock(&g_tavor_state_lock); 460 461 dapl_os_lock_destroy(&g_tavor_uar_lock); 462 dapl_os_lock_destroy(&g_tavor_state_lock); 463 dapl_os_lock_destroy(&dapls_ib_dbp_lock); 464 465 dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 466 "ib_state_fini: cleaned %d hcas\n", count); 467 } 468 469 /* 470 * dapls_ib_open_hca 471 * 472 * Open HCA 473 * 474 * Input: 475 * *hca_ptr pointer to hca device 476 * *ib_hca_handle_p pointer to provide HCA handle 477 * 478 * Output: 479 * none 480 * 481 * Return: 482 * DAT_SUCCESS 483 * DAT_INSUFFICIENT_RESOURCES 484 * 485 */ 486 DAT_RETURN 487 dapls_ib_open_hca( 488 IN DAPL_HCA *hca_ptr, 489 OUT ib_hca_handle_t *ib_hca_handle_p) 490 { 491 dapl_ia_create_t args; 492 DAT_RETURN dat_status; 493 struct dapls_ib_hca_handle *hca_p; 494 int fd; 495 #ifndef _LP64 496 int tmpfd; 497 #endif 498 int retval; 499 struct sockaddr *s; 500 struct sockaddr_in6 *v6addr; 501 struct sockaddr_in *v4addr; 502 dapl_ia_addr_t *sap; 503 504 dat_status = dapli_init_hca(hca_ptr); 505 if (dat_status != DAT_SUCCESS) { 506 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 507 "dapls_ib_open_hca: init_hca failed %d\n", dat_status); 508 return (dat_status); 509 } 510 511 fd = open(DEVDAPLT, O_RDONLY); 512 if (fd < 0) { 513 return (DAT_INSUFFICIENT_RESOURCES); 514 } 515 516 #ifndef _LP64 517 /* 518 * libc can't handle fd's greater than 255, in order to 519 * ensure that these values remain available make fd > 255. 520 * Note: not needed for LP64 521 */ 522 tmpfd = fcntl(fd, F_DUPFD, 256); 523 if (tmpfd < 0) { 524 dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 525 "dapls_ib_open_hca: cannot F_DUPFD: %s\n", 526 strerror(errno)); 527 } else { 528 (void) close(fd); 529 fd = tmpfd; 530 } 531 #endif /* _LP64 */ 532 533 if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) { 534 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 535 "dapls_ib_open_hca: cannot F_SETFD: %s\n", strerror(errno)); 536 (void) close(fd); 537 return (DAT_INTERNAL_ERROR); 538 } 539 540 hca_p = (struct dapls_ib_hca_handle *)dapl_os_alloc( 541 sizeof (struct dapls_ib_hca_handle)); 542 if (hca_p == NULL) { 543 (void) close(fd); 544 return (DAT_INSUFFICIENT_RESOURCES); 545 } 546 547 args.ia_guid = hca_ptr->node_GUID; 548 args.ia_port = hca_ptr->port_num; 549 args.ia_pkey = hca_ptr->partition_key; 550 args.ia_version = DAPL_IF_VERSION; 551 (void) dapl_os_memzero((void *)args.ia_sadata, DAPL_ATS_NBYTES); 552 553 /* pass down local ip address to be stored in SA */ 554 s = (struct sockaddr *)&hca_ptr->hca_address; 555 /* LINTED: E_BAD_PTR_CAST_ALIGN */ 556 sap = (dapl_ia_addr_t *)args.ia_sadata; 557 switch (s->sa_family) { 558 case AF_INET: 559 /* LINTED: E_BAD_PTR_CAST_ALIGN */ 560 v4addr = (struct sockaddr_in *)s; 561 sap->iad_v4 = v4addr->sin_addr; 562 break; 563 case AF_INET6: 564 /* LINTED: E_BAD_PTR_CAST_ALIGN */ 565 v6addr = (struct sockaddr_in6 *)s; 566 sap->iad_v6 = v6addr->sin6_addr; 567 break; 568 default: 569 break; /* fall through */ 570 } 571 572 retval = ioctl(fd, DAPL_IA_CREATE, &args); 573 if (retval != 0) { 574 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 575 "open_hca: ia_create failed, fd %d, " 576 "guid 0x%016llx, port %d, pkey 0x%x, version %d\n", 577 fd, args.ia_guid, args.ia_port, args.ia_pkey, 578 args.ia_version); 579 580 dapl_os_free(hca_p, sizeof (*hca_p)); 581 (void) close(fd); 582 return (dapls_convert_error(errno, retval)); 583 } 584 585 hca_p->ia_fd = fd; 586 hca_p->ia_rnum = args.ia_resnum; 587 hca_p->hca_fd = g_tavor_state[hca_ptr->tavor_idx].hca_fd; 588 hca_p->ia_uar = g_tavor_state[hca_ptr->tavor_idx].uarpg_baseaddr; 589 hca_p->ia_bf = g_tavor_state[hca_ptr->tavor_idx].bf_pg_baseaddr; 590 hca_p->ia_bf_toggle = 0; 591 *ib_hca_handle_p = hca_p; 592 dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 593 "open_hca: ia_created, hca_p 0x%p, fd %d, " 594 "rnum %d, guid 0x%016llx, port %d, pkey 0x%x\n", 595 hca_p, hca_p->ia_fd, hca_p->ia_rnum, hca_ptr->node_GUID, 596 hca_ptr->port_num, hca_ptr->partition_key); 597 598 return (DAT_SUCCESS); 599 } 600 601 /* 602 * dapls_ib_close_hca 603 * 604 * Open HCA 605 * 606 * Input: 607 * ib_hca_handle provide HCA handle 608 * 609 * Output: 610 * none 611 * 612 * Return: 613 * DAT_SUCCESS 614 * DAT_INSUFFICIENT_RESOURCES 615 * 616 */ 617 DAT_RETURN 618 dapls_ib_close_hca( 619 IN ib_hca_handle_t ib_hca_handle) 620 { 621 if (ib_hca_handle == NULL) { 622 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 623 "close_hca: ib_hca_handle == NULL\n"); 624 return (DAT_SUCCESS); 625 } 626 dapl_dbg_log(DAPL_DBG_TYPE_UTIL, 627 "close_hca: closing hca 0x%p, fd %d, rnum %d\n", 628 ib_hca_handle, ib_hca_handle->ia_fd, ib_hca_handle->ia_rnum); 629 630 (void) close(ib_hca_handle->ia_fd); 631 dapl_os_free((void *)ib_hca_handle, 632 sizeof (struct dapls_ib_hca_handle)); 633 return (DAT_SUCCESS); 634 } 635 636 #if defined(IBHOSTS_NAMING) 637 #define LINE_LEN 256 638 static int 639 dapli_process_fake_ibds(DAPL_HCA *hca_ptr, int hca_idx) 640 { 641 char line_buf[LINE_LEN]; 642 char host_buf[LINE_LEN]; 643 char localhost[LINE_LEN]; 644 ib_guid_t prefix; 645 ib_guid_t guid; 646 FILE *fp; 647 int count = 0; 648 DAPL_HCA *hca_ptr; 649 650 fp = fopen("/etc/dapl/ibhosts", "r"); 651 if (fp == NULL) { 652 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 653 "fake_ibds: ibhosts not found!\n"); 654 return (0); 655 } 656 if (gethostname(localhost, LINE_LEN) != 0) { 657 dapl_dbg_log(DAPL_DBG_TYPE_ERR, 658 "fake_ibds: hostname not found!\n"); 659 return (0); 660 } 661 while (!feof(fp)) { 662 (void) fgets(line_buf, LINE_LEN, fp); 663 sscanf(line_buf, "%s %llx %llx", host_buf, &prefix, &guid); 664 (void) sprintf(line_buf, "%s-ib%d", localhost, count + 1); 665 if (strncmp(line_buf, host_buf, strlen(line_buf)) == 0) { 666 guid &= 0xfffffffffffffff0; 667 hca_ptr->hca_ibd_inst = count + 1; 668 hca_ptr->tavor_idx = hca_idx; 669 hca_ptr->node_GUID = guid; 670 hca_ptr->port_num = count + 1; 671 hca_ptr->partition_key = 0x0000ffff; 672 count++; 673 } 674 if (count >= 2) break; 675 } 676 (void) fclose(fp); 677 return (count); 678 } 679 680 #endif /* IBHOSTS_NAMING */ 681