1219820Sjeff/*
2219820Sjeff * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
3219820Sjeff * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4219820Sjeff * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5219820Sjeff *
6219820Sjeff * This software is available to you under a choice of one of two
7219820Sjeff * licenses.  You may choose to be licensed under the terms of the GNU
8219820Sjeff * General Public License (GPL) Version 2, available from the file
9219820Sjeff * COPYING in the main directory of this source tree, or the
10219820Sjeff * OpenIB.org BSD license below:
11219820Sjeff *
12219820Sjeff *     Redistribution and use in source and binary forms, with or
13219820Sjeff *     without modification, are permitted provided that the following
14219820Sjeff *     conditions are met:
15219820Sjeff *
16219820Sjeff *      - Redistributions of source code must retain the above
17219820Sjeff *        copyright notice, this list of conditions and the following
18219820Sjeff *        disclaimer.
19219820Sjeff *
20219820Sjeff *      - Redistributions in binary form must reproduce the above
21219820Sjeff *        copyright notice, this list of conditions and the following
22219820Sjeff *        disclaimer in the documentation and/or other materials
23219820Sjeff *        provided with the distribution.
24219820Sjeff *
25219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32219820Sjeff * SOFTWARE.
33219820Sjeff *
34219820Sjeff */
35219820Sjeff
36219820Sjeff#if HAVE_CONFIG_H
37219820Sjeff#  include <config.h>
38219820Sjeff#endif				/* HAVE_CONFIG_H */
39219820Sjeff
40219820Sjeff#include <stdlib.h>
41219820Sjeff#include <string.h>
42219820Sjeff#include <complib/cl_debug.h>
43219820Sjeff#include <complib/cl_timer.h>
44219820Sjeff#include <complib/cl_event.h>
45219820Sjeff#include <vendor/osm_vendor_api.h>
46219820Sjeff#include <vendor/osm_vendor_sa_api.h>
47219820Sjeff
48219820Sjeff/*****************************************************************************
49219820Sjeff *****************************************************************************/
50219820Sjeff
51219820Sjeff/* this struct is the internal rep of the bind handle */
52219820Sjefftypedef struct _osmv_sa_bind_info {
53219820Sjeff	osm_bind_handle_t h_bind;
54219820Sjeff	osm_log_t *p_log;
55219820Sjeff	osm_vendor_t *p_vendor;
56219820Sjeff	osm_mad_pool_t *p_mad_pool;
57219820Sjeff	uint64_t port_guid;
58219820Sjeff	cl_event_t sync_event;
59219820Sjeff	uint64_t last_lids_update_sec;
60219820Sjeff	uint16_t lid;
61219820Sjeff	uint16_t sm_lid;
62219820Sjeff} osmv_sa_bind_info_t;
63219820Sjeff
64219820Sjeff/*****************************************************************************
65219820Sjeff *****************************************************************************/
66219820Sjeff
67219820Sjeff/*
68219820Sjeff  Call back on new mad received:
69219820Sjeff
70219820Sjeff  We basically only need to set the context of the query.
71219820Sjeff  Or report an error.
72219820Sjeff
73219820Sjeff  A pointer to the actual context of the request (a copy of the oriignal
74219820Sjeff  request structure) is attached as the p_madw->context.ni_context.node_guid
75219820Sjeff*/
76219820Sjeffvoid
77219820Sjeff__osmv_sa_mad_rcv_cb(IN osm_madw_t * p_madw,
78219820Sjeff		     IN void *bind_context, IN osm_madw_t * p_req_madw)
79219820Sjeff{
80219820Sjeff	osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) bind_context;
81219820Sjeff	osmv_query_req_t *p_query_req_copy = NULL;
82219820Sjeff	osmv_query_res_t query_res;
83219820Sjeff	ib_sa_mad_t *p_sa_mad;
84219820Sjeff	ib_net16_t mad_status;
85219820Sjeff
86219820Sjeff	OSM_LOG_ENTER(p_bind->p_log);
87219820Sjeff
88219820Sjeff	if (!p_req_madw) {
89219820Sjeff		osm_log(p_bind->p_log, OSM_LOG_DEBUG,
90219820Sjeff			"__osmv_sa_mad_rcv_cb: "
91219820Sjeff			"Ignoring a non-response mad\n");
92219820Sjeff		osm_mad_pool_put(p_bind->p_mad_pool, p_madw);
93219820Sjeff		goto Exit;
94219820Sjeff	}
95219820Sjeff
96219820Sjeff	/* obtain the sent context */
97219820Sjeff	p_query_req_copy =
98219820Sjeff	    (osmv_query_req_t *) (p_req_madw->context.arb_context.context1);
99219820Sjeff
100219820Sjeff	/* provide the context of the original request in the result */
101219820Sjeff	query_res.query_context = p_query_req_copy->query_context;
102219820Sjeff
103219820Sjeff	/* provide the resulting madw */
104219820Sjeff	query_res.p_result_madw = p_madw;
105219820Sjeff
106219820Sjeff	/* update the req fields */
107219820Sjeff	p_sa_mad = (ib_sa_mad_t *) p_madw->p_mad;
108219820Sjeff
109219820Sjeff	/* if we got a remote error track it in the status */
110219820Sjeff	mad_status = (ib_net16_t) (p_sa_mad->status & IB_SMP_STATUS_MASK);
111219820Sjeff	if (mad_status != IB_SUCCESS) {
112219820Sjeff		osm_log(p_bind->p_log, OSM_LOG_ERROR,
113219820Sjeff			"__osmv_sa_mad_rcv_cb: ERR 0501: "
114219820Sjeff			"Remote error:0x%04X .\n", mad_status);
115219820Sjeff		query_res.status = IB_REMOTE_ERROR;
116219820Sjeff	} else {
117219820Sjeff		query_res.status = IB_SUCCESS;
118219820Sjeff	}
119219820Sjeff
120219820Sjeff	/* what if we have got back an empty mad ? */
121219820Sjeff	if (!p_madw->mad_size) {
122219820Sjeff		osm_log(p_bind->p_log, OSM_LOG_ERROR,
123219820Sjeff			"__osmv_sa_mad_rcv_cb: ERR 0502: "
124219820Sjeff			"Got an empty mad.\n");
125219820Sjeff		query_res.status = IB_ERROR;
126219820Sjeff	}
127219820Sjeff
128219820Sjeff	if (IB_SUCCESS == mad_status) {
129219820Sjeff
130219820Sjeff		/* if we are in not in a method response of an rmpp nature we must get only 1 */
131219820Sjeff		/* HACK: in the future we might need to be smarter for other methods... */
132219820Sjeff		if (p_sa_mad->method != IB_MAD_METHOD_GETTABLE_RESP) {
133219820Sjeff			query_res.result_cnt = 1;
134219820Sjeff		} else {
135219820Sjeff#ifndef VENDOR_RMPP_SUPPORT
136219820Sjeff			if (mad_status != IB_SUCCESS)
137219820Sjeff				query_res.result_cnt = 0;
138219820Sjeff			else
139219820Sjeff				query_res.result_cnt = 1;
140219820Sjeff#else
141219820Sjeff			/* we used the offset value to calculate the number of
142219820Sjeff			   records in here */
143219820Sjeff			if (ib_get_attr_size(p_sa_mad->attr_offset) == 0) {
144219820Sjeff				query_res.result_cnt = 0;
145219820Sjeff				osm_log(p_bind->p_log, OSM_LOG_DEBUG,
146219820Sjeff					"__osmv_sa_mad_rcv_cb: Count = 0\n");
147219820Sjeff			}
148219820Sjeff			else {
149219820Sjeff				query_res.result_cnt = (uintn_t)
150219820Sjeff					((p_madw->mad_size - IB_SA_MAD_HDR_SIZE) /
151219820Sjeff					 ib_get_attr_size(p_sa_mad->attr_offset));
152219820Sjeff				osm_log(p_bind->p_log, OSM_LOG_DEBUG,
153219820Sjeff					"__osmv_sa_mad_rcv_cb: "
154219820Sjeff					"Count = %u = %zu / %u (%zu)\n",
155219820Sjeff					query_res.result_cnt,
156219820Sjeff					p_madw->mad_size - IB_SA_MAD_HDR_SIZE,
157219820Sjeff					ib_get_attr_size(p_sa_mad->attr_offset),
158219820Sjeff					(p_madw->mad_size - IB_SA_MAD_HDR_SIZE) %
159219820Sjeff					ib_get_attr_size(p_sa_mad->attr_offset));
160219820Sjeff			}
161219820Sjeff#endif
162219820Sjeff		}
163219820Sjeff	}
164219820Sjeff
165219820Sjeff	query_res.query_type = p_query_req_copy->query_type;
166219820Sjeff
167219820Sjeff	p_query_req_copy->pfn_query_cb(&query_res);
168219820Sjeff
169219820Sjeff	if ((p_query_req_copy->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC)
170219820Sjeff		cl_event_signal(&p_bind->sync_event);
171219820Sjeff
172219820SjeffExit:
173219820Sjeff
174219820Sjeff	/* free the copied query request if found */
175219820Sjeff	if (p_query_req_copy)
176219820Sjeff		free(p_query_req_copy);
177219820Sjeff
178219820Sjeff	/* put back the request madw */
179219820Sjeff	if (p_req_madw)
180219820Sjeff		osm_mad_pool_put(p_bind->p_mad_pool, p_req_madw);
181219820Sjeff
182219820Sjeff	OSM_LOG_EXIT(p_bind->p_log);
183219820Sjeff}
184219820Sjeff
185219820Sjeff/*****************************************************************************
186219820Sjeff ****************************************************************************/
187219820Sjeff/*
188219820Sjeff  Send Error Callback:
189219820Sjeff
190219820Sjeff  Only report the error and get rid of the mad wrapper
191219820Sjeff*/
192219820Sjeffvoid __osmv_sa_mad_err_cb(IN void *bind_context, IN osm_madw_t * p_madw)
193219820Sjeff{
194219820Sjeff	osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) bind_context;
195219820Sjeff	osmv_query_req_t *p_query_req_copy = NULL;
196219820Sjeff	osmv_query_res_t query_res;
197219820Sjeff
198219820Sjeff	OSM_LOG_ENTER(p_bind->p_log);
199219820Sjeff
200219820Sjeff	/* Obtain the sent context etc */
201219820Sjeff	p_query_req_copy =
202219820Sjeff	    (osmv_query_req_t *) (p_madw->context.arb_context.context1);
203219820Sjeff
204219820Sjeff	/* provide the context of the original request in the result */
205219820Sjeff	query_res.query_context = p_query_req_copy->query_context;
206219820Sjeff
207219820Sjeff	query_res.p_result_madw = p_madw;
208219820Sjeff
209219820Sjeff	query_res.status = IB_TIMEOUT;
210219820Sjeff	query_res.result_cnt = 0;
211219820Sjeff	query_res.p_result_madw->status = IB_TIMEOUT;
212219820Sjeff	p_madw->status = IB_TIMEOUT;
213219820Sjeff	query_res.query_type = p_query_req_copy->query_type;
214219820Sjeff
215219820Sjeff	p_query_req_copy->pfn_query_cb(&query_res);
216219820Sjeff
217219820Sjeff	if ((p_query_req_copy->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC)
218219820Sjeff		cl_event_signal(&p_bind->sync_event);
219219820Sjeff
220219820Sjeff	if (p_query_req_copy)
221219820Sjeff		free(p_query_req_copy);
222219820Sjeff	OSM_LOG_EXIT(p_bind->p_log);
223219820Sjeff}
224219820Sjeff
225219820Sjeff/*****************************************************************************
226219820Sjeff This routine needs to be invoked on every send - since the SM LID and Local
227219820Sjeff lid might change. To do that without any major perfoermance impact we cache
228219820Sjeff the results and time they were obtained. Refresh only twice a minute.
229219820Sjeff To avoid the need to use statics and risk a race - we require the refresh time
230219820Sjeff to be stored in the context of the results. Also this coveres cases were
231219820Sjeff we query for multiple guids.
232219820Sjeff *****************************************************************************/
233219820Sjeffib_api_status_t
234219820Sjeff__osmv_get_lid_and_sm_lid_by_port_guid(IN osm_vendor_t * const p_vend,
235219820Sjeff				       IN ib_net64_t port_guid,
236219820Sjeff				       IN OUT uint64_t * p_lids_update_time_sec,
237219820Sjeff				       OUT uint16_t * lid,
238219820Sjeff				       OUT uint16_t * sm_lid)
239219820Sjeff{
240219820Sjeff
241219820Sjeff	ib_api_status_t status;
242219820Sjeff	ib_port_attr_t *p_attr_array;
243219820Sjeff	uint32_t num_ports;
244219820Sjeff	uint32_t port_num;
245219820Sjeff
246219820Sjeff	OSM_LOG_ENTER(p_vend->p_log);
247219820Sjeff
248219820Sjeff	/* use prevous values if current time is close enough to previous query */
249219820Sjeff	if (cl_get_time_stamp_sec() <= *p_lids_update_time_sec + 30) {
250219820Sjeff		osm_log(p_vend->p_log, OSM_LOG_DEBUG,
251219820Sjeff			"__osmv_get_lid_and_sm_lid_by_port_guid: "
252219820Sjeff			"Using previously stored lid:0x%04x sm_lid:0x%04x\n",
253219820Sjeff			*lid, *sm_lid);
254219820Sjeff		status = IB_SUCCESS;
255219820Sjeff		goto Exit;
256219820Sjeff	}
257219820Sjeff
258219820Sjeff	/* obtain the number of available ports */
259219820Sjeff	num_ports = 0;
260219820Sjeff	status = osm_vendor_get_all_port_attr(p_vend, NULL, &num_ports);
261219820Sjeff	if (status != IB_INSUFFICIENT_MEMORY) {
262219820Sjeff		osm_log(p_vend->p_log, OSM_LOG_ERROR,
263219820Sjeff			"__osmv_get_lid_and_sm_lid_by_port_guid: ERR 0503: "
264219820Sjeff			"expected to get the IB_INSUFFICIENT_MEMORY but got: %s\n",
265219820Sjeff			ib_get_err_str(status)
266219820Sjeff		    );
267219820Sjeff		status = IB_ERROR;
268219820Sjeff		goto Exit;
269219820Sjeff	}
270219820Sjeff
271219820Sjeff	osm_log(p_vend->p_log, OSM_LOG_DEBUG,
272219820Sjeff		"__osmv_get_lid_and_sm_lid_by_port_guid: "
273219820Sjeff		"Found total of %u ports. Looking for guid:0x%016" PRIx64 "\n",
274219820Sjeff		num_ports, cl_ntoh64(port_guid)
275219820Sjeff	    );
276219820Sjeff
277219820Sjeff	/* allocate the attributes */
278219820Sjeff	p_attr_array =
279219820Sjeff	    (ib_port_attr_t *) malloc(sizeof(ib_port_attr_t) * num_ports);
280219820Sjeff
281219820Sjeff	/* obtain the attributes */
282219820Sjeff	status = osm_vendor_get_all_port_attr(p_vend, p_attr_array, &num_ports);
283219820Sjeff	if (status != IB_SUCCESS) {
284219820Sjeff		osm_log(p_vend->p_log, OSM_LOG_ERROR,
285219820Sjeff			"__osmv_get_lid_and_sm_lid_by_port_guid: ERR 0504: "
286219820Sjeff			"Fail to get port attributes (error: %s)\n",
287219820Sjeff			ib_get_err_str(status)
288219820Sjeff		    );
289219820Sjeff		free(p_attr_array);
290219820Sjeff		goto Exit;
291219820Sjeff	}
292219820Sjeff
293219820Sjeff	status = IB_ERROR;
294219820Sjeff	/* find the port requested in the list */
295219820Sjeff	for (port_num = 0; (port_num < num_ports) && (status == IB_ERROR);
296219820Sjeff	     port_num++) {
297219820Sjeff		if (p_attr_array[port_num].port_guid == port_guid) {
298219820Sjeff			*lid = p_attr_array[port_num].lid;
299219820Sjeff			*sm_lid = p_attr_array[port_num].sm_lid;
300219820Sjeff			*p_lids_update_time_sec = cl_get_time_stamp_sec();
301219820Sjeff			status = IB_SUCCESS;
302219820Sjeff			osm_log(p_vend->p_log, OSM_LOG_DEBUG,
303219820Sjeff				"__osmv_get_lid_and_sm_lid_by_port_guid: "
304219820Sjeff				"Found guid:0x%016" PRIx64 " with idx:%d\n",
305219820Sjeff				cl_ntoh64(port_guid), port_num);
306219820Sjeff		}
307219820Sjeff	}
308219820Sjeff
309219820Sjeff	free(p_attr_array);
310219820Sjeff
311219820SjeffExit:
312219820Sjeff	OSM_LOG_EXIT(p_vend->p_log);
313219820Sjeff	return (status);
314219820Sjeff}
315219820Sjeff
316219820Sjeff/*****************************************************************************
317219820Sjeff *****************************************************************************/
318219820Sjeffosm_bind_handle_t
319219820Sjeffosmv_bind_sa(IN osm_vendor_t * const p_vend,
320219820Sjeff	     IN osm_mad_pool_t * const p_mad_pool, IN ib_net64_t port_guid)
321219820Sjeff{
322219820Sjeff	osm_bind_info_t bind_info;
323219820Sjeff	osm_log_t *p_log = p_vend->p_log;
324219820Sjeff	ib_api_status_t status = IB_SUCCESS;
325219820Sjeff	osmv_sa_bind_info_t *p_sa_bind_info;
326219820Sjeff	cl_status_t cl_status;
327219820Sjeff
328219820Sjeff	OSM_LOG_ENTER(p_log);
329219820Sjeff
330219820Sjeff	osm_log(p_log, OSM_LOG_DEBUG,
331219820Sjeff		"osmv_bind_sa: "
332219820Sjeff		"Binding to port 0x%" PRIx64 ".\n", cl_ntoh64(port_guid));
333219820Sjeff
334219820Sjeff	bind_info.port_guid = port_guid;
335219820Sjeff	bind_info.mad_class = IB_MCLASS_SUBN_ADM;
336219820Sjeff	bind_info.class_version = 2;
337219820Sjeff	bind_info.is_responder = TRUE;
338219820Sjeff	bind_info.is_trap_processor = FALSE;
339219820Sjeff	bind_info.is_report_processor = TRUE;
340219820Sjeff	bind_info.send_q_size = 256;
341219820Sjeff	bind_info.recv_q_size = 256;
342219820Sjeff
343219820Sjeff	/* allocate the new sa bind info */
344219820Sjeff	p_sa_bind_info =
345219820Sjeff	    (osmv_sa_bind_info_t *) malloc(sizeof(osmv_sa_bind_info_t));
346219820Sjeff	if (!p_sa_bind_info) {
347219820Sjeff		osm_log(p_log, OSM_LOG_ERROR,
348219820Sjeff			"osmv_bind_sa: ERR 0505: "
349219820Sjeff			"Fail to allocate new bidn structure\n");
350219820Sjeff		p_sa_bind_info = OSM_BIND_INVALID_HANDLE;
351219820Sjeff		goto Exit;
352219820Sjeff	}
353219820Sjeff
354219820Sjeff	/* store some important context */
355219820Sjeff	p_sa_bind_info->p_log = p_log;
356219820Sjeff	p_sa_bind_info->port_guid = port_guid;
357219820Sjeff	p_sa_bind_info->p_mad_pool = p_mad_pool;
358219820Sjeff	p_sa_bind_info->p_vendor = p_vend;
359219820Sjeff	p_sa_bind_info->last_lids_update_sec = 0;
360219820Sjeff
361219820Sjeff	/* Bind to the lower level */
362219820Sjeff	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 */
363219820Sjeff
364219820Sjeff	if (p_sa_bind_info->h_bind == OSM_BIND_INVALID_HANDLE) {
365219820Sjeff		free(p_sa_bind_info);
366219820Sjeff		p_sa_bind_info = OSM_BIND_INVALID_HANDLE;
367219820Sjeff		osm_log(p_log, OSM_LOG_ERROR,
368219820Sjeff			"osmv_bind_sa: ERR 0506: "
369219820Sjeff			"Fail to bind to vendor SMI.\n");
370219820Sjeff		goto Exit;
371219820Sjeff	}
372219820Sjeff
373219820Sjeff	/* obtain the sm_lid from the vendor */
374219820Sjeff	status =
375219820Sjeff	    __osmv_get_lid_and_sm_lid_by_port_guid(p_vend, port_guid,
376219820Sjeff						   &p_sa_bind_info->
377219820Sjeff						   last_lids_update_sec,
378219820Sjeff						   &p_sa_bind_info->lid,
379219820Sjeff						   &p_sa_bind_info->sm_lid);
380219820Sjeff	if (status != IB_SUCCESS) {
381219820Sjeff		free(p_sa_bind_info);
382219820Sjeff		p_sa_bind_info = OSM_BIND_INVALID_HANDLE;
383219820Sjeff		osm_log(p_log, OSM_LOG_ERROR,
384219820Sjeff			"osmv_bind_sa: ERR 0507: "
385219820Sjeff			"Fail to obtain the sm lid.\n");
386219820Sjeff		goto Exit;
387219820Sjeff	}
388219820Sjeff
389219820Sjeff	/* initialize the sync_event */
390219820Sjeff	cl_event_construct(&p_sa_bind_info->sync_event);
391219820Sjeff	cl_status = cl_event_init(&p_sa_bind_info->sync_event, TRUE);
392219820Sjeff	if (cl_status != CL_SUCCESS) {
393219820Sjeff		osm_log(p_log, OSM_LOG_ERROR,
394219820Sjeff			"osmv_bind_sa: ERR 0508: "
395219820Sjeff			"cl_init_event failed: %s\n", ib_get_err_str(cl_status)
396219820Sjeff		    );
397219820Sjeff		free(p_sa_bind_info);
398219820Sjeff		p_sa_bind_info = OSM_BIND_INVALID_HANDLE;
399219820Sjeff	}
400219820Sjeff
401219820SjeffExit:
402219820Sjeff	OSM_LOG_EXIT(p_log);
403219820Sjeff	return (p_sa_bind_info);
404219820Sjeff}
405219820Sjeff
406219820Sjeff/*****************************************************************************
407219820Sjeff *****************************************************************************/
408219820Sjeff
409219820Sjeff/****t* OSM Vendor SA Client/osmv_sa_mad_data
410219820Sjeff * NAME
411219820Sjeff *    osmv_sa_mad_data
412219820Sjeff *
413219820Sjeff * DESCRIPTION
414219820Sjeff * Extra fields required to perform a mad query
415219820Sjeff *  This struct is passed to the actual send method
416219820Sjeff *
417219820Sjeff * SYNOPSIS
418219820Sjeff */
419219820Sjefftypedef struct _osmv_sa_mad_data {
420219820Sjeff	/* MAD data. */
421219820Sjeff	uint8_t method;
422219820Sjeff	ib_net16_t attr_id;
423219820Sjeff	ib_net16_t attr_offset;
424219820Sjeff	ib_net32_t attr_mod;
425219820Sjeff	ib_net64_t comp_mask;
426219820Sjeff	void *p_attr;
427219820Sjeff} osmv_sa_mad_data_t;
428219820Sjeff/*
429219820Sjeff * method
430219820Sjeff *    The method of the mad to be sent
431219820Sjeff *
432219820Sjeff *  attr_id
433219820Sjeff *     Attribute ID
434219820Sjeff *
435219820Sjeff *  attr_offset
436219820Sjeff *     Offset as defined by RMPP
437219820Sjeff *
438219820Sjeff *  attr_mod
439219820Sjeff *     Attribute modifier
440219820Sjeff *
441219820Sjeff *  comp_mask
442219820Sjeff *     The component mask of the query
443219820Sjeff *
444219820Sjeff *  p_attr
445219820Sjeff *     A pointer to the record of the attribute to be sent.
446219820Sjeff *
447219820Sjeff *****/
448219820Sjeff
449219820Sjeff/*****************************************************************************
450219820Sjeff *****************************************************************************/
451219820Sjeff/* Send a MAD out on the GSI interface */
452219820Sjeffib_api_status_t
453219820Sjeff__osmv_send_sa_req(IN osmv_sa_bind_info_t * p_bind,
454219820Sjeff		   IN const osmv_sa_mad_data_t * const p_sa_mad_data,
455219820Sjeff		   IN const osmv_query_req_t * const p_query_req)
456219820Sjeff{
457219820Sjeff	ib_api_status_t status;
458219820Sjeff	ib_mad_t *p_mad_hdr;
459219820Sjeff	ib_sa_mad_t *p_sa_mad;
460219820Sjeff	osm_madw_t *p_madw;
461219820Sjeff	osm_log_t *p_log = p_bind->p_log;
462219820Sjeff	static atomic32_t trans_id;
463219820Sjeff	boolean_t sync;
464219820Sjeff	osmv_query_req_t *p_query_req_copy;
465219820Sjeff
466219820Sjeff	OSM_LOG_ENTER(p_log);
467219820Sjeff
468219820Sjeff	/*
469219820Sjeff	   since the sm_lid might change we obtain it every send
470219820Sjeff	   (actually it is cached in the bind object and refreshed
471219820Sjeff	   every 30sec by this proc )
472219820Sjeff	 */
473219820Sjeff	status =
474219820Sjeff	    __osmv_get_lid_and_sm_lid_by_port_guid(p_bind->p_vendor,
475219820Sjeff						   p_bind->port_guid,
476219820Sjeff						   &p_bind->
477219820Sjeff						   last_lids_update_sec,
478219820Sjeff						   &p_bind->lid,
479219820Sjeff						   &p_bind->sm_lid);
480219820Sjeff	if (status != IB_SUCCESS) {
481219820Sjeff		osm_log(p_log, OSM_LOG_ERROR,
482219820Sjeff			"__osmv_send_sa_req: ERR 0509: "
483219820Sjeff			"Fail to obtain the sm lid.\n");
484219820Sjeff		goto Exit;
485219820Sjeff	}
486219820Sjeff
487219820Sjeff	/* Get a MAD wrapper for the send */
488219820Sjeff	p_madw = osm_mad_pool_get(p_bind->p_mad_pool,
489219820Sjeff				  p_bind->h_bind, MAD_BLOCK_SIZE, NULL);
490219820Sjeff
491219820Sjeff	if (p_madw == NULL) {
492219820Sjeff		osm_log(p_log, OSM_LOG_ERROR,
493219820Sjeff			"__osmv_send_sa_req: ERR 0510: "
494219820Sjeff			"Unable to acquire MAD.\n");
495219820Sjeff		status = IB_INSUFFICIENT_RESOURCES;
496219820Sjeff		goto Exit;
497219820Sjeff	}
498219820Sjeff
499219820Sjeff	/* Initialize the Sent MAD: */
500219820Sjeff
501219820Sjeff	/* Initialize the MAD buffer for the send operation. */
502219820Sjeff	p_mad_hdr = osm_madw_get_mad_ptr(p_madw);
503219820Sjeff	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
504219820Sjeff
505219820Sjeff	/* Get a new transaction Id */
506219820Sjeff	cl_atomic_inc(&trans_id);
507219820Sjeff
508219820Sjeff	/* Cleanup the MAD from any residue */
509219820Sjeff	memset(p_sa_mad, 0, MAD_BLOCK_SIZE);
510219820Sjeff
511219820Sjeff	/* Initialize the standard MAD header. */
512219820Sjeff	ib_mad_init_new(p_mad_hdr,	/* mad pointer */
513219820Sjeff			IB_MCLASS_SUBN_ADM,	/* class */
514219820Sjeff			(uint8_t) 2,	/* version */
515219820Sjeff			p_sa_mad_data->method,	/* method */
516219820Sjeff			cl_hton64((uint64_t) trans_id),	/* tid */
517219820Sjeff			p_sa_mad_data->attr_id,	/* attr id */
518219820Sjeff			p_sa_mad_data->attr_mod	/* attr mod */
519219820Sjeff	    );
520219820Sjeff
521219820Sjeff	/* Set the query information. */
522219820Sjeff	p_sa_mad->sm_key = p_query_req->sm_key;
523219820Sjeff	p_sa_mad->attr_offset = 0;
524219820Sjeff	p_sa_mad->comp_mask = p_sa_mad_data->comp_mask;
525219820Sjeff	if (p_sa_mad->comp_mask) {
526219820Sjeff		memcpy(p_sa_mad->data, p_sa_mad_data->p_attr,
527219820Sjeff		       ib_get_attr_size(p_sa_mad_data->attr_offset));
528219820Sjeff	}
529219820Sjeff
530219820Sjeff	/*
531219820Sjeff	   Provide the address to send to
532219820Sjeff	 */
533219820Sjeff	/* Patch to handle IBAL - host order , where it should take destination lid in network order */
534219820Sjeff#ifdef OSM_VENDOR_INTF_AL
535219820Sjeff	p_madw->mad_addr.dest_lid = p_bind->sm_lid;
536219820Sjeff#else
537219820Sjeff	p_madw->mad_addr.dest_lid = cl_hton16(p_bind->sm_lid);
538219820Sjeff#endif
539219820Sjeff	p_madw->mad_addr.addr_type.smi.source_lid = cl_hton16(p_bind->lid);
540219820Sjeff	p_madw->mad_addr.addr_type.gsi.remote_qp = CL_HTON32(1);
541219820Sjeff	p_madw->mad_addr.addr_type.gsi.remote_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
542219820Sjeff	p_madw->mad_addr.addr_type.gsi.pkey_ix = 0;
543219820Sjeff	p_madw->resp_expected = TRUE;
544219820Sjeff	p_madw->fail_msg = CL_DISP_MSGID_NONE;
545219820Sjeff
546219820Sjeff	/*
547219820Sjeff	   Provide MAD context such that the call back will know what to do.
548219820Sjeff	   We have to keep the entire request structure so we know the CB.
549219820Sjeff	   Since we can not rely on the client to keep it arroud until
550219820Sjeff	   the response - we duplicate it and will later dispose it (in CB).
551219820Sjeff	   To store on the MADW we cast it into what opensm has:
552219820Sjeff	   p_madw->context.arb_context.context1
553219820Sjeff	 */
554219820Sjeff	p_query_req_copy = malloc(sizeof(*p_query_req_copy));
555219820Sjeff	*p_query_req_copy = *p_query_req;
556219820Sjeff	p_madw->context.arb_context.context1 = p_query_req_copy;
557219820Sjeff
558219820Sjeff	/* we can support async as well as sync calls */
559219820Sjeff	sync = ((p_query_req->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC);
560219820Sjeff
561219820Sjeff	/* send the mad asynchronously */
562219820Sjeff	status = osm_vendor_send(osm_madw_get_bind_handle(p_madw),
563219820Sjeff				 p_madw, p_madw->resp_expected);
564219820Sjeff
565219820Sjeff	/* if synchronous - wait on the event */
566219820Sjeff	if (sync) {
567219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
568219820Sjeff			"__osmv_send_sa_req: " "Waiting for async event.\n");
569219820Sjeff		cl_event_wait_on(&p_bind->sync_event, EVENT_NO_TIMEOUT, FALSE);
570219820Sjeff		cl_event_reset(&p_bind->sync_event);
571219820Sjeff		status = p_madw->status;
572219820Sjeff	}
573219820Sjeff
574219820SjeffExit:
575219820Sjeff	OSM_LOG_EXIT(p_log);
576219820Sjeff	return status;
577219820Sjeff}
578219820Sjeff
579219820Sjeff/*****************************************************************************
580219820Sjeff *****************************************************************************/
581219820Sjeff/*
582219820Sjeff * Query the SA based on the user's request.
583219820Sjeff */
584219820Sjeffib_api_status_t
585219820Sjeffosmv_query_sa(IN osm_bind_handle_t h_bind,
586219820Sjeff	      IN const osmv_query_req_t * const p_query_req)
587219820Sjeff{
588219820Sjeff	osmv_sa_bind_info_t *p_bind = (osmv_sa_bind_info_t *) h_bind;
589219820Sjeff	osmv_sa_mad_data_t sa_mad_data;
590219820Sjeff	osmv_user_query_t *p_user_query;
591219820Sjeff	ib_service_record_t svc_rec;
592219820Sjeff	ib_node_record_t node_rec;
593219820Sjeff	ib_portinfo_record_t port_info;
594219820Sjeff	ib_path_rec_t path_rec;
595219820Sjeff	ib_class_port_info_t class_port_info;
596219820Sjeff	osm_log_t *p_log = p_bind->p_log;
597219820Sjeff	ib_api_status_t status;
598219820Sjeff
599219820Sjeff	OSM_LOG_ENTER(p_log);
600219820Sjeff
601219820Sjeff	/* Set the request information. */
602219820Sjeff	sa_mad_data.method = IB_MAD_METHOD_GETTABLE;
603219820Sjeff	sa_mad_data.attr_mod = 0;
604219820Sjeff
605219820Sjeff	/* Set the MAD attributes and component mask correctly. */
606219820Sjeff	switch (p_query_req->query_type) {
607219820Sjeff
608219820Sjeff	case OSMV_QUERY_USER_DEFINED:
609219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
610219820Sjeff			"osmv_query_sa DBG:001 %s", "USER_DEFINED\n");
611219820Sjeff		p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
612219820Sjeff		if (p_user_query->method)
613219820Sjeff			sa_mad_data.method = p_user_query->method;
614219820Sjeff		sa_mad_data.attr_offset = p_user_query->attr_offset;
615219820Sjeff		sa_mad_data.attr_id = p_user_query->attr_id;
616219820Sjeff		sa_mad_data.attr_mod = p_user_query->attr_mod;
617219820Sjeff		sa_mad_data.comp_mask = p_user_query->comp_mask;
618219820Sjeff		sa_mad_data.p_attr = p_user_query->p_attr;
619219820Sjeff		break;
620219820Sjeff
621219820Sjeff	case OSMV_QUERY_ALL_SVC_RECS:
622219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
623219820Sjeff			"osmv_query_sa DBG:001 %s", "SVC_REC_BY_NAME\n");
624219820Sjeff		sa_mad_data.method = IB_MAD_METHOD_GETTABLE;
625219820Sjeff		sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
626219820Sjeff		sa_mad_data.attr_offset =
627219820Sjeff		    ib_get_attr_offset(sizeof(ib_service_record_t));
628219820Sjeff		sa_mad_data.comp_mask = 0;
629219820Sjeff		sa_mad_data.p_attr = &svc_rec;
630219820Sjeff		break;
631219820Sjeff
632219820Sjeff	case OSMV_QUERY_SVC_REC_BY_NAME:
633219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
634219820Sjeff			"osmv_query_sa DBG:001 %s", "SVC_REC_BY_NAME\n");
635219820Sjeff		sa_mad_data.method = IB_MAD_METHOD_GET;
636219820Sjeff		sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
637219820Sjeff		sa_mad_data.comp_mask = IB_SR_COMPMASK_SNAME;
638219820Sjeff		sa_mad_data.attr_offset =
639219820Sjeff		    ib_get_attr_offset(sizeof(ib_service_record_t));
640219820Sjeff		sa_mad_data.p_attr = &svc_rec;
641219820Sjeff		memcpy(svc_rec.service_name, p_query_req->p_query_input,
642219820Sjeff		       sizeof(ib_svc_name_t));
643219820Sjeff		break;
644219820Sjeff
645219820Sjeff	case OSMV_QUERY_SVC_REC_BY_ID:
646219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
647219820Sjeff			"osmv_query_sa DBG:001 %s", "SVC_REC_BY_ID\n");
648219820Sjeff		sa_mad_data.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
649219820Sjeff		sa_mad_data.comp_mask = IB_SR_COMPMASK_SID;
650219820Sjeff		sa_mad_data.attr_offset =
651219820Sjeff		    ib_get_attr_offset(sizeof(ib_service_record_t));
652219820Sjeff		sa_mad_data.p_attr = &svc_rec;
653219820Sjeff		svc_rec.service_id =
654219820Sjeff		    *(ib_net64_t *) (p_query_req->p_query_input);
655219820Sjeff		break;
656219820Sjeff
657219820Sjeff	case OSMV_QUERY_CLASS_PORT_INFO:
658219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
659219820Sjeff			"osmv_query_sa DBG:001 %s", "CLASS_PORT_INFO\n");
660219820Sjeff		sa_mad_data.method = IB_MAD_METHOD_GET;
661219820Sjeff		sa_mad_data.attr_id = IB_MAD_ATTR_CLASS_PORT_INFO;
662219820Sjeff		sa_mad_data.attr_offset =
663219820Sjeff		    ib_get_attr_offset(sizeof(ib_class_port_info_t));
664219820Sjeff		sa_mad_data.comp_mask = 0;
665219820Sjeff		sa_mad_data.p_attr = &class_port_info;
666219820Sjeff
667219820Sjeff		break;
668219820Sjeff
669219820Sjeff	case OSMV_QUERY_NODE_REC_BY_NODE_GUID:
670219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
671219820Sjeff			"osmv_query_sa DBG:001 %s", "NODE_REC_BY_NODE_GUID\n");
672219820Sjeff		sa_mad_data.method = IB_MAD_METHOD_GETTABLE;
673219820Sjeff		sa_mad_data.attr_id = IB_MAD_ATTR_NODE_RECORD;
674219820Sjeff		sa_mad_data.attr_offset =
675219820Sjeff		    ib_get_attr_offset(sizeof(ib_node_record_t));
676219820Sjeff		sa_mad_data.comp_mask = IB_NR_COMPMASK_NODEGUID;
677219820Sjeff		sa_mad_data.p_attr = &node_rec;
678219820Sjeff		node_rec.node_info.node_guid =
679219820Sjeff		    *(ib_net64_t *) (p_query_req->p_query_input);
680219820Sjeff
681219820Sjeff		break;
682219820Sjeff
683219820Sjeff	case OSMV_QUERY_PORT_REC_BY_LID:
684219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
685219820Sjeff			"osmv_query_sa DBG:001 %s", "PORT_REC_BY_LID\n");
686219820Sjeff		sa_mad_data.attr_id = IB_MAD_ATTR_PORTINFO_RECORD;
687219820Sjeff		sa_mad_data.attr_offset =
688219820Sjeff		    ib_get_attr_offset(sizeof(ib_portinfo_record_t));
689219820Sjeff		sa_mad_data.comp_mask = IB_PIR_COMPMASK_LID;
690219820Sjeff		sa_mad_data.p_attr = &port_info;
691219820Sjeff		port_info.lid = *(ib_net16_t *) (p_query_req->p_query_input);
692219820Sjeff		break;
693219820Sjeff
694219820Sjeff	case OSMV_QUERY_PORT_REC_BY_LID_AND_NUM:
695219820Sjeff		sa_mad_data.method = IB_MAD_METHOD_GET;
696219820Sjeff		p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
697219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
698219820Sjeff			"osmv_query_sa DBG:001 %s",
699219820Sjeff			"PORT_REC_BY_LID_AND_NUM\n");
700219820Sjeff		sa_mad_data.attr_id = IB_MAD_ATTR_PORTINFO_RECORD;
701219820Sjeff		sa_mad_data.attr_offset =
702219820Sjeff		    ib_get_attr_offset(sizeof(ib_portinfo_record_t));
703219820Sjeff		sa_mad_data.comp_mask =
704219820Sjeff		    IB_PIR_COMPMASK_LID | IB_PIR_COMPMASK_PORTNUM;
705219820Sjeff		sa_mad_data.p_attr = p_user_query->p_attr;
706219820Sjeff		break;
707219820Sjeff
708219820Sjeff	case OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK:
709219820Sjeff		sa_mad_data.method = IB_MAD_METHOD_GET;
710219820Sjeff		p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
711219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
712219820Sjeff			"osmv_query_sa DBG:001 %s",
713219820Sjeff			"OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK\n");
714219820Sjeff		sa_mad_data.attr_id = IB_MAD_ATTR_VLARB_RECORD;
715219820Sjeff		sa_mad_data.attr_offset =
716219820Sjeff		    ib_get_attr_offset(sizeof(ib_vl_arb_table_record_t));
717219820Sjeff		sa_mad_data.comp_mask =
718219820Sjeff		    IB_VLA_COMPMASK_LID | IB_VLA_COMPMASK_OUT_PORT |
719219820Sjeff		    IB_VLA_COMPMASK_BLOCK;
720219820Sjeff		sa_mad_data.p_attr = p_user_query->p_attr;
721219820Sjeff		break;
722219820Sjeff
723219820Sjeff	case OSMV_QUERY_SLVL_BY_LID_AND_PORTS:
724219820Sjeff		sa_mad_data.method = IB_MAD_METHOD_GET;
725219820Sjeff		p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
726219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
727219820Sjeff			"osmv_query_sa DBG:001 %s",
728219820Sjeff			"OSMV_QUERY_VLARB_BY_LID_PORT_BLOCK\n");
729219820Sjeff		sa_mad_data.attr_id = IB_MAD_ATTR_SLVL_RECORD;
730219820Sjeff		sa_mad_data.attr_offset =
731219820Sjeff		    ib_get_attr_offset(sizeof(ib_slvl_table_record_t));
732219820Sjeff		sa_mad_data.comp_mask =
733219820Sjeff		    IB_SLVL_COMPMASK_LID | IB_SLVL_COMPMASK_OUT_PORT |
734219820Sjeff		    IB_SLVL_COMPMASK_IN_PORT;
735219820Sjeff		sa_mad_data.p_attr = p_user_query->p_attr;
736219820Sjeff		break;
737219820Sjeff
738219820Sjeff	case OSMV_QUERY_PATH_REC_BY_PORT_GUIDS:
739219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
740219820Sjeff			"osmv_query_sa DBG:001 %s", "PATH_REC_BY_PORT_GUIDS\n");
741219820Sjeff		memset(&path_rec, 0, sizeof(ib_path_rec_t));
742219820Sjeff		sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD;
743219820Sjeff		sa_mad_data.attr_offset =
744219820Sjeff		    ib_get_attr_offset(sizeof(ib_path_rec_t));
745219820Sjeff		sa_mad_data.comp_mask =
746219820Sjeff		    (IB_PR_COMPMASK_DGID | IB_PR_COMPMASK_SGID);
747219820Sjeff		sa_mad_data.p_attr = &path_rec;
748219820Sjeff		ib_gid_set_default(&path_rec.dgid,
749219820Sjeff				   ((osmv_guid_pair_t *) (p_query_req->
750219820Sjeff							  p_query_input))->
751219820Sjeff				   dest_guid);
752219820Sjeff		ib_gid_set_default(&path_rec.sgid,
753219820Sjeff				   ((osmv_guid_pair_t *) (p_query_req->
754219820Sjeff							  p_query_input))->
755219820Sjeff				   src_guid);
756219820Sjeff		break;
757219820Sjeff
758219820Sjeff	case OSMV_QUERY_PATH_REC_BY_GIDS:
759219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
760219820Sjeff			"osmv_query_sa DBG:001 %s", "PATH_REC_BY_GIDS\n");
761219820Sjeff		memset(&path_rec, 0, sizeof(ib_path_rec_t));
762219820Sjeff		sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD;
763219820Sjeff		sa_mad_data.attr_offset =
764219820Sjeff		    ib_get_attr_offset(sizeof(ib_path_rec_t));
765219820Sjeff		sa_mad_data.comp_mask =
766219820Sjeff		    (IB_PR_COMPMASK_DGID | IB_PR_COMPMASK_SGID);
767219820Sjeff		sa_mad_data.p_attr = &path_rec;
768219820Sjeff		memcpy(&path_rec.dgid,
769219820Sjeff		       &((osmv_gid_pair_t *) (p_query_req->p_query_input))->
770219820Sjeff		       dest_gid, sizeof(ib_gid_t));
771219820Sjeff		memcpy(&path_rec.sgid,
772219820Sjeff		       &((osmv_gid_pair_t *) (p_query_req->p_query_input))->
773219820Sjeff		       src_gid, sizeof(ib_gid_t));
774219820Sjeff		break;
775219820Sjeff
776219820Sjeff	case OSMV_QUERY_PATH_REC_BY_LIDS:
777219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
778219820Sjeff			"osmv_query_sa DBG:001 %s", "PATH_REC_BY_LIDS\n");
779219820Sjeff		memset(&path_rec, 0, sizeof(ib_path_rec_t));
780219820Sjeff		sa_mad_data.method = IB_MAD_METHOD_GET;
781219820Sjeff		sa_mad_data.attr_id = IB_MAD_ATTR_PATH_RECORD;
782219820Sjeff		sa_mad_data.attr_offset =
783219820Sjeff		    ib_get_attr_offset(sizeof(ib_path_rec_t));
784219820Sjeff		sa_mad_data.comp_mask =
785219820Sjeff		    (IB_PR_COMPMASK_DLID | IB_PR_COMPMASK_SLID);
786219820Sjeff		sa_mad_data.p_attr = &path_rec;
787219820Sjeff		path_rec.dlid =
788219820Sjeff		    ((osmv_lid_pair_t *) (p_query_req->p_query_input))->
789219820Sjeff		    dest_lid;
790219820Sjeff		path_rec.slid =
791219820Sjeff		    ((osmv_lid_pair_t *) (p_query_req->p_query_input))->src_lid;
792219820Sjeff		break;
793219820Sjeff
794219820Sjeff	case OSMV_QUERY_UD_MULTICAST_SET:
795219820Sjeff		sa_mad_data.method = IB_MAD_METHOD_SET;
796219820Sjeff		p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
797219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
798219820Sjeff			"osmv_query_sa DBG:001 %s",
799219820Sjeff			"OSMV_QUERY_UD_MULTICAST_SET\n");
800219820Sjeff		sa_mad_data.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
801219820Sjeff		sa_mad_data.attr_offset =
802219820Sjeff		    ib_get_attr_offset(sizeof(ib_member_rec_t));
803219820Sjeff		sa_mad_data.comp_mask = p_user_query->comp_mask;
804219820Sjeff		sa_mad_data.p_attr = p_user_query->p_attr;
805219820Sjeff		break;
806219820Sjeff
807219820Sjeff	case OSMV_QUERY_UD_MULTICAST_DELETE:
808219820Sjeff		sa_mad_data.method = IB_MAD_METHOD_DELETE;
809219820Sjeff		p_user_query = (osmv_user_query_t *) p_query_req->p_query_input;
810219820Sjeff		osm_log(p_log, OSM_LOG_DEBUG,
811219820Sjeff			"osmv_query_sa DBG:001 %s",
812219820Sjeff			"OSMV_QUERY_UD_MULTICAST_DELETE\n");
813219820Sjeff		sa_mad_data.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
814219820Sjeff		sa_mad_data.attr_offset =
815219820Sjeff		    ib_get_attr_offset(sizeof(ib_member_rec_t));
816219820Sjeff		sa_mad_data.comp_mask = p_user_query->comp_mask;
817219820Sjeff		sa_mad_data.p_attr = p_user_query->p_attr;
818219820Sjeff		break;
819219820Sjeff
820219820Sjeff	default:
821219820Sjeff		osm_log(p_log, OSM_LOG_ERROR,
822219820Sjeff			"osmv_query_sa DBG:001 %s", "UNKNOWN\n");
823219820Sjeff		CL_ASSERT(0);
824219820Sjeff		return IB_ERROR;
825219820Sjeff	}
826219820Sjeff
827219820Sjeff	status = __osmv_send_sa_req(h_bind, &sa_mad_data, p_query_req);
828219820Sjeff
829219820Sjeff	OSM_LOG_EXIT(p_log);
830219820Sjeff	return status;
831219820Sjeff}
832219820Sjeff
833219820Sjeff/*****************************************************************************
834219820Sjeff *****************************************************************************/
835