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.
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:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
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.
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
38 #endif /* HAVE_CONFIG_H */
43 #include <vendor/osm_vendor_api.h>
44 #include <vendor/osm_vendor_sa_api.h>
45 #include <complib/cl_event.h>
47 /*****************************************************************************
48 *****************************************************************************/
50 /* this struct is the internal rep of the bind handle */
51 typedef struct _osmv_sa_bind_info {
52 osm_bind_handle_t h_bind;
54 osm_vendor_t *p_vendor;
55 osm_mad_pool_t *p_mad_pool;
56 cl_event_t sync_event;
57 time_t last_lids_update_sec;
58 } osmv_sa_bind_info_t;
60 /*****************************************************************************
61 *****************************************************************************/
64 Call back on new mad received:
66 We basically only need to set the context of the query.
69 A pointer to the actual context of the request (a copy of the oriignal
70 request structure) is attached as the p_madw->context.ni_context.node_guid
73 __osmv_sa_mad_rcv_cb(IN osm_madw_t * p_madw,
74 IN void *bind_context, IN osm_madw_t * p_req_madw)
76 osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) bind_context;
77 osmv_query_req_t *p_query_req_copy = NULL;
78 osmv_query_res_t query_res;
79 ib_sa_mad_t *p_sa_mad;
80 ib_net16_t mad_status;
82 OSM_LOG_ENTER(p_bind->p_log);
85 OSM_LOG(p_bind->p_log, OSM_LOG_DEBUG,
86 "Ignoring a non-response mad\n");
87 osm_mad_pool_put(p_bind->p_mad_pool, p_madw);
91 /* obtain the sent context since we store it during send in the ni_ctx */
93 (osmv_query_req_t *) (long *)(long)(p_req_madw->context.ni_context.
96 /* provide the context of the original request in the result */
97 query_res.query_context = p_query_req_copy->query_context;
99 /* provide the resulting madw */
100 query_res.p_result_madw = p_madw;
102 /* update the req fields */
103 p_sa_mad = (ib_sa_mad_t *) p_madw->p_mad;
105 /* if we got a remote error track it in the status */
106 mad_status = (ib_net16_t) (p_sa_mad->status & IB_SMP_STATUS_MASK);
107 if (mad_status != IB_SUCCESS) {
108 OSM_LOG(p_bind->p_log, OSM_LOG_ERROR, "ERR 5501: "
109 "Remote error:0x%04X\n", cl_ntoh16(mad_status));
110 query_res.status = IB_REMOTE_ERROR;
112 query_res.status = IB_SUCCESS;
114 /* what if we have got back an empty mad ? */
115 if (!p_madw->mad_size) {
116 OSM_LOG(p_bind->p_log, OSM_LOG_ERROR, "ERR 5502: "
117 "Got an empty mad\n");
118 query_res.status = IB_ERROR;
121 if (IB_SUCCESS == mad_status) {
123 /* if we are in not in a method response of an rmpp nature we must get only 1 */
124 /* HACK: in the future we might need to be smarter for other methods... */
125 if (p_sa_mad->method != IB_MAD_METHOD_GETTABLE_RESP) {
126 query_res.result_cnt = 1;
128 #ifndef VENDOR_RMPP_SUPPORT
129 if (mad_status != IB_SUCCESS)
130 query_res.result_cnt = 0;
132 query_res.result_cnt = 1;
134 if (ib_get_attr_size(p_sa_mad->attr_offset)) {
135 /* we used the offset value to calculate the
136 number of records in here */
137 query_res.result_cnt = (uintn_t)
138 ((p_madw->mad_size - IB_SA_MAD_HDR_SIZE) /
139 ib_get_attr_size(p_sa_mad->attr_offset));
140 OSM_LOG(p_bind->p_log, OSM_LOG_DEBUG,
141 "Count = %u = %zu / %u (%zu)\n",
142 query_res.result_cnt,
143 p_madw->mad_size - IB_SA_MAD_HDR_SIZE,
144 ib_get_attr_size(p_sa_mad->attr_offset),
146 IB_SA_MAD_HDR_SIZE) %
147 ib_get_attr_size(p_sa_mad->attr_offset));
149 query_res.result_cnt = 0;
154 query_res.query_type = p_query_req_copy->query_type;
156 p_query_req_copy->pfn_query_cb(&query_res);
158 if ((p_query_req_copy->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC)
159 cl_event_signal(&p_bind->sync_event);
163 /* free the copied query request if found */
164 if (p_query_req_copy)
165 free(p_query_req_copy);
167 /* put back the request madw */
169 osm_mad_pool_put(p_bind->p_mad_pool, p_req_madw);
171 OSM_LOG_EXIT(p_bind->p_log);
174 /*****************************************************************************
175 ****************************************************************************/
179 Only report the error and get rid of the mad wrapper
181 static void __osmv_sa_mad_err_cb(IN void *bind_context, IN osm_madw_t * p_madw)
183 osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) bind_context;
184 osmv_query_req_t *p_query_req_copy = NULL;
185 osmv_query_res_t query_res;
187 OSM_LOG_ENTER(p_bind->p_log);
189 /* Obtain the sent context etc */
191 (osmv_query_req_t *) (long *)(long)(p_madw->context.ni_context.
194 /* provide the context of the original request in the result */
195 query_res.query_context = p_query_req_copy->query_context;
197 query_res.p_result_madw = p_madw;
199 query_res.status = IB_TIMEOUT;
200 query_res.result_cnt = 0;
202 query_res.query_type = p_query_req_copy->query_type;
204 p_query_req_copy->pfn_query_cb(&query_res);
206 if ((p_query_req_copy->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC)
207 cl_event_signal(&p_bind->sync_event);
209 if (p_query_req_copy)
210 free(p_query_req_copy);
211 OSM_LOG_EXIT(p_bind->p_log);
214 /*****************************************************************************
215 Update lids of vendor umad_port.
216 *****************************************************************************/
217 static ib_api_status_t update_umad_port(osm_vendor_t * p_vend)
220 if (umad_get_port(p_vend->umad_port.ca_name,
221 p_vend->umad_port.portnum, &port) < 0)
223 p_vend->umad_port.base_lid = port.base_lid;
224 p_vend->umad_port.sm_lid = port.sm_lid;
225 umad_release_port(&port);
229 /*****************************************************************************
230 *****************************************************************************/
232 osmv_bind_sa(IN osm_vendor_t * const p_vend,
233 IN osm_mad_pool_t * const p_mad_pool, IN ib_net64_t port_guid)
235 osm_bind_info_t bind_info;
236 osm_log_t *p_log = p_vend->p_log;
237 osmv_sa_bind_info_t *p_sa_bind_info;
238 cl_status_t cl_status;
240 OSM_LOG_ENTER(p_log);
242 OSM_LOG(p_log, OSM_LOG_DEBUG,
243 "Binding to port 0x%" PRIx64 "\n", cl_ntoh64(port_guid));
245 bind_info.port_guid = port_guid;
246 bind_info.mad_class = IB_MCLASS_SUBN_ADM;
247 bind_info.class_version = 2;
248 bind_info.is_responder = FALSE;
249 bind_info.is_trap_processor = FALSE;
250 bind_info.is_report_processor = FALSE;
251 bind_info.send_q_size = OSM_SM_DEFAULT_QP1_RCV_SIZE;
252 bind_info.recv_q_size = OSM_SM_DEFAULT_QP1_SEND_SIZE;
254 /* allocate the new sa bind info */
256 (osmv_sa_bind_info_t *) malloc(sizeof(osmv_sa_bind_info_t));
257 if (!p_sa_bind_info) {
258 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5505: "
259 "Failed to allocate new bind structure\n");
260 p_sa_bind_info = OSM_BIND_INVALID_HANDLE;
264 /* store some important context */
265 p_sa_bind_info->p_log = p_log;
266 p_sa_bind_info->p_mad_pool = p_mad_pool;
267 p_sa_bind_info->p_vendor = p_vend;
269 /* Bind to the lower level */
270 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 */
272 if (p_sa_bind_info->h_bind == OSM_BIND_INVALID_HANDLE) {
273 free(p_sa_bind_info);
274 p_sa_bind_info = OSM_BIND_INVALID_HANDLE;
275 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5506: "
276 "Failed to bind to vendor GSI\n");
280 /* update time umad_port is initilized now */
281 p_sa_bind_info->last_lids_update_sec = time(NULL);
283 /* initialize the sync_event */
284 cl_event_construct(&p_sa_bind_info->sync_event);
285 cl_status = cl_event_init(&p_sa_bind_info->sync_event, TRUE);
286 if (cl_status != CL_SUCCESS) {
287 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5508: "
288 "cl_init_event failed: %s\n", ib_get_err_str(cl_status));
289 free(p_sa_bind_info);
290 p_sa_bind_info = OSM_BIND_INVALID_HANDLE;
295 return (p_sa_bind_info);
298 /*****************************************************************************
299 *****************************************************************************/
301 /****t* OSM Vendor SA Client/osmv_sa_mad_data
306 * Extra fields required to perform a mad query
307 * This struct is passed to the actual send method
311 typedef struct _osmv_sa_mad_data {
315 ib_net16_t attr_offset;
317 ib_net64_t comp_mask;
319 } osmv_sa_mad_data_t;
322 * The method of the mad to be sent
328 * Offset as defined by RMPP
334 * The component mask of the query
337 * A pointer to the record of the attribute to be sent.
341 /*****************************************************************************
342 *****************************************************************************/
343 /* Send a MAD out on the GSI interface */
344 static ib_api_status_t
345 __osmv_send_sa_req(IN osmv_sa_bind_info_t * p_bind,
346 IN const osmv_sa_mad_data_t * const p_sa_mad_data,
347 IN const osmv_query_req_t * const p_query_req)
349 ib_api_status_t status;
351 ib_sa_mad_t *p_sa_mad;
353 osm_log_t *p_log = p_bind->p_log;
354 static atomic32_t trans_id;
356 osmv_query_req_t *p_query_req_copy;
358 OSM_LOG_ENTER(p_log);
361 since the sm_lid might change we obtain it every send
362 (actually it is cached in the bind object and refreshed
363 every 30sec by this proc)
365 if (time(NULL) > p_bind->last_lids_update_sec + 30) {
366 status = update_umad_port(p_bind->p_vendor);
367 if (status != IB_SUCCESS) {
368 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5509: "
369 "Failed to obtain the SM lid\n");
372 p_bind->last_lids_update_sec = time(NULL);
375 /* Get a MAD wrapper for the send */
376 p_madw = osm_mad_pool_get(p_bind->p_mad_pool,
377 p_bind->h_bind, MAD_BLOCK_SIZE, NULL);
379 if (p_madw == NULL) {
380 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5510: "
381 "Unable to acquire MAD\n");
382 status = IB_INSUFFICIENT_RESOURCES;
386 /* Initialize the Sent MAD: */
388 /* Initialize the MAD buffer for the send operation. */
389 p_mad_hdr = osm_madw_get_mad_ptr(p_madw);
390 p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
392 /* Get a new transaction Id */
393 cl_atomic_inc(&trans_id);
395 /* Cleanup the MAD from any residue */
396 memset(p_sa_mad, 0, MAD_BLOCK_SIZE);
398 /* Initialize the standard MAD header. */
399 ib_mad_init_new(p_mad_hdr, /* mad pointer */
400 IB_MCLASS_SUBN_ADM, /* class */
401 (uint8_t) 2, /* version */
402 p_sa_mad_data->method, /* method */
403 cl_hton64((uint64_t) trans_id), /* tid */
404 p_sa_mad_data->attr_id, /* attr id */
405 p_sa_mad_data->attr_mod /* attr mod */);
407 /* Set the query information. */
408 p_sa_mad->sm_key = p_query_req->sm_key;
409 p_sa_mad->attr_offset = 0;
410 p_sa_mad->comp_mask = p_sa_mad_data->comp_mask;
411 #ifdef DUAL_SIDED_RMPP
412 if (p_sa_mad->method == IB_MAD_METHOD_GETMULTI)
413 p_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
415 if (p_sa_mad->comp_mask) {
416 memcpy(p_sa_mad->data, p_sa_mad_data->p_attr,
417 ib_get_attr_size(p_sa_mad_data->attr_offset));
421 Provide the address to send to
423 p_madw->mad_addr.dest_lid =
424 cl_hton16(p_bind->p_vendor->umad_port.sm_lid);
425 p_madw->mad_addr.addr_type.smi.source_lid =
426 cl_hton16(p_bind->p_vendor->umad_port.base_lid);
427 p_madw->mad_addr.addr_type.gsi.remote_qp = CL_HTON32(1);
428 p_madw->resp_expected = TRUE;
429 p_madw->fail_msg = CL_DISP_MSGID_NONE;
432 Provide MAD context such that the call back will know what to do.
433 We have to keep the entire request structure so we know the CB.
434 Since we can not rely on the client to keep it around until
435 the response - we duplicate it and will later dispose it (in CB).
436 To store on the MADW we cast it into what opensm has:
437 p_madw->context.ni_context.node_guid
439 p_query_req_copy = malloc(sizeof(*p_query_req_copy));
440 *p_query_req_copy = *p_query_req;
441 p_madw->context.ni_context.node_guid =
442 (ib_net64_t) (long)p_query_req_copy;
444 /* we can support async as well as sync calls */
445 sync = ((p_query_req->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC);
447 /* send the mad asynchronously */
448 status = osm_vendor_send(osm_madw_get_bind_handle(p_madw),
449 p_madw, p_madw->resp_expected);
451 /* if synchronous - wait on the event */
453 OSM_LOG(p_log, OSM_LOG_DEBUG, "Waiting for async event\n");
454 cl_event_wait_on(&p_bind->sync_event, EVENT_NO_TIMEOUT, FALSE);
455 cl_event_reset(&p_bind->sync_event);
456 status = p_madw->status;
464 /*****************************************************************************
465 *****************************************************************************/
467 * Query the SA based on the user's request.
470 osmv_query_sa(IN osm_bind_handle_t h_bind,
471 IN const osmv_query_req_t * const p_query_req)
473 osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) h_bind;
474 osmv_sa_mad_data_t sa_mad_data;
475 osmv_user_query_t *p_user_query;
476 ib_service_record_t svc_rec;
477 ib_node_record_t node_rec;
478 ib_portinfo_record_t port_info;
479 ib_path_rec_t path_rec;
480 #ifdef DUAL_SIDED_RMPP
481 ib_multipath_rec_t multipath_rec;
482 osmv_multipath_req_t *p_mpr_req;
485 ib_class_port_info_t class_port_info;
486 osm_log_t *p_log = p_bind->p_log;
487 ib_api_status_t status;
489 OSM_LOG_ENTER(p_log);
491 /* Set the request information. */
492 sa_mad_data.method = IB_MAD_METHOD_GETTABLE;
493 sa_mad_data.attr_mod = 0;
495 /* Set the MAD attributes and component mask correctly. */
496 switch (p_query_req->query_type) {
498 case OSMV_QUERY_USER_DEFINED:
499 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 USER_DEFINED\n");
500 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
501 if (p_user_query->method)
502 sa_mad_data.method = p_user_query->method;
503 sa_mad_data.attr_offset = p_user_query->attr_offset;
504 sa_mad_data.attr_id = p_user_query->attr_id;
505 sa_mad_data.attr_mod = p_user_query->attr_mod;
506 sa_mad_data.comp_mask = p_user_query->comp_mask;
507 sa_mad_data.p_attr = p_user_query->p_attr;
510 case OSMV_QUERY_ALL_SVC_RECS:
511 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 SVC_REC_BY_NAME\n");
512 sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
513 sa_mad_data.attr_offset =
514 ib_get_attr_offset(sizeof(ib_service_record_t));
515 sa_mad_data.comp_mask = 0;
516 sa_mad_data.p_attr = &svc_rec;
519 case OSMV_QUERY_SVC_REC_BY_NAME:
520 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 SVC_REC_BY_NAME\n");
521 sa_mad_data.method = IB_MAD_METHOD_GET;
522 sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
523 sa_mad_data.comp_mask = IB_SR_COMPMASK_SNAME;
524 sa_mad_data.attr_offset =
525 ib_get_attr_offset(sizeof(ib_service_record_t));
526 sa_mad_data.p_attr = &svc_rec;
527 memcpy(svc_rec.service_name, p_query_req->p_query_input,
528 sizeof(ib_svc_name_t));
531 case OSMV_QUERY_SVC_REC_BY_ID:
532 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 SVC_REC_BY_ID\n");
533 sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
534 sa_mad_data.comp_mask = IB_SR_COMPMASK_SID;
535 sa_mad_data.attr_offset =
536 ib_get_attr_offset(sizeof(ib_service_record_t));
537 sa_mad_data.p_attr = &svc_rec;
539 *(ib_net64_t *) (p_query_req->p_query_input);
542 case OSMV_QUERY_CLASS_PORT_INFO:
543 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 CLASS_PORT_INFO\n");
544 sa_mad_data.method = IB_MAD_METHOD_GET;
545 sa_mad_data.attr_id = IB_MAD_ATTR_CLASS_PORT_INFO;
546 sa_mad_data.attr_offset =
547 ib_get_attr_offset(sizeof(ib_class_port_info_t));
548 sa_mad_data.comp_mask = 0;
549 sa_mad_data.p_attr = &class_port_info;
552 case OSMV_QUERY_NODE_REC_BY_NODE_GUID:
553 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 NODE_REC_BY_NODE_GUID\n");
554 sa_mad_data.attr_id = IB_MAD_ATTR_NODE_RECORD;
555 sa_mad_data.attr_offset =
556 ib_get_attr_offset(sizeof(ib_node_record_t));
557 sa_mad_data.comp_mask = IB_NR_COMPMASK_NODEGUID;
558 sa_mad_data.p_attr = &node_rec;
559 node_rec.node_info.node_guid =
560 *(ib_net64_t *) (p_query_req->p_query_input);
563 case OSMV_QUERY_PORT_REC_BY_LID:
564 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PORT_REC_BY_LID\n");
565 sa_mad_data.attr_id = IB_MAD_ATTR_PORTINFO_RECORD;
566 sa_mad_data.attr_offset =
567 ib_get_attr_offset(sizeof(ib_portinfo_record_t));
568 sa_mad_data.comp_mask = IB_PIR_COMPMASK_LID;
569 sa_mad_data.p_attr = &port_info;
570 port_info.lid = *(ib_net16_t *) (p_query_req->p_query_input);
573 case OSMV_QUERY_PORT_REC_BY_LID_AND_NUM:
574 sa_mad_data.method = IB_MAD_METHOD_GET;
575 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
576 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PORT_REC_BY_LID_AND_NUM\n");
577 sa_mad_data.attr_id = IB_MAD_ATTR_PORTINFO_RECORD;
578 sa_mad_data.attr_offset =
579 ib_get_attr_offset(sizeof(ib_portinfo_record_t));
580 sa_mad_data.comp_mask =
581 IB_PIR_COMPMASK_LID | IB_PIR_COMPMASK_PORTNUM;
582 sa_mad_data.p_attr = p_user_query->p_attr;
585 case OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK:
586 sa_mad_data.method = IB_MAD_METHOD_GET;
587 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
588 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK\n");
589 sa_mad_data.attr_id = IB_MAD_ATTR_VLARB_RECORD;
590 sa_mad_data.attr_offset =
591 ib_get_attr_offset(sizeof(ib_vl_arb_table_record_t));
592 sa_mad_data.comp_mask =
593 IB_VLA_COMPMASK_LID | IB_VLA_COMPMASK_OUT_PORT |
594 IB_VLA_COMPMASK_BLOCK;
595 sa_mad_data.p_attr = p_user_query->p_attr;
598 case OSMV_QUERY_SLVL_BY_LID_AND_PORTS:
599 sa_mad_data.method = IB_MAD_METHOD_GET;
600 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
601 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK\n");
602 sa_mad_data.attr_id = IB_MAD_ATTR_SLVL_RECORD;
603 sa_mad_data.attr_offset =
604 ib_get_attr_offset(sizeof(ib_slvl_table_record_t));
605 sa_mad_data.comp_mask =
606 IB_SLVL_COMPMASK_LID | IB_SLVL_COMPMASK_OUT_PORT |
607 IB_SLVL_COMPMASK_IN_PORT;
608 sa_mad_data.p_attr = p_user_query->p_attr;
611 case OSMV_QUERY_PATH_REC_BY_PORT_GUIDS:
612 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PATH_REC_BY_PORT_GUIDS\n");
613 memset(&path_rec, 0, sizeof(ib_path_rec_t));
614 sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD;
615 sa_mad_data.attr_offset =
616 ib_get_attr_offset(sizeof(ib_path_rec_t));
617 sa_mad_data.comp_mask =
618 (IB_PR_COMPMASK_DGID | IB_PR_COMPMASK_SGID);
619 sa_mad_data.p_attr = &path_rec;
620 ib_gid_set_default(&path_rec.dgid,
621 ((osmv_guid_pair_t *) (p_query_req->
624 ib_gid_set_default(&path_rec.sgid,
625 ((osmv_guid_pair_t *) (p_query_req->
630 case OSMV_QUERY_PATH_REC_BY_GIDS:
631 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PATH_REC_BY_GIDS\n");
632 memset(&path_rec, 0, sizeof(ib_path_rec_t));
633 sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD;
634 sa_mad_data.attr_offset =
635 ib_get_attr_offset(sizeof(ib_path_rec_t));
636 sa_mad_data.comp_mask =
637 (IB_PR_COMPMASK_DGID | IB_PR_COMPMASK_SGID);
638 sa_mad_data.p_attr = &path_rec;
639 memcpy(&path_rec.dgid,
640 &((osmv_gid_pair_t *) (p_query_req->p_query_input))->
641 dest_gid, sizeof(ib_gid_t));
642 memcpy(&path_rec.sgid,
643 &((osmv_gid_pair_t *) (p_query_req->p_query_input))->
644 src_gid, sizeof(ib_gid_t));
647 case OSMV_QUERY_PATH_REC_BY_LIDS:
648 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PATH_REC_BY_LIDS\n");
649 memset(&path_rec, 0, sizeof(ib_path_rec_t));
650 sa_mad_data.method = IB_MAD_METHOD_GET;
651 sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD;
652 sa_mad_data.attr_offset =
653 ib_get_attr_offset(sizeof(ib_path_rec_t));
654 sa_mad_data.comp_mask =
655 (IB_PR_COMPMASK_DLID | IB_PR_COMPMASK_SLID);
656 sa_mad_data.p_attr = &path_rec;
658 ((osmv_lid_pair_t *) (p_query_req->p_query_input))->
661 ((osmv_lid_pair_t *) (p_query_req->p_query_input))->src_lid;
664 case OSMV_QUERY_UD_MULTICAST_SET:
665 sa_mad_data.method = IB_MAD_METHOD_SET;
666 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
667 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 OSMV_QUERY_UD_MULTICAST_SET\n");
668 sa_mad_data.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
669 sa_mad_data.attr_offset =
670 ib_get_attr_offset(sizeof(ib_member_rec_t));
671 sa_mad_data.comp_mask = p_user_query->comp_mask;
672 sa_mad_data.p_attr = p_user_query->p_attr;
675 case OSMV_QUERY_UD_MULTICAST_DELETE:
676 sa_mad_data.method = IB_MAD_METHOD_DELETE;
677 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
678 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 OSMV_QUERY_UD_MULTICAST_DELETE\n");
679 sa_mad_data.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
680 sa_mad_data.attr_offset =
681 ib_get_attr_offset(sizeof(ib_member_rec_t));
682 sa_mad_data.comp_mask = p_user_query->comp_mask;
683 sa_mad_data.p_attr = p_user_query->p_attr;
686 #ifdef DUAL_SIDED_RMPP
687 case OSMV_QUERY_MULTIPATH_REC:
688 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 MULTIPATH_REC\n");
689 /* Validate sgid/dgid counts against SA client limit */
690 p_mpr_req = (osmv_multipath_req_t *) p_query_req->p_query_input;
691 if (p_mpr_req->sgid_count + p_mpr_req->dgid_count >
692 IB_MULTIPATH_MAX_GIDS) {
693 OSM_LOG(p_log, OSM_LOG_ERROR, "DBG:001 MULTIPATH_REC "
694 "SGID count %d DGID count %d max count %d\n",
695 p_mpr_req->sgid_count, p_mpr_req->dgid_count,
696 IB_MULTIPATH_MAX_GIDS);
700 memset(&multipath_rec, 0, sizeof(ib_multipath_rec_t));
701 sa_mad_data.method = IB_MAD_METHOD_GETMULTI;
702 sa_mad_data.attr_id = IB_MAD_ATTR_MULTIPATH_RECORD;
703 sa_mad_data.attr_offset =
704 ib_get_attr_offset(sizeof(ib_multipath_rec_t));
705 sa_mad_data.p_attr = &multipath_rec;
706 sa_mad_data.comp_mask = p_mpr_req->comp_mask;
707 multipath_rec.num_path = p_mpr_req->num_path;
708 if (p_mpr_req->reversible)
709 multipath_rec.num_path |= 0x80;
711 multipath_rec.num_path &= ~0x80;
712 multipath_rec.pkey = p_mpr_req->pkey;
713 ib_multipath_rec_set_sl(&multipath_rec, p_mpr_req->sl);
714 ib_multipath_rec_set_qos_class(&multipath_rec, 0);
715 multipath_rec.independence = p_mpr_req->independence;
716 multipath_rec.sgid_count = p_mpr_req->sgid_count;
717 multipath_rec.dgid_count = p_mpr_req->dgid_count;
719 for (i = 0; i < p_mpr_req->sgid_count; i++, j++)
720 multipath_rec.gids[j] = p_mpr_req->gids[j];
721 for (i = 0; i < p_mpr_req->dgid_count; i++, j++)
722 multipath_rec.gids[j] = p_mpr_req->gids[j];
727 OSM_LOG(p_log, OSM_LOG_ERROR, "DBG:001 UNKNOWN\n");
732 status = __osmv_send_sa_req(h_bind, &sa_mad_data, p_query_req);