]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ofed/management/opensm/libvendor/osm_vendor_ibumad_sa.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / ofed / management / opensm / libvendor / osm_vendor_ibumad_sa.c
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 <sys/time.h>
43 #include <vendor/osm_vendor_api.h>
44 #include <vendor/osm_vendor_sa_api.h>
45 #include <complib/cl_event.h>
46
47 /*****************************************************************************
48  *****************************************************************************/
49
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;
53         osm_log_t *p_log;
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;
59
60 /*****************************************************************************
61  *****************************************************************************/
62
63 /*
64   Call back on new mad received:
65
66   We basically only need to set the context of the query.
67   Or report an error.
68
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
71 */
72 static void
73 __osmv_sa_mad_rcv_cb(IN osm_madw_t * p_madw,
74                      IN void *bind_context, IN osm_madw_t * p_req_madw)
75 {
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;
81
82         OSM_LOG_ENTER(p_bind->p_log);
83
84         if (!p_req_madw) {
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);
88                 goto Exit;
89         }
90
91         /* obtain the sent context since we store it during send in the ni_ctx */
92         p_query_req_copy =
93             (osmv_query_req_t *) (long *)(long)(p_req_madw->context.ni_context.
94                                                 node_guid);
95
96         /* provide the context of the original request in the result */
97         query_res.query_context = p_query_req_copy->query_context;
98
99         /* provide the resulting madw */
100         query_res.p_result_madw = p_madw;
101
102         /* update the req fields */
103         p_sa_mad = (ib_sa_mad_t *) p_madw->p_mad;
104
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;
111         } else
112                 query_res.status = IB_SUCCESS;
113
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;
119         }
120
121         if (IB_SUCCESS == mad_status) {
122
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;
127                 } else {
128 #ifndef VENDOR_RMPP_SUPPORT
129                         if (mad_status != IB_SUCCESS)
130                                 query_res.result_cnt = 0;
131                         else
132                                 query_res.result_cnt = 1;
133 #else
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),
145                                         (p_madw->mad_size -
146                                          IB_SA_MAD_HDR_SIZE) %
147                                         ib_get_attr_size(p_sa_mad->attr_offset));
148                         } else
149                                 query_res.result_cnt = 0;
150 #endif
151                 }
152         }
153
154         query_res.query_type = p_query_req_copy->query_type;
155
156         p_query_req_copy->pfn_query_cb(&query_res);
157
158         if ((p_query_req_copy->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC)
159                 cl_event_signal(&p_bind->sync_event);
160
161 Exit:
162
163         /* free the copied query request if found */
164         if (p_query_req_copy)
165                 free(p_query_req_copy);
166
167         /* put back the request madw */
168         if (p_req_madw)
169                 osm_mad_pool_put(p_bind->p_mad_pool, p_req_madw);
170
171         OSM_LOG_EXIT(p_bind->p_log);
172 }
173
174 /*****************************************************************************
175  ****************************************************************************/
176 /*
177   Send Error Callback:
178
179   Only report the error and get rid of the mad wrapper
180 */
181 static void __osmv_sa_mad_err_cb(IN void *bind_context, IN osm_madw_t * p_madw)
182 {
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;
186
187         OSM_LOG_ENTER(p_bind->p_log);
188
189         /* Obtain the sent context etc */
190         p_query_req_copy =
191             (osmv_query_req_t *) (long *)(long)(p_madw->context.ni_context.
192                                                 node_guid);
193
194         /* provide the context of the original request in the result */
195         query_res.query_context = p_query_req_copy->query_context;
196
197         query_res.p_result_madw = p_madw;
198
199         query_res.status = IB_TIMEOUT;
200         query_res.result_cnt = 0;
201
202         query_res.query_type = p_query_req_copy->query_type;
203
204         p_query_req_copy->pfn_query_cb(&query_res);
205
206         if ((p_query_req_copy->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC)
207                 cl_event_signal(&p_bind->sync_event);
208
209         if (p_query_req_copy)
210                 free(p_query_req_copy);
211         OSM_LOG_EXIT(p_bind->p_log);
212 }
213
214 /*****************************************************************************
215  Update lids of vendor umad_port.
216  *****************************************************************************/
217 static ib_api_status_t update_umad_port(osm_vendor_t * p_vend)
218 {
219         umad_port_t port;
220         if (umad_get_port(p_vend->umad_port.ca_name,
221                           p_vend->umad_port.portnum, &port) < 0)
222                 return IB_ERROR;
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);
226         return IB_SUCCESS;
227 }
228
229 /*****************************************************************************
230  *****************************************************************************/
231 osm_bind_handle_t
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)
234 {
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;
239
240         OSM_LOG_ENTER(p_log);
241
242         OSM_LOG(p_log, OSM_LOG_DEBUG,
243                 "Binding to port 0x%" PRIx64 "\n", cl_ntoh64(port_guid));
244
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;
253
254         /* allocate the new sa bind info */
255         p_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;
261                 goto Exit;
262         }
263
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;
268
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 */
271
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");
277                 goto Exit;
278         }
279
280         /* update time umad_port is initilized now */
281         p_sa_bind_info->last_lids_update_sec = time(NULL);
282
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;
291         }
292
293 Exit:
294         OSM_LOG_EXIT(p_log);
295         return (p_sa_bind_info);
296 }
297
298 /*****************************************************************************
299  *****************************************************************************/
300
301 /****t* OSM Vendor SA Client/osmv_sa_mad_data
302  * NAME
303  *    osmv_sa_mad_data
304  *
305  * DESCRIPTION
306  * Extra fields required to perform a mad query
307  *  This struct is passed to the actual send method
308  *
309  * SYNOPSIS
310  */
311 typedef struct _osmv_sa_mad_data {
312         /* MAD data. */
313         uint8_t method;
314         ib_net16_t attr_id;
315         ib_net16_t attr_offset;
316         ib_net32_t attr_mod;
317         ib_net64_t comp_mask;
318         void *p_attr;
319 } osmv_sa_mad_data_t;
320 /*
321  * method
322  *    The method of the mad to be sent
323  *
324  *  attr_id
325  *     Attribute ID
326  *
327  *  attr_offset
328  *     Offset as defined by RMPP
329  *
330  *  attr_mod
331  *     Attribute modifier
332  *
333  *  comp_mask
334  *     The component mask of the query
335  *
336  *  p_attr
337  *     A pointer to the record of the attribute to be sent.
338  *
339  *****/
340
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)
348 {
349         ib_api_status_t status;
350         ib_mad_t *p_mad_hdr;
351         ib_sa_mad_t *p_sa_mad;
352         osm_madw_t *p_madw;
353         osm_log_t *p_log = p_bind->p_log;
354         static atomic32_t trans_id;
355         boolean_t sync;
356         osmv_query_req_t *p_query_req_copy;
357
358         OSM_LOG_ENTER(p_log);
359
360         /*
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)
364          */
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");
370                         goto Exit;
371                 }
372                 p_bind->last_lids_update_sec = time(NULL);
373         }
374
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);
378
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;
383                 goto Exit;
384         }
385
386         /* Initialize the Sent MAD: */
387
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);
391
392         /* Get a new transaction Id */
393         cl_atomic_inc(&trans_id);
394
395         /* Cleanup the MAD from any residue */
396         memset(p_sa_mad, 0, MAD_BLOCK_SIZE);
397
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 */);
406
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;
414 #endif
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));
418         }
419
420         /*
421            Provide the address to send to
422          */
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;
430
431         /*
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
438          */
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;
443
444         /* we can support async as well as sync calls */
445         sync = ((p_query_req->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC);
446
447         /* send the mad asynchronously */
448         status = osm_vendor_send(osm_madw_get_bind_handle(p_madw),
449                                  p_madw, p_madw->resp_expected);
450
451         /* if synchronous - wait on the event */
452         if (sync) {
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;
457         }
458
459 Exit:
460         OSM_LOG_EXIT(p_log);
461         return status;
462 }
463
464 /*****************************************************************************
465  *****************************************************************************/
466 /*
467  * Query the SA based on the user's request.
468  */
469 ib_api_status_t
470 osmv_query_sa(IN osm_bind_handle_t h_bind,
471               IN const osmv_query_req_t * const p_query_req)
472 {
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;
483         int i, j;
484 #endif
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;
488
489         OSM_LOG_ENTER(p_log);
490
491         /* Set the request information. */
492         sa_mad_data.method = IB_MAD_METHOD_GETTABLE;
493         sa_mad_data.attr_mod = 0;
494
495         /* Set the MAD attributes and component mask correctly. */
496         switch (p_query_req->query_type) {
497
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;
508                 break;
509
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;
517                 break;
518
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));
529                 break;
530
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;
538                 svc_rec.service_id =
539                     *(ib_net64_t *) (p_query_req->p_query_input);
540                 break;
541
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;
550                 break;
551
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);
561                 break;
562
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);
571                 break;
572
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;
583                 break;
584
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;
596                 break;
597
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;
609                 break;
610
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->
622                                                           p_query_input))->
623                                    dest_guid);
624                 ib_gid_set_default(&path_rec.sgid,
625                                    ((osmv_guid_pair_t *) (p_query_req->
626                                                           p_query_input))->
627                                    src_guid);
628                 break;
629
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));
645                 break;
646
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;
657                 path_rec.dlid =
658                     ((osmv_lid_pair_t *) (p_query_req->p_query_input))->
659                     dest_lid;
660                 path_rec.slid =
661                     ((osmv_lid_pair_t *) (p_query_req->p_query_input))->src_lid;
662                 break;
663
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;
673                 break;
674
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;
684                 break;
685
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);
697                         CL_ASSERT(0);
698                         return IB_ERROR;
699                 }
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;
710                 else
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;
718                 j = 0;
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];
723                 break;
724 #endif
725
726         default:
727                 OSM_LOG(p_log, OSM_LOG_ERROR, "DBG:001 UNKNOWN\n");
728                 CL_ASSERT(0);
729                 return IB_ERROR;
730         }
731
732         status = __osmv_send_sa_req(h_bind, &sa_mad_data, p_query_req);
733
734         OSM_LOG_EXIT(p_log);
735         return status;
736 }