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/* 37 * Abstract: 38 * Implementation of osm_req_t. 39 * This object represents the generic attribute requester. 40 * This object is part of the opensm family of objects. 41 * 42 */ 43 44/* 45 Next available error code: 0x300 46*/ 47 48#if HAVE_CONFIG_H 49# include <config.h> 50#endif /* HAVE_CONFIG_H */ 51 52#ifdef OSM_VENDOR_INTF_AL 53 54#include <stdlib.h> 55#include <string.h> 56#include <complib/cl_qlist.h> 57#include <complib/cl_thread.h> 58#include <complib/cl_math.h> 59#include <complib/cl_debug.h> 60#include <iba/ib_types.h> 61#include <opensm/osm_madw.h> 62#include <opensm/osm_log.h> 63#include <opensm/osm_mad_pool.h> 64#include <vendor/osm_vendor_api.h> 65 66/****s* OpenSM: Vendor AL/osm_al_bind_info_t 67 * NAME 68 * osm_al_bind_info_t 69 * 70 * DESCRIPTION 71 * Structure containing bind information. 72 * 73 * SYNOPSIS 74 */ 75typedef struct _osm_al_bind_info { 76 osm_vendor_t *p_vend; 77 void *client_context; 78 ib_qp_handle_t h_qp; 79 ib_mad_svc_handle_t h_svc; 80 uint8_t port_num; 81 ib_pool_key_t pool_key; 82 osm_vend_mad_recv_callback_t rcv_callback; 83 osm_vend_mad_send_err_callback_t send_err_callback; 84 osm_mad_pool_t *p_osm_pool; 85 ib_av_handle_t h_dr_av; 86 87} osm_al_bind_info_t; 88/* 89 * FIELDS 90 * p_vend 91 * Pointer to the vendor object. 92 * 93 * client_context 94 * User's context passed during osm_bind 95 * 96 * h_qp 97 * Handle the QP for this bind. 98 * 99 * h_qp_svc 100 * Handle the QP mad service for this bind. 101 * 102 * port_num 103 * Port number (within the HCA) of the bound port. 104 * 105 * pool_key 106 * Pool key returned by all for this QP. 107 * 108 * h_dr_av 109 * Address vector handle used for all directed route SMPs. 110 * 111 * SEE ALSO 112 *********/ 113 114/********************************************************************** 115 **********************************************************************/ 116inline static ib_api_status_t 117__osm_al_convert_wcs(IN ib_wc_status_t const wc_status) 118{ 119 switch (wc_status) { 120 case IB_WCS_SUCCESS: 121 return (IB_SUCCESS); 122 123 case IB_WCS_TIMEOUT_RETRY_ERR: 124 return (IB_TIMEOUT); 125 126 default: 127 return (IB_ERROR); 128 } 129} 130 131/********************************************************************** 132 **********************************************************************/ 133static void __osm_al_ca_err_callback(IN ib_async_event_rec_t * p_async_rec) 134{ 135 osm_vendor_t *p_vend = (osm_vendor_t *) p_async_rec->context; 136 OSM_LOG_ENTER(p_vend->p_log); 137 138 osm_log(p_vend->p_log, OSM_LOG_ERROR, 139 "__osm_al_ca_err_callback: ERR 3B01: " 140 "Event on channel adapter (%s).\n", 141 ib_get_async_event_str(p_async_rec->code)); 142 143 OSM_LOG_EXIT(p_vend->p_log); 144} 145 146/********************************************************************** 147 **********************************************************************/ 148static void __osm_al_ca_destroy_callback(IN void *context) 149{ 150 osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) context; 151 osm_vendor_t *p_vend = p_bind->p_vend; 152 OSM_LOG_ENTER(p_vend->p_log); 153 154 osm_log(p_vend->p_log, OSM_LOG_INFO, 155 "__osm_al_ca_destroy_callback: " 156 "Closing local channel adapter.\n"); 157 158 OSM_LOG_EXIT(p_vend->p_log); 159} 160 161/********************************************************************** 162 **********************************************************************/ 163static void __osm_al_err_callback(IN ib_async_event_rec_t * p_async_rec) 164{ 165 osm_al_bind_info_t *p_bind = 166 (osm_al_bind_info_t *) p_async_rec->context; 167 osm_vendor_t *p_vend = p_bind->p_vend; 168 OSM_LOG_ENTER(p_vend->p_log); 169 170 osm_log(p_vend->p_log, OSM_LOG_ERROR, 171 "__osm_al_err_callback: ERR 3B02: " 172 "Error on QP (%s).\n", 173 ib_get_async_event_str(p_async_rec->code)); 174 175 OSM_LOG_EXIT(p_vend->p_log); 176} 177 178/********************************************************************** 179 **********************************************************************/ 180static void 181__osm_al_send_callback(IN void *mad_svc_context, IN ib_mad_element_t * p_elem) 182{ 183 osm_al_bind_info_t *const p_bind = 184 (osm_al_bind_info_t *) mad_svc_context; 185 osm_vendor_t *const p_vend = p_bind->p_vend; 186 osm_madw_t *const p_madw = (osm_madw_t *) p_elem->context1; 187 osm_vend_wrap_t *const p_vw = osm_madw_get_vend_ptr(p_madw); 188 ib_mad_t *p_mad; 189 190 OSM_LOG_ENTER(p_vend->p_log); 191 192 CL_ASSERT(p_vw); 193 CL_ASSERT(p_vw->h_av); 194 195 /* 196 Destroy the address vector as necessary. 197 */ 198 if (p_vw->h_av != p_bind->h_dr_av) { 199 if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) { 200 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 201 "__osm_al_send_callback: " 202 "Destroying av handle %p.\n", p_vw->h_av); 203 } 204 205 ib_destroy_av(p_vw->h_av); 206 } 207 208 p_mad = ib_get_mad_buf(p_elem); 209 210 if (p_elem->resp_expected) { 211 /* 212 If the send was unsuccessful, notify the user 213 for MADs that were expecting a response. 214 A NULL mad wrapper parameter is the user's clue 215 that the transaction turned sour. 216 217 Otherwise, do nothing for successful sends when a 218 reponse is expected. The mad will be returned to the 219 pool later. 220 */ 221 p_madw->status = __osm_al_convert_wcs(p_elem->status); 222 if (p_elem->status != IB_WCS_SUCCESS) { 223 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 224 "__osm_al_send_callback: " 225 "MAD completed with work queue error: %s.\n", 226 ib_get_wc_status_str(p_elem->status)); 227 /* 228 Return any wrappers to the pool that may have been 229 pre-emptively allocated to handle a receive. 230 */ 231 if (p_vw->p_resp_madw) { 232 osm_mad_pool_put(p_bind->p_osm_pool, 233 p_vw->p_resp_madw); 234 p_vw->p_resp_madw = NULL; 235 } 236 237 p_bind->send_err_callback(p_bind->client_context, 238 p_madw); 239 } 240 } else { 241 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 242 "__osm_al_send_callback: " 243 "Returning MAD to pool, TID = 0x%" PRIx64 ".\n", 244 cl_ntoh64(p_mad->trans_id)); 245 osm_mad_pool_put(p_bind->p_osm_pool, p_madw); 246 goto Exit; 247 } 248 249Exit: 250 OSM_LOG_EXIT(p_vend->p_log); 251} 252 253/********************************************************************** 254 **********************************************************************/ 255static void 256__osm_al_rcv_callback(IN void *mad_svc_context, IN ib_mad_element_t * p_elem) 257{ 258 osm_al_bind_info_t *const p_bind = 259 (osm_al_bind_info_t *) mad_svc_context; 260 osm_vendor_t *const p_vend = p_bind->p_vend; 261 osm_madw_t *p_old_madw; 262 osm_madw_t *p_new_madw; 263 osm_vend_wrap_t *p_old_vw; 264 osm_vend_wrap_t *p_new_vw; 265 ib_mad_t *p_new_mad; 266 osm_mad_addr_t mad_addr; 267 268 OSM_LOG_ENTER(p_vend->p_log); 269 270 CL_ASSERT(p_elem->context1 == NULL); 271 CL_ASSERT(p_elem->context2 == NULL); 272 273 p_new_mad = ib_get_mad_buf(p_elem); 274 275 /* 276 In preperation for initializing the new mad wrapper, 277 Initialize the mad_addr structure for the received wire MAD. 278 */ 279 mad_addr.dest_lid = p_elem->remote_lid; 280 mad_addr.path_bits = p_elem->path_bits; 281 282 /* TO DO - figure out which #define to use for the 2.5 Gb rate... */ 283 mad_addr.static_rate = 0; 284 285 if (p_new_mad->mgmt_class == IB_MCLASS_SUBN_LID || 286 p_new_mad->mgmt_class == IB_MCLASS_SUBN_DIR) { 287 mad_addr.addr_type.smi.source_lid = p_elem->remote_lid; 288 } else { 289 mad_addr.addr_type.gsi.remote_qp = p_elem->remote_qp; 290 mad_addr.addr_type.gsi.remote_qkey = p_elem->remote_qkey; 291 mad_addr.addr_type.gsi.pkey_ix = p_elem->pkey_index; 292 mad_addr.addr_type.gsi.service_level = p_elem->remote_sl; 293 mad_addr.addr_type.gsi.global_route = FALSE; 294 } 295 296 /* 297 If this MAD is a response to a previous request, 298 then grab our pre-allocated MAD wrapper. 299 Otherwise, allocate a new MAD wrapper. 300 */ 301 if (ib_mad_is_response(p_new_mad)) { 302 CL_ASSERT(p_elem->send_context1 != NULL); 303 CL_ASSERT(p_elem->send_context2 == NULL); 304 305 p_old_madw = (osm_madw_t *) p_elem->send_context1; 306 p_old_vw = osm_madw_get_vend_ptr(p_old_madw); 307 p_new_madw = p_old_vw->p_resp_madw; 308 309 CL_ASSERT(p_new_madw); 310 311 osm_madw_init(p_new_madw, p_bind, p_elem->size, &mad_addr); 312 osm_madw_set_mad(p_new_madw, p_new_mad); 313 } else { 314 CL_ASSERT(p_elem->send_context1 == NULL); 315 CL_ASSERT(p_elem->send_context2 == NULL); 316 317 p_new_madw = osm_mad_pool_get_wrapper(p_bind->p_osm_pool, 318 p_bind, p_elem->size, 319 p_new_mad, &mad_addr); 320 } 321 322 CL_ASSERT(p_new_madw); 323 p_new_vw = osm_madw_get_vend_ptr(p_new_madw); 324 325 p_new_vw->h_bind = p_bind; 326 p_new_vw->size = p_elem->size; 327 p_new_vw->p_elem = p_elem; 328 p_new_vw->h_av = 0; 329 p_new_vw->p_resp_madw = NULL; 330 331 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 332 "__osm_al_rcv_callback: " 333 "Calling receive callback function %p.\n", 334 p_bind->rcv_callback); 335 336 p_bind->rcv_callback(p_new_madw, p_bind->client_context, 337 p_elem->send_context1); 338 339 OSM_LOG_EXIT(p_vend->p_log); 340} 341 342/********************************************************************** 343 **********************************************************************/ 344ib_api_status_t 345osm_vendor_init(IN osm_vendor_t * const p_vend, 346 IN osm_log_t * const p_log, IN const uint32_t timeout) 347{ 348 ib_api_status_t status; 349 OSM_LOG_ENTER(p_log); 350 351 p_vend->p_log = p_log; 352 353 /* 354 Open our instance of AL. 355 */ 356 status = ib_open_al(&p_vend->h_al); 357 if (status != IB_SUCCESS) { 358 osm_log(p_vend->p_log, OSM_LOG_ERROR, 359 "osm_vendor_init: ERR 3B03: " 360 "Error opening AL (%s).\n", ib_get_err_str(status)); 361 362 goto Exit; 363 } 364 365 p_vend->timeout = timeout; 366 367Exit: 368 OSM_LOG_EXIT(p_log); 369 return (status); 370} 371 372/********************************************************************** 373 **********************************************************************/ 374osm_vendor_t *osm_vendor_new(IN osm_log_t * const p_log, 375 IN const uint32_t timeout) 376{ 377 ib_api_status_t status; 378 osm_vendor_t *p_vend; 379 380 OSM_LOG_ENTER(p_log); 381 382 p_vend = malloc(sizeof(*p_vend)); 383 if (p_vend == NULL) { 384 osm_log(p_vend->p_log, OSM_LOG_ERROR, 385 "osm_vendor_new: ERR 3B04: " 386 "Unable to allocate vendor object.\n"); 387 goto Exit; 388 } 389 390 memset(p_vend, 0, sizeof(*p_vend)); 391 392 status = osm_vendor_init(p_vend, p_log, timeout); 393 if (status != IB_SUCCESS) { 394 free(p_vend); 395 p_vend = NULL; 396 } 397 398Exit: 399 OSM_LOG_EXIT(p_log); 400 return (p_vend); 401} 402 403/********************************************************************** 404 **********************************************************************/ 405void osm_vendor_delete(IN osm_vendor_t ** const pp_vend) 406{ 407 /* TO DO - fill this in */ 408 ib_close_al((*pp_vend)->h_al); 409 free(*pp_vend); 410 *pp_vend = NULL; 411} 412 413/********************************************************************** 414 **********************************************************************/ 415static ib_api_status_t 416__osm_ca_info_init(IN osm_vendor_t * const p_vend, 417 IN osm_ca_info_t * const p_ca_info, 418 IN const ib_net64_t ca_guid) 419{ 420 ib_api_status_t status; 421 422 OSM_LOG_ENTER(p_vend->p_log); 423 424 p_ca_info->guid = ca_guid; 425 426 if (osm_log_is_active(p_vend->p_log, OSM_LOG_VERBOSE)) { 427 osm_log(p_vend->p_log, OSM_LOG_VERBOSE, 428 "__osm_ca_info_init: " 429 "Querying CA 0x%" PRIx64 ".\n", cl_ntoh64(ca_guid)); 430 } 431 432 status = ib_query_ca_by_guid(p_vend->h_al, ca_guid, NULL, 433 &p_ca_info->attr_size); 434 if ((status != IB_INSUFFICIENT_MEMORY) && (status != IB_SUCCESS)) { 435 osm_log(p_vend->p_log, OSM_LOG_ERROR, 436 "__osm_ca_info_init: ERR 3B05: " 437 "Unexpected status getting CA attributes (%s).\n", 438 ib_get_err_str(status)); 439 goto Exit; 440 } 441 442 CL_ASSERT(p_ca_info->attr_size); 443 444 p_ca_info->p_attr = malloc(p_ca_info->attr_size); 445 if (p_ca_info->p_attr == NULL) { 446 osm_log(p_vend->p_log, OSM_LOG_ERROR, 447 "__osm_ca_info_init: ERR 3B06: " 448 "Unable to allocate attribute storage.\n"); 449 goto Exit; 450 } 451 452 status = ib_query_ca_by_guid(p_vend->h_al, ca_guid, p_ca_info->p_attr, 453 &p_ca_info->attr_size); 454 if (status != IB_SUCCESS) { 455 osm_log(p_vend->p_log, OSM_LOG_ERROR, 456 "__osm_ca_info_init: ERR 3B07: " 457 "Unexpected status getting CA attributes (%s).\n", 458 ib_get_err_str(status)); 459 goto Exit; 460 } 461 462Exit: 463 OSM_LOG_EXIT(p_vend->p_log); 464 return (status); 465} 466 467/********************************************************************** 468 **********************************************************************/ 469void 470osm_ca_info_destroy(IN osm_vendor_t * const p_vend, 471 IN osm_ca_info_t * const p_ca_info) 472{ 473 OSM_LOG_ENTER(p_vend->p_log); 474 475 if (p_ca_info->p_attr) 476 free(p_ca_info->p_attr); 477 478 free(p_ca_info); 479 480 OSM_LOG_EXIT(p_vend->p_log); 481} 482 483/********************************************************************** 484 **********************************************************************/ 485osm_ca_info_t *osm_ca_info_new(IN osm_vendor_t * const p_vend, 486 IN const ib_net64_t ca_guid) 487{ 488 ib_api_status_t status; 489 osm_ca_info_t *p_ca_info; 490 491 OSM_LOG_ENTER(p_vend->p_log); 492 493 CL_ASSERT(ca_guid); 494 495 p_ca_info = malloc(sizeof(*p_ca_info)); 496 if (p_ca_info == NULL) 497 goto Exit; 498 499 memset(p_ca_info, 0, sizeof(*p_ca_info)); 500 501 status = __osm_ca_info_init(p_vend, p_ca_info, ca_guid); 502 if (status != IB_SUCCESS) { 503 osm_ca_info_destroy(p_vend, p_ca_info); 504 p_ca_info = NULL; 505 goto Exit; 506 } 507 508Exit: 509 OSM_LOG_EXIT(p_vend->p_log); 510 return (p_ca_info); 511} 512 513/********************************************************************** 514 **********************************************************************/ 515static ib_api_status_t 516__osm_vendor_get_ca_guids(IN osm_vendor_t * const p_vend, 517 IN ib_net64_t ** const p_guids, 518 IN uintn_t * const p_num_guids) 519{ 520 ib_api_status_t status; 521 522 OSM_LOG_ENTER(p_vend->p_log); 523 524 CL_ASSERT(p_guids); 525 CL_ASSERT(p_num_guids); 526 527 status = ib_get_ca_guids(p_vend->h_al, NULL, p_num_guids); 528 if ((status != IB_INSUFFICIENT_MEMORY) && (status != IB_SUCCESS)) { 529 osm_log(p_vend->p_log, OSM_LOG_ERROR, 530 "__osm_vendor_get_ca_guids: ERR 3B08: " 531 "Unexpected status getting CA GUID array (%s).\n", 532 ib_get_err_str(status)); 533 goto Exit; 534 } 535 536 if (*p_num_guids == 0) { 537 osm_log(p_vend->p_log, OSM_LOG_ERROR, 538 "__osm_vendor_get_ca_guids: ERR 3B09: " 539 "No available channel adapters.\n"); 540 status = IB_INSUFFICIENT_RESOURCES; 541 goto Exit; 542 } 543 544 *p_guids = malloc(*p_num_guids * sizeof(**p_guids)); 545 if (*p_guids == NULL) { 546 osm_log(p_vend->p_log, OSM_LOG_ERROR, 547 "__osm_vendor_get_ca_guids: ERR 3B10: " 548 "Unable to allocate CA GUID array.\n"); 549 goto Exit; 550 } 551 552 status = ib_get_ca_guids(p_vend->h_al, *p_guids, p_num_guids); 553 CL_ASSERT(*p_num_guids); 554 555 if (osm_log_is_active(p_vend->p_log, OSM_LOG_VERBOSE)) { 556 osm_log(p_vend->p_log, OSM_LOG_VERBOSE, 557 "__osm_vendor_get_ca_guids: " 558 "Detected %u local channel adapters.\n", *p_num_guids); 559 } 560 561Exit: 562 OSM_LOG_EXIT(p_vend->p_log); 563 return (status); 564} 565 566/****f* OpenSM: CA Info/osm_ca_info_get_pi_ptr 567 * NAME 568 * osm_ca_info_get_pi_ptr 569 * 570 * DESCRIPTION 571 * Returns a pointer to the port attribute of the specified port 572 * owned by this CA. 573 * 574 * SYNOPSIS 575 */ 576static ib_port_attr_t *__osm_ca_info_get_port_attr_ptr(IN const osm_ca_info_t * 577 const p_ca_info, 578 IN const uint8_t index) 579{ 580 return (&p_ca_info->p_attr->p_port_attr[index]); 581} 582 583/* 584 * PARAMETERS 585 * p_ca_info 586 * [in] Pointer to a CA Info object. 587 * 588 * index 589 * [in] Port "index" for which to retrieve the port attribute. 590 * The index is the offset into the ca's internal array 591 * of port attributes. 592 * 593 * RETURN VALUE 594 * Returns a pointer to the port attribute of the specified port 595 * owned by this CA. 596 * 597 * NOTES 598 * 599 * SEE ALSO 600 *********/ 601 602/********************************************************************** 603 **********************************************************************/ 604ib_api_status_t 605osm_vendor_get_all_port_attr(IN osm_vendor_t * const p_vend, 606 IN ib_port_attr_t * const p_attr_array, 607 IN uint32_t * const p_num_ports) 608{ 609 ib_api_status_t status; 610 611 uint32_t ca; 612 uintn_t ca_count; 613 uint32_t port_count = 0; 614 uint8_t port_num; 615 uint32_t total_ports = 0; 616 ib_net64_t *p_ca_guid = NULL; 617 osm_ca_info_t *p_ca_info; 618 619 OSM_LOG_ENTER(p_vend->p_log); 620 621 CL_ASSERT(p_vend); 622 CL_ASSERT(p_vend->p_ca_info == NULL); 623 624 /* 625 1) Determine the number of CA's 626 2) Allocate an array big enough to hold the ca info objects. 627 3) Call again to retrieve the guids. 628 */ 629 status = __osm_vendor_get_ca_guids(p_vend, &p_ca_guid, &ca_count); 630 631 p_vend->p_ca_info = malloc(ca_count * sizeof(*p_vend->p_ca_info)); 632 if (p_vend->p_ca_info == NULL) { 633 osm_log(p_vend->p_log, OSM_LOG_ERROR, 634 "osm_vendor_get_all_port_attr: ERR 3B11: " 635 "Unable to allocate CA information array.\n"); 636 goto Exit; 637 } 638 639 memset(p_vend->p_ca_info, 0, ca_count * sizeof(*p_vend->p_ca_info)); 640 p_vend->ca_count = ca_count; 641 642 /* 643 For each CA, retrieve the port info attributes 644 */ 645 for (ca = 0; ca < ca_count; ca++) { 646 p_ca_info = &p_vend->p_ca_info[ca]; 647 648 status = __osm_ca_info_init(p_vend, p_ca_info, p_ca_guid[ca]); 649 650 if (status != IB_SUCCESS) { 651 osm_log(p_vend->p_log, OSM_LOG_ERROR, 652 "osm_vendor_get_all_port_attr: ERR 3B12: " 653 "Unable to initialize CA Info object (%s).\n", 654 ib_get_err_str(status)); 655 } 656 657 total_ports += osm_ca_info_get_num_ports(p_ca_info); 658 } 659 660 /* 661 If the user supplied enough storage, return the port guids, 662 otherwise, return the appropriate error. 663 */ 664 if (*p_num_ports >= total_ports) { 665 for (ca = 0; ca < ca_count; ca++) { 666 uint32_t num_ports; 667 668 p_ca_info = &p_vend->p_ca_info[ca]; 669 670 num_ports = osm_ca_info_get_num_ports(p_ca_info); 671 672 for (port_num = 0; port_num < num_ports; port_num++) { 673 p_attr_array[port_count] = 674 *__osm_ca_info_get_port_attr_ptr(p_ca_info, 675 port_num); 676 port_count++; 677 } 678 } 679 } else { 680 status = IB_INSUFFICIENT_MEMORY; 681 } 682 683 *p_num_ports = total_ports; 684 685Exit: 686 if (p_ca_guid) 687 free(p_ca_guid); 688 689 OSM_LOG_EXIT(p_vend->p_log); 690 return (status); 691} 692 693/********************************************************************** 694 **********************************************************************/ 695ib_net64_t 696osm_vendor_get_ca_guid(IN osm_vendor_t * const p_vend, 697 IN const ib_net64_t port_guid) 698{ 699 uint8_t index; 700 uint8_t num_ports; 701 uint32_t num_guids = 0; 702 osm_ca_info_t *p_ca_info; 703 uint32_t ca; 704 705 OSM_LOG_ENTER(p_vend->p_log); 706 707 CL_ASSERT(port_guid); 708 /* 709 First, locate the HCA that owns this port. 710 */ 711 if (p_vend->p_ca_info == NULL) { 712 /* 713 Initialize the osm_ca_info_t array which allows 714 us to match port GUID to CA. 715 */ 716 osm_vendor_get_all_port_attr(p_vend, NULL, &num_guids); 717 } 718 719 CL_ASSERT(p_vend->p_ca_info); 720 CL_ASSERT(p_vend->ca_count); 721 722 for (ca = 0; ca < p_vend->ca_count; ca++) { 723 p_ca_info = &p_vend->p_ca_info[ca]; 724 725 num_ports = osm_ca_info_get_num_ports(p_ca_info); 726 CL_ASSERT(num_ports); 727 728 for (index = 0; index < num_ports; index++) { 729 if (port_guid == 730 osm_ca_info_get_port_guid(p_ca_info, index)) { 731 OSM_LOG_EXIT(p_vend->p_log); 732 return (osm_ca_info_get_ca_guid(p_ca_info)); 733 } 734 } 735 } 736 737 /* 738 No local CA owns this guid! 739 */ 740 osm_log(p_vend->p_log, OSM_LOG_ERROR, 741 "osm_vendor_get_ca_guid: ERR 3B13: " 742 "Unable to determine CA guid.\n"); 743 744 OSM_LOG_EXIT(p_vend->p_log); 745 return (0); 746} 747 748/********************************************************************** 749 **********************************************************************/ 750uint8_t 751osm_vendor_get_port_num(IN osm_vendor_t * const p_vend, 752 IN const ib_net64_t port_guid) 753{ 754 uint8_t index; 755 uint8_t num_ports; 756 uint32_t num_guids = 0; 757 osm_ca_info_t *p_ca_info; 758 uint32_t ca; 759 760 OSM_LOG_ENTER(p_vend->p_log); 761 762 CL_ASSERT(port_guid); 763 /* 764 First, locate the HCA that owns this port. 765 */ 766 if (p_vend->p_ca_info == NULL) { 767 /* 768 Initialize the osm_ca_info_t array which allows 769 us to match port GUID to CA. 770 */ 771 osm_vendor_get_all_port_attr(p_vend, NULL, &num_guids); 772 } 773 774 CL_ASSERT(p_vend->p_ca_info); 775 CL_ASSERT(p_vend->ca_count); 776 777 for (ca = 0; ca < p_vend->ca_count; ca++) { 778 p_ca_info = &p_vend->p_ca_info[ca]; 779 780 num_ports = osm_ca_info_get_num_ports(p_ca_info); 781 CL_ASSERT(num_ports); 782 783 for (index = 0; index < num_ports; index++) { 784 if (port_guid == 785 osm_ca_info_get_port_guid(p_ca_info, index)) { 786 OSM_LOG_EXIT(p_vend->p_log); 787 return (osm_ca_info_get_port_num 788 (p_ca_info, index)); 789 } 790 } 791 } 792 793 /* 794 No local CA owns this guid! 795 */ 796 osm_log(p_vend->p_log, OSM_LOG_ERROR, 797 "osm_vendor_get_port_num: ERR 3B30: " 798 "Unable to determine CA guid.\n"); 799 800 OSM_LOG_EXIT(p_vend->p_log); 801 return (0); 802} 803 804/********************************************************************** 805 **********************************************************************/ 806static ib_api_status_t 807__osm_vendor_open_ca(IN osm_vendor_t * const p_vend, 808 IN const ib_net64_t port_guid) 809{ 810 ib_net64_t ca_guid; 811 ib_api_status_t status; 812 813 OSM_LOG_ENTER(p_vend->p_log); 814 815 ca_guid = osm_vendor_get_ca_guid(p_vend, port_guid); 816 if (ca_guid == 0) { 817 osm_log(p_vend->p_log, OSM_LOG_ERROR, 818 "__osm_vendor_open_ca: ERR 3B31: " 819 "Bad port GUID value 0x%" PRIx64 ".\n", 820 cl_ntoh64(port_guid)); 821 status = IB_ERROR; 822 goto Exit; 823 } 824 825 osm_log(p_vend->p_log, OSM_LOG_VERBOSE, 826 "__osm_vendor_open_ca: " 827 "Opening HCA 0x%" PRIx64 ".\n", cl_ntoh64(ca_guid)); 828 829 status = ib_open_ca(p_vend->h_al, 830 ca_guid, 831 __osm_al_ca_err_callback, p_vend, &p_vend->h_ca); 832 833 if (status != IB_SUCCESS) { 834 osm_log(p_vend->p_log, OSM_LOG_ERROR, 835 "__osm_vendor_open_ca: ERR 3B15: " 836 "Unable to open CA (%s).\n", ib_get_err_str(status)); 837 goto Exit; 838 } 839 840 CL_ASSERT(p_vend->h_ca); 841 842 status = ib_alloc_pd(p_vend->h_ca, IB_PDT_ALIAS, p_vend, &p_vend->h_pd); 843 844 if (status != IB_SUCCESS) { 845 ib_close_ca(p_vend->h_ca, __osm_al_ca_destroy_callback); 846 osm_log(p_vend->p_log, OSM_LOG_ERROR, 847 "__osm_vendor_open_ca: ERR 3B16: " 848 "Unable to allocate protection domain (%s).\n", 849 ib_get_err_str(status)); 850 goto Exit; 851 } 852 853 CL_ASSERT(p_vend->h_pd); 854 855Exit: 856 OSM_LOG_EXIT(p_vend->p_log); 857 return (status); 858} 859 860/********************************************************************** 861 **********************************************************************/ 862static void 863__osm_vendor_init_av(IN const osm_al_bind_info_t * p_bind, 864 IN ib_av_attr_t * p_av) 865{ 866 memset(p_av, 0, sizeof(*p_av)); 867 p_av->port_num = p_bind->port_num; 868 p_av->dlid = IB_LID_PERMISSIVE; 869} 870 871/********************************************************************** 872 **********************************************************************/ 873osm_bind_handle_t 874osm_vendor_bind(IN osm_vendor_t * const p_vend, 875 IN osm_bind_info_t * const p_user_bind, 876 IN osm_mad_pool_t * const p_mad_pool, 877 IN osm_vend_mad_recv_callback_t mad_recv_callback, 878 IN osm_vend_mad_send_err_callback_t send_err_callback, 879 IN void *context) 880{ 881 ib_net64_t port_guid; 882 osm_al_bind_info_t *p_bind = 0; 883 ib_api_status_t status; 884 ib_qp_create_t qp_create; 885 ib_mad_svc_t mad_svc; 886 ib_av_attr_t av; 887 888 OSM_LOG_ENTER(p_vend->p_log); 889 890 CL_ASSERT(p_user_bind); 891 CL_ASSERT(p_mad_pool); 892 CL_ASSERT(mad_recv_callback); 893 CL_ASSERT(send_err_callback); 894 895 port_guid = p_user_bind->port_guid; 896 897 osm_log(p_vend->p_log, OSM_LOG_INFO, 898 "osm_vendor_bind: " 899 "Binding to port 0x%" PRIx64 ".\n", cl_ntoh64(port_guid)); 900 901 if (p_vend->h_ca == 0) { 902 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 903 "osm_vendor_bind: " 904 "Opening CA that owns port 0x%" PRIx64 ".\n", 905 port_guid); 906 907 status = __osm_vendor_open_ca(p_vend, port_guid); 908 if (status != IB_SUCCESS) { 909 osm_log(p_vend->p_log, OSM_LOG_ERROR, 910 "osm_vendor_bind: ERR 3B17: " 911 "Unable to Open CA (%s).\n", 912 ib_get_err_str(status)); 913 goto Exit; 914 } 915 } 916 917 p_bind = malloc(sizeof(*p_bind)); 918 if (p_bind == NULL) { 919 osm_log(p_vend->p_log, OSM_LOG_ERROR, 920 "osm_vendor_bind: ERR 3B18: " 921 "Unable to allocate internal bind object.\n"); 922 goto Exit; 923 } 924 925 memset(p_bind, 0, sizeof(*p_bind)); 926 p_bind->p_vend = p_vend; 927 p_bind->client_context = context; 928 p_bind->port_num = osm_vendor_get_port_num(p_vend, port_guid); 929 p_bind->rcv_callback = mad_recv_callback; 930 p_bind->send_err_callback = send_err_callback; 931 p_bind->p_osm_pool = p_mad_pool; 932 933 CL_ASSERT(p_bind->port_num); 934 935 /* 936 Get the proper QP. 937 */ 938 memset(&qp_create, 0, sizeof(qp_create)); 939 940 switch (p_user_bind->mad_class) { 941 case IB_MCLASS_SUBN_LID: 942 case IB_MCLASS_SUBN_DIR: 943 qp_create.qp_type = IB_QPT_QP0_ALIAS; 944 break; 945 946 case IB_MCLASS_SUBN_ADM: 947 default: 948 qp_create.qp_type = IB_QPT_QP1_ALIAS; 949 break; 950 } 951 952 qp_create.sq_depth = p_user_bind->send_q_size; 953 qp_create.rq_depth = p_user_bind->recv_q_size; 954 qp_create.sq_sge = OSM_AL_SQ_SGE; 955 qp_create.rq_sge = OSM_AL_RQ_SGE; 956 957 status = ib_get_spl_qp(p_vend->h_pd, 958 port_guid, 959 &qp_create, 960 p_bind, 961 __osm_al_err_callback, 962 &p_bind->pool_key, &p_bind->h_qp); 963 964 if (status != IB_SUCCESS) { 965 free(p_bind); 966 osm_log(p_vend->p_log, OSM_LOG_ERROR, 967 "osm_vendor_bind: ERR 3B19: " 968 "Unable to get QP handle (%s).\n", 969 ib_get_err_str(status)); 970 goto Exit; 971 } 972 973 CL_ASSERT(p_bind->h_qp); 974 CL_ASSERT(p_bind->pool_key); 975 976 memset(&mad_svc, 0, sizeof(mad_svc)); 977 978 mad_svc.mad_svc_context = p_bind; 979 mad_svc.pfn_mad_send_cb = __osm_al_send_callback; 980 mad_svc.pfn_mad_recv_cb = __osm_al_rcv_callback; 981 mad_svc.mgmt_class = p_user_bind->mad_class; 982 mad_svc.mgmt_version = p_user_bind->class_version; 983 mad_svc.support_unsol = p_user_bind->is_responder; 984 mad_svc.method_array[IB_MAD_METHOD_GET] = TRUE; 985 mad_svc.method_array[IB_MAD_METHOD_SET] = TRUE; 986 mad_svc.method_array[IB_MAD_METHOD_DELETE] = TRUE; 987 mad_svc.method_array[IB_MAD_METHOD_TRAP] = TRUE; 988 mad_svc.method_array[IB_MAD_METHOD_GETTABLE] = TRUE; 989 990 status = ib_reg_mad_svc(p_bind->h_qp, &mad_svc, &p_bind->h_svc); 991 992 if (status != IB_SUCCESS) { 993 free(p_bind); 994 osm_log(p_vend->p_log, OSM_LOG_ERROR, 995 "osm_vendor_bind: ERR 3B21: " 996 "Unable to register QP0 MAD service (%s).\n", 997 ib_get_err_str(status)); 998 goto Exit; 999 } 1000 1001 __osm_vendor_init_av(p_bind, &av); 1002 1003 status = ib_create_av(p_vend->h_pd, &av, &p_bind->h_dr_av); 1004 if (status != IB_SUCCESS) { 1005 osm_log(p_vend->p_log, OSM_LOG_ERROR, 1006 "osm_vendor_bind: ERR 3B22: " 1007 "Unable to create address vector (%s).\n", 1008 ib_get_err_str(status)); 1009 1010 goto Exit; 1011 } 1012 1013 if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) { 1014 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 1015 "osm_vendor_bind: " 1016 "Allocating av handle %p.\n", p_bind->h_dr_av); 1017 } 1018 1019Exit: 1020 OSM_LOG_EXIT(p_vend->p_log); 1021 return ((osm_bind_handle_t) p_bind); 1022} 1023 1024/********************************************************************** 1025 **********************************************************************/ 1026ib_mad_t *osm_vendor_get(IN osm_bind_handle_t h_bind, 1027 IN const uint32_t mad_size, 1028 IN osm_vend_wrap_t * const p_vw) 1029{ 1030 ib_mad_t *p_mad; 1031 osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) h_bind; 1032 osm_vendor_t *p_vend = p_bind->p_vend; 1033 ib_api_status_t status; 1034 1035 OSM_LOG_ENTER(p_vend->p_log); 1036 1037 CL_ASSERT(p_vw); 1038 1039 p_vw->size = mad_size; 1040 p_vw->h_bind = h_bind; 1041 1042 /* 1043 Retrieve a MAD element from the pool and give the user direct 1044 access to its buffer. 1045 */ 1046 status = ib_get_mad(p_bind->pool_key, mad_size, &p_vw->p_elem); 1047 if (status != IB_SUCCESS) { 1048 osm_log(p_vend->p_log, OSM_LOG_ERROR, 1049 "osm_vendor_get: ERR 3B25: " 1050 "Unable to acquire MAD (%s).\n", 1051 ib_get_err_str(status)); 1052 1053 p_mad = NULL; 1054 goto Exit; 1055 } 1056 1057 CL_ASSERT(p_vw->p_elem); 1058 p_mad = ib_get_mad_buf(p_vw->p_elem); 1059 1060 if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) { 1061 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 1062 "osm_vendor_get: " 1063 "Acquired MAD %p, size = %u.\n", p_mad, mad_size); 1064 } 1065 1066Exit: 1067 OSM_LOG_EXIT(p_vend->p_log); 1068 return (p_mad); 1069} 1070 1071/********************************************************************** 1072 **********************************************************************/ 1073void 1074osm_vendor_put(IN osm_bind_handle_t h_bind, IN osm_vend_wrap_t * const p_vw) 1075{ 1076 osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) h_bind; 1077 osm_vendor_t *p_vend = p_bind->p_vend; 1078 ib_api_status_t status; 1079 1080 OSM_LOG_ENTER(p_vend->p_log); 1081 1082 CL_ASSERT(p_vw); 1083 CL_ASSERT(p_vw->p_elem); 1084 CL_ASSERT(p_vw->h_bind == h_bind); 1085 1086 if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) { 1087 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 1088 "osm_vendor_put: " 1089 "Retiring MAD %p.\n", ib_get_mad_buf(p_vw->p_elem)); 1090 } 1091 1092 status = ib_put_mad(p_vw->p_elem); 1093 if (status != IB_SUCCESS) { 1094 osm_log(p_vend->p_log, OSM_LOG_ERROR, 1095 "osm_vendor_put: ERR 3B26: " 1096 "Unable to retire MAD (%s).\n", ib_get_err_str(status)); 1097 } 1098 1099 OSM_LOG_EXIT(p_vend->p_log); 1100} 1101 1102/********************************************************************** 1103 **********************************************************************/ 1104ib_api_status_t 1105osm_vendor_send(IN osm_bind_handle_t h_bind, 1106 IN osm_madw_t * const p_madw, IN boolean_t const resp_expected) 1107{ 1108 osm_al_bind_info_t *const p_bind = h_bind; 1109 osm_vendor_t *const p_vend = p_bind->p_vend; 1110 osm_vend_wrap_t *const p_vw = osm_madw_get_vend_ptr(p_madw); 1111 osm_mad_addr_t *const p_mad_addr = osm_madw_get_mad_addr_ptr(p_madw); 1112 ib_mad_t *const p_mad = osm_madw_get_mad_ptr(p_madw); 1113 ib_api_status_t status; 1114 ib_mad_element_t *p_elem; 1115 ib_av_attr_t av; 1116 1117 OSM_LOG_ENTER(p_vend->p_log); 1118 1119 CL_ASSERT(p_vw->h_bind == h_bind); 1120 CL_ASSERT(p_vw->p_elem); 1121 1122 p_elem = p_vw->p_elem; 1123 1124 /* 1125 If a response is expected to this MAD, then preallocate 1126 a mad wrapper to contain the wire MAD received in the 1127 response. Allocating a wrapper here allows for easier 1128 failure paths than after we already received the wire mad. 1129 */ 1130 if (resp_expected) { 1131 p_vw->p_resp_madw = 1132 osm_mad_pool_get_wrapper_raw(p_bind->p_osm_pool); 1133 if (p_vw->p_resp_madw == NULL) { 1134 osm_log(p_vend->p_log, OSM_LOG_ERROR, 1135 "osm_vendor_send: ERR 3B27: " 1136 "Unable to allocate MAD wrapper.\n"); 1137 status = IB_INSUFFICIENT_RESOURCES; 1138 goto Exit; 1139 } 1140 } else 1141 p_vw->p_resp_madw = NULL; 1142 1143 /* 1144 For all sends other than directed route SM MADs, 1145 acquire an address vector for the destination. 1146 */ 1147 if (p_mad->mgmt_class != IB_MCLASS_SUBN_DIR) { 1148 memset(&av, 0, sizeof(av)); 1149 av.port_num = p_bind->port_num; 1150 av.dlid = p_mad_addr->dest_lid; 1151 av.static_rate = p_mad_addr->static_rate; 1152 av.path_bits = p_mad_addr->path_bits; 1153 1154 if ((p_mad->mgmt_class != IB_MCLASS_SUBN_LID) && 1155 (p_mad->mgmt_class != IB_MCLASS_SUBN_DIR)) { 1156 av.sl = p_mad_addr->addr_type.gsi.service_level; 1157 1158 if (p_mad_addr->addr_type.gsi.global_route) { 1159 av.grh_valid = TRUE; 1160 /* ANIL */ 1161 /* av.grh = p_mad_addr->addr_type.gsi.grh_info; */ 1162 } 1163 } 1164 1165 if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) { 1166 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 1167 "osm_vendor_send: " 1168 "av.port_num 0x%X, " 1169 "av.dlid 0x%X, " 1170 "av.static_rate %d, " 1171 "av.path_bits %d.\n", 1172 av.port_num, cl_ntoh16(av.dlid), 1173 av.static_rate, av.path_bits); 1174 } 1175 1176 status = ib_create_av(p_vend->h_pd, &av, &p_vw->h_av); 1177 if (status != IB_SUCCESS) { 1178 osm_log(p_vend->p_log, OSM_LOG_ERROR, 1179 "osm_vendor_send: ERR 3B28: " 1180 "Unable to create address vector (%s).\n", 1181 ib_get_err_str(status)); 1182 1183 if (p_vw->p_resp_madw) 1184 osm_mad_pool_put(p_bind->p_osm_pool, 1185 p_vw->p_resp_madw); 1186 goto Exit; 1187 } 1188 1189 if (osm_log_is_active(p_vend->p_log, OSM_LOG_DEBUG)) { 1190 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 1191 "osm_vendor_send: " 1192 "Allocating av handle %p.\n", p_vw->h_av); 1193 } 1194 } else { 1195 p_vw->h_av = p_bind->h_dr_av; 1196 } 1197 1198 p_elem->h_av = p_vw->h_av; 1199 1200 p_elem->context1 = p_madw; 1201 p_elem->context2 = NULL; 1202 1203 p_elem->immediate_data = 0; 1204 p_elem->p_grh = NULL; 1205 p_elem->resp_expected = resp_expected; 1206 p_elem->retry_cnt = OSM_DEFAULT_RETRY_COUNT; 1207 1208 p_elem->send_opt = IB_SEND_OPT_SIGNALED; 1209 p_elem->timeout_ms = p_vend->timeout; 1210 1211 /* Completion information. */ 1212 p_elem->status = 0; /* Not trusting AL */ 1213 1214 if ((p_mad->mgmt_class == IB_MCLASS_SUBN_LID) || 1215 (p_mad->mgmt_class == IB_MCLASS_SUBN_DIR)) { 1216 p_elem->remote_qp = 0; 1217 p_elem->remote_qkey = 0; 1218 } else { 1219 p_elem->remote_qp = p_mad_addr->addr_type.gsi.remote_qp; 1220 p_elem->remote_qkey = p_mad_addr->addr_type.gsi.remote_qkey; 1221 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 1222 "osm_vendor_send: " 1223 "remote qp = 0x%X, remote qkey = 0x%X.\n", 1224 cl_ntoh32(p_elem->remote_qp), 1225 cl_ntoh32(p_elem->remote_qkey)); 1226 } 1227 1228 status = ib_send_mad(p_bind->h_svc, p_elem, NULL); 1229 if (status != IB_SUCCESS) { 1230 osm_log(p_vend->p_log, OSM_LOG_ERROR, 1231 "osm_vendor_send: ERR 3B29: " 1232 "Send failed (%s).\n", ib_get_err_str(status)); 1233 if (p_vw->p_resp_madw) 1234 osm_mad_pool_put(p_bind->p_osm_pool, p_vw->p_resp_madw); 1235 goto Exit; 1236 } 1237 1238Exit: 1239 OSM_LOG_EXIT(p_vend->p_log); 1240 return (status); 1241} 1242 1243/********************************************************************** 1244 **********************************************************************/ 1245ib_api_status_t osm_vendor_local_lid_change(IN osm_bind_handle_t h_bind) 1246{ 1247 osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) h_bind; 1248 osm_vendor_t *p_vend = p_bind->p_vend; 1249 ib_av_attr_t av; 1250 ib_api_status_t status; 1251 1252 OSM_LOG_ENTER(p_vend->p_log); 1253 1254 /* 1255 The only thing we need to do is refresh the directed 1256 route address vector. 1257 */ 1258 __osm_vendor_init_av(p_bind, &av); 1259 1260 status = ib_destroy_av(p_bind->h_dr_av); 1261 if (status != IB_SUCCESS) { 1262 osm_log(p_vend->p_log, OSM_LOG_ERROR, 1263 "osm_vendor_local_lid_change: ERR 3B32: " 1264 "Unable to destroy address vector (%s).\n", 1265 ib_get_err_str(status)); 1266 1267 goto Exit; 1268 } 1269 1270 status = ib_create_av(p_vend->h_pd, &av, &p_bind->h_dr_av); 1271 if (status != IB_SUCCESS) { 1272 osm_log(p_vend->p_log, OSM_LOG_ERROR, 1273 "osm_vendor_local_lid_change: ERR 3B33: " 1274 "Unable to create address vector (%s).\n", 1275 ib_get_err_str(status)); 1276 1277 goto Exit; 1278 } 1279 1280Exit: 1281 OSM_LOG_EXIT(p_vend->p_log); 1282 return (status); 1283} 1284 1285/********************************************************************** 1286 **********************************************************************/ 1287void osm_vendor_set_sm(IN osm_bind_handle_t h_bind, IN boolean_t is_sm_val) 1288{ 1289 osm_al_bind_info_t *p_bind = (osm_al_bind_info_t *) h_bind; 1290 osm_vendor_t *p_vend = p_bind->p_vend; 1291 ib_api_status_t status; 1292 ib_port_attr_mod_t attr_mod; 1293 1294 OSM_LOG_ENTER(p_vend->p_log); 1295 1296 memset(&attr_mod, 0, sizeof(attr_mod)); 1297 1298 attr_mod.cap.sm = is_sm_val; 1299 1300 status = ib_modify_ca(p_vend->h_ca, p_bind->port_num, 1301 IB_CA_MOD_IS_SM, &attr_mod); 1302 1303 if (status != IB_SUCCESS) { 1304 osm_log(p_vend->p_log, OSM_LOG_ERROR, 1305 "osm_vendor_set_sm: ERR 3B34: " 1306 "Unable set 'IS_SM' bit to:%u in port attributes (%s).\n", 1307 is_sm_val, ib_get_err_str(status)); 1308 } 1309 1310 OSM_LOG_EXIT(p_vend->p_log); 1311} 1312 1313/********************************************************************** 1314 **********************************************************************/ 1315void osm_vendor_set_debug(IN osm_vendor_t * const p_vend, IN int32_t level) 1316{ 1317 1318} 1319 1320#endif /* OSM_VENDOR_INTF_AL */ 1321