osm_vendor_mlx_sa.c revision 219820
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#include <stdlib.h> 41#include <string.h> 42#include <complib/cl_debug.h> 43#include <complib/cl_timer.h> 44#include <complib/cl_event.h> 45#include <vendor/osm_vendor_api.h> 46#include <vendor/osm_vendor_sa_api.h> 47 48/***************************************************************************** 49 *****************************************************************************/ 50 51/* this struct is the internal rep of the bind handle */ 52typedef struct _osmv_sa_bind_info { 53 osm_bind_handle_t h_bind; 54 osm_log_t *p_log; 55 osm_vendor_t *p_vendor; 56 osm_mad_pool_t *p_mad_pool; 57 uint64_t port_guid; 58 cl_event_t sync_event; 59 uint64_t last_lids_update_sec; 60 uint16_t lid; 61 uint16_t sm_lid; 62} osmv_sa_bind_info_t; 63 64/***************************************************************************** 65 *****************************************************************************/ 66 67/* 68 Call back on new mad received: 69 70 We basically only need to set the context of the query. 71 Or report an error. 72 73 A pointer to the actual context of the request (a copy of the oriignal 74 request structure) is attached as the p_madw->context.ni_context.node_guid 75*/ 76void 77__osmv_sa_mad_rcv_cb(IN osm_madw_t * p_madw, 78 IN void *bind_context, IN osm_madw_t * p_req_madw) 79{ 80 osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) bind_context; 81 osmv_query_req_t *p_query_req_copy = NULL; 82 osmv_query_res_t query_res; 83 ib_sa_mad_t *p_sa_mad; 84 ib_net16_t mad_status; 85 86 OSM_LOG_ENTER(p_bind->p_log); 87 88 if (!p_req_madw) { 89 osm_log(p_bind->p_log, OSM_LOG_DEBUG, 90 "__osmv_sa_mad_rcv_cb: " 91 "Ignoring a non-response mad\n"); 92 osm_mad_pool_put(p_bind->p_mad_pool, p_madw); 93 goto Exit; 94 } 95 96 /* obtain the sent context */ 97 p_query_req_copy = 98 (osmv_query_req_t *) (p_req_madw->context.arb_context.context1); 99 100 /* provide the context of the original request in the result */ 101 query_res.query_context = p_query_req_copy->query_context; 102 103 /* provide the resulting madw */ 104 query_res.p_result_madw = p_madw; 105 106 /* update the req fields */ 107 p_sa_mad = (ib_sa_mad_t *) p_madw->p_mad; 108 109 /* if we got a remote error track it in the status */ 110 mad_status = (ib_net16_t) (p_sa_mad->status & IB_SMP_STATUS_MASK); 111 if (mad_status != IB_SUCCESS) { 112 osm_log(p_bind->p_log, OSM_LOG_ERROR, 113 "__osmv_sa_mad_rcv_cb: ERR 0501: " 114 "Remote error:0x%04X .\n", mad_status); 115 query_res.status = IB_REMOTE_ERROR; 116 } else { 117 query_res.status = IB_SUCCESS; 118 } 119 120 /* what if we have got back an empty mad ? */ 121 if (!p_madw->mad_size) { 122 osm_log(p_bind->p_log, OSM_LOG_ERROR, 123 "__osmv_sa_mad_rcv_cb: ERR 0502: " 124 "Got an empty mad.\n"); 125 query_res.status = IB_ERROR; 126 } 127 128 if (IB_SUCCESS == mad_status) { 129 130 /* if we are in not in a method response of an rmpp nature we must get only 1 */ 131 /* HACK: in the future we might need to be smarter for other methods... */ 132 if (p_sa_mad->method != IB_MAD_METHOD_GETTABLE_RESP) { 133 query_res.result_cnt = 1; 134 } else { 135#ifndef VENDOR_RMPP_SUPPORT 136 if (mad_status != IB_SUCCESS) 137 query_res.result_cnt = 0; 138 else 139 query_res.result_cnt = 1; 140#else 141 /* we used the offset value to calculate the number of 142 records in here */ 143 if (ib_get_attr_size(p_sa_mad->attr_offset) == 0) { 144 query_res.result_cnt = 0; 145 osm_log(p_bind->p_log, OSM_LOG_DEBUG, 146 "__osmv_sa_mad_rcv_cb: Count = 0\n"); 147 } 148 else { 149 query_res.result_cnt = (uintn_t) 150 ((p_madw->mad_size - IB_SA_MAD_HDR_SIZE) / 151 ib_get_attr_size(p_sa_mad->attr_offset)); 152 osm_log(p_bind->p_log, OSM_LOG_DEBUG, 153 "__osmv_sa_mad_rcv_cb: " 154 "Count = %u = %zu / %u (%zu)\n", 155 query_res.result_cnt, 156 p_madw->mad_size - IB_SA_MAD_HDR_SIZE, 157 ib_get_attr_size(p_sa_mad->attr_offset), 158 (p_madw->mad_size - IB_SA_MAD_HDR_SIZE) % 159 ib_get_attr_size(p_sa_mad->attr_offset)); 160 } 161#endif 162 } 163 } 164 165 query_res.query_type = p_query_req_copy->query_type; 166 167 p_query_req_copy->pfn_query_cb(&query_res); 168 169 if ((p_query_req_copy->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC) 170 cl_event_signal(&p_bind->sync_event); 171 172Exit: 173 174 /* free the copied query request if found */ 175 if (p_query_req_copy) 176 free(p_query_req_copy); 177 178 /* put back the request madw */ 179 if (p_req_madw) 180 osm_mad_pool_put(p_bind->p_mad_pool, p_req_madw); 181 182 OSM_LOG_EXIT(p_bind->p_log); 183} 184 185/***************************************************************************** 186 ****************************************************************************/ 187/* 188 Send Error Callback: 189 190 Only report the error and get rid of the mad wrapper 191*/ 192void __osmv_sa_mad_err_cb(IN void *bind_context, IN osm_madw_t * p_madw) 193{ 194 osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) bind_context; 195 osmv_query_req_t *p_query_req_copy = NULL; 196 osmv_query_res_t query_res; 197 198 OSM_LOG_ENTER(p_bind->p_log); 199 200 /* Obtain the sent context etc */ 201 p_query_req_copy = 202 (osmv_query_req_t *) (p_madw->context.arb_context.context1); 203 204 /* provide the context of the original request in the result */ 205 query_res.query_context = p_query_req_copy->query_context; 206 207 query_res.p_result_madw = p_madw; 208 209 query_res.status = IB_TIMEOUT; 210 query_res.result_cnt = 0; 211 query_res.p_result_madw->status = IB_TIMEOUT; 212 p_madw->status = IB_TIMEOUT; 213 query_res.query_type = p_query_req_copy->query_type; 214 215 p_query_req_copy->pfn_query_cb(&query_res); 216 217 if ((p_query_req_copy->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC) 218 cl_event_signal(&p_bind->sync_event); 219 220 if (p_query_req_copy) 221 free(p_query_req_copy); 222 OSM_LOG_EXIT(p_bind->p_log); 223} 224 225/***************************************************************************** 226 This routine needs to be invoked on every send - since the SM LID and Local 227 lid might change. To do that without any major perfoermance impact we cache 228 the results and time they were obtained. Refresh only twice a minute. 229 To avoid the need to use statics and risk a race - we require the refresh time 230 to be stored in the context of the results. Also this coveres cases were 231 we query for multiple guids. 232 *****************************************************************************/ 233ib_api_status_t 234__osmv_get_lid_and_sm_lid_by_port_guid(IN osm_vendor_t * const p_vend, 235 IN ib_net64_t port_guid, 236 IN OUT uint64_t * p_lids_update_time_sec, 237 OUT uint16_t * lid, 238 OUT uint16_t * sm_lid) 239{ 240 241 ib_api_status_t status; 242 ib_port_attr_t *p_attr_array; 243 uint32_t num_ports; 244 uint32_t port_num; 245 246 OSM_LOG_ENTER(p_vend->p_log); 247 248 /* use prevous values if current time is close enough to previous query */ 249 if (cl_get_time_stamp_sec() <= *p_lids_update_time_sec + 30) { 250 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 251 "__osmv_get_lid_and_sm_lid_by_port_guid: " 252 "Using previously stored lid:0x%04x sm_lid:0x%04x\n", 253 *lid, *sm_lid); 254 status = IB_SUCCESS; 255 goto Exit; 256 } 257 258 /* obtain the number of available ports */ 259 num_ports = 0; 260 status = osm_vendor_get_all_port_attr(p_vend, NULL, &num_ports); 261 if (status != IB_INSUFFICIENT_MEMORY) { 262 osm_log(p_vend->p_log, OSM_LOG_ERROR, 263 "__osmv_get_lid_and_sm_lid_by_port_guid: ERR 0503: " 264 "expected to get the IB_INSUFFICIENT_MEMORY but got: %s\n", 265 ib_get_err_str(status) 266 ); 267 status = IB_ERROR; 268 goto Exit; 269 } 270 271 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 272 "__osmv_get_lid_and_sm_lid_by_port_guid: " 273 "Found total of %u ports. Looking for guid:0x%016" PRIx64 "\n", 274 num_ports, cl_ntoh64(port_guid) 275 ); 276 277 /* allocate the attributes */ 278 p_attr_array = 279 (ib_port_attr_t *) malloc(sizeof(ib_port_attr_t) * num_ports); 280 281 /* obtain the attributes */ 282 status = osm_vendor_get_all_port_attr(p_vend, p_attr_array, &num_ports); 283 if (status != IB_SUCCESS) { 284 osm_log(p_vend->p_log, OSM_LOG_ERROR, 285 "__osmv_get_lid_and_sm_lid_by_port_guid: ERR 0504: " 286 "Fail to get port attributes (error: %s)\n", 287 ib_get_err_str(status) 288 ); 289 free(p_attr_array); 290 goto Exit; 291 } 292 293 status = IB_ERROR; 294 /* find the port requested in the list */ 295 for (port_num = 0; (port_num < num_ports) && (status == IB_ERROR); 296 port_num++) { 297 if (p_attr_array[port_num].port_guid == port_guid) { 298 *lid = p_attr_array[port_num].lid; 299 *sm_lid = p_attr_array[port_num].sm_lid; 300 *p_lids_update_time_sec = cl_get_time_stamp_sec(); 301 status = IB_SUCCESS; 302 osm_log(p_vend->p_log, OSM_LOG_DEBUG, 303 "__osmv_get_lid_and_sm_lid_by_port_guid: " 304 "Found guid:0x%016" PRIx64 " with idx:%d\n", 305 cl_ntoh64(port_guid), port_num); 306 } 307 } 308 309 free(p_attr_array); 310 311Exit: 312 OSM_LOG_EXIT(p_vend->p_log); 313 return (status); 314} 315 316/***************************************************************************** 317 *****************************************************************************/ 318osm_bind_handle_t 319osmv_bind_sa(IN osm_vendor_t * const p_vend, 320 IN osm_mad_pool_t * const p_mad_pool, IN ib_net64_t port_guid) 321{ 322 osm_bind_info_t bind_info; 323 osm_log_t *p_log = p_vend->p_log; 324 ib_api_status_t status = IB_SUCCESS; 325 osmv_sa_bind_info_t *p_sa_bind_info; 326 cl_status_t cl_status; 327 328 OSM_LOG_ENTER(p_log); 329 330 osm_log(p_log, OSM_LOG_DEBUG, 331 "osmv_bind_sa: " 332 "Binding to port 0x%" PRIx64 ".\n", cl_ntoh64(port_guid)); 333 334 bind_info.port_guid = port_guid; 335 bind_info.mad_class = IB_MCLASS_SUBN_ADM; 336 bind_info.class_version = 2; 337 bind_info.is_responder = TRUE; 338 bind_info.is_trap_processor = FALSE; 339 bind_info.is_report_processor = TRUE; 340 bind_info.send_q_size = 256; 341 bind_info.recv_q_size = 256; 342 343 /* allocate the new sa bind info */ 344 p_sa_bind_info = 345 (osmv_sa_bind_info_t *) malloc(sizeof(osmv_sa_bind_info_t)); 346 if (!p_sa_bind_info) { 347 osm_log(p_log, OSM_LOG_ERROR, 348 "osmv_bind_sa: ERR 0505: " 349 "Fail to allocate new bidn structure\n"); 350 p_sa_bind_info = OSM_BIND_INVALID_HANDLE; 351 goto Exit; 352 } 353 354 /* store some important context */ 355 p_sa_bind_info->p_log = p_log; 356 p_sa_bind_info->port_guid = port_guid; 357 p_sa_bind_info->p_mad_pool = p_mad_pool; 358 p_sa_bind_info->p_vendor = p_vend; 359 p_sa_bind_info->last_lids_update_sec = 0; 360 361 /* Bind to the lower level */ 362 p_sa_bind_info->h_bind = osm_vendor_bind(p_vend, &bind_info, p_mad_pool, __osmv_sa_mad_rcv_cb, __osmv_sa_mad_err_cb, p_sa_bind_info); /* context provided to CBs */ 363 364 if (p_sa_bind_info->h_bind == OSM_BIND_INVALID_HANDLE) { 365 free(p_sa_bind_info); 366 p_sa_bind_info = OSM_BIND_INVALID_HANDLE; 367 osm_log(p_log, OSM_LOG_ERROR, 368 "osmv_bind_sa: ERR 0506: " 369 "Fail to bind to vendor SMI.\n"); 370 goto Exit; 371 } 372 373 /* obtain the sm_lid from the vendor */ 374 status = 375 __osmv_get_lid_and_sm_lid_by_port_guid(p_vend, port_guid, 376 &p_sa_bind_info-> 377 last_lids_update_sec, 378 &p_sa_bind_info->lid, 379 &p_sa_bind_info->sm_lid); 380 if (status != IB_SUCCESS) { 381 free(p_sa_bind_info); 382 p_sa_bind_info = OSM_BIND_INVALID_HANDLE; 383 osm_log(p_log, OSM_LOG_ERROR, 384 "osmv_bind_sa: ERR 0507: " 385 "Fail to obtain the sm lid.\n"); 386 goto Exit; 387 } 388 389 /* initialize the sync_event */ 390 cl_event_construct(&p_sa_bind_info->sync_event); 391 cl_status = cl_event_init(&p_sa_bind_info->sync_event, TRUE); 392 if (cl_status != CL_SUCCESS) { 393 osm_log(p_log, OSM_LOG_ERROR, 394 "osmv_bind_sa: ERR 0508: " 395 "cl_init_event failed: %s\n", ib_get_err_str(cl_status) 396 ); 397 free(p_sa_bind_info); 398 p_sa_bind_info = OSM_BIND_INVALID_HANDLE; 399 } 400 401Exit: 402 OSM_LOG_EXIT(p_log); 403 return (p_sa_bind_info); 404} 405 406/***************************************************************************** 407 *****************************************************************************/ 408 409/****t* OSM Vendor SA Client/osmv_sa_mad_data 410 * NAME 411 * osmv_sa_mad_data 412 * 413 * DESCRIPTION 414 * Extra fields required to perform a mad query 415 * This struct is passed to the actual send method 416 * 417 * SYNOPSIS 418 */ 419typedef struct _osmv_sa_mad_data { 420 /* MAD data. */ 421 uint8_t method; 422 ib_net16_t attr_id; 423 ib_net16_t attr_offset; 424 ib_net32_t attr_mod; 425 ib_net64_t comp_mask; 426 void *p_attr; 427} osmv_sa_mad_data_t; 428/* 429 * method 430 * The method of the mad to be sent 431 * 432 * attr_id 433 * Attribute ID 434 * 435 * attr_offset 436 * Offset as defined by RMPP 437 * 438 * attr_mod 439 * Attribute modifier 440 * 441 * comp_mask 442 * The component mask of the query 443 * 444 * p_attr 445 * A pointer to the record of the attribute to be sent. 446 * 447 *****/ 448 449/***************************************************************************** 450 *****************************************************************************/ 451/* Send a MAD out on the GSI interface */ 452ib_api_status_t 453__osmv_send_sa_req(IN osmv_sa_bind_info_t * p_bind, 454 IN const osmv_sa_mad_data_t * const p_sa_mad_data, 455 IN const osmv_query_req_t * const p_query_req) 456{ 457 ib_api_status_t status; 458 ib_mad_t *p_mad_hdr; 459 ib_sa_mad_t *p_sa_mad; 460 osm_madw_t *p_madw; 461 osm_log_t *p_log = p_bind->p_log; 462 static atomic32_t trans_id; 463 boolean_t sync; 464 osmv_query_req_t *p_query_req_copy; 465 466 OSM_LOG_ENTER(p_log); 467 468 /* 469 since the sm_lid might change we obtain it every send 470 (actually it is cached in the bind object and refreshed 471 every 30sec by this proc ) 472 */ 473 status = 474 __osmv_get_lid_and_sm_lid_by_port_guid(p_bind->p_vendor, 475 p_bind->port_guid, 476 &p_bind-> 477 last_lids_update_sec, 478 &p_bind->lid, 479 &p_bind->sm_lid); 480 if (status != IB_SUCCESS) { 481 osm_log(p_log, OSM_LOG_ERROR, 482 "__osmv_send_sa_req: ERR 0509: " 483 "Fail to obtain the sm lid.\n"); 484 goto Exit; 485 } 486 487 /* Get a MAD wrapper for the send */ 488 p_madw = osm_mad_pool_get(p_bind->p_mad_pool, 489 p_bind->h_bind, MAD_BLOCK_SIZE, NULL); 490 491 if (p_madw == NULL) { 492 osm_log(p_log, OSM_LOG_ERROR, 493 "__osmv_send_sa_req: ERR 0510: " 494 "Unable to acquire MAD.\n"); 495 status = IB_INSUFFICIENT_RESOURCES; 496 goto Exit; 497 } 498 499 /* Initialize the Sent MAD: */ 500 501 /* Initialize the MAD buffer for the send operation. */ 502 p_mad_hdr = osm_madw_get_mad_ptr(p_madw); 503 p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw); 504 505 /* Get a new transaction Id */ 506 cl_atomic_inc(&trans_id); 507 508 /* Cleanup the MAD from any residue */ 509 memset(p_sa_mad, 0, MAD_BLOCK_SIZE); 510 511 /* Initialize the standard MAD header. */ 512 ib_mad_init_new(p_mad_hdr, /* mad pointer */ 513 IB_MCLASS_SUBN_ADM, /* class */ 514 (uint8_t) 2, /* version */ 515 p_sa_mad_data->method, /* method */ 516 cl_hton64((uint64_t) trans_id), /* tid */ 517 p_sa_mad_data->attr_id, /* attr id */ 518 p_sa_mad_data->attr_mod /* attr mod */ 519 ); 520 521 /* Set the query information. */ 522 p_sa_mad->sm_key = p_query_req->sm_key; 523 p_sa_mad->attr_offset = 0; 524 p_sa_mad->comp_mask = p_sa_mad_data->comp_mask; 525 if (p_sa_mad->comp_mask) { 526 memcpy(p_sa_mad->data, p_sa_mad_data->p_attr, 527 ib_get_attr_size(p_sa_mad_data->attr_offset)); 528 } 529 530 /* 531 Provide the address to send to 532 */ 533 /* Patch to handle IBAL - host order , where it should take destination lid in network order */ 534#ifdef OSM_VENDOR_INTF_AL 535 p_madw->mad_addr.dest_lid = p_bind->sm_lid; 536#else 537 p_madw->mad_addr.dest_lid = cl_hton16(p_bind->sm_lid); 538#endif 539 p_madw->mad_addr.addr_type.smi.source_lid = cl_hton16(p_bind->lid); 540 p_madw->mad_addr.addr_type.gsi.remote_qp = CL_HTON32(1); 541 p_madw->mad_addr.addr_type.gsi.remote_qkey = IB_QP1_WELL_KNOWN_Q_KEY; 542 p_madw->mad_addr.addr_type.gsi.pkey_ix = 0; 543 p_madw->resp_expected = TRUE; 544 p_madw->fail_msg = CL_DISP_MSGID_NONE; 545 546 /* 547 Provide MAD context such that the call back will know what to do. 548 We have to keep the entire request structure so we know the CB. 549 Since we can not rely on the client to keep it arroud until 550 the response - we duplicate it and will later dispose it (in CB). 551 To store on the MADW we cast it into what opensm has: 552 p_madw->context.arb_context.context1 553 */ 554 p_query_req_copy = malloc(sizeof(*p_query_req_copy)); 555 *p_query_req_copy = *p_query_req; 556 p_madw->context.arb_context.context1 = p_query_req_copy; 557 558 /* we can support async as well as sync calls */ 559 sync = ((p_query_req->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC); 560 561 /* send the mad asynchronously */ 562 status = osm_vendor_send(osm_madw_get_bind_handle(p_madw), 563 p_madw, p_madw->resp_expected); 564 565 /* if synchronous - wait on the event */ 566 if (sync) { 567 osm_log(p_log, OSM_LOG_DEBUG, 568 "__osmv_send_sa_req: " "Waiting for async event.\n"); 569 cl_event_wait_on(&p_bind->sync_event, EVENT_NO_TIMEOUT, FALSE); 570 cl_event_reset(&p_bind->sync_event); 571 status = p_madw->status; 572 } 573 574Exit: 575 OSM_LOG_EXIT(p_log); 576 return status; 577} 578 579/***************************************************************************** 580 *****************************************************************************/ 581/* 582 * Query the SA based on the user's request. 583 */ 584ib_api_status_t 585osmv_query_sa(IN osm_bind_handle_t h_bind, 586 IN const osmv_query_req_t * const p_query_req) 587{ 588 osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) h_bind; 589 osmv_sa_mad_data_t sa_mad_data; 590 osmv_user_query_t *p_user_query; 591 ib_service_record_t svc_rec; 592 ib_node_record_t node_rec; 593 ib_portinfo_record_t port_info; 594 ib_path_rec_t path_rec; 595 ib_class_port_info_t class_port_info; 596 osm_log_t *p_log = p_bind->p_log; 597 ib_api_status_t status; 598 599 OSM_LOG_ENTER(p_log); 600 601 /* Set the request information. */ 602 sa_mad_data.method = IB_MAD_METHOD_GETTABLE; 603 sa_mad_data.attr_mod = 0; 604 605 /* Set the MAD attributes and component mask correctly. */ 606 switch (p_query_req->query_type) { 607 608 case OSMV_QUERY_USER_DEFINED: 609 osm_log(p_log, OSM_LOG_DEBUG, 610 "osmv_query_sa DBG:001 %s", "USER_DEFINED\n"); 611 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input; 612 if (p_user_query->method) 613 sa_mad_data.method = p_user_query->method; 614 sa_mad_data.attr_offset = p_user_query->attr_offset; 615 sa_mad_data.attr_id = p_user_query->attr_id; 616 sa_mad_data.attr_mod = p_user_query->attr_mod; 617 sa_mad_data.comp_mask = p_user_query->comp_mask; 618 sa_mad_data.p_attr = p_user_query->p_attr; 619 break; 620 621 case OSMV_QUERY_ALL_SVC_RECS: 622 osm_log(p_log, OSM_LOG_DEBUG, 623 "osmv_query_sa DBG:001 %s", "SVC_REC_BY_NAME\n"); 624 sa_mad_data.method = IB_MAD_METHOD_GETTABLE; 625 sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD; 626 sa_mad_data.attr_offset = 627 ib_get_attr_offset(sizeof(ib_service_record_t)); 628 sa_mad_data.comp_mask = 0; 629 sa_mad_data.p_attr = &svc_rec; 630 break; 631 632 case OSMV_QUERY_SVC_REC_BY_NAME: 633 osm_log(p_log, OSM_LOG_DEBUG, 634 "osmv_query_sa DBG:001 %s", "SVC_REC_BY_NAME\n"); 635 sa_mad_data.method = IB_MAD_METHOD_GET; 636 sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD; 637 sa_mad_data.comp_mask = IB_SR_COMPMASK_SNAME; 638 sa_mad_data.attr_offset = 639 ib_get_attr_offset(sizeof(ib_service_record_t)); 640 sa_mad_data.p_attr = &svc_rec; 641 memcpy(svc_rec.service_name, p_query_req->p_query_input, 642 sizeof(ib_svc_name_t)); 643 break; 644 645 case OSMV_QUERY_SVC_REC_BY_ID: 646 osm_log(p_log, OSM_LOG_DEBUG, 647 "osmv_query_sa DBG:001 %s", "SVC_REC_BY_ID\n"); 648 sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD; 649 sa_mad_data.comp_mask = IB_SR_COMPMASK_SID; 650 sa_mad_data.attr_offset = 651 ib_get_attr_offset(sizeof(ib_service_record_t)); 652 sa_mad_data.p_attr = &svc_rec; 653 svc_rec.service_id = 654 *(ib_net64_t *) (p_query_req->p_query_input); 655 break; 656 657 case OSMV_QUERY_CLASS_PORT_INFO: 658 osm_log(p_log, OSM_LOG_DEBUG, 659 "osmv_query_sa DBG:001 %s", "CLASS_PORT_INFO\n"); 660 sa_mad_data.method = IB_MAD_METHOD_GET; 661 sa_mad_data.attr_id = IB_MAD_ATTR_CLASS_PORT_INFO; 662 sa_mad_data.attr_offset = 663 ib_get_attr_offset(sizeof(ib_class_port_info_t)); 664 sa_mad_data.comp_mask = 0; 665 sa_mad_data.p_attr = &class_port_info; 666 667 break; 668 669 case OSMV_QUERY_NODE_REC_BY_NODE_GUID: 670 osm_log(p_log, OSM_LOG_DEBUG, 671 "osmv_query_sa DBG:001 %s", "NODE_REC_BY_NODE_GUID\n"); 672 sa_mad_data.method = IB_MAD_METHOD_GETTABLE; 673 sa_mad_data.attr_id = IB_MAD_ATTR_NODE_RECORD; 674 sa_mad_data.attr_offset = 675 ib_get_attr_offset(sizeof(ib_node_record_t)); 676 sa_mad_data.comp_mask = IB_NR_COMPMASK_NODEGUID; 677 sa_mad_data.p_attr = &node_rec; 678 node_rec.node_info.node_guid = 679 *(ib_net64_t *) (p_query_req->p_query_input); 680 681 break; 682 683 case OSMV_QUERY_PORT_REC_BY_LID: 684 osm_log(p_log, OSM_LOG_DEBUG, 685 "osmv_query_sa DBG:001 %s", "PORT_REC_BY_LID\n"); 686 sa_mad_data.attr_id = IB_MAD_ATTR_PORTINFO_RECORD; 687 sa_mad_data.attr_offset = 688 ib_get_attr_offset(sizeof(ib_portinfo_record_t)); 689 sa_mad_data.comp_mask = IB_PIR_COMPMASK_LID; 690 sa_mad_data.p_attr = &port_info; 691 port_info.lid = *(ib_net16_t *) (p_query_req->p_query_input); 692 break; 693 694 case OSMV_QUERY_PORT_REC_BY_LID_AND_NUM: 695 sa_mad_data.method = IB_MAD_METHOD_GET; 696 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input; 697 osm_log(p_log, OSM_LOG_DEBUG, 698 "osmv_query_sa DBG:001 %s", 699 "PORT_REC_BY_LID_AND_NUM\n"); 700 sa_mad_data.attr_id = IB_MAD_ATTR_PORTINFO_RECORD; 701 sa_mad_data.attr_offset = 702 ib_get_attr_offset(sizeof(ib_portinfo_record_t)); 703 sa_mad_data.comp_mask = 704 IB_PIR_COMPMASK_LID | IB_PIR_COMPMASK_PORTNUM; 705 sa_mad_data.p_attr = p_user_query->p_attr; 706 break; 707 708 case OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK: 709 sa_mad_data.method = IB_MAD_METHOD_GET; 710 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input; 711 osm_log(p_log, OSM_LOG_DEBUG, 712 "osmv_query_sa DBG:001 %s", 713 "OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK\n"); 714 sa_mad_data.attr_id = IB_MAD_ATTR_VLARB_RECORD; 715 sa_mad_data.attr_offset = 716 ib_get_attr_offset(sizeof(ib_vl_arb_table_record_t)); 717 sa_mad_data.comp_mask = 718 IB_VLA_COMPMASK_LID | IB_VLA_COMPMASK_OUT_PORT | 719 IB_VLA_COMPMASK_BLOCK; 720 sa_mad_data.p_attr = p_user_query->p_attr; 721 break; 722 723 case OSMV_QUERY_SLVL_BY_LID_AND_PORTS: 724 sa_mad_data.method = IB_MAD_METHOD_GET; 725 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input; 726 osm_log(p_log, OSM_LOG_DEBUG, 727 "osmv_query_sa DBG:001 %s", 728 "OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK\n"); 729 sa_mad_data.attr_id = IB_MAD_ATTR_SLVL_RECORD; 730 sa_mad_data.attr_offset = 731 ib_get_attr_offset(sizeof(ib_slvl_table_record_t)); 732 sa_mad_data.comp_mask = 733 IB_SLVL_COMPMASK_LID | IB_SLVL_COMPMASK_OUT_PORT | 734 IB_SLVL_COMPMASK_IN_PORT; 735 sa_mad_data.p_attr = p_user_query->p_attr; 736 break; 737 738 case OSMV_QUERY_PATH_REC_BY_PORT_GUIDS: 739 osm_log(p_log, OSM_LOG_DEBUG, 740 "osmv_query_sa DBG:001 %s", "PATH_REC_BY_PORT_GUIDS\n"); 741 memset(&path_rec, 0, sizeof(ib_path_rec_t)); 742 sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD; 743 sa_mad_data.attr_offset = 744 ib_get_attr_offset(sizeof(ib_path_rec_t)); 745 sa_mad_data.comp_mask = 746 (IB_PR_COMPMASK_DGID | IB_PR_COMPMASK_SGID); 747 sa_mad_data.p_attr = &path_rec; 748 ib_gid_set_default(&path_rec.dgid, 749 ((osmv_guid_pair_t *) (p_query_req-> 750 p_query_input))-> 751 dest_guid); 752 ib_gid_set_default(&path_rec.sgid, 753 ((osmv_guid_pair_t *) (p_query_req-> 754 p_query_input))-> 755 src_guid); 756 break; 757 758 case OSMV_QUERY_PATH_REC_BY_GIDS: 759 osm_log(p_log, OSM_LOG_DEBUG, 760 "osmv_query_sa DBG:001 %s", "PATH_REC_BY_GIDS\n"); 761 memset(&path_rec, 0, sizeof(ib_path_rec_t)); 762 sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD; 763 sa_mad_data.attr_offset = 764 ib_get_attr_offset(sizeof(ib_path_rec_t)); 765 sa_mad_data.comp_mask = 766 (IB_PR_COMPMASK_DGID | IB_PR_COMPMASK_SGID); 767 sa_mad_data.p_attr = &path_rec; 768 memcpy(&path_rec.dgid, 769 &((osmv_gid_pair_t *) (p_query_req->p_query_input))-> 770 dest_gid, sizeof(ib_gid_t)); 771 memcpy(&path_rec.sgid, 772 &((osmv_gid_pair_t *) (p_query_req->p_query_input))-> 773 src_gid, sizeof(ib_gid_t)); 774 break; 775 776 case OSMV_QUERY_PATH_REC_BY_LIDS: 777 osm_log(p_log, OSM_LOG_DEBUG, 778 "osmv_query_sa DBG:001 %s", "PATH_REC_BY_LIDS\n"); 779 memset(&path_rec, 0, sizeof(ib_path_rec_t)); 780 sa_mad_data.method = IB_MAD_METHOD_GET; 781 sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD; 782 sa_mad_data.attr_offset = 783 ib_get_attr_offset(sizeof(ib_path_rec_t)); 784 sa_mad_data.comp_mask = 785 (IB_PR_COMPMASK_DLID | IB_PR_COMPMASK_SLID); 786 sa_mad_data.p_attr = &path_rec; 787 path_rec.dlid = 788 ((osmv_lid_pair_t *) (p_query_req->p_query_input))-> 789 dest_lid; 790 path_rec.slid = 791 ((osmv_lid_pair_t *) (p_query_req->p_query_input))->src_lid; 792 break; 793 794 case OSMV_QUERY_UD_MULTICAST_SET: 795 sa_mad_data.method = IB_MAD_METHOD_SET; 796 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input; 797 osm_log(p_log, OSM_LOG_DEBUG, 798 "osmv_query_sa DBG:001 %s", 799 "OSMV_QUERY_UD_MULTICAST_SET\n"); 800 sa_mad_data.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD; 801 sa_mad_data.attr_offset = 802 ib_get_attr_offset(sizeof(ib_member_rec_t)); 803 sa_mad_data.comp_mask = p_user_query->comp_mask; 804 sa_mad_data.p_attr = p_user_query->p_attr; 805 break; 806 807 case OSMV_QUERY_UD_MULTICAST_DELETE: 808 sa_mad_data.method = IB_MAD_METHOD_DELETE; 809 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input; 810 osm_log(p_log, OSM_LOG_DEBUG, 811 "osmv_query_sa DBG:001 %s", 812 "OSMV_QUERY_UD_MULTICAST_DELETE\n"); 813 sa_mad_data.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD; 814 sa_mad_data.attr_offset = 815 ib_get_attr_offset(sizeof(ib_member_rec_t)); 816 sa_mad_data.comp_mask = p_user_query->comp_mask; 817 sa_mad_data.p_attr = p_user_query->p_attr; 818 break; 819 820 default: 821 osm_log(p_log, OSM_LOG_ERROR, 822 "osmv_query_sa DBG:001 %s", "UNKNOWN\n"); 823 CL_ASSERT(0); 824 return IB_ERROR; 825 } 826 827 status = __osmv_send_sa_req(h_bind, &sa_mad_data, p_query_req); 828 829 OSM_LOG_EXIT(p_log); 830 return status; 831} 832 833/***************************************************************************** 834 *****************************************************************************/ 835