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