1/* 2 * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved. 4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5 * 6 * This software is available to you under a choice of one of two 7 * licenses. You may choose to be licensed under the terms of the GNU 8 * General Public License (GPL) Version 2, available from the file 9 * COPYING in the main directory of this source tree, or the 10 * OpenIB.org BSD license below: 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above 17 * copyright notice, this list of conditions and the following 18 * disclaimer. 19 * 20 * - Redistributions in binary form must reproduce the above 21 * copyright notice, this list of conditions and the following 22 * disclaimer in the documentation and/or other materials 23 * provided with the distribution. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 * SOFTWARE. 33 * 34 */ 35 36#if HAVE_CONFIG_H 37# include <config.h> 38#endif /* HAVE_CONFIG_H */ 39 40#if defined(OSM_VENDOR_INTF_SIM) 41#undef IN 42#undef OUT 43 44#include <unistd.h> 45#include <vendor/osm_vendor_api.h> 46#include <opensm/osm_log.h> 47#include <stdlib.h> 48#include <stdio.h> 49#include <sys/types.h> 50#include <dirent.h> 51#include <stdlib.h> 52#include <sys/stat.h> 53#include <stdint.h> 54#include <fcntl.h> 55 56/****************************************************************************** 57* 58* Provides the functionality for selecting an HCA Port and Obtaining it's guid. 59* This version is based on $IBMGTSIM_DIR/$IBMGTSIM_NODE file system. 60* This is a mimic of the OpenIB gen1 file system 61* 62******************************************************************************/ 63 64char *__get_simulator_dir(void) 65{ 66 static char *ibmgtSimDir = NULL; 67 static char *defaultIbmgtSimDir = "/tmp/ibmgtsim"; 68 static char *ibmgtSimNode = NULL; 69 static char dirName[1024]; 70 71 /* we use the first pointer to know if we were here */ 72 if (ibmgtSimDir == NULL) { 73 /* obtain the simulator directory */ 74 ibmgtSimDir = getenv("IBMGTSIM_DIR"); 75 if (ibmgtSimDir == NULL) { 76 printf 77 ("-W- Environment variable: IBMGTSIM_DIR does not exist.\n"); 78 printf 79 (" Please create one used by the simulator.\n"); 80 printf(" Using /tmp/ibmgtsim as default.\n"); 81 ibmgtSimDir = defaultIbmgtSimDir; 82 } 83 84 /* obtain the node name we simulate */ 85 ibmgtSimNode = getenv("IBMGTSIM_NODE"); 86 if (ibmgtSimNode == NULL) { 87 printf 88 ("-W- Environment variable: IBMGTSIM_NODE does not exist.\n"); 89 printf 90 (" This variable should be the name of the node you wish to simulate.\n"); 91 printf(" Using H-1 as default.\n"); 92 ibmgtSimNode = "H-1"; 93 } 94 sprintf(dirName, "%s/%s", ibmgtSimDir, ibmgtSimNode); 95 } 96 97 return dirName; 98} 99 100typedef struct _osm_ca_info { 101 ib_net64_t guid; 102 size_t attr_size; 103 ib_ca_attr_t *p_attr; 104 105} osm_ca_info_t; 106 107/********************************************************************** 108 * Returns a pointer to the port attribute of the specified port 109 * owned by this CA. 110 ************************************************************************/ 111static ib_port_attr_t *__osm_ca_info_get_port_attr_ptr(IN const osm_ca_info_t * 112 const p_ca_info, 113 IN const uint8_t index) 114{ 115 return (&p_ca_info->p_attr->p_port_attr[index]); 116} 117 118/********************************************************************** 119 * Obtain the number of local CAs by scanning /proc/infiniband/core 120 **********************************************************************/ 121int __hca_sim_get_num_cas(void) 122{ 123 int num_cas = 0; 124 DIR *dp; 125 struct dirent *ep; 126 127 dp = opendir(__get_simulator_dir()); 128 129 if (dp != NULL) { 130 while ((ep = readdir(dp))) { 131 /* CAs are directories with the format ca[1-9][0-9]* */ 132 /* if ((ep->d_type == DT_DIR) && !strncmp(ep->d_name, "ca", 2)) */ 133 if (!strncmp(ep->d_name, "ca", 2)) { 134 num_cas++; 135 } 136 } 137 closedir(dp); 138 } else { 139 printf("__hca_sim_get_num_cas: ERROR : ail to open dir %s\n", 140 __get_simulator_dir()); 141 exit(1); 142 } 143 144 if (!num_cas) 145 exit(1); 146 return num_cas; 147} 148 149/* 150 name: InfiniHost0 151 provider: tavor 152 node GUID: 0002:c900:0120:3470 153 ports: 2 154 vendor ID: 0x2c9 155 device ID: 0x5a44 156 HW revision: 0xa1 157 FW revision: 0x300020080 158*/ 159typedef struct _sim_ca_info { 160 char name[32]; 161 char provider[32]; 162 uint64_t guid; 163 uint8_t num_ports; 164 uint32_t vend_id; 165 uint16_t dev_id; 166 uint16_t rev_id; 167 uint64_t fw_rev; 168} sim_ca_info_t; 169 170/********************************************************************** 171 * Parse the CA Info file available in ibmgtSimDir/caN/info 172 **********************************************************************/ 173static ib_api_status_t 174__parse_ca_info_file(IN osm_vendor_t * const p_vend, 175 IN uint32_t idx, OUT sim_ca_info_t * sim_ca_info) 176{ 177 ib_api_status_t status = IB_ERROR; 178 int info_file; 179 char file_name[256]; 180 char file_buffer[3200]; 181 char *p_ch; 182 int g1, g2, g3, g4; 183 int num_ports; 184 uint32_t len; 185 186 OSM_LOG_ENTER(p_vend->p_log); 187 188 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 189 "__parse_ca_info_file: " "Querying CA %d.\n", idx); 190 191 /* we use the proc file system so we must be able to open the info file .. */ 192 sprintf(file_name, "%s/ca%d/info", __get_simulator_dir(), idx); 193 info_file = open(file_name, O_RDONLY); 194 if (!info_file) { 195 osm_log(p_vend->p_log, OSM_LOG_ERROR, 196 "__parse_ca_info_file: ERR 5105: " 197 "Fail to open HCA:%d info file:(%s).\n", idx, 198 file_name); 199 goto Exit; 200 } 201 202 /* read in the file */ 203 len = read(info_file, file_buffer, 3200); 204 close(info_file); 205 file_buffer[len] = '\0'; 206 207 /* 208 parse the file ... 209 name: InfiniHost0 210 provider: tavor 211 node GUID: 0002:c900:0120:3470 212 ports: 2 213 vendor ID: 0x2c9 214 device ID: 0x5a44 215 HW revision: 0xa1 216 FW revision: 0x300020080 217 */ 218 if (!(p_ch = strstr(file_buffer, "name:"))) { 219 osm_log(p_vend->p_log, OSM_LOG_ERROR, 220 "__parse_ca_info_file: ERR 5106: " 221 "Fail to obtain HCA name. In info file:(%s).\n", 222 file_buffer); 223 goto Exit; 224 } 225 if (sscanf(p_ch, "name: %s", sim_ca_info->name) != 1) { 226 osm_log(p_vend->p_log, OSM_LOG_ERROR, 227 "__parse_ca_info_file: ERR 5107: " 228 "Fail to parse name in info file:(%s).\n", p_ch); 229 goto Exit; 230 } 231 232 /* get the guid of the HCA */ 233 if (!(p_ch = strstr(file_buffer, "node GUID:"))) { 234 osm_log(p_vend->p_log, OSM_LOG_ERROR, 235 "__parse_ca_info_file: ERR 5108: " 236 "Fail to obtain GUID in info file:(%s).\n", 237 file_buffer); 238 goto Exit; 239 } 240 if (sscanf(p_ch, "node GUID: %x:%x:%x:%x", &g1, &g2, &g3, &g4) != 4) { 241 osm_log(p_vend->p_log, OSM_LOG_ERROR, 242 "__parse_ca_info_file: ERR 5109: " 243 "Fail to parse GUID in info file:(%s).\n", p_ch); 244 goto Exit; 245 } 246 sim_ca_info->guid = (uint64_t) g1 << 48 | (uint64_t) g1 << 32 247 | (uint64_t) g1 << 16 | (uint64_t) g3; 248 249 /* obtain number of ports */ 250 if (!(p_ch = strstr(file_buffer, "ports:"))) { 251 osm_log(p_vend->p_log, OSM_LOG_ERROR, 252 "__parse_ca_info_file: ERR 5110: " 253 "Fail to obtain number of ports in info file:(%s).\n", 254 file_buffer); 255 goto Exit; 256 } 257 if (sscanf(p_ch, "ports: %d", &num_ports) != 1) { 258 osm_log(p_vend->p_log, OSM_LOG_ERROR, 259 "__parse_ca_info_file: ERR 5111: " 260 "Fail to parse num ports in info file:(%s).\n", p_ch); 261 goto Exit; 262 } 263 sim_ca_info->num_ports = num_ports; 264 265 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 266 "__parse_ca_info_file: " 267 "CA1 = name:%s guid:0x%" PRIx64 " ports:%d\n", 268 sim_ca_info->name, sim_ca_info->guid, sim_ca_info->num_ports); 269 270 status = IB_SUCCESS; 271Exit: 272 OSM_LOG_EXIT(p_vend->p_log); 273 return status; 274} 275 276/* 277 state: ACTIVE 278 LID: 0x0001 279 LMC: 0x0000 280 SM LID: 0x0001 281 SM SL: 0x0000 282 Capabilities: IsSM 283 IsTrapSupported 284 IsAutomaticMigrationSupported 285 IsSLMappingSupported 286 IsLEDInfoSupported 287 IsSystemImageGUIDSupported 288 IsVendorClassSupported 289 IsCapabilityMaskNoticeSupported 290*/ 291typedef struct _sim_port_info { 292 uint8_t state; 293 uint16_t lid; 294 uint8_t lmc; 295 uint16_t sm_lid; 296 uint8_t sm_sl; 297} sim_port_info_t; 298 299/********************************************************************** 300 * Parse the Port Info file available in ibmgtSimDir/caN/portM/info 301 * Port num is 1..N 302 **********************************************************************/ 303static ib_api_status_t 304__parse_port_info_file(IN osm_vendor_t * const p_vend, 305 IN uint32_t hca_idx, 306 IN uint8_t port_num, OUT sim_port_info_t * sim_port_info) 307{ 308 ib_api_status_t status = IB_ERROR; 309 int info_file; 310 char file_name[256]; 311 char file_buffer[3200]; 312 char state[12]; 313 char *p_ch; 314 int lid, sm_lid, lmc, sm_sl; 315 uint32_t len; 316 317 OSM_LOG_ENTER(p_vend->p_log); 318 319 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 320 "__parse_port_info_file: " 321 "Parsing Proc File System Port Info CA %d Port %d.\n", hca_idx, 322 port_num); 323 324 /* we use the proc file system so we must be able to open the info file .. */ 325 sprintf(file_name, "%s/ca%d/port%d/info", __get_simulator_dir(), 326 hca_idx, port_num); 327 info_file = open(file_name, O_RDONLY); 328 if (!info_file) { 329 osm_log(p_vend->p_log, OSM_LOG_ERROR, 330 "__parse_port_info_file: ERR 5112: " 331 "Fail to open HCA:%d Port:%d info file:(%s).\n", 332 hca_idx, port_num, file_name); 333 goto Exit; 334 } 335 336 /* read in the file */ 337 len = read(info_file, file_buffer, 3200); 338 close(info_file); 339 file_buffer[len] = '\0'; 340 341 /* 342 parse the file ... 343 state: ACTIVE 344 LID: 0x0001 345 LMC: 0x0000 346 SM LID: 0x0001 347 SM SL: 0x0000 348 ... 349 */ 350 if (!(p_ch = strstr(file_buffer, "state:"))) { 351 osm_log(p_vend->p_log, OSM_LOG_ERROR, 352 "__parse_port_info_file: ERR 5113: " 353 "Fail to obtain port state. In info file:(%s).\n", 354 file_buffer); 355 goto Exit; 356 } 357 if (sscanf(p_ch, "state: %s", state) != 1) { 358 osm_log(p_vend->p_log, OSM_LOG_ERROR, 359 "__parse_port_info_file: ERR 5114: " 360 "Fail to parse state from info file:(%s).\n", p_ch); 361 goto Exit; 362 } 363 364 if (!strcmp(state, "ACTIVE")) 365 sim_port_info->state = IB_LINK_ACTIVE; 366 else if (!strcmp(state, "DOWN")) 367 sim_port_info->state = IB_LINK_DOWN; 368 else if (!strcmp(state, "INIT")) 369 sim_port_info->state = IB_LINK_INIT; 370 else if (!strcmp(state, "ARMED")) 371 sim_port_info->state = IB_LINK_ARMED; 372 else 373 sim_port_info->state = 0; 374 375 /* get lid */ 376 if (!(p_ch = strstr(file_buffer, "LID:"))) { 377 osm_log(p_vend->p_log, OSM_LOG_ERROR, 378 "__parse_port_info_file: ERR 5115: " 379 "Fail to obtain port lid. In info file:(%s).\n", 380 file_buffer); 381 goto Exit; 382 } 383 if (sscanf(p_ch, "LID: %x", &lid) != 1) { 384 osm_log(p_vend->p_log, OSM_LOG_ERROR, 385 "__parse_port_info_file: ERR 5116: " 386 "Fail to parse lid from info file:(%s).\n", p_ch); 387 goto Exit; 388 } 389 sim_port_info->lid = lid; 390 /* get LMC */ 391 if (!(p_ch = strstr(file_buffer, "LMC:"))) { 392 osm_log(p_vend->p_log, OSM_LOG_ERROR, 393 "__parse_port_info_file: ERR 5117: " 394 "Fail to obtain port LMC. In info file:(%s).\n", 395 file_buffer); 396 goto Exit; 397 } 398 if (sscanf(p_ch, "LMC: %x", &lmc) != 1) { 399 osm_log(p_vend->p_log, OSM_LOG_ERROR, 400 "__parse_port_info_file: ERR 5118: " 401 "Fail to parse LMC from info file:(%s).\n", p_ch); 402 goto Exit; 403 } 404 sim_port_info->lmc = lmc; 405 406 /* get SM LID */ 407 if (!(p_ch = strstr(file_buffer, "SM LID:"))) { 408 osm_log(p_vend->p_log, OSM_LOG_ERROR, 409 "__parse_port_info_file: ERR 5119: " 410 "Fail to obtain port SM LID. In info file:(%s).\n", 411 file_buffer); 412 goto Exit; 413 } 414 if (sscanf(p_ch, "SM LID: %x", &sm_lid) != 1) { 415 osm_log(p_vend->p_log, OSM_LOG_ERROR, 416 "__parse_port_info_file: ERR 5120: " 417 "Fail to parse SM LID from info file:(%s).\n", p_ch); 418 goto Exit; 419 } 420 sim_port_info->sm_lid = sm_lid; 421 422 /* get SM LID */ 423 if (!(p_ch = strstr(file_buffer, "SM SL:"))) { 424 osm_log(p_vend->p_log, OSM_LOG_ERROR, 425 "__parse_port_info_file: ERR 5121: " 426 "Fail to obtain port SM SL. In info file:(%s).\n", 427 file_buffer); 428 goto Exit; 429 } 430 if (sscanf(p_ch, "SM SL: %x", &sm_sl) != 1) { 431 osm_log(p_vend->p_log, OSM_LOG_ERROR, 432 "__parse_port_info_file: ERR 5122: " 433 "Fail to parse SM SL from info file:(%s).\n", p_ch); 434 goto Exit; 435 } 436 sim_port_info->sm_sl = sm_sl; 437 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 438 "__parse_port_info_file: " 439 "Obtained Port:%d = state:%d, lid:0x%04X, lmc:%d, sm_lid:0x%04X, sm_sl:%d\n", 440 port_num, sim_port_info->state, sim_port_info->lid, 441 sim_port_info->lmc, sim_port_info->sm_lid, 442 sim_port_info->sm_sl); 443 444 status = IB_SUCCESS; 445Exit: 446 OSM_LOG_EXIT(p_vend->p_log); 447 return status; 448} 449 450/********************************************************************** 451 * Parse the port guid_tbl file to obtain the port guid. 452 * File format is: 453 * [ 0] fe80:0000:0000:0000:0002:c900:0120:3472 454 **********************************************************************/ 455static ib_api_status_t 456__get_port_guid_from_port_gid_tbl(IN osm_vendor_t * const p_vend, 457 IN uint32_t hca_idx, 458 IN uint8_t port_num, OUT uint64_t * port_guid) 459{ 460 ib_api_status_t status = IB_ERROR; 461 int info_file; 462 char file_name[256]; 463 char file_buffer[3200]; 464 char *p_ch; 465 int g[8]; 466 uint32_t len; 467 468 OSM_LOG_ENTER(p_vend->p_log); 469 470 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 471 "__get_port_guid_from_port_gid_tbl: " 472 "Parsing Proc File System Port Guid Table CA %d Port %d.\n", 473 hca_idx, port_num); 474 475 /* we use the proc file system so we must be able to open the info file .. */ 476 sprintf(file_name, "%s/ca%d/port%d/gid_table", 477 __get_simulator_dir(), hca_idx, port_num); 478 info_file = open(file_name, O_RDONLY); 479 if (!info_file) { 480 osm_log(p_vend->p_log, OSM_LOG_ERROR, 481 "__get_port_guid_from_port_gid_tbl: ERR 5123: " 482 "Fail to open HCA:%d Port:%d gid_table file:(%s).\n", 483 hca_idx, port_num, file_name); 484 goto Exit; 485 } 486 487 /* read in the file */ 488 len = read(info_file, file_buffer, 3200); 489 close(info_file); 490 file_buffer[len] = '\0'; 491 492 /* 493 parse the file ... 494 [ 0] fe80:0000:0000:0000:0002:c900:0120:3472 495 ... 496 */ 497 if (!(p_ch = strstr(file_buffer, "[ 0]"))) { 498 osm_log(p_vend->p_log, OSM_LOG_ERROR, 499 "__get_port_guid_from_port_gid_tbl: ERR 5124: " 500 "Fail to obtain first gid index. In gid_table file:(%s).\n", 501 file_buffer); 502 goto Exit; 503 } 504 if (sscanf(p_ch + 6, "%x:%x:%x:%x:%x:%x:%x:%x", 505 &g[7], &g[6], &g[5], &g[4], &g[3], &g[2], &g[1], &g[0]) != 8) 506 { 507 osm_log(p_vend->p_log, OSM_LOG_ERROR, 508 "__get_port_guid_from_port_gid_tbl: ERR 5125: " 509 "Fail to parse gid from gid_table file:(%s).\n", p_ch); 510 goto Exit; 511 } 512 513 *port_guid = 514 (uint64_t) g[3] << 48 | (uint64_t) g[2] << 32 | (uint64_t) g[1] << 515 16 | g[0]; 516 status = IB_SUCCESS; 517Exit: 518 OSM_LOG_EXIT(p_vend->p_log); 519 return status; 520} 521 522/********************************************************************** 523 * Initialize an Info Struct for the Given HCA by its index 1..N 524 **********************************************************************/ 525static ib_api_status_t 526__osm_ca_info_init(IN osm_vendor_t * const p_vend, 527 IN uint32_t const idx, OUT osm_ca_info_t * const p_ca_info) 528{ 529 ib_api_status_t status = IB_ERROR; 530 uint8_t port_num; 531 uint64_t port_guid; 532 533 sim_ca_info_t sim_ca_info; 534 535 OSM_LOG_ENTER(p_vend->p_log); 536 537 /* parse the CA info file */ 538 if (__parse_ca_info_file(p_vend, idx, &sim_ca_info) != IB_SUCCESS) 539 goto Exit; 540 541 p_ca_info->guid = cl_hton64(sim_ca_info.guid); 542 543 /* set size of attributes and allocate them */ 544 p_ca_info->attr_size = 1; 545 p_ca_info->p_attr = (ib_ca_attr_t *) malloc(sizeof(ib_ca_attr_t)); 546 547 p_ca_info->p_attr->ca_guid = p_ca_info->guid; 548 p_ca_info->p_attr->num_ports = sim_ca_info.num_ports; 549 550 /* now obtain the attributes of the ports */ 551 p_ca_info->p_attr->p_port_attr = 552 (ib_port_attr_t *) malloc(sim_ca_info.num_ports * 553 sizeof(ib_port_attr_t)); 554 555 /* get all the ports info */ 556 for (port_num = 1; port_num <= sim_ca_info.num_ports; port_num++) { 557 sim_port_info_t sim_port_info; 558 /* query the port attributes */ 559 if (__parse_port_info_file 560 (p_vend, idx, port_num, &sim_port_info)) { 561 osm_log(p_vend->p_log, OSM_LOG_ERROR, 562 "__osm_ca_info_init: ERR 5126: " 563 "Fail to get HCA:%d Port:%d Attributes.\n", idx, 564 port_num); 565 goto Exit; 566 } 567 568 /* HACK: the lids should have been converted to network but the rest of the code 569 is wrong and provdes them as is (host order) - so we stick with it. */ 570 p_ca_info->p_attr->p_port_attr[port_num - 1].lid = 571 sim_port_info.lid; 572 p_ca_info->p_attr->p_port_attr[port_num - 1].link_state = 573 sim_port_info.state; 574 p_ca_info->p_attr->p_port_attr[port_num - 1].sm_lid = 575 sim_port_info.sm_lid; 576 577 /* get the port guid */ 578 if (__get_port_guid_from_port_gid_tbl 579 (p_vend, idx, port_num, &port_guid)) { 580 osm_log(p_vend->p_log, OSM_LOG_ERROR, 581 "__osm_ca_info_init: ERR 5127: " 582 "Fail to get HCA:%d Port:%d Guid.\n", idx, 583 port_num); 584 goto Exit; 585 } 586 p_ca_info->p_attr->p_port_attr[port_num - 1].port_guid = 587 cl_hton64(port_guid); 588 } 589 590 status = IB_SUCCESS; 591Exit: 592 OSM_LOG_EXIT(p_vend->p_log); 593 return (status); 594} 595 596void 597osm_ca_info_destroy(IN osm_vendor_t * const p_vend, 598 IN osm_ca_info_t * const p_ca_info, IN uint8_t num_ca) 599{ 600 osm_ca_info_t *p_ca; 601 uint8_t i; 602 603 OSM_LOG_ENTER(p_vend->p_log); 604 605 for (i = 0; i < num_ca; i++) { 606 p_ca = &p_ca_info[i]; 607 608 if (NULL != p_ca->p_attr) { 609 if (0 != p_ca->p_attr->num_ports) { 610 free(p_ca->p_attr->p_port_attr); 611 } 612 613 free(p_ca->p_attr); 614 } 615 } 616 617 free(p_ca_info); 618 619 OSM_LOG_EXIT(p_vend->p_log); 620} 621 622/********************************************************************** 623 * Fill in the array of port_attr with all available ports on ALL the 624 * avilable CAs on this machine. 625 **********************************************************************/ 626ib_api_status_t 627osm_vendor_get_all_port_attr(IN osm_vendor_t * const p_vend, 628 IN ib_port_attr_t * const p_attr_array, 629 IN uint32_t * const p_num_ports) 630{ 631 ib_api_status_t status = IB_SUCCESS; 632 633 uint32_t caIdx; 634 uint32_t ca_count = 0; 635 uint32_t port_count = 0; 636 uint8_t port_num; 637 uint32_t total_ports = 0; 638 osm_ca_info_t *p_ca_infos = NULL; 639 uint32_t attr_array_sz = *p_num_ports; 640 641 OSM_LOG_ENTER(p_vend->p_log); 642 643 CL_ASSERT(p_vend); 644 645 /* determine the number of CA's */ 646 ca_count = __hca_sim_get_num_cas(); 647 if (!ca_count) { 648 osm_log(p_vend->p_log, OSM_LOG_ERROR, 649 "osm_vendor_get_all_port_attr: ERR 5128: " 650 "Fail to get Any CA Ids.\n"); 651 goto Exit; 652 } 653 654 /* Allocate an array big enough to hold the ca info objects */ 655 p_ca_infos = malloc(ca_count * sizeof(osm_ca_info_t)); 656 if (p_ca_infos == NULL) { 657 osm_log(p_vend->p_log, OSM_LOG_ERROR, 658 "osm_vendor_get_all_port_attr: ERR 5129: " 659 "Unable to allocate CA information array.\n"); 660 goto Exit; 661 } 662 663 memset(p_ca_infos, 0, ca_count * sizeof(osm_ca_info_t)); 664 665 /* 666 * For each CA, retrieve the CA info attributes 667 */ 668 for (caIdx = 1; caIdx <= ca_count; caIdx++) { 669 status = 670 __osm_ca_info_init(p_vend, caIdx, &p_ca_infos[caIdx - 1]); 671 if (status != IB_SUCCESS) { 672 osm_log(p_vend->p_log, OSM_LOG_ERROR, 673 "osm_vendor_get_all_port_attr: ERR 5130: " 674 "Unable to initialize CA Info object (%s).\n", 675 ib_get_err_str(status)); 676 goto Exit; 677 } 678 total_ports += p_ca_infos[caIdx - 1].p_attr->num_ports; 679 } 680 681 *p_num_ports = total_ports; 682 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 683 "osm_vendor_get_all_port_attr: total ports:%u \n", total_ports); 684 685 /* 686 * If the user supplied enough storage, return the port guids, 687 * otherwise, return the appropriate error. 688 */ 689 if (attr_array_sz >= total_ports) { 690 for (caIdx = 1; caIdx <= ca_count; caIdx++) { 691 uint32_t num_ports; 692 693 num_ports = p_ca_infos[caIdx - 1].p_attr->num_ports; 694 695 for (port_num = 0; port_num < num_ports; port_num++) { 696 p_attr_array[port_count] = 697 *__osm_ca_info_get_port_attr_ptr(&p_ca_infos 698 [caIdx - 699 1], 700 port_num); 701 port_count++; 702 } 703 } 704 } else { 705 status = IB_INSUFFICIENT_MEMORY; 706 goto Exit; 707 } 708 709 status = IB_SUCCESS; 710 711Exit: 712 if (p_ca_infos) { 713 osm_ca_info_destroy(p_vend, p_ca_infos, ca_count); 714 } 715 716 OSM_LOG_EXIT(p_vend->p_log); 717 return (status); 718} 719 720/********************************************************************** 721 * Given the vendor obj and a port guid 722 * return the ca id and port number that have that guid 723 **********************************************************************/ 724 725ib_api_status_t 726osm_vendor_get_guid_ca_and_port(IN osm_vendor_t * const p_vend, 727 IN ib_net64_t const guid, 728 OUT uint32_t * p_hca_hndl, 729 OUT char *p_hca_id, 730 OUT uint8_t * p_hca_idx, 731 OUT uint32_t * p_port_num) 732{ 733 uint32_t caIdx; 734 uint32_t ca_count = 0; 735 uint8_t port_num; 736 ib_api_status_t status = IB_ERROR; 737 738 OSM_LOG_ENTER(p_vend->p_log); 739 740 CL_ASSERT(p_vend); 741 742 /* determine the number of CA's */ 743 ca_count = __hca_sim_get_num_cas(); 744 if (!ca_count) { 745 osm_log(p_vend->p_log, OSM_LOG_ERROR, 746 "osm_vendor_get_guid_ca_and_port: ERR 5131: " 747 "Fail to get Any CA Ids.\n"); 748 goto Exit; 749 } 750 751 /* 752 * For each CA, retrieve the CA info attributes 753 */ 754 for (caIdx = 1; caIdx <= ca_count; caIdx++) { 755 sim_ca_info_t sim_ca_info; 756 if (__parse_ca_info_file(p_vend, caIdx, &sim_ca_info) == 757 IB_SUCCESS) { 758 /* get all the ports info */ 759 for (port_num = 1; port_num <= sim_ca_info.num_ports; 760 port_num++) { 761 uint64_t port_guid; 762 if (!__get_port_guid_from_port_gid_tbl 763 (p_vend, caIdx, port_num, &port_guid)) { 764 if (cl_hton64(port_guid) == guid) { 765 osm_log(p_vend->p_log, 766 OSM_LOG_DEBUG, 767 "osm_vendor_get_guid_ca_and_port: " 768 "Found Matching guid on HCA:%d Port:%d.\n", 769 caIdx, port_num); 770 strcpy(p_hca_id, 771 sim_ca_info.name); 772 *p_port_num = port_num; 773 *p_hca_idx = caIdx - 1; 774 *p_hca_hndl = 0; 775 status = IB_SUCCESS; 776 goto Exit; 777 } 778 } 779 } 780 } 781 } 782 783 osm_log(p_vend->p_log, OSM_LOG_ERROR, 784 "osm_vendor_get_guid_ca_and_port: ERR 5132: " 785 "Fail to find HCA and Port for Port Guid 0x%" PRIx64 "\n", 786 cl_ntoh64(guid)); 787 status = IB_INVALID_GUID; 788 789Exit: 790 791 OSM_LOG_EXIT(p_vend->p_log); 792 return (status); 793} 794 795/********************************************************************** 796 * Given the vendor obj HCA ID and Port Num 797 * update the given port guid if found. Return 0 on success. 798 **********************************************************************/ 799 800ib_api_status_t 801osm_vendor_get_guid_by_ca_and_port(IN osm_vendor_t * const p_vend, 802 IN char *hca_id, 803 IN uint32_t port_num, 804 OUT uint64_t * p_port_guid) 805{ 806 uint32_t caIdx; 807 uint32_t ca_count = 0; 808 ib_api_status_t status = IB_ERROR; 809 810 OSM_LOG_ENTER(p_vend->p_log); 811 812 CL_ASSERT(p_vend); 813 814 /* determine the number of CA's */ 815 ca_count = __hca_sim_get_num_cas(); 816 if (!ca_count) { 817 osm_log(p_vend->p_log, OSM_LOG_ERROR, 818 "osm_vendor_get_guid_by_ca_and_port: ERR 5133: " 819 "Fail to get Any CA Ids.\n"); 820 goto Exit; 821 } 822 823 /* 824 * For each CA, retrieve the CA info attributes 825 */ 826 for (caIdx = 1; caIdx <= ca_count; caIdx++) { 827 sim_ca_info_t sim_ca_info; 828 if (__parse_ca_info_file(p_vend, caIdx, &sim_ca_info) == 829 IB_SUCCESS) { 830 /* if not identical by id - go to next one */ 831 if (strcmp(sim_ca_info.name, hca_id)) 832 continue; 833 834 if ((port_num < 1) 835 || (port_num > sim_ca_info.num_ports)) { 836 return 1; 837 } 838 839 if (!__get_port_guid_from_port_gid_tbl 840 (p_vend, caIdx, port_num, p_port_guid)) { 841 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 842 "osm_vendor_get_guid_by_ca_and_port: " 843 "Found Matching guid on HCA:%d Port:%d.\n", 844 caIdx, port_num); 845 status = IB_SUCCESS; 846 goto Exit; 847 } 848 } 849 } 850 851 osm_log(p_vend->p_log, OSM_LOG_ERROR, 852 "osm_vendor_get_guid_by_ca_and_port: ERR 5134: " 853 "Fail to find HCA:%s\n", hca_id); 854 status = IB_INVALID_GUID; 855 856Exit: 857 858 OSM_LOG_EXIT(p_vend->p_log); 859 return (status); 860} 861 862#endif 863