2 * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2005,2008 Mellanox Technologies LTD. All rights reserved.
4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5 * Copyright (c) 2009,2010 HNR Consulting. All rights reserved.
7 * This software is available to you under a choice of one of two
8 * licenses. You may choose to be licensed under the terms of the GNU
9 * General Public License (GPL) Version 2, available from the file
10 * COPYING in the main directory of this source tree, or the
11 * OpenIB.org BSD license below:
13 * Redistribution and use in source and binary forms, with or
14 * without modification, are permitted provided that the following
17 * - Redistributions of source code must retain the above
18 * copyright notice, this list of conditions and the following
21 * - Redistributions in binary form must reproduce the above
22 * copyright notice, this list of conditions and the following
23 * disclaimer in the documentation and/or other materials
24 * provided with the distribution.
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39 #endif /* HAVE_CONFIG_H */
43 #include <complib/cl_debug.h>
44 #include <complib/cl_timer.h>
45 #include <complib/cl_event.h>
46 #include <vendor/osm_vendor_api.h>
47 #include <vendor/osm_vendor_sa_api.h>
49 /* this struct is the internal rep of the bind handle */
50 typedef struct _osmv_sa_bind_info {
51 osm_bind_handle_t h_bind;
53 osm_vendor_t *p_vendor;
54 osm_mad_pool_t *p_mad_pool;
56 cl_event_t sync_event;
57 uint64_t last_lids_update_sec;
60 } osmv_sa_bind_info_t;
63 Call back on new mad received:
65 We basically only need to set the context of the query.
68 A pointer to the actual context of the request (a copy of the oriignal
69 request structure) is attached as the p_madw->context.ni_context.node_guid
72 __osmv_sa_mad_rcv_cb(IN osm_madw_t * p_madw,
73 IN void *bind_context, IN osm_madw_t * p_req_madw)
75 osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) bind_context;
76 osmv_query_req_t *p_query_req_copy = NULL;
77 osmv_query_res_t query_res;
78 ib_sa_mad_t *p_sa_mad;
79 ib_net16_t mad_status;
81 OSM_LOG_ENTER(p_bind->p_log);
84 OSM_LOG(p_bind->p_log, OSM_LOG_DEBUG,
85 "Ignoring a non-response mad\n");
86 osm_mad_pool_put(p_bind->p_mad_pool, p_madw);
90 /* obtain the sent context */
92 (osmv_query_req_t *) (p_req_madw->context.arb_context.context1);
94 /* provide the context of the original request in the result */
95 query_res.query_context = p_query_req_copy->query_context;
97 /* provide the resulting madw */
98 query_res.p_result_madw = p_madw;
100 /* update the req fields */
101 p_sa_mad = (ib_sa_mad_t *) p_madw->p_mad;
103 /* if we got a remote error track it in the status */
104 mad_status = (ib_net16_t) (p_sa_mad->status & IB_SMP_STATUS_MASK);
105 if (mad_status != IB_SUCCESS) {
106 OSM_LOG(p_bind->p_log, OSM_LOG_ERROR, "ERR 0501: "
107 "Remote error:0x%04X\n", cl_ntoh16(mad_status));
108 query_res.status = IB_REMOTE_ERROR;
110 query_res.status = IB_SUCCESS;
112 /* what if we have got back an empty mad ? */
113 if (!p_madw->mad_size) {
114 OSM_LOG(p_bind->p_log, OSM_LOG_ERROR, "ERR 0502: "
115 "Got an empty mad\n");
116 query_res.status = IB_ERROR;
119 if (IB_SUCCESS == mad_status) {
121 /* if we are in not in a method response of an rmpp nature we must get only 1 */
122 /* HACK: in the future we might need to be smarter for other methods... */
123 if (p_sa_mad->method != IB_MAD_METHOD_GETTABLE_RESP) {
124 query_res.result_cnt = 1;
126 #ifndef VENDOR_RMPP_SUPPORT
127 if (mad_status != IB_SUCCESS)
128 query_res.result_cnt = 0;
130 query_res.result_cnt = 1;
132 /* we used the offset value to calculate the number of
134 if (ib_get_attr_size(p_sa_mad->attr_offset) == 0) {
135 query_res.result_cnt = 0;
136 OSM_LOG(p_bind->p_log, OSM_LOG_DEBUG,
140 query_res.result_cnt =
141 (p_madw->mad_size - IB_SA_MAD_HDR_SIZE) /
142 ib_get_attr_size(p_sa_mad->attr_offset);
143 OSM_LOG(p_bind->p_log, OSM_LOG_DEBUG,
144 "Count = %u = %zu / %u (%zu)\n",
145 query_res.result_cnt,
146 p_madw->mad_size - IB_SA_MAD_HDR_SIZE,
147 ib_get_attr_size(p_sa_mad->attr_offset),
148 (p_madw->mad_size - IB_SA_MAD_HDR_SIZE) %
149 ib_get_attr_size(p_sa_mad->attr_offset));
155 query_res.query_type = p_query_req_copy->query_type;
157 p_query_req_copy->pfn_query_cb(&query_res);
159 if ((p_query_req_copy->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC)
160 cl_event_signal(&p_bind->sync_event);
164 /* free the copied query request if found */
165 if (p_query_req_copy)
166 free(p_query_req_copy);
168 /* put back the request madw */
170 osm_mad_pool_put(p_bind->p_mad_pool, p_req_madw);
172 OSM_LOG_EXIT(p_bind->p_log);
178 Only report the error and get rid of the mad wrapper
180 static void __osmv_sa_mad_err_cb(IN void *bind_context, IN osm_madw_t * p_madw)
182 osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) bind_context;
183 osmv_query_req_t *p_query_req_copy = NULL;
184 osmv_query_res_t query_res;
186 OSM_LOG_ENTER(p_bind->p_log);
188 /* Obtain the sent context etc */
190 (osmv_query_req_t *) (p_madw->context.arb_context.context1);
192 /* provide the context of the original request in the result */
193 query_res.query_context = p_query_req_copy->query_context;
195 query_res.p_result_madw = p_madw;
197 query_res.status = IB_TIMEOUT;
198 query_res.result_cnt = 0;
199 query_res.p_result_madw->status = IB_TIMEOUT;
200 p_madw->status = IB_TIMEOUT;
201 query_res.query_type = p_query_req_copy->query_type;
203 p_query_req_copy->pfn_query_cb(&query_res);
205 if ((p_query_req_copy->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC)
206 cl_event_signal(&p_bind->sync_event);
208 free(p_query_req_copy);
209 OSM_LOG_EXIT(p_bind->p_log);
212 /*****************************************************************************
213 This routine needs to be invoked on every send - since the SM LID and Local
214 lid might change. To do that without any major perfoermance impact we cache
215 the results and time they were obtained. Refresh only twice a minute.
216 To avoid the need to use statics and risk a race - we require the refresh time
217 to be stored in the context of the results. Also this coveres cases were
218 we query for multiple guids.
219 *****************************************************************************/
220 static ib_api_status_t
221 __osmv_get_lid_and_sm_lid_by_port_guid(IN osm_vendor_t * const p_vend,
222 IN ib_net64_t port_guid,
223 IN OUT uint64_t * p_lids_update_time_sec,
225 OUT uint16_t * sm_lid)
228 ib_api_status_t status;
229 ib_port_attr_t *p_attr_array;
233 OSM_LOG_ENTER(p_vend->p_log);
235 /* use prevous values if current time is close enough to previous query */
236 if (cl_get_time_stamp_sec() <= *p_lids_update_time_sec + 30) {
237 OSM_LOG(p_vend->p_log, OSM_LOG_DEBUG,
238 "Using previously stored lid:0x%04x sm_lid:0x%04x\n",
244 /* obtain the number of available ports */
246 status = osm_vendor_get_all_port_attr(p_vend, NULL, &num_ports);
247 if (status != IB_INSUFFICIENT_MEMORY) {
248 OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 0503: "
249 "Expected to get the IB_INSUFFICIENT_MEMORY but got: %s\n",
250 ib_get_err_str(status));
255 OSM_LOG(p_vend->p_log, OSM_LOG_DEBUG,
256 "Found total of %u ports. Looking for guid:0x%016" PRIx64 "\n",
257 num_ports, cl_ntoh64(port_guid));
259 /* allocate the attributes */
261 (ib_port_attr_t *) malloc(sizeof(ib_port_attr_t) * num_ports);
263 /* obtain the attributes */
264 status = osm_vendor_get_all_port_attr(p_vend, p_attr_array, &num_ports);
265 if (status != IB_SUCCESS) {
266 OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 0504: "
267 "Failed to get port attributes (error: %s)\n",
268 ib_get_err_str(status));
274 /* find the port requested in the list */
275 for (port_num = 0; (port_num < num_ports) && (status == IB_ERROR);
277 if (p_attr_array[port_num].port_guid == port_guid) {
278 *lid = p_attr_array[port_num].lid;
279 *sm_lid = p_attr_array[port_num].sm_lid;
280 *p_lids_update_time_sec = cl_get_time_stamp_sec();
282 OSM_LOG(p_vend->p_log, OSM_LOG_DEBUG,
283 "Found guid:0x%016" PRIx64 " with idx:%d\n",
284 cl_ntoh64(port_guid), port_num);
291 OSM_LOG_EXIT(p_vend->p_log);
296 osmv_bind_sa(IN osm_vendor_t * const p_vend,
297 IN osm_mad_pool_t * const p_mad_pool, IN ib_net64_t port_guid)
299 osm_bind_info_t bind_info;
300 osm_log_t *p_log = p_vend->p_log;
301 ib_api_status_t status = IB_SUCCESS;
302 osmv_sa_bind_info_t *p_sa_bind_info;
303 cl_status_t cl_status;
305 OSM_LOG_ENTER(p_log);
307 OSM_LOG(p_log, OSM_LOG_DEBUG,
308 "Binding to port 0x%" PRIx64 "\n", cl_ntoh64(port_guid));
310 bind_info.port_guid = port_guid;
311 bind_info.mad_class = IB_MCLASS_SUBN_ADM;
312 bind_info.class_version = 2;
313 bind_info.is_responder = FALSE;
314 bind_info.is_trap_processor = FALSE;
315 bind_info.is_report_processor = FALSE;
316 bind_info.send_q_size = 256;
317 bind_info.recv_q_size = 256;
319 /* allocate the new sa bind info */
321 (osmv_sa_bind_info_t *) malloc(sizeof(osmv_sa_bind_info_t));
322 if (!p_sa_bind_info) {
323 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0505: "
324 "Failed to allocate new bind structure\n");
325 p_sa_bind_info = OSM_BIND_INVALID_HANDLE;
329 /* store some important context */
330 p_sa_bind_info->p_log = p_log;
331 p_sa_bind_info->port_guid = port_guid;
332 p_sa_bind_info->p_mad_pool = p_mad_pool;
333 p_sa_bind_info->p_vendor = p_vend;
334 p_sa_bind_info->last_lids_update_sec = 0;
336 /* Bind to the lower level */
337 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 */
339 if (p_sa_bind_info->h_bind == OSM_BIND_INVALID_HANDLE) {
340 free(p_sa_bind_info);
341 p_sa_bind_info = OSM_BIND_INVALID_HANDLE;
342 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0506: "
343 "Failed to bind to vendor GSI\n");
347 /* obtain the sm_lid from the vendor */
349 __osmv_get_lid_and_sm_lid_by_port_guid(p_vend, port_guid,
351 last_lids_update_sec,
352 &p_sa_bind_info->lid,
353 &p_sa_bind_info->sm_lid);
354 if (status != IB_SUCCESS) {
355 free(p_sa_bind_info);
356 p_sa_bind_info = OSM_BIND_INVALID_HANDLE;
357 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0507: "
358 "Failed to obtain the SM lid\n");
362 /* initialize the sync_event */
363 cl_event_construct(&p_sa_bind_info->sync_event);
364 cl_status = cl_event_init(&p_sa_bind_info->sync_event, TRUE);
365 if (cl_status != CL_SUCCESS) {
366 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0508: "
367 "cl_init_event failed: %s\n", ib_get_err_str(cl_status));
368 free(p_sa_bind_info);
369 p_sa_bind_info = OSM_BIND_INVALID_HANDLE;
374 return (p_sa_bind_info);
377 /****t* OSM Vendor SA Client/osmv_sa_mad_data
382 * Extra fields required to perform a mad query
383 * This struct is passed to the actual send method
387 typedef struct _osmv_sa_mad_data {
391 ib_net16_t attr_offset;
393 ib_net64_t comp_mask;
395 } osmv_sa_mad_data_t;
398 * The method of the mad to be sent
404 * Offset as defined by RMPP
410 * The component mask of the query
413 * A pointer to the record of the attribute to be sent.
417 /* Send a MAD out on the GSI interface */
418 static ib_api_status_t
419 __osmv_send_sa_req(IN osmv_sa_bind_info_t * p_bind,
420 IN const osmv_sa_mad_data_t * const p_sa_mad_data,
421 IN const osmv_query_req_t * const p_query_req)
423 ib_api_status_t status;
425 ib_sa_mad_t *p_sa_mad;
427 osm_log_t *p_log = p_bind->p_log;
428 static atomic32_t trans_id;
430 osmv_query_req_t *p_query_req_copy;
433 OSM_LOG_ENTER(p_log);
436 since the sm_lid might change we obtain it every send
437 (actually it is cached in the bind object and refreshed
438 every 30sec by this proc)
441 __osmv_get_lid_and_sm_lid_by_port_guid(p_bind->p_vendor,
444 last_lids_update_sec,
447 if (status != IB_SUCCESS) {
448 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0509: "
449 "Failed to obtain the SM lid\n");
453 /* Get a MAD wrapper for the send */
454 p_madw = osm_mad_pool_get(p_bind->p_mad_pool,
455 p_bind->h_bind, MAD_BLOCK_SIZE, NULL);
457 if (p_madw == NULL) {
458 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0510: "
459 "Unable to acquire MAD\n");
460 status = IB_INSUFFICIENT_RESOURCES;
464 /* Initialize the Sent MAD: */
466 /* Initialize the MAD buffer for the send operation. */
467 p_mad_hdr = osm_madw_get_mad_ptr(p_madw);
468 p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
470 /* Get a new transaction Id */
471 cl_atomic_inc(&trans_id);
473 /* Cleanup the MAD from any residue */
474 memset(p_sa_mad, 0, MAD_BLOCK_SIZE);
476 /* Initialize the standard MAD header. */
477 ib_mad_init_new(p_mad_hdr, /* mad pointer */
478 IB_MCLASS_SUBN_ADM, /* class */
479 (uint8_t) 2, /* version */
480 p_sa_mad_data->method, /* method */
481 cl_hton64((uint64_t) trans_id), /* tid */
482 p_sa_mad_data->attr_id, /* attr id */
483 p_sa_mad_data->attr_mod /* attr mod */);
485 /* Set the query information. */
486 p_sa_mad->sm_key = p_query_req->sm_key;
487 p_sa_mad->attr_offset = 0;
488 p_sa_mad->comp_mask = p_sa_mad_data->comp_mask;
489 if (p_sa_mad->comp_mask) {
490 p_sa_mad_data->attr_offset ? (sa_size = ib_get_attr_size(p_sa_mad_data->attr_offset)) : (sa_size = IB_SA_DATA_SIZE);
491 memcpy(p_sa_mad->data, p_sa_mad_data->p_attr, sa_size);
495 Provide the address to send to
497 /* Patch to handle IBAL - host order , where it should take destination lid in network order */
498 #ifdef OSM_VENDOR_INTF_AL
499 p_madw->mad_addr.dest_lid = p_bind->sm_lid;
501 p_madw->mad_addr.dest_lid = cl_hton16(p_bind->sm_lid);
503 p_madw->mad_addr.addr_type.smi.source_lid = cl_hton16(p_bind->lid);
504 p_madw->mad_addr.addr_type.gsi.remote_qp = CL_HTON32(1);
505 p_madw->resp_expected = TRUE;
506 p_madw->fail_msg = CL_DISP_MSGID_NONE;
509 Provide MAD context such that the call back will know what to do.
510 We have to keep the entire request structure so we know the CB.
511 Since we can not rely on the client to keep it around until
512 the response - we duplicate it and will later dispose it (in CB).
513 To store on the MADW we cast it into what opensm has:
514 p_madw->context.arb_context.context1
516 p_query_req_copy = malloc(sizeof(*p_query_req_copy));
517 if (!p_query_req_copy) {
518 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0511: "
519 "Unable to acquire memory for query copy\n");
520 osm_mad_pool_put(p_bind->p_mad_pool, p_madw);
521 status = IB_INSUFFICIENT_RESOURCES;
524 *p_query_req_copy = *p_query_req;
525 p_madw->context.arb_context.context1 = p_query_req_copy;
527 /* we can support async as well as sync calls */
528 sync = ((p_query_req->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC);
530 /* send the mad asynchronously */
531 status = osm_vendor_send(osm_madw_get_bind_handle(p_madw),
532 p_madw, p_madw->resp_expected);
534 /* if synchronous - wait on the event */
536 OSM_LOG(p_log, OSM_LOG_DEBUG, "Waiting for async event\n");
537 cl_event_wait_on(&p_bind->sync_event, EVENT_NO_TIMEOUT, FALSE);
538 cl_event_reset(&p_bind->sync_event);
539 status = p_madw->status;
548 * Query the SA based on the user's request.
551 osmv_query_sa(IN osm_bind_handle_t h_bind,
552 IN const osmv_query_req_t * const p_query_req)
555 ib_service_record_t svc_rec;
556 ib_node_record_t node_rec;
557 ib_portinfo_record_t port_info;
558 ib_path_rec_t path_rec;
559 #ifdef DUAL_SIDED_RMPP
560 ib_multipath_rec_t multipath_rec;
562 ib_class_port_info_t class_port_info;
564 osmv_sa_mad_data_t sa_mad_data;
565 osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) h_bind;
566 osmv_user_query_t *p_user_query;
567 #ifdef DUAL_SIDED_RMPP
568 osmv_multipath_req_t *p_mpr_req;
571 osm_log_t *p_log = p_bind->p_log;
572 ib_api_status_t status;
574 OSM_LOG_ENTER(p_log);
576 /* Set the request information. */
577 sa_mad_data.method = IB_MAD_METHOD_GETTABLE;
578 sa_mad_data.attr_mod = 0;
579 sa_mad_data.attr_offset = 0;
581 /* Set the MAD attributes and component mask correctly. */
582 switch (p_query_req->query_type) {
584 case OSMV_QUERY_USER_DEFINED:
585 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 USER_DEFINED\n");
586 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
587 if (p_user_query->method)
588 sa_mad_data.method = p_user_query->method;
589 #ifdef DUAL_SIDED_RMPP
590 if (sa_mad_data.method == IB_MAD_METHOD_GETMULTI ||
591 sa_mad_data.method == IB_MAD_METHOD_GETTRACETABLE)
592 sa_mad_data.attr_offset = p_user_query->attr_offset;
594 sa_mad_data.attr_id = p_user_query->attr_id;
595 sa_mad_data.attr_mod = p_user_query->attr_mod;
596 sa_mad_data.comp_mask = p_user_query->comp_mask;
597 sa_mad_data.p_attr = p_user_query->p_attr;
600 case OSMV_QUERY_ALL_SVC_RECS:
601 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 SVC_REC_BY_NAME\n");
602 sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
603 sa_mad_data.comp_mask = 0;
604 sa_mad_data.p_attr = &u.svc_rec;
607 case OSMV_QUERY_SVC_REC_BY_NAME:
608 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 SVC_REC_BY_NAME\n");
609 sa_mad_data.method = IB_MAD_METHOD_GET;
610 sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
611 sa_mad_data.comp_mask = IB_SR_COMPMASK_SNAME;
612 sa_mad_data.p_attr = &u.svc_rec;
613 memcpy(u.svc_rec.service_name, p_query_req->p_query_input,
614 sizeof(ib_svc_name_t));
617 case OSMV_QUERY_SVC_REC_BY_ID:
618 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 SVC_REC_BY_ID\n");
619 sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
620 sa_mad_data.comp_mask = IB_SR_COMPMASK_SID;
621 sa_mad_data.p_attr = &u.svc_rec;
622 u.svc_rec.service_id =
623 *(ib_net64_t *) (p_query_req->p_query_input);
626 case OSMV_QUERY_CLASS_PORT_INFO:
627 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 CLASS_PORT_INFO\n");
628 sa_mad_data.method = IB_MAD_METHOD_GET;
629 sa_mad_data.attr_id = IB_MAD_ATTR_CLASS_PORT_INFO;
630 sa_mad_data.comp_mask = 0;
631 sa_mad_data.p_attr = &u.class_port_info;
634 case OSMV_QUERY_NODE_REC_BY_NODE_GUID:
635 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 NODE_REC_BY_NODE_GUID\n");
636 sa_mad_data.attr_id = IB_MAD_ATTR_NODE_RECORD;
637 sa_mad_data.comp_mask = IB_NR_COMPMASK_NODEGUID;
638 sa_mad_data.p_attr = &u.node_rec;
639 u.node_rec.node_info.node_guid =
640 *(ib_net64_t *) (p_query_req->p_query_input);
643 case OSMV_QUERY_PORT_REC_BY_LID:
644 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PORT_REC_BY_LID\n");
645 sa_mad_data.attr_id = IB_MAD_ATTR_PORTINFO_RECORD;
646 sa_mad_data.comp_mask = IB_PIR_COMPMASK_LID;
647 sa_mad_data.p_attr = &u.port_info;
648 u.port_info.lid = *(ib_net16_t *) (p_query_req->p_query_input);
651 case OSMV_QUERY_PORT_REC_BY_LID_AND_NUM:
652 sa_mad_data.method = IB_MAD_METHOD_GET;
653 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
654 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PORT_REC_BY_LID_AND_NUM\n");
655 sa_mad_data.attr_id = IB_MAD_ATTR_PORTINFO_RECORD;
656 sa_mad_data.comp_mask =
657 IB_PIR_COMPMASK_LID | IB_PIR_COMPMASK_PORTNUM;
658 sa_mad_data.p_attr = p_user_query->p_attr;
661 case OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK:
662 sa_mad_data.method = IB_MAD_METHOD_GET;
663 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
664 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK\n");
665 sa_mad_data.attr_id = IB_MAD_ATTR_VLARB_RECORD;
666 sa_mad_data.comp_mask =
667 IB_VLA_COMPMASK_LID | IB_VLA_COMPMASK_OUT_PORT |
668 IB_VLA_COMPMASK_BLOCK;
669 sa_mad_data.p_attr = p_user_query->p_attr;
672 case OSMV_QUERY_SLVL_BY_LID_AND_PORTS:
673 sa_mad_data.method = IB_MAD_METHOD_GET;
674 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
675 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK\n");
676 sa_mad_data.attr_id = IB_MAD_ATTR_SLVL_RECORD;
677 sa_mad_data.comp_mask =
678 IB_SLVL_COMPMASK_LID | IB_SLVL_COMPMASK_OUT_PORT |
679 IB_SLVL_COMPMASK_IN_PORT;
680 sa_mad_data.p_attr = p_user_query->p_attr;
683 case OSMV_QUERY_PATH_REC_BY_PORT_GUIDS:
684 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PATH_REC_BY_PORT_GUIDS\n");
685 memset(&u.path_rec, 0, sizeof(ib_path_rec_t));
686 sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD;
687 sa_mad_data.comp_mask =
688 (IB_PR_COMPMASK_DGID | IB_PR_COMPMASK_SGID | IB_PR_COMPMASK_NUMBPATH);
689 u.path_rec.num_path = 0x7f;
690 sa_mad_data.p_attr = &u.path_rec;
691 ib_gid_set_default(&u.path_rec.dgid,
692 ((osmv_guid_pair_t *) (p_query_req->
695 ib_gid_set_default(&u.path_rec.sgid,
696 ((osmv_guid_pair_t *) (p_query_req->
701 case OSMV_QUERY_PATH_REC_BY_GIDS:
702 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PATH_REC_BY_GIDS\n");
703 memset(&u.path_rec, 0, sizeof(ib_path_rec_t));
704 sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD;
705 sa_mad_data.comp_mask =
706 (IB_PR_COMPMASK_DGID | IB_PR_COMPMASK_SGID | IB_PR_COMPMASK_NUMBPATH);
707 u.path_rec.num_path = 0x7f;
708 sa_mad_data.p_attr = &u.path_rec;
709 memcpy(&u.path_rec.dgid,
710 &((osmv_gid_pair_t *) (p_query_req->p_query_input))->
711 dest_gid, sizeof(ib_gid_t));
712 memcpy(&u.path_rec.sgid,
713 &((osmv_gid_pair_t *) (p_query_req->p_query_input))->
714 src_gid, sizeof(ib_gid_t));
717 case OSMV_QUERY_PATH_REC_BY_LIDS:
718 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 PATH_REC_BY_LIDS\n");
719 memset(&u.path_rec, 0, sizeof(ib_path_rec_t));
720 sa_mad_data.method = IB_MAD_METHOD_GET;
721 sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD;
722 sa_mad_data.comp_mask =
723 (IB_PR_COMPMASK_DLID | IB_PR_COMPMASK_SLID);
724 sa_mad_data.p_attr = &u.path_rec;
726 ((osmv_lid_pair_t *) (p_query_req->p_query_input))->
729 ((osmv_lid_pair_t *) (p_query_req->p_query_input))->src_lid;
732 case OSMV_QUERY_UD_MULTICAST_SET:
733 sa_mad_data.method = IB_MAD_METHOD_SET;
734 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
735 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 OSMV_QUERY_UD_MULTICAST_SET\n");
736 sa_mad_data.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
737 sa_mad_data.comp_mask = p_user_query->comp_mask;
738 sa_mad_data.p_attr = p_user_query->p_attr;
741 case OSMV_QUERY_UD_MULTICAST_DELETE:
742 sa_mad_data.method = IB_MAD_METHOD_DELETE;
743 p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
744 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 OSMV_QUERY_UD_MULTICAST_DELETE\n");
745 sa_mad_data.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
746 sa_mad_data.comp_mask = p_user_query->comp_mask;
747 sa_mad_data.p_attr = p_user_query->p_attr;
750 #ifdef DUAL_SIDED_RMPP
751 case OSMV_QUERY_MULTIPATH_REC:
752 OSM_LOG(p_log, OSM_LOG_DEBUG, "DBG:001 MULTIPATH_REC\n");
753 /* Validate sgid/dgid counts against SA client limit */
754 p_mpr_req = (osmv_multipath_req_t *) p_query_req->p_query_input;
755 if (p_mpr_req->sgid_count + p_mpr_req->dgid_count >
756 IB_MULTIPATH_MAX_GIDS) {
757 OSM_LOG(p_log, OSM_LOG_ERROR, "DBG:001 MULTIPATH_REC "
758 "SGID count %d DGID count %d max count %d\n",
759 p_mpr_req->sgid_count, p_mpr_req->dgid_count,
760 IB_MULTIPATH_MAX_GIDS);
764 memset(&u.multipath_rec, 0, sizeof(ib_multipath_rec_t));
765 sa_mad_data.method = IB_MAD_METHOD_GETMULTI;
766 sa_mad_data.attr_id = IB_MAD_ATTR_MULTIPATH_RECORD;
767 sa_mad_data.attr_offset =
768 ib_get_attr_offset(sizeof(ib_multipath_rec_t));
769 sa_mad_data.p_attr = &u.multipath_rec;
770 sa_mad_data.comp_mask = p_mpr_req->comp_mask;
771 u.multipath_rec.num_path = p_mpr_req->num_path;
772 if (p_mpr_req->reversible)
773 u.multipath_rec.num_path |= 0x80;
775 u.multipath_rec.num_path &= ~0x80;
776 u.multipath_rec.pkey = p_mpr_req->pkey;
777 ib_multipath_rec_set_sl(&u.multipath_rec, p_mpr_req->sl);
778 ib_multipath_rec_set_qos_class(&u.multipath_rec, 0);
779 u.multipath_rec.independence = p_mpr_req->independence;
780 u.multipath_rec.sgid_count = p_mpr_req->sgid_count;
781 u.multipath_rec.dgid_count = p_mpr_req->dgid_count;
783 for (i = 0; i < p_mpr_req->sgid_count; i++, j++)
784 u.multipath_rec.gids[j] = p_mpr_req->gids[j];
785 for (i = 0; i < p_mpr_req->dgid_count; i++, j++)
786 u.multipath_rec.gids[j] = p_mpr_req->gids[j];
791 OSM_LOG(p_log, OSM_LOG_ERROR, "DBG:001 UNKNOWN\n");
796 status = __osmv_send_sa_req(h_bind, &sa_mad_data, p_query_req);