xref: /freebsd/contrib/ofed/opensm/libvendor/osm_vendor_ts.c (revision 87181516ef48be852d5e5fee53c6e0dbfc62f21e)
1*d6b92ffaSHans Petter Selasky /*
2*d6b92ffaSHans Petter Selasky  * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
3*d6b92ffaSHans Petter Selasky  * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4*d6b92ffaSHans Petter Selasky  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5*d6b92ffaSHans Petter Selasky  *
6*d6b92ffaSHans Petter Selasky  * This software is available to you under a choice of one of two
7*d6b92ffaSHans Petter Selasky  * licenses.  You may choose to be licensed under the terms of the GNU
8*d6b92ffaSHans Petter Selasky  * General Public License (GPL) Version 2, available from the file
9*d6b92ffaSHans Petter Selasky  * COPYING in the main directory of this source tree, or the
10*d6b92ffaSHans Petter Selasky  * OpenIB.org BSD license below:
11*d6b92ffaSHans Petter Selasky  *
12*d6b92ffaSHans Petter Selasky  *     Redistribution and use in source and binary forms, with or
13*d6b92ffaSHans Petter Selasky  *     without modification, are permitted provided that the following
14*d6b92ffaSHans Petter Selasky  *     conditions are met:
15*d6b92ffaSHans Petter Selasky  *
16*d6b92ffaSHans Petter Selasky  *      - Redistributions of source code must retain the above
17*d6b92ffaSHans Petter Selasky  *        copyright notice, this list of conditions and the following
18*d6b92ffaSHans Petter Selasky  *        disclaimer.
19*d6b92ffaSHans Petter Selasky  *
20*d6b92ffaSHans Petter Selasky  *      - Redistributions in binary form must reproduce the above
21*d6b92ffaSHans Petter Selasky  *        copyright notice, this list of conditions and the following
22*d6b92ffaSHans Petter Selasky  *        disclaimer in the documentation and/or other materials
23*d6b92ffaSHans Petter Selasky  *        provided with the distribution.
24*d6b92ffaSHans Petter Selasky  *
25*d6b92ffaSHans Petter Selasky  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26*d6b92ffaSHans Petter Selasky  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27*d6b92ffaSHans Petter Selasky  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28*d6b92ffaSHans Petter Selasky  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29*d6b92ffaSHans Petter Selasky  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30*d6b92ffaSHans Petter Selasky  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31*d6b92ffaSHans Petter Selasky  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32*d6b92ffaSHans Petter Selasky  * SOFTWARE.
33*d6b92ffaSHans Petter Selasky  *
34*d6b92ffaSHans Petter Selasky  */
35*d6b92ffaSHans Petter Selasky 
36*d6b92ffaSHans Petter Selasky #undef __init
37*d6b92ffaSHans Petter Selasky #if HAVE_CONFIG_H
38*d6b92ffaSHans Petter Selasky #  include <config.h>
39*d6b92ffaSHans Petter Selasky #endif				/* HAVE_CONFIG_H */
40*d6b92ffaSHans Petter Selasky 
41*d6b92ffaSHans Petter Selasky #include <stdlib.h>
42*d6b92ffaSHans Petter Selasky #include <string.h>
43*d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_ts.h>
44*d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_api.h>
45*d6b92ffaSHans Petter Selasky #include <vendor/osm_ts_useraccess.h>
46*d6b92ffaSHans Petter Selasky #include <opensm/osm_subnet.h>
47*d6b92ffaSHans Petter Selasky #include <opensm/osm_opensm.h>
48*d6b92ffaSHans Petter Selasky 
49*d6b92ffaSHans Petter Selasky /*
50*d6b92ffaSHans Petter Selasky   Since a race can accure on requests. Meaning - a response is received before
51*d6b92ffaSHans Petter Selasky   the send_callback is called - we will save both the madw_p and the fact
52*d6b92ffaSHans Petter Selasky   whether or not it is a response. A race can occure only on requests that did
53*d6b92ffaSHans Petter Selasky   not fail, and then the madw_p will be put back in the pool before the
54*d6b92ffaSHans Petter Selasky   callback.
55*d6b92ffaSHans Petter Selasky */
__osm_set_wrid_by_p_madw(IN osm_madw_t * p_madw)56*d6b92ffaSHans Petter Selasky uint64_t __osm_set_wrid_by_p_madw(IN osm_madw_t * p_madw)
57*d6b92ffaSHans Petter Selasky {
58*d6b92ffaSHans Petter Selasky 	uint64_t wrid = 0;
59*d6b92ffaSHans Petter Selasky 
60*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_madw->p_mad);
61*d6b92ffaSHans Petter Selasky 
62*d6b92ffaSHans Petter Selasky 	memcpy(&wrid, &p_madw, sizeof(osm_madw_t *));
63*d6b92ffaSHans Petter Selasky 	wrid = (wrid << 1) |
64*d6b92ffaSHans Petter Selasky 	    ib_mad_is_response(p_madw->p_mad);
65*d6b92ffaSHans Petter Selasky 	return wrid;
66*d6b92ffaSHans Petter Selasky }
67*d6b92ffaSHans Petter Selasky 
68*d6b92ffaSHans Petter Selasky void
__osm_set_p_madw_and_resp_by_wrid(IN uint64_t wrid,OUT uint8_t * is_resp,OUT osm_madw_t ** pp_madw)69*d6b92ffaSHans Petter Selasky __osm_set_p_madw_and_resp_by_wrid(IN uint64_t wrid,
70*d6b92ffaSHans Petter Selasky 				  OUT uint8_t * is_resp,
71*d6b92ffaSHans Petter Selasky 				  OUT osm_madw_t ** pp_madw)
72*d6b92ffaSHans Petter Selasky {
73*d6b92ffaSHans Petter Selasky 	*is_resp = wrid & 0x0000000000000001;
74*d6b92ffaSHans Petter Selasky 	wrid = wrid >> 1;
75*d6b92ffaSHans Petter Selasky 	memcpy(pp_madw, &wrid, sizeof(osm_madw_t *));
76*d6b92ffaSHans Petter Selasky }
77*d6b92ffaSHans Petter Selasky 
78*d6b92ffaSHans Petter Selasky /**********************************************************************
79*d6b92ffaSHans Petter Selasky  * TS MAD to OSM ADDRESS VECTOR
80*d6b92ffaSHans Petter Selasky  **********************************************************************/
81*d6b92ffaSHans Petter Selasky void
__osm_ts_conv_mad_rcv_desc_to_osm_addr(IN osm_vendor_t * const p_vend,IN struct ib_mad * p_mad,IN uint8_t is_smi,OUT osm_mad_addr_t * p_mad_addr)82*d6b92ffaSHans Petter Selasky __osm_ts_conv_mad_rcv_desc_to_osm_addr(IN osm_vendor_t * const p_vend,
83*d6b92ffaSHans Petter Selasky 				       IN struct ib_mad *p_mad,
84*d6b92ffaSHans Petter Selasky 				       IN uint8_t is_smi,
85*d6b92ffaSHans Petter Selasky 				       OUT osm_mad_addr_t * p_mad_addr)
86*d6b92ffaSHans Petter Selasky {
87*d6b92ffaSHans Petter Selasky 	p_mad_addr->dest_lid = cl_hton16(p_mad->slid);
88*d6b92ffaSHans Petter Selasky 	p_mad_addr->static_rate = 0;	/*  HACK - we do not know the rate ! */
89*d6b92ffaSHans Petter Selasky 	p_mad_addr->path_bits = 0;	/*  HACK - no way to know in TS */
90*d6b92ffaSHans Petter Selasky 	if (is_smi) {
91*d6b92ffaSHans Petter Selasky 		/* SMI */
92*d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.smi.source_lid = cl_hton16(p_mad->slid);
93*d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.smi.port_num = p_mad->port;
94*d6b92ffaSHans Petter Selasky 	} else {
95*d6b92ffaSHans Petter Selasky 		/* GSI */
96*d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.remote_qp = p_mad->sqpn;
97*d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.remote_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
98*d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.pkey_ix = p_mad->pkey_index;
99*d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.service_level = 0;	/*  HACK no way to know */
100*d6b92ffaSHans Petter Selasky 
101*d6b92ffaSHans Petter Selasky 		p_mad_addr->addr_type.gsi.global_route = FALSE;	/*  HACK no way to know */
102*d6b92ffaSHans Petter Selasky 		/* copy the GRH data if relevant */
103*d6b92ffaSHans Petter Selasky 		/*
104*d6b92ffaSHans Petter Selasky 		   if (p_mad_addr->addr_type.gsi.global_route)
105*d6b92ffaSHans Petter Selasky 		   {
106*d6b92ffaSHans Petter Selasky 		   p_mad_addr->addr_type.gsi.grh_info.ver_class_flow =
107*d6b92ffaSHans Petter Selasky 		   ib_grh_set_ver_class_flow(p_rcv_desc->grh.IP_version,
108*d6b92ffaSHans Petter Selasky 		   p_rcv_desc->grh.traffic_class,
109*d6b92ffaSHans Petter Selasky 		   p_rcv_desc->grh.flow_label);
110*d6b92ffaSHans Petter Selasky 		   p_mad_addr->addr_type.gsi.grh_info.hop_limit =  p_rcv_desc->grh.hop_limit;
111*d6b92ffaSHans Petter Selasky 		   memcpy(&p_mad_addr->addr_type.gsi.grh_info.src_gid.raw,
112*d6b92ffaSHans Petter Selasky 		   &p_rcv_desc->grh.sgid, sizeof(ib_net64_t));
113*d6b92ffaSHans Petter Selasky 		   memcpy(&p_mad_addr->addr_type.gsi.grh_info.dest_gid.raw,
114*d6b92ffaSHans Petter Selasky 		   p_rcv_desc->grh.dgid,  sizeof(ib_net64_t));
115*d6b92ffaSHans Petter Selasky 		   }
116*d6b92ffaSHans Petter Selasky 		 */
117*d6b92ffaSHans Petter Selasky 	}
118*d6b92ffaSHans Petter Selasky }
119*d6b92ffaSHans Petter Selasky 
120*d6b92ffaSHans Petter Selasky /**********************************************************************
121*d6b92ffaSHans Petter Selasky  * OSM ADDR VECTOR TO TS MAD:
122*d6b92ffaSHans Petter Selasky  **********************************************************************/
123*d6b92ffaSHans Petter Selasky void
__osm_ts_conv_osm_addr_to_ts_addr(IN osm_mad_addr_t * p_mad_addr,IN uint8_t is_smi,OUT struct ib_mad * p_mad)124*d6b92ffaSHans Petter Selasky __osm_ts_conv_osm_addr_to_ts_addr(IN osm_mad_addr_t * p_mad_addr,
125*d6b92ffaSHans Petter Selasky 				  IN uint8_t is_smi, OUT struct ib_mad *p_mad)
126*d6b92ffaSHans Petter Selasky {
127*d6b92ffaSHans Petter Selasky 
128*d6b92ffaSHans Petter Selasky 	/* For global destination or Multicast address: */
129*d6b92ffaSHans Petter Selasky 	p_mad->dlid = cl_ntoh16(p_mad_addr->dest_lid);
130*d6b92ffaSHans Petter Selasky 	p_mad->sl = 0;
131*d6b92ffaSHans Petter Selasky 	if (is_smi) {
132*d6b92ffaSHans Petter Selasky 		p_mad->sqpn = 0;
133*d6b92ffaSHans Petter Selasky 		p_mad->dqpn = 0;
134*d6b92ffaSHans Petter Selasky 	} else {
135*d6b92ffaSHans Petter Selasky 		p_mad->sqpn = 1;
136*d6b92ffaSHans Petter Selasky 		p_mad->dqpn = p_mad_addr->addr_type.gsi.remote_qp;
137*d6b92ffaSHans Petter Selasky 	}
138*d6b92ffaSHans Petter Selasky }
139*d6b92ffaSHans Petter Selasky 
__osm_vendor_clear_sm(IN osm_bind_handle_t h_bind)140*d6b92ffaSHans Petter Selasky void __osm_vendor_clear_sm(IN osm_bind_handle_t h_bind)
141*d6b92ffaSHans Petter Selasky {
142*d6b92ffaSHans Petter Selasky 	osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
143*d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = p_bind->p_vend;
144*d6b92ffaSHans Petter Selasky 	VAPI_ret_t status;
145*d6b92ffaSHans Petter Selasky 	VAPI_hca_attr_t attr_mod;
146*d6b92ffaSHans Petter Selasky 	VAPI_hca_attr_mask_t attr_mask;
147*d6b92ffaSHans Petter Selasky 
148*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
149*d6b92ffaSHans Petter Selasky 
150*d6b92ffaSHans Petter Selasky 	memset(&attr_mod, 0, sizeof(attr_mod));
151*d6b92ffaSHans Petter Selasky 	memset(&attr_mask, 0, sizeof(attr_mask));
152*d6b92ffaSHans Petter Selasky 
153*d6b92ffaSHans Petter Selasky 	attr_mod.is_sm = FALSE;
154*d6b92ffaSHans Petter Selasky 	attr_mask = HCA_ATTR_IS_SM;
155*d6b92ffaSHans Petter Selasky 
156*d6b92ffaSHans Petter Selasky 	status =
157*d6b92ffaSHans Petter Selasky 	    VAPI_modify_hca_attr(p_bind->hca_hndl, p_bind->port_num, &attr_mod,
158*d6b92ffaSHans Petter Selasky 				 &attr_mask);
159*d6b92ffaSHans Petter Selasky 	if (status != VAPI_OK) {
160*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
161*d6b92ffaSHans Petter Selasky 			"__osm_vendor_clear_sm: ERR 5021: "
162*d6b92ffaSHans Petter Selasky 			"Unable set 'IS_SM' bit in port attributes (%d).\n",
163*d6b92ffaSHans Petter Selasky 			status);
164*d6b92ffaSHans Petter Selasky 	}
165*d6b92ffaSHans Petter Selasky 
166*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
167*d6b92ffaSHans Petter Selasky }
168*d6b92ffaSHans Petter Selasky 
169*d6b92ffaSHans Petter Selasky /**********************************************************************
170*d6b92ffaSHans Petter Selasky  * ANY CONSTRUCTION OF THE osm_vendor_t OBJECT
171*d6b92ffaSHans Petter Selasky  **********************************************************************/
osm_vendor_construct(IN osm_vendor_t * const p_vend)172*d6b92ffaSHans Petter Selasky void osm_vendor_construct(IN osm_vendor_t * const p_vend)
173*d6b92ffaSHans Petter Selasky {
174*d6b92ffaSHans Petter Selasky 	memset(p_vend, 0, sizeof(*p_vend));
175*d6b92ffaSHans Petter Selasky 	cl_thread_construct(&(p_vend->smi_bind.poller));
176*d6b92ffaSHans Petter Selasky 	cl_thread_construct(&(p_vend->gsi_bind.poller));
177*d6b92ffaSHans Petter Selasky }
178*d6b92ffaSHans Petter Selasky 
179*d6b92ffaSHans Petter Selasky /**********************************************************************
180*d6b92ffaSHans Petter Selasky  * DEALOCATE osm_vendor_t
181*d6b92ffaSHans Petter Selasky  **********************************************************************/
osm_vendor_destroy(IN osm_vendor_t * const p_vend)182*d6b92ffaSHans Petter Selasky void osm_vendor_destroy(IN osm_vendor_t * const p_vend)
183*d6b92ffaSHans Petter Selasky {
184*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
185*d6b92ffaSHans Petter Selasky 	osm_transaction_mgr_destroy(p_vend);
186*d6b92ffaSHans Petter Selasky 
187*d6b92ffaSHans Petter Selasky 	/* Destroy the poller threads */
188*d6b92ffaSHans Petter Selasky 	/* HACK: can you destroy an un-initialized thread ? */
189*d6b92ffaSHans Petter Selasky 	pthread_cancel(p_vend->smi_bind.poller.osd.id);
190*d6b92ffaSHans Petter Selasky 	pthread_cancel(p_vend->gsi_bind.poller.osd.id);
191*d6b92ffaSHans Petter Selasky 	cl_thread_destroy(&(p_vend->smi_bind.poller));
192*d6b92ffaSHans Petter Selasky 	cl_thread_destroy(&(p_vend->gsi_bind.poller));
193*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
194*d6b92ffaSHans Petter Selasky }
195*d6b92ffaSHans Petter Selasky 
196*d6b92ffaSHans Petter Selasky /**********************************************************************
197*d6b92ffaSHans Petter Selasky DEALLOCATE A POINTER TO osm_vendor_t
198*d6b92ffaSHans Petter Selasky **********************************************************************/
osm_vendor_delete(IN osm_vendor_t ** const pp_vend)199*d6b92ffaSHans Petter Selasky void osm_vendor_delete(IN osm_vendor_t ** const pp_vend)
200*d6b92ffaSHans Petter Selasky {
201*d6b92ffaSHans Petter Selasky 	CL_ASSERT(pp_vend);
202*d6b92ffaSHans Petter Selasky 
203*d6b92ffaSHans Petter Selasky 	osm_vendor_destroy(*pp_vend);
204*d6b92ffaSHans Petter Selasky 	free(*pp_vend);
205*d6b92ffaSHans Petter Selasky 	*pp_vend = NULL;
206*d6b92ffaSHans Petter Selasky }
207*d6b92ffaSHans Petter Selasky 
208*d6b92ffaSHans Petter Selasky /**********************************************************************
209*d6b92ffaSHans Petter Selasky  Initializes the vendor:
210*d6b92ffaSHans Petter Selasky **********************************************************************/
211*d6b92ffaSHans Petter Selasky 
212*d6b92ffaSHans Petter Selasky ib_api_status_t
osm_vendor_init(IN osm_vendor_t * const p_vend,IN osm_log_t * const p_log,IN const uint32_t timeout)213*d6b92ffaSHans Petter Selasky osm_vendor_init(IN osm_vendor_t * const p_vend,
214*d6b92ffaSHans Petter Selasky 		IN osm_log_t * const p_log, IN const uint32_t timeout)
215*d6b92ffaSHans Petter Selasky {
216*d6b92ffaSHans Petter Selasky 	ib_api_status_t status = IB_SUCCESS;
217*d6b92ffaSHans Petter Selasky 
218*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
219*d6b92ffaSHans Petter Selasky 
220*d6b92ffaSHans Petter Selasky 	p_vend->p_log = p_log;
221*d6b92ffaSHans Petter Selasky 	p_vend->p_transaction_mgr = NULL;
222*d6b92ffaSHans Petter Selasky 	osm_transaction_mgr_init(p_vend);
223*d6b92ffaSHans Petter Selasky 	p_vend->timeout = timeout;
224*d6b92ffaSHans Petter Selasky 
225*d6b92ffaSHans Petter Selasky 	/* we use the file handle to track the binding */
226*d6b92ffaSHans Petter Selasky 	p_vend->smi_bind.ul_dev_fd = -1;
227*d6b92ffaSHans Petter Selasky 	p_vend->gsi_bind.ul_dev_fd = -1;
228*d6b92ffaSHans Petter Selasky 
229*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
230*d6b92ffaSHans Petter Selasky 	return (status);
231*d6b92ffaSHans Petter Selasky }
232*d6b92ffaSHans Petter Selasky 
233*d6b92ffaSHans Petter Selasky /**********************************************************************
234*d6b92ffaSHans Petter Selasky  *  Create and Initialize osm_vendor_t Object
235*d6b92ffaSHans Petter Selasky  **********************************************************************/
osm_vendor_new(IN osm_log_t * const p_log,IN const uint32_t timeout)236*d6b92ffaSHans Petter Selasky osm_vendor_t *osm_vendor_new(IN osm_log_t * const p_log,
237*d6b92ffaSHans Petter Selasky 			     IN const uint32_t timeout)
238*d6b92ffaSHans Petter Selasky {
239*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
240*d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend;
241*d6b92ffaSHans Petter Selasky 
242*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
243*d6b92ffaSHans Petter Selasky 
244*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_log);
245*d6b92ffaSHans Petter Selasky 
246*d6b92ffaSHans Petter Selasky 	p_vend = malloc(sizeof(*p_vend));
247*d6b92ffaSHans Petter Selasky 	if (p_vend != NULL) {
248*d6b92ffaSHans Petter Selasky 		memset(p_vend, 0, sizeof(*p_vend));
249*d6b92ffaSHans Petter Selasky 
250*d6b92ffaSHans Petter Selasky 		status = osm_vendor_init(p_vend, p_log, timeout);
251*d6b92ffaSHans Petter Selasky 		if (status != IB_SUCCESS) {
252*d6b92ffaSHans Petter Selasky 			osm_vendor_delete(&p_vend);
253*d6b92ffaSHans Petter Selasky 		}
254*d6b92ffaSHans Petter Selasky 	} else {
255*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
256*d6b92ffaSHans Petter Selasky 			"osm_vendor_new: ERR 5007: "
257*d6b92ffaSHans Petter Selasky 			"Fail to allocate vendor object.\n");
258*d6b92ffaSHans Petter Selasky 	}
259*d6b92ffaSHans Petter Selasky 
260*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
261*d6b92ffaSHans Petter Selasky 	return (p_vend);
262*d6b92ffaSHans Petter Selasky }
263*d6b92ffaSHans Petter Selasky 
264*d6b92ffaSHans Petter Selasky /**********************************************************************
265*d6b92ffaSHans Petter Selasky  * TS RCV Thread callback
266*d6b92ffaSHans Petter Selasky  * HACK: - we need to make this support arbitrary size mads.
267*d6b92ffaSHans Petter Selasky  **********************************************************************/
268*d6b92ffaSHans Petter Selasky void
__osm_ts_rcv_callback(IN osm_ts_bind_info_t * p_bind,IN osm_mad_addr_t * p_mad_addr,IN uint32_t mad_size,IN void * p_mad)269*d6b92ffaSHans Petter Selasky __osm_ts_rcv_callback(IN osm_ts_bind_info_t * p_bind,
270*d6b92ffaSHans Petter Selasky 		      IN osm_mad_addr_t * p_mad_addr,
271*d6b92ffaSHans Petter Selasky 		      IN uint32_t mad_size, IN void *p_mad)
272*d6b92ffaSHans Petter Selasky {
273*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
274*d6b92ffaSHans Petter Selasky 	osm_madw_t *p_req_madw = NULL;
275*d6b92ffaSHans Petter Selasky 	osm_madw_t *p_madw;
276*d6b92ffaSHans Petter Selasky 	osm_vend_wrap_t *p_new_vw;
277*d6b92ffaSHans Petter Selasky 	ib_mad_t *p_mad_buf;
278*d6b92ffaSHans Petter Selasky 	osm_log_t *const p_log = p_bind->p_vend->p_log;
279*d6b92ffaSHans Petter Selasky 
280*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
281*d6b92ffaSHans Petter Selasky 
282*d6b92ffaSHans Petter Selasky 	/* if it is a response MAD we mustbe able to get the request */
283*d6b92ffaSHans Petter Selasky 	if (ib_mad_is_response((ib_mad_t *) p_mad)) {
284*d6b92ffaSHans Petter Selasky 		/* can we find a matching madw by this payload TID */
285*d6b92ffaSHans Petter Selasky 		status =
286*d6b92ffaSHans Petter Selasky 		    osm_transaction_mgr_get_madw_for_tid(p_bind->p_vend,
287*d6b92ffaSHans Petter Selasky 							 (ib_mad_t *) p_mad,
288*d6b92ffaSHans Petter Selasky 							 &p_req_madw);
289*d6b92ffaSHans Petter Selasky 		if (status != IB_SUCCESS) {
290*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
291*d6b92ffaSHans Petter Selasky 				"__osm_ts_rcv_callback: ERR 5008: "
292*d6b92ffaSHans Petter Selasky 				"Error obtaining request madw by TID (%d).\n",
293*d6b92ffaSHans Petter Selasky 				status);
294*d6b92ffaSHans Petter Selasky 			p_req_madw = NULL;
295*d6b92ffaSHans Petter Selasky 		}
296*d6b92ffaSHans Petter Selasky 
297*d6b92ffaSHans Petter Selasky 		if (p_req_madw == NULL) {
298*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
299*d6b92ffaSHans Petter Selasky 				"__osm_ts_rcv_callback: ERR 5009:  "
300*d6b92ffaSHans Petter Selasky 				"Fail to obtain request madw for receined MAD. Aborting CB.\n");
301*d6b92ffaSHans Petter Selasky 			goto Exit;
302*d6b92ffaSHans Petter Selasky 		}
303*d6b92ffaSHans Petter Selasky 	}
304*d6b92ffaSHans Petter Selasky 
305*d6b92ffaSHans Petter Selasky 	/* do we have a request ??? */
306*d6b92ffaSHans Petter Selasky 	if (p_req_madw == NULL) {
307*d6b92ffaSHans Petter Selasky 
308*d6b92ffaSHans Petter Selasky 		/* if not - get new osm_madw and arrange it. */
309*d6b92ffaSHans Petter Selasky 		/* create the new madw in the pool */
310*d6b92ffaSHans Petter Selasky 		p_madw = osm_mad_pool_get(p_bind->p_osm_pool,
311*d6b92ffaSHans Petter Selasky 					  (osm_bind_handle_t) p_bind,
312*d6b92ffaSHans Petter Selasky 					  mad_size, p_mad_addr);
313*d6b92ffaSHans Petter Selasky 		if (p_madw == NULL) {
314*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
315*d6b92ffaSHans Petter Selasky 				"__osm_ts_rcv_callback: ERR 5010: "
316*d6b92ffaSHans Petter Selasky 				"Error request for a new madw.\n");
317*d6b92ffaSHans Petter Selasky 			goto Exit;
318*d6b92ffaSHans Petter Selasky 		}
319*d6b92ffaSHans Petter Selasky 		/* HACK: we cust to avoid the const ??? */
320*d6b92ffaSHans Petter Selasky 		p_mad_buf = (void *)p_madw->p_mad;
321*d6b92ffaSHans Petter Selasky 	} else {
322*d6b92ffaSHans Petter Selasky 		/* we have the madw defined during the send and stored in the vend_wrap */
323*d6b92ffaSHans Petter Selasky 		/* we need to make sure the wrapper is correctly init there */
324*d6b92ffaSHans Petter Selasky 		CL_ASSERT(p_req_madw->vend_wrap.p_resp_madw != 0);
325*d6b92ffaSHans Petter Selasky 		p_madw = p_req_madw->vend_wrap.p_resp_madw;
326*d6b92ffaSHans Petter Selasky 
327*d6b92ffaSHans Petter Selasky 		CL_ASSERT(p_madw->h_bind);
328*d6b92ffaSHans Petter Selasky 		p_mad_buf =
329*d6b92ffaSHans Petter Selasky 		    osm_vendor_get(p_madw->h_bind, mad_size,
330*d6b92ffaSHans Petter Selasky 				   &p_madw->vend_wrap);
331*d6b92ffaSHans Petter Selasky 
332*d6b92ffaSHans Petter Selasky 		if (p_mad_buf == NULL) {
333*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
334*d6b92ffaSHans Petter Selasky 				"__osm_ts_rcv_callback: ERR 5011: "
335*d6b92ffaSHans Petter Selasky 				"Unable to acquire wire MAD.\n");
336*d6b92ffaSHans Petter Selasky 
337*d6b92ffaSHans Petter Selasky 			goto Exit;
338*d6b92ffaSHans Petter Selasky 		}
339*d6b92ffaSHans Petter Selasky 
340*d6b92ffaSHans Petter Selasky 		/*
341*d6b92ffaSHans Petter Selasky 		   Finally, attach the wire MAD to this wrapper.
342*d6b92ffaSHans Petter Selasky 		 */
343*d6b92ffaSHans Petter Selasky 		osm_madw_set_mad(p_madw, p_mad_buf);
344*d6b92ffaSHans Petter Selasky 	}
345*d6b92ffaSHans Petter Selasky 
346*d6b92ffaSHans Petter Selasky 	/* init some fields of the vendor wrapper */
347*d6b92ffaSHans Petter Selasky 	p_new_vw = osm_madw_get_vend_ptr(p_madw);
348*d6b92ffaSHans Petter Selasky 	p_new_vw->h_bind = p_bind;
349*d6b92ffaSHans Petter Selasky 	p_new_vw->size = mad_size;
350*d6b92ffaSHans Petter Selasky 	p_new_vw->p_resp_madw = NULL;
351*d6b92ffaSHans Petter Selasky 	p_new_vw->p_mad_buf = p_mad_buf;
352*d6b92ffaSHans Petter Selasky 
353*d6b92ffaSHans Petter Selasky 	memcpy(p_new_vw->p_mad_buf, p_mad, mad_size);
354*d6b92ffaSHans Petter Selasky 
355*d6b92ffaSHans Petter Selasky 	/* attach the buffer to the wrapper */
356*d6b92ffaSHans Petter Selasky 	p_madw->p_mad = p_mad_buf;
357*d6b92ffaSHans Petter Selasky 
358*d6b92ffaSHans Petter Selasky 	/* we can also make sure we marked the size and bind on the returned madw */
359*d6b92ffaSHans Petter Selasky 	p_madw->h_bind = p_new_vw->h_bind;
360*d6b92ffaSHans Petter Selasky 
361*d6b92ffaSHans Petter Selasky 	/* call the CB */
362*d6b92ffaSHans Petter Selasky 	(*(osm_vend_mad_recv_callback_t) p_bind->rcv_callback)
363*d6b92ffaSHans Petter Selasky 	    (p_madw, p_bind->client_context, p_req_madw);
364*d6b92ffaSHans Petter Selasky 
365*d6b92ffaSHans Petter Selasky Exit:
366*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
367*d6b92ffaSHans Petter Selasky }
368*d6b92ffaSHans Petter Selasky 
369*d6b92ffaSHans Petter Selasky /**********************************************************************
370*d6b92ffaSHans Petter Selasky  * TS Send callback : invoked after each send
371*d6b92ffaSHans Petter Selasky  *
372*d6b92ffaSHans Petter Selasky  **********************************************************************/
373*d6b92ffaSHans Petter Selasky void
__osm_ts_send_callback(IN osm_ts_bind_info_t * bind_info_p,IN boolean_t is_resp,IN osm_madw_t * madw_p,IN IB_comp_status_t status)374*d6b92ffaSHans Petter Selasky __osm_ts_send_callback(IN osm_ts_bind_info_t * bind_info_p,
375*d6b92ffaSHans Petter Selasky 		       IN boolean_t is_resp,
376*d6b92ffaSHans Petter Selasky 		       IN osm_madw_t * madw_p, IN IB_comp_status_t status)
377*d6b92ffaSHans Petter Selasky {
378*d6b92ffaSHans Petter Selasky 	osm_log_t *const p_log = bind_info_p->p_vend->p_log;
379*d6b92ffaSHans Petter Selasky 	osm_vend_wrap_t *p_vw;
380*d6b92ffaSHans Petter Selasky 
381*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
382*d6b92ffaSHans Petter Selasky 
383*d6b92ffaSHans Petter Selasky 	osm_log(p_log, OSM_LOG_DEBUG,
384*d6b92ffaSHans Petter Selasky 		"__osm_ts_send_callback: INFO 1008: "
385*d6b92ffaSHans Petter Selasky 		"Handling Send of MADW:%p Is Resp:%d.\n", madw_p, is_resp);
386*d6b92ffaSHans Petter Selasky 
387*d6b92ffaSHans Petter Selasky 	/* we need to handle requests and responses differently */
388*d6b92ffaSHans Petter Selasky 	if (is_resp) {
389*d6b92ffaSHans Petter Selasky 		if (status != IB_COMP_SUCCESS) {
390*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
391*d6b92ffaSHans Petter Selasky 				"__osm_ts_send_callback: ERR 5012: "
392*d6b92ffaSHans Petter Selasky 				"Error Sending Response MADW:%p.\n", madw_p);
393*d6b92ffaSHans Petter Selasky 		} else {
394*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_DEBUG,
395*d6b92ffaSHans Petter Selasky 				"__osm_ts_send_callback: DBG 1008: "
396*d6b92ffaSHans Petter Selasky 				"Completed Sending Response MADW:%p.\n",
397*d6b92ffaSHans Petter Selasky 				madw_p);
398*d6b92ffaSHans Petter Selasky 		}
399*d6b92ffaSHans Petter Selasky 
400*d6b92ffaSHans Petter Selasky 		/* if we are a response - we need to clean it up */
401*d6b92ffaSHans Petter Selasky 		osm_mad_pool_put(bind_info_p->p_osm_pool, madw_p);
402*d6b92ffaSHans Petter Selasky 	} else {
403*d6b92ffaSHans Petter Selasky 
404*d6b92ffaSHans Petter Selasky 		/* this call back is invoked on completion of send - error or not */
405*d6b92ffaSHans Petter Selasky 		if (status != IB_COMP_SUCCESS) {
406*d6b92ffaSHans Petter Selasky 
407*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_ERROR,
408*d6b92ffaSHans Petter Selasky 				"__osm_ts_send_callback: ERR 5013: "
409*d6b92ffaSHans Petter Selasky 				"Received an Error from IB_MGT Send (%d).\n",
410*d6b92ffaSHans Petter Selasky 				status);
411*d6b92ffaSHans Petter Selasky 
412*d6b92ffaSHans Petter Selasky 			p_vw = osm_madw_get_vend_ptr(madw_p);
413*d6b92ffaSHans Petter Selasky 			CL_ASSERT(p_vw);
414*d6b92ffaSHans Petter Selasky 
415*d6b92ffaSHans Petter Selasky 			/*
416*d6b92ffaSHans Petter Selasky 			   Return any wrappers to the pool that may have been
417*d6b92ffaSHans Petter Selasky 			   pre-emptively allocated to handle a receive.
418*d6b92ffaSHans Petter Selasky 			 */
419*d6b92ffaSHans Petter Selasky 			if (p_vw->p_resp_madw) {
420*d6b92ffaSHans Petter Selasky 				osm_mad_pool_put(bind_info_p->p_osm_pool,
421*d6b92ffaSHans Petter Selasky 						 p_vw->p_resp_madw);
422*d6b92ffaSHans Petter Selasky 				p_vw->p_resp_madw = NULL;
423*d6b92ffaSHans Petter Selasky 			}
424*d6b92ffaSHans Petter Selasky 
425*d6b92ffaSHans Petter Selasky 			/* invoke the CB */
426*d6b92ffaSHans Petter Selasky 			(*(osm_vend_mad_send_err_callback_t) bind_info_p->
427*d6b92ffaSHans Petter Selasky 			 send_err_callback)
428*d6b92ffaSHans Petter Selasky 			    (bind_info_p->client_context, madw_p);
429*d6b92ffaSHans Petter Selasky 		} else {
430*d6b92ffaSHans Petter Selasky 			/* successful request send - do nothing - the response will need the
431*d6b92ffaSHans Petter Selasky 			   out mad */
432*d6b92ffaSHans Petter Selasky 			osm_log(p_log, OSM_LOG_DEBUG,
433*d6b92ffaSHans Petter Selasky 				"__osm_ts_send_callback: DBG 1008: "
434*d6b92ffaSHans Petter Selasky 				"Completed Sending Request MADW:%p.\n", madw_p);
435*d6b92ffaSHans Petter Selasky 		}
436*d6b92ffaSHans Petter Selasky 	}
437*d6b92ffaSHans Petter Selasky 
438*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
439*d6b92ffaSHans Petter Selasky }
440*d6b92ffaSHans Petter Selasky 
441*d6b92ffaSHans Petter Selasky /**********************************************************************
442*d6b92ffaSHans Petter Selasky  * Poller thread:
443*d6b92ffaSHans Petter Selasky  * Always receive 256byte mads from the devcie file
444*d6b92ffaSHans Petter Selasky  **********************************************************************/
__osm_vendor_ts_poller(IN void * p_ptr)445*d6b92ffaSHans Petter Selasky void __osm_vendor_ts_poller(IN void *p_ptr)
446*d6b92ffaSHans Petter Selasky {
447*d6b92ffaSHans Petter Selasky 	int ts_ret_code;
448*d6b92ffaSHans Petter Selasky 	struct ib_mad mad;
449*d6b92ffaSHans Petter Selasky 	osm_mad_addr_t mad_addr;
450*d6b92ffaSHans Petter Selasky 	osm_ts_bind_info_t *const p_bind = (osm_ts_bind_info_t *) p_ptr;
451*d6b92ffaSHans Petter Selasky 
452*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_bind->p_vend->p_log);
453*d6b92ffaSHans Petter Selasky 	/* we set the type of cancelation for this thread */
454*d6b92ffaSHans Petter Selasky 	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
455*d6b92ffaSHans Petter Selasky 
456*d6b92ffaSHans Petter Selasky 	while (1) {
457*d6b92ffaSHans Petter Selasky 		/* we read one mad at a time and pass it to the read callback function */
458*d6b92ffaSHans Petter Selasky 		ts_ret_code = read(p_bind->ul_dev_fd, &mad, sizeof(mad));
459*d6b92ffaSHans Petter Selasky 		if (ts_ret_code != sizeof(mad)) {
460*d6b92ffaSHans Petter Selasky 			osm_log(p_bind->p_vend->p_log, OSM_LOG_ERROR,
461*d6b92ffaSHans Petter Selasky 				"__osm_vendor_ts_poller: ERR 5003: "
462*d6b92ffaSHans Petter Selasky 				"error with read, bytes = %d, errno = %d\n",
463*d6b92ffaSHans Petter Selasky 				ts_ret_code, errno);
464*d6b92ffaSHans Petter Selasky 		} else {
465*d6b92ffaSHans Petter Selasky 			osm_log(p_bind->p_vend->p_log, OSM_LOG_DEBUG,
466*d6b92ffaSHans Petter Selasky 				"__osm_vendor_ts_poller: "
467*d6b92ffaSHans Petter Selasky 				"MAD QPN:%d SLID:0x%04x class:0x%02x "
468*d6b92ffaSHans Petter Selasky 				"__osm_vendor_ts_poller:0x%02x attr:0x%04x status:0x%04x "
469*d6b92ffaSHans Petter Selasky 				"__osm_vendor_ts_poller:0x%016" PRIx64 "\n",
470*d6b92ffaSHans Petter Selasky 				cl_ntoh32(mad.dqpn),
471*d6b92ffaSHans Petter Selasky 				cl_ntoh16(mad.slid),
472*d6b92ffaSHans Petter Selasky 				mad.mgmt_class,
473*d6b92ffaSHans Petter Selasky 				mad.r_method,
474*d6b92ffaSHans Petter Selasky 				cl_ntoh16(mad.attribute_id),
475*d6b92ffaSHans Petter Selasky 				cl_ntoh16(mad.status),
476*d6b92ffaSHans Petter Selasky 				cl_ntoh64(mad.transaction_id));
477*d6b92ffaSHans Petter Selasky 
478*d6b92ffaSHans Petter Selasky 			/* first arrange an address */
479*d6b92ffaSHans Petter Selasky 			__osm_ts_conv_mad_rcv_desc_to_osm_addr(p_bind->p_vend,
480*d6b92ffaSHans Petter Selasky 							       &mad,
481*d6b92ffaSHans Petter Selasky 							       (((ib_mad_t *) &
482*d6b92ffaSHans Petter Selasky 								 mad)->
483*d6b92ffaSHans Petter Selasky 								mgmt_class ==
484*d6b92ffaSHans Petter Selasky 								IB_MCLASS_SUBN_LID)
485*d6b92ffaSHans Petter Selasky 							       ||
486*d6b92ffaSHans Petter Selasky 							       (((ib_mad_t *) &
487*d6b92ffaSHans Petter Selasky 								 mad)->
488*d6b92ffaSHans Petter Selasky 								mgmt_class ==
489*d6b92ffaSHans Petter Selasky 								IB_MCLASS_SUBN_DIR),
490*d6b92ffaSHans Petter Selasky 							       &mad_addr);
491*d6b92ffaSHans Petter Selasky 
492*d6b92ffaSHans Petter Selasky 			/* call the receiver callback */
493*d6b92ffaSHans Petter Selasky 			/* HACK: this should be replaced with a call to the RMPP Assembly ... */
494*d6b92ffaSHans Petter Selasky 			__osm_ts_rcv_callback(p_bind, &mad_addr, 256, &mad);
495*d6b92ffaSHans Petter Selasky 		}
496*d6b92ffaSHans Petter Selasky 	}
497*d6b92ffaSHans Petter Selasky 
498*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_bind->p_vend->p_log);
499*d6b92ffaSHans Petter Selasky }
500*d6b92ffaSHans Petter Selasky 
501*d6b92ffaSHans Petter Selasky /**********************************************************************
502*d6b92ffaSHans Petter Selasky  * BINDs a callback (rcv and send error) for a given class and method
503*d6b92ffaSHans Petter Selasky  * defined by the given:  osm_bind_info_t
504*d6b92ffaSHans Petter Selasky  **********************************************************************/
505*d6b92ffaSHans Petter Selasky osm_bind_handle_t
osm_vendor_bind(IN osm_vendor_t * const p_vend,IN osm_bind_info_t * const p_user_bind,IN osm_mad_pool_t * const p_mad_pool,IN osm_vend_mad_recv_callback_t mad_recv_callback,IN osm_vend_mad_send_err_callback_t send_err_callback,IN void * context)506*d6b92ffaSHans Petter Selasky osm_vendor_bind(IN osm_vendor_t * const p_vend,
507*d6b92ffaSHans Petter Selasky 		IN osm_bind_info_t * const p_user_bind,
508*d6b92ffaSHans Petter Selasky 		IN osm_mad_pool_t * const p_mad_pool,
509*d6b92ffaSHans Petter Selasky 		IN osm_vend_mad_recv_callback_t mad_recv_callback,
510*d6b92ffaSHans Petter Selasky 		IN osm_vend_mad_send_err_callback_t send_err_callback,
511*d6b92ffaSHans Petter Selasky 		IN void *context)
512*d6b92ffaSHans Petter Selasky {
513*d6b92ffaSHans Petter Selasky 	ib_net64_t port_guid;
514*d6b92ffaSHans Petter Selasky 	osm_ts_bind_info_t *p_bind = NULL;
515*d6b92ffaSHans Petter Selasky 	VAPI_hca_hndl_t hca_hndl;
516*d6b92ffaSHans Petter Selasky 	VAPI_hca_id_t hca_id;
517*d6b92ffaSHans Petter Selasky 	uint32_t port_num;
518*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
519*d6b92ffaSHans Petter Selasky 	int device_fd;
520*d6b92ffaSHans Petter Selasky 	char device_file[16];
521*d6b92ffaSHans Petter Selasky 	osm_ts_user_mad_filter filter;
522*d6b92ffaSHans Petter Selasky 	int ts_ioctl_ret;
523*d6b92ffaSHans Petter Selasky 	int qpn;
524*d6b92ffaSHans Petter Selasky 
525*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
526*d6b92ffaSHans Petter Selasky 
527*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_mad_pool);
528*d6b92ffaSHans Petter Selasky 
529*d6b92ffaSHans Petter Selasky 	port_guid = p_user_bind->port_guid;
530*d6b92ffaSHans Petter Selasky 
531*d6b92ffaSHans Petter Selasky 	osm_log(p_vend->p_log, OSM_LOG_INFO,
532*d6b92ffaSHans Petter Selasky 		"osm_vendor_bind: "
533*d6b92ffaSHans Petter Selasky 		"Binding to port 0x%" PRIx64 ".\n", cl_ntoh64(port_guid));
534*d6b92ffaSHans Petter Selasky 
535*d6b92ffaSHans Petter Selasky 	switch (p_user_bind->mad_class) {
536*d6b92ffaSHans Petter Selasky 	case IB_MCLASS_SUBN_LID:
537*d6b92ffaSHans Petter Selasky 	case IB_MCLASS_SUBN_DIR:
538*d6b92ffaSHans Petter Selasky 		p_bind = &(p_vend->smi_bind);
539*d6b92ffaSHans Petter Selasky 		qpn = 0;
540*d6b92ffaSHans Petter Selasky 		break;
541*d6b92ffaSHans Petter Selasky 
542*d6b92ffaSHans Petter Selasky 	case IB_MCLASS_SUBN_ADM:
543*d6b92ffaSHans Petter Selasky 	default:
544*d6b92ffaSHans Petter Selasky 		p_bind = &(p_vend->gsi_bind);
545*d6b92ffaSHans Petter Selasky 		qpn = 1;
546*d6b92ffaSHans Petter Selasky 		break;
547*d6b92ffaSHans Petter Selasky 	}
548*d6b92ffaSHans Petter Selasky 
549*d6b92ffaSHans Petter Selasky 	/* Make sure we did not previously opened the file */
550*d6b92ffaSHans Petter Selasky 	if (p_bind->ul_dev_fd >= 0) {
551*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
552*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 5004: "
553*d6b92ffaSHans Petter Selasky 			"Already binded to port %u\n", p_bind->port_num);
554*d6b92ffaSHans Petter Selasky 		goto Exit;
555*d6b92ffaSHans Petter Selasky 	}
556*d6b92ffaSHans Petter Selasky 
557*d6b92ffaSHans Petter Selasky 	/*
558*d6b92ffaSHans Petter Selasky 	   We need to figure out what is the TS file name to attach to.
559*d6b92ffaSHans Petter Selasky 	   I guess it is following the index of the port in the table of
560*d6b92ffaSHans Petter Selasky 	   ports.
561*d6b92ffaSHans Petter Selasky 	 */
562*d6b92ffaSHans Petter Selasky 
563*d6b92ffaSHans Petter Selasky 	/* obtain the hca name and port num from the guid */
564*d6b92ffaSHans Petter Selasky 	osm_log(p_vend->p_log, OSM_LOG_DEBUG,
565*d6b92ffaSHans Petter Selasky 		"osm_vendor_bind: "
566*d6b92ffaSHans Petter Selasky 		"Finding CA and Port that owns port guid 0x%" PRIx64 ".\n",
567*d6b92ffaSHans Petter Selasky 		cl_ntoh64(port_guid));
568*d6b92ffaSHans Petter Selasky 	status =
569*d6b92ffaSHans Petter Selasky 	    osm_vendor_get_guid_ca_and_port(p_vend, port_guid, &hca_hndl,
570*d6b92ffaSHans Petter Selasky 					    &hca_id, &port_num);
571*d6b92ffaSHans Petter Selasky 	if (status != IB_SUCCESS) {
572*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
573*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 5005: "
574*d6b92ffaSHans Petter Selasky 			"Fail to find port number of port guid:0x%016" PRIx64
575*d6b92ffaSHans Petter Selasky 			"\n", port_guid);
576*d6b92ffaSHans Petter Selasky 		goto Exit;
577*d6b92ffaSHans Petter Selasky 	}
578*d6b92ffaSHans Petter Selasky 
579*d6b92ffaSHans Petter Selasky 	/* the file name is just /dev/ts_ua0: */
580*d6b92ffaSHans Petter Selasky 	strcpy(device_file, "/dev/ts_ua0");
581*d6b92ffaSHans Petter Selasky 
582*d6b92ffaSHans Petter Selasky 	osm_log(p_vend->p_log, OSM_LOG_ERROR,
583*d6b92ffaSHans Petter Selasky 		"osm_vendor_bind: " "Opening TS UL dev file:%s\n", device_file);
584*d6b92ffaSHans Petter Selasky 
585*d6b92ffaSHans Petter Selasky 	/* Open the file ... */
586*d6b92ffaSHans Petter Selasky 	device_fd = open(device_file, O_RDWR);
587*d6b92ffaSHans Petter Selasky 	if (device_fd < 0) {
588*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
589*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 5006: "
590*d6b92ffaSHans Petter Selasky 			"Fail to open TS UL dev file:%s\n", device_file);
591*d6b92ffaSHans Petter Selasky 		goto Exit;
592*d6b92ffaSHans Petter Selasky 	}
593*d6b92ffaSHans Petter Selasky 
594*d6b92ffaSHans Petter Selasky 	/* track this bind request info */
595*d6b92ffaSHans Petter Selasky 	p_bind->ul_dev_fd = device_fd;
596*d6b92ffaSHans Petter Selasky 	p_bind->port_num = port_num;
597*d6b92ffaSHans Petter Selasky 	p_bind->p_vend = p_vend;
598*d6b92ffaSHans Petter Selasky 	p_bind->client_context = context;
599*d6b92ffaSHans Petter Selasky 	p_bind->rcv_callback = mad_recv_callback;
600*d6b92ffaSHans Petter Selasky 	p_bind->send_err_callback = send_err_callback;
601*d6b92ffaSHans Petter Selasky 	p_bind->p_osm_pool = p_mad_pool;
602*d6b92ffaSHans Petter Selasky 	p_bind->hca_hndl = hca_hndl;
603*d6b92ffaSHans Petter Selasky 
604*d6b92ffaSHans Petter Selasky 	/*
605*d6b92ffaSHans Petter Selasky 	 * Create the MAD filter on this file handle.
606*d6b92ffaSHans Petter Selasky 	 */
607*d6b92ffaSHans Petter Selasky 	filter.port = port_num;
608*d6b92ffaSHans Petter Selasky 
609*d6b92ffaSHans Petter Selasky 	filter.qpn = qpn;
610*d6b92ffaSHans Petter Selasky 	filter.mgmt_class = p_user_bind->mad_class;
611*d6b92ffaSHans Petter Selasky 	filter.direction = TS_IB_MAD_DIRECTION_IN;
612*d6b92ffaSHans Petter Selasky 	filter.mask =
613*d6b92ffaSHans Petter Selasky 	    TS_IB_MAD_FILTER_DIRECTION |
614*d6b92ffaSHans Petter Selasky 	    TS_IB_MAD_FILTER_PORT |
615*d6b92ffaSHans Petter Selasky 	    TS_IB_MAD_FILTER_QPN | TS_IB_MAD_FILTER_MGMT_CLASS;
616*d6b92ffaSHans Petter Selasky 
617*d6b92ffaSHans Petter Selasky 	ts_ioctl_ret = ioctl(device_fd, TS_IB_IOCSMADFILTADD, &filter);
618*d6b92ffaSHans Petter Selasky 	if (ts_ioctl_ret < 0) {
619*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
620*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 5014: "
621*d6b92ffaSHans Petter Selasky 			"Fail to register MAD filter with err:%u\n",
622*d6b92ffaSHans Petter Selasky 			ts_ioctl_ret);
623*d6b92ffaSHans Petter Selasky 		goto Exit;
624*d6b92ffaSHans Petter Selasky 	}
625*d6b92ffaSHans Petter Selasky 
626*d6b92ffaSHans Petter Selasky 	/* Initialize the listener thread for this port */
627*d6b92ffaSHans Petter Selasky 	status = cl_thread_init(&p_bind->poller,
628*d6b92ffaSHans Petter Selasky 				__osm_vendor_ts_poller, p_bind,
629*d6b92ffaSHans Petter Selasky 				"osm ts poller");
630*d6b92ffaSHans Petter Selasky 	if (status != IB_SUCCESS)
631*d6b92ffaSHans Petter Selasky 		goto Exit;
632*d6b92ffaSHans Petter Selasky 
633*d6b92ffaSHans Petter Selasky Exit:
634*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
635*d6b92ffaSHans Petter Selasky 	return ((osm_bind_handle_t) p_bind);
636*d6b92ffaSHans Petter Selasky }
637*d6b92ffaSHans Petter Selasky 
638*d6b92ffaSHans Petter Selasky /**********************************************************************
639*d6b92ffaSHans Petter Selasky Get a mad from the lower level.
640*d6b92ffaSHans Petter Selasky The osm_vend_wrap_t is a wrapper used to connect the mad to the response.
641*d6b92ffaSHans Petter Selasky **********************************************************************/
osm_vendor_get(IN osm_bind_handle_t h_bind,IN const uint32_t mad_size,IN osm_vend_wrap_t * const p_vw)642*d6b92ffaSHans Petter Selasky ib_mad_t *osm_vendor_get(IN osm_bind_handle_t h_bind,
643*d6b92ffaSHans Petter Selasky 			 IN const uint32_t mad_size,
644*d6b92ffaSHans Petter Selasky 			 IN osm_vend_wrap_t * const p_vw)
645*d6b92ffaSHans Petter Selasky {
646*d6b92ffaSHans Petter Selasky 	ib_mad_t *p_mad;
647*d6b92ffaSHans Petter Selasky 	osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
648*d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = p_bind->p_vend;
649*d6b92ffaSHans Petter Selasky 
650*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
651*d6b92ffaSHans Petter Selasky 
652*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_vw);
653*d6b92ffaSHans Petter Selasky 
654*d6b92ffaSHans Petter Selasky 	p_vw->size = mad_size;
655*d6b92ffaSHans Petter Selasky 
656*d6b92ffaSHans Petter Selasky 	/* allocate it */
657*d6b92ffaSHans Petter Selasky 	p_mad = (ib_mad_t *) malloc(p_vw->size);
658*d6b92ffaSHans Petter Selasky 	if (p_mad == NULL) {
659*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
660*d6b92ffaSHans Petter Selasky 			"osm_vendor_get: ERR 5022: "
661*d6b92ffaSHans Petter Selasky 			"Error Obtaining MAD buffer.\n");
662*d6b92ffaSHans Petter Selasky 		goto Exit;
663*d6b92ffaSHans Petter Selasky 	}
664*d6b92ffaSHans Petter Selasky 
665*d6b92ffaSHans Petter Selasky 	memset(p_mad, 0, p_vw->size);
666*d6b92ffaSHans Petter Selasky 
667*d6b92ffaSHans Petter Selasky 	/* track locally */
668*d6b92ffaSHans Petter Selasky 	p_vw->p_mad_buf = p_mad;
669*d6b92ffaSHans Petter Selasky 	p_vw->h_bind = h_bind;
670*d6b92ffaSHans Petter Selasky 	p_vw->p_resp_madw = NULL;
671*d6b92ffaSHans Petter Selasky 
672*d6b92ffaSHans Petter Selasky 	if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
673*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_DEBUG,
674*d6b92ffaSHans Petter Selasky 			"osm_vendor_get: "
675*d6b92ffaSHans Petter Selasky 			"Acquired MAD %p, size = %u.\n", p_mad, p_vw->size);
676*d6b92ffaSHans Petter Selasky 	}
677*d6b92ffaSHans Petter Selasky 
678*d6b92ffaSHans Petter Selasky Exit:
679*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
680*d6b92ffaSHans Petter Selasky 	return (p_mad);
681*d6b92ffaSHans Petter Selasky }
682*d6b92ffaSHans Petter Selasky 
683*d6b92ffaSHans Petter Selasky /**********************************************************************
684*d6b92ffaSHans Petter Selasky  * Return a MAD by providing it's wrapper object.
685*d6b92ffaSHans Petter Selasky  **********************************************************************/
686*d6b92ffaSHans Petter Selasky void
osm_vendor_put(IN osm_bind_handle_t h_bind,IN osm_vend_wrap_t * const p_vw)687*d6b92ffaSHans Petter Selasky osm_vendor_put(IN osm_bind_handle_t h_bind, IN osm_vend_wrap_t * const p_vw)
688*d6b92ffaSHans Petter Selasky {
689*d6b92ffaSHans Petter Selasky 	osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
690*d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = p_bind->p_vend;
691*d6b92ffaSHans Petter Selasky 	osm_madw_t *p_madw;
692*d6b92ffaSHans Petter Selasky 
693*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
694*d6b92ffaSHans Petter Selasky 
695*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_vw);
696*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_vw->p_mad_buf);
697*d6b92ffaSHans Petter Selasky 
698*d6b92ffaSHans Petter Selasky 	if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
699*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_DEBUG,
700*d6b92ffaSHans Petter Selasky 			"osm_vendor_put: " "Retiring MAD %p.\n",
701*d6b92ffaSHans Petter Selasky 			p_vw->p_mad_buf);
702*d6b92ffaSHans Petter Selasky 	}
703*d6b92ffaSHans Petter Selasky 
704*d6b92ffaSHans Petter Selasky 	/*
705*d6b92ffaSHans Petter Selasky 	 * We moved the removal of the transaction to immediatly after
706*d6b92ffaSHans Petter Selasky 	 * it was looked up.
707*d6b92ffaSHans Petter Selasky 	 */
708*d6b92ffaSHans Petter Selasky 
709*d6b92ffaSHans Petter Selasky 	/* free the mad but the wrapper is part of the madw object */
710*d6b92ffaSHans Petter Selasky 	free(p_vw->p_mad_buf);
711*d6b92ffaSHans Petter Selasky 	p_vw->p_mad_buf = NULL;
712*d6b92ffaSHans Petter Selasky 	p_madw = PARENT_STRUCT(p_vw, osm_madw_t, vend_wrap);
713*d6b92ffaSHans Petter Selasky 	p_madw->p_mad = NULL;
714*d6b92ffaSHans Petter Selasky 
715*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
716*d6b92ffaSHans Petter Selasky }
717*d6b92ffaSHans Petter Selasky 
718*d6b92ffaSHans Petter Selasky /**********************************************************************
719*d6b92ffaSHans Petter Selasky Actually Send a MAD
720*d6b92ffaSHans Petter Selasky 
721*d6b92ffaSHans Petter Selasky MADs are buffers of type: struct ib_mad - so they are limited by size.
722*d6b92ffaSHans Petter Selasky This is for internal use by osm_vendor_send and the transaction mgr
723*d6b92ffaSHans Petter Selasky retry too.
724*d6b92ffaSHans Petter Selasky **********************************************************************/
725*d6b92ffaSHans Petter Selasky ib_api_status_t
osm_ts_send_mad(IN osm_ts_bind_info_t * p_bind,IN osm_madw_t * const p_madw)726*d6b92ffaSHans Petter Selasky osm_ts_send_mad(IN osm_ts_bind_info_t * p_bind, IN osm_madw_t * const p_madw)
727*d6b92ffaSHans Petter Selasky {
728*d6b92ffaSHans Petter Selasky 	osm_vendor_t *const p_vend = p_bind->p_vend;
729*d6b92ffaSHans Petter Selasky 	osm_mad_addr_t *const p_mad_addr = osm_madw_get_mad_addr_ptr(p_madw);
730*d6b92ffaSHans Petter Selasky 	ib_mad_t *const p_mad = osm_madw_get_mad_ptr(p_madw);
731*d6b92ffaSHans Petter Selasky 	struct ib_mad ts_mad;
732*d6b92ffaSHans Petter Selasky 	int ret;
733*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
734*d6b92ffaSHans Petter Selasky 
735*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
736*d6b92ffaSHans Petter Selasky 
737*d6b92ffaSHans Petter Selasky 	/*
738*d6b92ffaSHans Petter Selasky 	 * Copy the MAD over to the sent mad
739*d6b92ffaSHans Petter Selasky 	 */
740*d6b92ffaSHans Petter Selasky 	memcpy(&ts_mad, p_mad, 256);
741*d6b92ffaSHans Petter Selasky 
742*d6b92ffaSHans Petter Selasky 	/*
743*d6b92ffaSHans Petter Selasky 	 * For all sends other than directed route SM MADs,
744*d6b92ffaSHans Petter Selasky 	 * acquire an address vector for the destination.
745*d6b92ffaSHans Petter Selasky 	 */
746*d6b92ffaSHans Petter Selasky 	if (p_mad->mgmt_class != IB_MCLASS_SUBN_DIR) {
747*d6b92ffaSHans Petter Selasky 		__osm_ts_conv_osm_addr_to_ts_addr(p_mad_addr,
748*d6b92ffaSHans Petter Selasky 						  p_mad->mgmt_class ==
749*d6b92ffaSHans Petter Selasky 						  IB_MCLASS_SUBN_LID, &ts_mad);
750*d6b92ffaSHans Petter Selasky 	} else {
751*d6b92ffaSHans Petter Selasky 		/* is a directed route - we need to construct a permissive address */
752*d6b92ffaSHans Petter Selasky 		/* we do not need port number since it is part of the mad_hndl */
753*d6b92ffaSHans Petter Selasky 		ts_mad.dlid = IB_LID_PERMISSIVE;
754*d6b92ffaSHans Petter Selasky 		ts_mad.slid = IB_LID_PERMISSIVE;
755*d6b92ffaSHans Petter Selasky 	}
756*d6b92ffaSHans Petter Selasky 	if ((p_mad->mgmt_class == IB_MCLASS_SUBN_DIR) ||
757*d6b92ffaSHans Petter Selasky 	    (p_mad->mgmt_class == IB_MCLASS_SUBN_LID)) {
758*d6b92ffaSHans Petter Selasky 		ts_mad.sqpn = 0;
759*d6b92ffaSHans Petter Selasky 		ts_mad.dqpn = 0;
760*d6b92ffaSHans Petter Selasky 	} else {
761*d6b92ffaSHans Petter Selasky 		ts_mad.sqpn = 1;
762*d6b92ffaSHans Petter Selasky 		ts_mad.dqpn = 1;
763*d6b92ffaSHans Petter Selasky 	}
764*d6b92ffaSHans Petter Selasky 	ts_mad.port = p_bind->port_num;
765*d6b92ffaSHans Petter Selasky 
766*d6b92ffaSHans Petter Selasky 	/* send it */
767*d6b92ffaSHans Petter Selasky 	ret = write(p_bind->ul_dev_fd, &ts_mad, sizeof(ts_mad));
768*d6b92ffaSHans Petter Selasky 
769*d6b92ffaSHans Petter Selasky 	if (ret != sizeof(ts_mad)) {
770*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
771*d6b92ffaSHans Petter Selasky 			"osm_ts_send_mad: ERR 5026: "
772*d6b92ffaSHans Petter Selasky 			"Error sending mad (%d).\n", ret);
773*d6b92ffaSHans Petter Selasky 		status = IB_ERROR;
774*d6b92ffaSHans Petter Selasky 		goto Exit;
775*d6b92ffaSHans Petter Selasky 	}
776*d6b92ffaSHans Petter Selasky 
777*d6b92ffaSHans Petter Selasky 	status = IB_SUCCESS;
778*d6b92ffaSHans Petter Selasky 
779*d6b92ffaSHans Petter Selasky Exit:
780*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
781*d6b92ffaSHans Petter Selasky 	return (status);
782*d6b92ffaSHans Petter Selasky }
783*d6b92ffaSHans Petter Selasky 
784*d6b92ffaSHans Petter Selasky /**********************************************************************
785*d6b92ffaSHans Petter Selasky Send a MAD through.
786*d6b92ffaSHans Petter Selasky 
787*d6b92ffaSHans Petter Selasky What is unclear to me is the need for the setting of all the MAD Wrapper
788*d6b92ffaSHans Petter Selasky fields. Seems like the OSM uses these values during it's processing...
789*d6b92ffaSHans Petter Selasky **********************************************************************/
790*d6b92ffaSHans Petter Selasky ib_api_status_t
osm_vendor_send(IN osm_bind_handle_t h_bind,IN osm_madw_t * const p_madw,IN boolean_t const resp_expected)791*d6b92ffaSHans Petter Selasky osm_vendor_send(IN osm_bind_handle_t h_bind,
792*d6b92ffaSHans Petter Selasky 		IN osm_madw_t * const p_madw, IN boolean_t const resp_expected)
793*d6b92ffaSHans Petter Selasky {
794*d6b92ffaSHans Petter Selasky 	osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
795*d6b92ffaSHans Petter Selasky 	osm_vendor_t *const p_vend = p_bind->p_vend;
796*d6b92ffaSHans Petter Selasky 	osm_vend_wrap_t *const p_vw = osm_madw_get_vend_ptr(p_madw);
797*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
798*d6b92ffaSHans Petter Selasky 
799*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
800*d6b92ffaSHans Petter Selasky 
801*d6b92ffaSHans Petter Selasky 	/*
802*d6b92ffaSHans Petter Selasky 	 * If a response is expected to this MAD, then preallocate
803*d6b92ffaSHans Petter Selasky 	 * a mad wrapper to contain the wire MAD received in the
804*d6b92ffaSHans Petter Selasky 	 * response.  Allocating a wrapper here allows for easier
805*d6b92ffaSHans Petter Selasky 	 * failure paths than after we already received the wire mad.
806*d6b92ffaSHans Petter Selasky 	 */
807*d6b92ffaSHans Petter Selasky 	if (resp_expected == TRUE) {
808*d6b92ffaSHans Petter Selasky 		/* we track it in the vendor wrapper */
809*d6b92ffaSHans Petter Selasky 		p_vw->p_resp_madw =
810*d6b92ffaSHans Petter Selasky 		    osm_mad_pool_get_wrapper_raw(p_bind->p_osm_pool);
811*d6b92ffaSHans Petter Selasky 		if (p_vw->p_resp_madw == NULL) {
812*d6b92ffaSHans Petter Selasky 			osm_log(p_vend->p_log, OSM_LOG_ERROR,
813*d6b92ffaSHans Petter Selasky 				"osm_vendor_send: ERR 5024: "
814*d6b92ffaSHans Petter Selasky 				"Unable to allocate MAD wrapper.\n");
815*d6b92ffaSHans Petter Selasky 			status = IB_INSUFFICIENT_RESOURCES;
816*d6b92ffaSHans Petter Selasky 			goto Exit;
817*d6b92ffaSHans Petter Selasky 		}
818*d6b92ffaSHans Petter Selasky 
819*d6b92ffaSHans Petter Selasky 		/* put some minimal info on that wrapper */
820*d6b92ffaSHans Petter Selasky 		((osm_madw_t *) (p_vw->p_resp_madw))->h_bind = h_bind;
821*d6b92ffaSHans Petter Selasky 
822*d6b92ffaSHans Petter Selasky 		/* we also want to track it in the TID based map */
823*d6b92ffaSHans Petter Selasky 		status = osm_transaction_mgr_insert_madw((osm_bind_handle_t *)
824*d6b92ffaSHans Petter Selasky 							 p_bind, p_madw);
825*d6b92ffaSHans Petter Selasky 		if (status != IB_SUCCESS) {
826*d6b92ffaSHans Petter Selasky 			osm_log(p_vend->p_log, OSM_LOG_ERROR,
827*d6b92ffaSHans Petter Selasky 				"osm_vendor_send: ERR 5025: "
828*d6b92ffaSHans Petter Selasky 				"Error inserting request madw by TID (%d).\n",
829*d6b92ffaSHans Petter Selasky 				status);
830*d6b92ffaSHans Petter Selasky 		}
831*d6b92ffaSHans Petter Selasky 	} else
832*d6b92ffaSHans Petter Selasky 		p_vw->p_resp_madw = NULL;
833*d6b92ffaSHans Petter Selasky 
834*d6b92ffaSHans Petter Selasky 	/* do the actual send */
835*d6b92ffaSHans Petter Selasky 	/* HACK: to be replaced by call to RMPP Segmentation */
836*d6b92ffaSHans Petter Selasky 	status = osm_ts_send_mad(p_bind, p_madw);
837*d6b92ffaSHans Petter Selasky 
838*d6b92ffaSHans Petter Selasky 	/* we do not get an asycn callback so call it ourselves */
839*d6b92ffaSHans Petter Selasky 	/* this will handle all cleanup if neccessary */
840*d6b92ffaSHans Petter Selasky 	__osm_ts_send_callback(p_bind, !resp_expected, p_madw, status);
841*d6b92ffaSHans Petter Selasky 
842*d6b92ffaSHans Petter Selasky Exit:
843*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
844*d6b92ffaSHans Petter Selasky 	return (status);
845*d6b92ffaSHans Petter Selasky }
846*d6b92ffaSHans Petter Selasky 
847*d6b92ffaSHans Petter Selasky /**********************************************************************
848*d6b92ffaSHans Petter Selasky  * the idea here is to change the content of the bind such that it
849*d6b92ffaSHans Petter Selasky  * will hold the local address used for sending directed route by the SMA.
850*d6b92ffaSHans Petter Selasky  **********************************************************************/
osm_vendor_local_lid_change(IN osm_bind_handle_t h_bind)851*d6b92ffaSHans Petter Selasky ib_api_status_t osm_vendor_local_lid_change(IN osm_bind_handle_t h_bind)
852*d6b92ffaSHans Petter Selasky {
853*d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = ((osm_ts_bind_info_t *) h_bind)->p_vend;
854*d6b92ffaSHans Petter Selasky 
855*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
856*d6b92ffaSHans Petter Selasky 
857*d6b92ffaSHans Petter Selasky 	osm_log(p_vend->p_log, OSM_LOG_DEBUG,
858*d6b92ffaSHans Petter Selasky 		"osm_vendor_local_lid_change: DEBUG 2202: " "Change of LID.\n");
859*d6b92ffaSHans Petter Selasky 
860*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
861*d6b92ffaSHans Petter Selasky 
862*d6b92ffaSHans Petter Selasky 	return (IB_SUCCESS);
863*d6b92ffaSHans Petter Selasky }
864*d6b92ffaSHans Petter Selasky 
osm_vendor_set_sm(IN osm_bind_handle_t h_bind,IN boolean_t is_sm_val)865*d6b92ffaSHans Petter Selasky void osm_vendor_set_sm(IN osm_bind_handle_t h_bind, IN boolean_t is_sm_val)
866*d6b92ffaSHans Petter Selasky {
867*d6b92ffaSHans Petter Selasky 	osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
868*d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend = p_bind->p_vend;
869*d6b92ffaSHans Petter Selasky 	VAPI_ret_t status;
870*d6b92ffaSHans Petter Selasky 	VAPI_hca_attr_t attr_mod;
871*d6b92ffaSHans Petter Selasky 	VAPI_hca_attr_mask_t attr_mask;
872*d6b92ffaSHans Petter Selasky 
873*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
874*d6b92ffaSHans Petter Selasky 
875*d6b92ffaSHans Petter Selasky 	memset(&attr_mod, 0, sizeof(attr_mod));
876*d6b92ffaSHans Petter Selasky 	memset(&attr_mask, 0, sizeof(attr_mask));
877*d6b92ffaSHans Petter Selasky 
878*d6b92ffaSHans Petter Selasky 	attr_mod.is_sm = is_sm_val;
879*d6b92ffaSHans Petter Selasky 	attr_mask = HCA_ATTR_IS_SM;
880*d6b92ffaSHans Petter Selasky 
881*d6b92ffaSHans Petter Selasky 	status =
882*d6b92ffaSHans Petter Selasky 	    VAPI_modify_hca_attr(p_bind->hca_hndl, p_bind->port_num, &attr_mod,
883*d6b92ffaSHans Petter Selasky 				 &attr_mask);
884*d6b92ffaSHans Petter Selasky 	if (status != VAPI_OK) {
885*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
886*d6b92ffaSHans Petter Selasky 			"osm_vendor_set_sm: ERR 5027: "
887*d6b92ffaSHans Petter Selasky 			"Unable set 'IS_SM' bit to:%u in port attributes (%d).\n",
888*d6b92ffaSHans Petter Selasky 			is_sm_val, status);
889*d6b92ffaSHans Petter Selasky 	}
890*d6b92ffaSHans Petter Selasky 
891*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
892*d6b92ffaSHans Petter Selasky }
893*d6b92ffaSHans Petter Selasky 
osm_vendor_set_debug(IN osm_vendor_t * const p_vend,IN int32_t level)894*d6b92ffaSHans Petter Selasky void osm_vendor_set_debug(IN osm_vendor_t * const p_vend, IN int32_t level)
895*d6b92ffaSHans Petter Selasky {
896*d6b92ffaSHans Petter Selasky 
897*d6b92ffaSHans Petter Selasky }
898