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