xref: /freebsd/contrib/ofed/opensm/libvendor/osm_vendor_mlx.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 #if HAVE_CONFIG_H
37*d6b92ffaSHans Petter Selasky #  include <config.h>
38*d6b92ffaSHans Petter Selasky #endif				/* HAVE_CONFIG_H */
39*d6b92ffaSHans Petter Selasky 
40*d6b92ffaSHans Petter Selasky #include <stdlib.h>
41*d6b92ffaSHans Petter Selasky #include <string.h>
42*d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_mlx.h>
43*d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_mlx_transport.h>
44*d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_mlx_svc.h>
45*d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_mlx_sender.h>
46*d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_mlx_hca.h>
47*d6b92ffaSHans Petter Selasky #include <vendor/osm_pkt_randomizer.h>
48*d6b92ffaSHans Petter Selasky 
49*d6b92ffaSHans Petter Selasky /**
50*d6b92ffaSHans Petter Selasky  *      FORWARD REFERENCES
51*d6b92ffaSHans Petter Selasky  */
52*d6b92ffaSHans Petter Selasky static ib_api_status_t
53*d6b92ffaSHans Petter Selasky __osmv_get_send_txn(IN osm_bind_handle_t h_bind,
54*d6b92ffaSHans Petter Selasky 		    IN osm_madw_t * const p_madw,
55*d6b92ffaSHans Petter Selasky 		    IN boolean_t is_rmpp,
56*d6b92ffaSHans Petter Selasky 		    IN boolean_t resp_expected, OUT osmv_txn_ctx_t ** pp_txn);
57*d6b92ffaSHans Petter Selasky 
58*d6b92ffaSHans Petter Selasky static void __osm_vendor_internal_unbind(osm_bind_handle_t h_bind);
59*d6b92ffaSHans Petter Selasky 
60*d6b92ffaSHans Petter Selasky /*
61*d6b92ffaSHans Petter Selasky  *  NAME            osm_vendor_new
62*d6b92ffaSHans Petter Selasky  *
63*d6b92ffaSHans Petter Selasky  *  DESCRIPTION     Create and Initialize the osm_vendor_t Object
64*d6b92ffaSHans Petter Selasky  */
65*d6b92ffaSHans Petter Selasky 
osm_vendor_new(IN osm_log_t * const p_log,IN const uint32_t timeout)66*d6b92ffaSHans Petter Selasky osm_vendor_t *osm_vendor_new(IN osm_log_t * const p_log,
67*d6b92ffaSHans Petter Selasky 			     IN const uint32_t timeout)
68*d6b92ffaSHans Petter Selasky {
69*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
70*d6b92ffaSHans Petter Selasky 	osm_vendor_t *p_vend;
71*d6b92ffaSHans Petter Selasky 
72*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
73*d6b92ffaSHans Petter Selasky 
74*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_log);
75*d6b92ffaSHans Petter Selasky 
76*d6b92ffaSHans Petter Selasky 	p_vend = malloc(sizeof(*p_vend));
77*d6b92ffaSHans Petter Selasky 	if (p_vend != NULL) {
78*d6b92ffaSHans Petter Selasky 		memset(p_vend, 0, sizeof(*p_vend));
79*d6b92ffaSHans Petter Selasky 
80*d6b92ffaSHans Petter Selasky 		status = osm_vendor_init(p_vend, p_log, timeout);
81*d6b92ffaSHans Petter Selasky 		if (status != IB_SUCCESS) {
82*d6b92ffaSHans Petter Selasky 			osm_vendor_delete(&p_vend);
83*d6b92ffaSHans Petter Selasky 		}
84*d6b92ffaSHans Petter Selasky 	} else {
85*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
86*d6b92ffaSHans Petter Selasky 			"osm_vendor_new: ERR 7301: "
87*d6b92ffaSHans Petter Selasky 			"Fail to allocate vendor object.\n");
88*d6b92ffaSHans Petter Selasky 	}
89*d6b92ffaSHans Petter Selasky 
90*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
91*d6b92ffaSHans Petter Selasky 	return (p_vend);
92*d6b92ffaSHans Petter Selasky }
93*d6b92ffaSHans Petter Selasky 
94*d6b92ffaSHans Petter Selasky /*
95*d6b92ffaSHans Petter Selasky  *  NAME            osm_vendor_delete
96*d6b92ffaSHans Petter Selasky  *
97*d6b92ffaSHans Petter Selasky  *  DESCRIPTION     Delete all the binds behind the vendor + free the vendor object
98*d6b92ffaSHans Petter Selasky  */
99*d6b92ffaSHans Petter Selasky 
osm_vendor_delete(IN osm_vendor_t ** const pp_vend)100*d6b92ffaSHans Petter Selasky void osm_vendor_delete(IN osm_vendor_t ** const pp_vend)
101*d6b92ffaSHans Petter Selasky {
102*d6b92ffaSHans Petter Selasky 	cl_list_item_t *p_item;
103*d6b92ffaSHans Petter Selasky 	cl_list_obj_t *p_obj;
104*d6b92ffaSHans Petter Selasky 	osm_bind_handle_t bind_h;
105*d6b92ffaSHans Petter Selasky 	osm_log_t *p_log;
106*d6b92ffaSHans Petter Selasky 
107*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER((*pp_vend)->p_log);
108*d6b92ffaSHans Petter Selasky 	p_log = (*pp_vend)->p_log;
109*d6b92ffaSHans Petter Selasky 
110*d6b92ffaSHans Petter Selasky 	/* go over the bind handles , unbind them and remove from list */
111*d6b92ffaSHans Petter Selasky 	p_item = cl_qlist_remove_head(&((*pp_vend)->bind_handles));
112*d6b92ffaSHans Petter Selasky 	while (p_item != cl_qlist_end(&((*pp_vend)->bind_handles))) {
113*d6b92ffaSHans Petter Selasky 
114*d6b92ffaSHans Petter Selasky 		p_obj = PARENT_STRUCT(p_item, cl_list_obj_t, list_item);
115*d6b92ffaSHans Petter Selasky 		bind_h = (osm_bind_handle_t *) cl_qlist_obj(p_obj);
116*d6b92ffaSHans Petter Selasky 		osm_log(p_log, OSM_LOG_DEBUG,
117*d6b92ffaSHans Petter Selasky 			"osm_vendor_delete: unbinding bind_h:%p \n", bind_h);
118*d6b92ffaSHans Petter Selasky 
119*d6b92ffaSHans Petter Selasky 		__osm_vendor_internal_unbind(bind_h);
120*d6b92ffaSHans Petter Selasky 
121*d6b92ffaSHans Petter Selasky 		free(p_obj);
122*d6b92ffaSHans Petter Selasky 		/*removing from list */
123*d6b92ffaSHans Petter Selasky 		p_item = cl_qlist_remove_head(&((*pp_vend)->bind_handles));
124*d6b92ffaSHans Petter Selasky 	}
125*d6b92ffaSHans Petter Selasky 
126*d6b92ffaSHans Petter Selasky 	if (NULL != ((*pp_vend)->p_transport_info)) {
127*d6b92ffaSHans Petter Selasky 		free((*pp_vend)->p_transport_info);
128*d6b92ffaSHans Petter Selasky 		(*pp_vend)->p_transport_info = NULL;
129*d6b92ffaSHans Petter Selasky 	}
130*d6b92ffaSHans Petter Selasky 
131*d6b92ffaSHans Petter Selasky 	/* remove the packet randomizer object */
132*d6b92ffaSHans Petter Selasky 	if ((*pp_vend)->run_randomizer == TRUE)
133*d6b92ffaSHans Petter Selasky 		osm_pkt_randomizer_destroy(&((*pp_vend)->p_pkt_randomizer),
134*d6b92ffaSHans Petter Selasky 					   p_log);
135*d6b92ffaSHans Petter Selasky 
136*d6b92ffaSHans Petter Selasky 	free(*pp_vend);
137*d6b92ffaSHans Petter Selasky 	*pp_vend = NULL;
138*d6b92ffaSHans Petter Selasky 
139*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
140*d6b92ffaSHans Petter Selasky }
141*d6b92ffaSHans Petter Selasky 
142*d6b92ffaSHans Petter Selasky /*
143*d6b92ffaSHans Petter Selasky  *  NAME            osm_vendor_init
144*d6b92ffaSHans Petter Selasky  *
145*d6b92ffaSHans Petter Selasky  *  DESCRIPTION     Initialize the vendor object
146*d6b92ffaSHans Petter Selasky  */
147*d6b92ffaSHans Petter Selasky 
148*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)149*d6b92ffaSHans Petter Selasky osm_vendor_init(IN osm_vendor_t * const p_vend,
150*d6b92ffaSHans Petter Selasky 		IN osm_log_t * const p_log, IN const uint32_t timeout)
151*d6b92ffaSHans Petter Selasky {
152*d6b92ffaSHans Petter Selasky 	ib_api_status_t status = IB_SUCCESS;
153*d6b92ffaSHans Petter Selasky 
154*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
155*d6b92ffaSHans Petter Selasky 
156*d6b92ffaSHans Petter Selasky 	p_vend->p_transport_info = NULL;
157*d6b92ffaSHans Petter Selasky 	p_vend->p_log = p_log;
158*d6b92ffaSHans Petter Selasky 	p_vend->resp_timeout = timeout;
159*d6b92ffaSHans Petter Selasky 	p_vend->ttime_timeout = timeout * OSMV_TXN_TIMEOUT_FACTOR;
160*d6b92ffaSHans Petter Selasky 
161*d6b92ffaSHans Petter Selasky 	cl_qlist_init(&p_vend->bind_handles);
162*d6b92ffaSHans Petter Selasky 
163*d6b92ffaSHans Petter Selasky 	/* update the run_randomizer flag */
164*d6b92ffaSHans Petter Selasky 	if (getenv("OSM_PKT_DROP_RATE") != NULL
165*d6b92ffaSHans Petter Selasky 	    && atol(getenv("OSM_PKT_DROP_RATE")) != 0) {
166*d6b92ffaSHans Petter Selasky 		/* if the OSM_PKT_DROP_RATE global variable is defined to a non-zero value -
167*d6b92ffaSHans Petter Selasky 		   then the randomizer should be called.
168*d6b92ffaSHans Petter Selasky 		   Need to create the packet randomizer object */
169*d6b92ffaSHans Petter Selasky 		p_vend->run_randomizer = TRUE;
170*d6b92ffaSHans Petter Selasky 		status =
171*d6b92ffaSHans Petter Selasky 		    osm_pkt_randomizer_init(&(p_vend->p_pkt_randomizer), p_log);
172*d6b92ffaSHans Petter Selasky 		if (status != IB_SUCCESS)
173*d6b92ffaSHans Petter Selasky 			return status;
174*d6b92ffaSHans Petter Selasky 	} else {
175*d6b92ffaSHans Petter Selasky 		p_vend->run_randomizer = FALSE;
176*d6b92ffaSHans Petter Selasky 		p_vend->p_pkt_randomizer = NULL;
177*d6b92ffaSHans Petter Selasky 	}
178*d6b92ffaSHans Petter Selasky 
179*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
180*d6b92ffaSHans Petter Selasky 	return (IB_SUCCESS);
181*d6b92ffaSHans Petter Selasky }
182*d6b92ffaSHans Petter Selasky 
183*d6b92ffaSHans Petter Selasky /*
184*d6b92ffaSHans Petter Selasky  *  NAME            osm_vendor_bind
185*d6b92ffaSHans Petter Selasky  *
186*d6b92ffaSHans Petter Selasky  *  DESCRIPTION     Create a new bind object under the vendor object
187*d6b92ffaSHans Petter Selasky  */
188*d6b92ffaSHans Petter Selasky 
189*d6b92ffaSHans Petter Selasky osm_bind_handle_t
osm_vendor_bind(IN osm_vendor_t * const p_vend,IN osm_bind_info_t * const p_bind_info,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)190*d6b92ffaSHans Petter Selasky osm_vendor_bind(IN osm_vendor_t * const p_vend,
191*d6b92ffaSHans Petter Selasky 		IN osm_bind_info_t * const p_bind_info,
192*d6b92ffaSHans Petter Selasky 		IN osm_mad_pool_t * const p_mad_pool,
193*d6b92ffaSHans Petter Selasky 		IN osm_vend_mad_recv_callback_t mad_recv_callback,
194*d6b92ffaSHans Petter Selasky 		IN osm_vend_mad_send_err_callback_t send_err_callback,
195*d6b92ffaSHans Petter Selasky 		IN void *context)
196*d6b92ffaSHans Petter Selasky {
197*d6b92ffaSHans Petter Selasky 	osmv_bind_obj_t *p_bo;
198*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
199*d6b92ffaSHans Petter Selasky 	char hca_id[32];
200*d6b92ffaSHans Petter Selasky 	cl_status_t cl_st;
201*d6b92ffaSHans Petter Selasky 	cl_list_obj_t *p_obj;
202*d6b92ffaSHans Petter Selasky 	uint8_t hca_index;
203*d6b92ffaSHans Petter Selasky 
204*d6b92ffaSHans Petter Selasky 	if (NULL == p_vend || NULL == p_bind_info || NULL == p_mad_pool
205*d6b92ffaSHans Petter Selasky 	    || NULL == mad_recv_callback || NULL == send_err_callback) {
206*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
207*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 7302: "
208*d6b92ffaSHans Petter Selasky 			"NULL parameter passed in: p_vend=%p p_bind_info=%p p_mad_pool=%p recv_cb=%p send_err_cb=%p\n",
209*d6b92ffaSHans Petter Selasky 			p_vend, p_bind_info, p_mad_pool, mad_recv_callback,
210*d6b92ffaSHans Petter Selasky 			send_err_callback);
211*d6b92ffaSHans Petter Selasky 
212*d6b92ffaSHans Petter Selasky 		return OSM_BIND_INVALID_HANDLE;
213*d6b92ffaSHans Petter Selasky 	}
214*d6b92ffaSHans Petter Selasky 
215*d6b92ffaSHans Petter Selasky 	p_bo = malloc(sizeof(osmv_bind_obj_t));
216*d6b92ffaSHans Petter Selasky 	if (NULL == p_bo) {
217*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
218*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 7303: could not allocate the bind object\n");
219*d6b92ffaSHans Petter Selasky 		return OSM_BIND_INVALID_HANDLE;
220*d6b92ffaSHans Petter Selasky 	}
221*d6b92ffaSHans Petter Selasky 
222*d6b92ffaSHans Petter Selasky 	memset(p_bo, 0, sizeof(osmv_bind_obj_t));
223*d6b92ffaSHans Petter Selasky 	p_bo->p_vendor = p_vend;
224*d6b92ffaSHans Petter Selasky 	p_bo->recv_cb = mad_recv_callback;
225*d6b92ffaSHans Petter Selasky 	p_bo->send_err_cb = send_err_callback;
226*d6b92ffaSHans Petter Selasky 	p_bo->cb_context = context;
227*d6b92ffaSHans Petter Selasky 	p_bo->p_osm_pool = p_mad_pool;
228*d6b92ffaSHans Petter Selasky 
229*d6b92ffaSHans Petter Selasky 	/* obtain the hca name and port num from the guid */
230*d6b92ffaSHans Petter Selasky 	osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
231*d6b92ffaSHans Petter Selasky 		"osm_vendor_bind: "
232*d6b92ffaSHans Petter Selasky 		"Finding CA and Port that owns port guid 0x%" PRIx64 ".\n",
233*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_bind_info->port_guid));
234*d6b92ffaSHans Petter Selasky 
235*d6b92ffaSHans Petter Selasky 	status = osm_vendor_get_guid_ca_and_port(p_bo->p_vendor,
236*d6b92ffaSHans Petter Selasky 						 p_bind_info->port_guid,
237*d6b92ffaSHans Petter Selasky 						 &(p_bo->hca_hndl),
238*d6b92ffaSHans Petter Selasky 						 hca_id,
239*d6b92ffaSHans Petter Selasky 						 &hca_index, &(p_bo->port_num));
240*d6b92ffaSHans Petter Selasky 	if (status != IB_SUCCESS) {
241*d6b92ffaSHans Petter Selasky 		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
242*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 7304: "
243*d6b92ffaSHans Petter Selasky 			"Fail to find port number of port guid:0x%016" PRIx64
244*d6b92ffaSHans Petter Selasky 			"\n", p_bind_info->port_guid);
245*d6b92ffaSHans Petter Selasky 		free(p_bo);
246*d6b92ffaSHans Petter Selasky 		return OSM_BIND_INVALID_HANDLE;
247*d6b92ffaSHans Petter Selasky 	}
248*d6b92ffaSHans Petter Selasky 
249*d6b92ffaSHans Petter Selasky 	/* Initialize the magic_ptr to the pointer of the p_bo info.
250*d6b92ffaSHans Petter Selasky 	   This will be used to signal when the object is being destroyed, so no
251*d6b92ffaSHans Petter Selasky 	   real action will be done then. */
252*d6b92ffaSHans Petter Selasky 	p_bo->magic_ptr = p_bo;
253*d6b92ffaSHans Petter Selasky 
254*d6b92ffaSHans Petter Selasky 	p_bo->is_closing = FALSE;
255*d6b92ffaSHans Petter Selasky 
256*d6b92ffaSHans Petter Selasky 	cl_spinlock_construct(&(p_bo->lock));
257*d6b92ffaSHans Petter Selasky 	cl_st = cl_spinlock_init(&(p_bo->lock));
258*d6b92ffaSHans Petter Selasky 	if (cl_st != CL_SUCCESS) {
259*d6b92ffaSHans Petter Selasky 		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
260*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 7305: "
261*d6b92ffaSHans Petter Selasky 			"could not initialize the spinlock ...\n");
262*d6b92ffaSHans Petter Selasky 		free(p_bo);
263*d6b92ffaSHans Petter Selasky 		return OSM_BIND_INVALID_HANDLE;
264*d6b92ffaSHans Petter Selasky 	}
265*d6b92ffaSHans Petter Selasky 
266*d6b92ffaSHans Petter Selasky 	osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
267*d6b92ffaSHans Petter Selasky 		"osm_vendor_bind: osmv_txnmgr_init ... \n");
268*d6b92ffaSHans Petter Selasky 	if (osmv_txnmgr_init(&p_bo->txn_mgr, p_vend->p_log, &(p_bo->lock)) !=
269*d6b92ffaSHans Petter Selasky 	    IB_SUCCESS) {
270*d6b92ffaSHans Petter Selasky 		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
271*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 7306: "
272*d6b92ffaSHans Petter Selasky 			"osmv_txnmgr_init failed \n");
273*d6b92ffaSHans Petter Selasky 		cl_spinlock_destroy(&p_bo->lock);
274*d6b92ffaSHans Petter Selasky 		free(p_bo);
275*d6b92ffaSHans Petter Selasky 		return OSM_BIND_INVALID_HANDLE;
276*d6b92ffaSHans Petter Selasky 	}
277*d6b92ffaSHans Petter Selasky 
278*d6b92ffaSHans Petter Selasky 	/* Do the real job! (Transport-dependent) */
279*d6b92ffaSHans Petter Selasky 	if (IB_SUCCESS !=
280*d6b92ffaSHans Petter Selasky 	    osmv_transport_init(p_bind_info, hca_id, hca_index, p_bo)) {
281*d6b92ffaSHans Petter Selasky 		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
282*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 7307: "
283*d6b92ffaSHans Petter Selasky 			"osmv_transport_init failed \n");
284*d6b92ffaSHans Petter Selasky 		osmv_txnmgr_done((osm_bind_handle_t) p_bo);
285*d6b92ffaSHans Petter Selasky 		cl_spinlock_destroy(&p_bo->lock);
286*d6b92ffaSHans Petter Selasky 		free(p_bo);
287*d6b92ffaSHans Petter Selasky 		return OSM_BIND_INVALID_HANDLE;
288*d6b92ffaSHans Petter Selasky 	}
289*d6b92ffaSHans Petter Selasky 
290*d6b92ffaSHans Petter Selasky 	/* insert bind handle into db */
291*d6b92ffaSHans Petter Selasky 	p_obj = malloc(sizeof(cl_list_obj_t));
292*d6b92ffaSHans Petter Selasky 	if (NULL == p_obj) {
293*d6b92ffaSHans Petter Selasky 
294*d6b92ffaSHans Petter Selasky 		osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
295*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: ERR 7308: "
296*d6b92ffaSHans Petter Selasky 			"osm_vendor_bind: could not allocate the list object\n");
297*d6b92ffaSHans Petter Selasky 
298*d6b92ffaSHans Petter Selasky 		osmv_transport_done(p_bo->p_transp_mgr);
299*d6b92ffaSHans Petter Selasky 		osmv_txnmgr_done((osm_bind_handle_t) p_bo);
300*d6b92ffaSHans Petter Selasky 		cl_spinlock_destroy(&p_bo->lock);
301*d6b92ffaSHans Petter Selasky 		free(p_bo);
302*d6b92ffaSHans Petter Selasky 		return OSM_BIND_INVALID_HANDLE;
303*d6b92ffaSHans Petter Selasky 	}
304*d6b92ffaSHans Petter Selasky 	memset(p_obj, 0, sizeof(cl_list_obj_t));
305*d6b92ffaSHans Petter Selasky 	cl_qlist_set_obj(p_obj, p_bo);
306*d6b92ffaSHans Petter Selasky 
307*d6b92ffaSHans Petter Selasky 	cl_qlist_insert_head(&p_vend->bind_handles, &p_obj->list_item);
308*d6b92ffaSHans Petter Selasky 
309*d6b92ffaSHans Petter Selasky 	return (osm_bind_handle_t) p_bo;
310*d6b92ffaSHans Petter Selasky }
311*d6b92ffaSHans Petter Selasky 
312*d6b92ffaSHans Petter Selasky /*
313*d6b92ffaSHans Petter Selasky  *  NAME            osm_vendor_unbind
314*d6b92ffaSHans Petter Selasky  *
315*d6b92ffaSHans Petter Selasky  *  DESCRIPTION     Destroy the bind object and remove it from the vendor's list
316*d6b92ffaSHans Petter Selasky  */
317*d6b92ffaSHans Petter Selasky 
osm_vendor_unbind(IN osm_bind_handle_t h_bind)318*d6b92ffaSHans Petter Selasky void osm_vendor_unbind(IN osm_bind_handle_t h_bind)
319*d6b92ffaSHans Petter Selasky {
320*d6b92ffaSHans Petter Selasky 	osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
321*d6b92ffaSHans Petter Selasky 	osm_log_t *p_log = p_bo->p_vendor->p_log;
322*d6b92ffaSHans Petter Selasky 	cl_list_obj_t *p_obj = NULL;
323*d6b92ffaSHans Petter Selasky 	cl_list_item_t *p_item, *p_item_tmp;
324*d6b92ffaSHans Petter Selasky 	cl_qlist_t *const p_bh_list =
325*d6b92ffaSHans Petter Selasky 	    (cl_qlist_t * const)&p_bo->p_vendor->bind_handles;
326*d6b92ffaSHans Petter Selasky 
327*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
328*d6b92ffaSHans Petter Selasky 
329*d6b92ffaSHans Petter Selasky 	/* go over all the items in the list and remove the specific item */
330*d6b92ffaSHans Petter Selasky 	p_item = cl_qlist_head(p_bh_list);
331*d6b92ffaSHans Petter Selasky 	while (p_item != cl_qlist_end(p_bh_list)) {
332*d6b92ffaSHans Petter Selasky 		p_obj = PARENT_STRUCT(p_item, cl_list_obj_t, list_item);
333*d6b92ffaSHans Petter Selasky 		if (cl_qlist_obj(p_obj) == h_bind) {
334*d6b92ffaSHans Petter Selasky 			break;
335*d6b92ffaSHans Petter Selasky 		}
336*d6b92ffaSHans Petter Selasky 		p_item_tmp = cl_qlist_next(p_item);
337*d6b92ffaSHans Petter Selasky 		p_item = p_item_tmp;
338*d6b92ffaSHans Petter Selasky 	}
339*d6b92ffaSHans Petter Selasky 
340*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_item != cl_qlist_end(p_bh_list));
341*d6b92ffaSHans Petter Selasky 
342*d6b92ffaSHans Petter Selasky 	cl_qlist_remove_item(p_bh_list, p_item);
343*d6b92ffaSHans Petter Selasky 	if (p_obj)
344*d6b92ffaSHans Petter Selasky 		free(p_obj);
345*d6b92ffaSHans Petter Selasky 
346*d6b92ffaSHans Petter Selasky 	if (h_bind != 0) {
347*d6b92ffaSHans Petter Selasky 		__osm_vendor_internal_unbind(h_bind);
348*d6b92ffaSHans Petter Selasky 	}
349*d6b92ffaSHans Petter Selasky 
350*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
351*d6b92ffaSHans Petter Selasky }
352*d6b92ffaSHans Petter Selasky 
353*d6b92ffaSHans Petter Selasky /*
354*d6b92ffaSHans Petter Selasky  *  NAME            osm_vendor_get
355*d6b92ffaSHans Petter Selasky  *
356*d6b92ffaSHans Petter Selasky  *  DESCRIPTION     Allocate the space for a new MAD
357*d6b92ffaSHans Petter Selasky  */
358*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)359*d6b92ffaSHans Petter Selasky ib_mad_t *osm_vendor_get(IN osm_bind_handle_t h_bind,
360*d6b92ffaSHans Petter Selasky 			 IN const uint32_t mad_size,
361*d6b92ffaSHans Petter Selasky 			 IN osm_vend_wrap_t * const p_vw)
362*d6b92ffaSHans Petter Selasky {
363*d6b92ffaSHans Petter Selasky 	ib_mad_t *p_mad;
364*d6b92ffaSHans Petter Selasky 	osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
365*d6b92ffaSHans Petter Selasky 	osm_vendor_t const *p_vend = p_bo->p_vendor;
366*d6b92ffaSHans Petter Selasky 	uint32_t act_mad_size;
367*d6b92ffaSHans Petter Selasky 
368*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
369*d6b92ffaSHans Petter Selasky 
370*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_vw);
371*d6b92ffaSHans Petter Selasky 
372*d6b92ffaSHans Petter Selasky 	if (mad_size < MAD_BLOCK_SIZE) {
373*d6b92ffaSHans Petter Selasky 		/* Stupid, but the applications want that! */
374*d6b92ffaSHans Petter Selasky 		act_mad_size = MAD_BLOCK_SIZE;
375*d6b92ffaSHans Petter Selasky 	} else {
376*d6b92ffaSHans Petter Selasky 		act_mad_size = mad_size;
377*d6b92ffaSHans Petter Selasky 	}
378*d6b92ffaSHans Petter Selasky 
379*d6b92ffaSHans Petter Selasky 	/* allocate it */
380*d6b92ffaSHans Petter Selasky 	p_mad = (ib_mad_t *) malloc(act_mad_size);
381*d6b92ffaSHans Petter Selasky 	if (p_mad == NULL) {
382*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
383*d6b92ffaSHans Petter Selasky 			"osm_vendor_get: ERR 7309: "
384*d6b92ffaSHans Petter Selasky 			"Error Obtaining MAD buffer.\n");
385*d6b92ffaSHans Petter Selasky 		goto Exit;
386*d6b92ffaSHans Petter Selasky 	}
387*d6b92ffaSHans Petter Selasky 
388*d6b92ffaSHans Petter Selasky 	memset(p_mad, 0, act_mad_size);
389*d6b92ffaSHans Petter Selasky 
390*d6b92ffaSHans Petter Selasky 	if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
391*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_DEBUG,
392*d6b92ffaSHans Petter Selasky 			"osm_vendor_get: "
393*d6b92ffaSHans Petter Selasky 			"Allocated MAD %p, size = %u.\n", p_mad, act_mad_size);
394*d6b92ffaSHans Petter Selasky 	}
395*d6b92ffaSHans Petter Selasky 	p_vw->p_mad = p_mad;
396*d6b92ffaSHans Petter Selasky 
397*d6b92ffaSHans Petter Selasky Exit:
398*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
399*d6b92ffaSHans Petter Selasky 	return (p_mad);
400*d6b92ffaSHans Petter Selasky }
401*d6b92ffaSHans Petter Selasky 
402*d6b92ffaSHans Petter Selasky /*
403*d6b92ffaSHans Petter Selasky  *  NAME            osm_vendor_send
404*d6b92ffaSHans Petter Selasky  *
405*d6b92ffaSHans Petter Selasky  *  DESCRIPTION     Send a MAD buffer (RMPP or simple send).
406*d6b92ffaSHans Petter Selasky  *
407*d6b92ffaSHans Petter Selasky  *                  Semantics:
408*d6b92ffaSHans Petter Selasky  *                   (1) The RMPP send completes when every segment
409*d6b92ffaSHans Petter Selasky  *                       is acknowledged (synchronous)
410*d6b92ffaSHans Petter Selasky  *                   (2) The simple send completes when the send completion
411*d6b92ffaSHans Petter Selasky  *                       is received (asynchronous)
412*d6b92ffaSHans Petter Selasky  */
413*d6b92ffaSHans Petter Selasky 
414*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)415*d6b92ffaSHans Petter Selasky osm_vendor_send(IN osm_bind_handle_t h_bind,
416*d6b92ffaSHans Petter Selasky 		IN osm_madw_t * const p_madw, IN boolean_t const resp_expected)
417*d6b92ffaSHans Petter Selasky {
418*d6b92ffaSHans Petter Selasky 	ib_api_status_t ret = IB_SUCCESS;
419*d6b92ffaSHans Petter Selasky 	osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
420*d6b92ffaSHans Petter Selasky 	boolean_t is_rmpp = FALSE, is_rmpp_ds = FALSE;
421*d6b92ffaSHans Petter Selasky 	osmv_txn_ctx_t *p_txn = NULL;
422*d6b92ffaSHans Petter Selasky 	ib_mad_t *p_mad;
423*d6b92ffaSHans Petter Selasky 	osm_log_t *p_log = p_bo->p_vendor->p_log;
424*d6b92ffaSHans Petter Selasky 	osm_mad_pool_t *p_mad_pool = p_bo->p_osm_pool;
425*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
426*d6b92ffaSHans Petter Selasky 
427*d6b92ffaSHans Petter Selasky 	if (NULL == h_bind || NULL == p_madw ||
428*d6b92ffaSHans Petter Selasky 	    NULL == (p_mad = osm_madw_get_mad_ptr(p_madw)) ||
429*d6b92ffaSHans Petter Selasky 	    NULL == osm_madw_get_mad_addr_ptr(p_madw)) {
430*d6b92ffaSHans Petter Selasky 
431*d6b92ffaSHans Petter Selasky 		return IB_INVALID_PARAMETER;
432*d6b92ffaSHans Petter Selasky 	}
433*d6b92ffaSHans Petter Selasky 
434*d6b92ffaSHans Petter Selasky 	is_rmpp = (p_madw->mad_size > MAD_BLOCK_SIZE
435*d6b92ffaSHans Petter Selasky 		   || osmv_mad_is_rmpp(p_mad));
436*d6b92ffaSHans Petter Selasky 	/* is this rmpp double sided? This means we expect a response that can be
437*d6b92ffaSHans Petter Selasky 	   an rmpp or not */
438*d6b92ffaSHans Petter Selasky 	is_rmpp_ds = (TRUE == is_rmpp && TRUE == resp_expected);
439*d6b92ffaSHans Petter Selasky 
440*d6b92ffaSHans Petter Selasky 	/* Make our operations with the send context atomic */
441*d6b92ffaSHans Petter Selasky 	osmv_txn_lock(p_bo);
442*d6b92ffaSHans Petter Selasky 
443*d6b92ffaSHans Petter Selasky 	if (TRUE == p_bo->is_closing) {
444*d6b92ffaSHans Petter Selasky 
445*d6b92ffaSHans Petter Selasky 		osm_log(p_log, OSM_LOG_ERROR,
446*d6b92ffaSHans Petter Selasky 			"osm_vendor_send: ERR 7310: "
447*d6b92ffaSHans Petter Selasky 			"The handle %p is being unbound, cannot send.\n",
448*d6b92ffaSHans Petter Selasky 			h_bind);
449*d6b92ffaSHans Petter Selasky 		ret = IB_INTERRUPTED;
450*d6b92ffaSHans Petter Selasky 		/* When closing p_bo could be detroyed or is going to , thus could not refer to it */
451*d6b92ffaSHans Petter Selasky 		goto send_done;
452*d6b92ffaSHans Petter Selasky 	}
453*d6b92ffaSHans Petter Selasky 
454*d6b92ffaSHans Petter Selasky 	if (TRUE == resp_expected || TRUE == is_rmpp) {
455*d6b92ffaSHans Petter Selasky 
456*d6b92ffaSHans Petter Selasky 		/* We must run under a transaction framework.
457*d6b92ffaSHans Petter Selasky 		 * Get the transaction object (old or new) */
458*d6b92ffaSHans Petter Selasky 		ret = __osmv_get_send_txn(h_bind, p_madw, is_rmpp,
459*d6b92ffaSHans Petter Selasky 					  resp_expected, &p_txn);
460*d6b92ffaSHans Petter Selasky 		if (IB_SUCCESS != ret) {
461*d6b92ffaSHans Petter Selasky 			goto send_done;
462*d6b92ffaSHans Petter Selasky 		}
463*d6b92ffaSHans Petter Selasky 	}
464*d6b92ffaSHans Petter Selasky 
465*d6b92ffaSHans Petter Selasky 	if (TRUE == is_rmpp) {
466*d6b92ffaSHans Petter Selasky 		/* Do the job - RMPP!
467*d6b92ffaSHans Petter Selasky 		 * The call returns as all the packets are ACK'ed/upon error
468*d6b92ffaSHans Petter Selasky 		 * The txn lock will be released each time the function sleeps
469*d6b92ffaSHans Petter Selasky 		 * and re-acquired when it wakes up
470*d6b92ffaSHans Petter Selasky 		 */
471*d6b92ffaSHans Petter Selasky 		ret = osmv_rmpp_send_madw(h_bind, p_madw, p_txn, is_rmpp_ds);
472*d6b92ffaSHans Petter Selasky 	} else {
473*d6b92ffaSHans Petter Selasky 
474*d6b92ffaSHans Petter Selasky 		/* Do the job - single MAD!
475*d6b92ffaSHans Petter Selasky 		 * The call returns as soon as the MAD is put on the wire
476*d6b92ffaSHans Petter Selasky 		 */
477*d6b92ffaSHans Petter Selasky 		ret = osmv_simple_send_madw(h_bind, p_madw, p_txn, FALSE);
478*d6b92ffaSHans Petter Selasky 	}
479*d6b92ffaSHans Petter Selasky 
480*d6b92ffaSHans Petter Selasky 	if (IB_SUCCESS == ret) {
481*d6b92ffaSHans Petter Selasky 
482*d6b92ffaSHans Petter Selasky 		if ((TRUE == is_rmpp) && (FALSE == is_rmpp_ds)) {
483*d6b92ffaSHans Petter Selasky 			/* For double-sided sends, the txn continues to live */
484*d6b92ffaSHans Petter Selasky 			osmv_txn_done(h_bind, osmv_txn_get_key(p_txn),
485*d6b92ffaSHans Petter Selasky 				      FALSE /*not in callback */ );
486*d6b92ffaSHans Petter Selasky 		}
487*d6b92ffaSHans Petter Selasky 
488*d6b92ffaSHans Petter Selasky 		if (FALSE == resp_expected) {
489*d6b92ffaSHans Petter Selasky 			osm_mad_pool_put(p_mad_pool, p_madw);
490*d6b92ffaSHans Petter Selasky 		}
491*d6b92ffaSHans Petter Selasky 	} else if (IB_INTERRUPTED != ret) {
492*d6b92ffaSHans Petter Selasky 		if (NULL != p_txn) {
493*d6b92ffaSHans Petter Selasky 			osmv_txn_done(h_bind, osmv_txn_get_key(p_txn),
494*d6b92ffaSHans Petter Selasky 				      FALSE /*not in callback */ );
495*d6b92ffaSHans Petter Selasky 		}
496*d6b92ffaSHans Petter Selasky 
497*d6b92ffaSHans Petter Selasky 		osm_log(p_log, OSM_LOG_ERROR,
498*d6b92ffaSHans Petter Selasky 			"osm_vendor_send: ERR 7311: failed to send MADW %p\n",
499*d6b92ffaSHans Petter Selasky 			p_madw);
500*d6b92ffaSHans Petter Selasky 
501*d6b92ffaSHans Petter Selasky 		if (TRUE == resp_expected) {
502*d6b92ffaSHans Petter Selasky 			/* Change the status on the p_madw */
503*d6b92ffaSHans Petter Selasky 			p_madw->status = ret;
504*d6b92ffaSHans Petter Selasky 			/* Only the requester expects the error callback */
505*d6b92ffaSHans Petter Selasky 			p_bo->send_err_cb(p_bo->cb_context, p_madw);
506*d6b92ffaSHans Petter Selasky 		} else {
507*d6b92ffaSHans Petter Selasky 			/* put back the mad - it is useless ... */
508*d6b92ffaSHans Petter Selasky 			osm_mad_pool_put(p_mad_pool, p_madw);
509*d6b92ffaSHans Petter Selasky 		}
510*d6b92ffaSHans Petter Selasky 	} else {		/* the transaction was aborted due to p_bo exit */
511*d6b92ffaSHans Petter Selasky 
512*d6b92ffaSHans Petter Selasky 		osm_mad_pool_put(p_mad_pool, p_madw);
513*d6b92ffaSHans Petter Selasky 		goto aborted;
514*d6b92ffaSHans Petter Selasky 	}
515*d6b92ffaSHans Petter Selasky send_done:
516*d6b92ffaSHans Petter Selasky 
517*d6b92ffaSHans Petter Selasky 	osmv_txn_unlock(p_bo);
518*d6b92ffaSHans Petter Selasky aborted:
519*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
520*d6b92ffaSHans Petter Selasky 	return ret;
521*d6b92ffaSHans Petter Selasky }
522*d6b92ffaSHans Petter Selasky 
523*d6b92ffaSHans Petter Selasky /*
524*d6b92ffaSHans Petter Selasky  *  NAME            osm_vendor_put
525*d6b92ffaSHans Petter Selasky  *
526*d6b92ffaSHans Petter Selasky  *  DESCRIPTION     Free the MAD's memory
527*d6b92ffaSHans Petter Selasky  */
528*d6b92ffaSHans Petter Selasky 
529*d6b92ffaSHans Petter Selasky void
osm_vendor_put(IN osm_bind_handle_t h_bind,IN osm_vend_wrap_t * const p_vw)530*d6b92ffaSHans Petter Selasky osm_vendor_put(IN osm_bind_handle_t h_bind, IN osm_vend_wrap_t * const p_vw)
531*d6b92ffaSHans Petter Selasky {
532*d6b92ffaSHans Petter Selasky 
533*d6b92ffaSHans Petter Selasky 	osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
534*d6b92ffaSHans Petter Selasky 	osm_vendor_t const *p_vend = p_bo->p_vendor;
535*d6b92ffaSHans Petter Selasky 
536*d6b92ffaSHans Petter Selasky 	if (p_bo->is_closing != TRUE) {
537*d6b92ffaSHans Petter Selasky 		OSM_LOG_ENTER(p_vend->p_log);
538*d6b92ffaSHans Petter Selasky 
539*d6b92ffaSHans Petter Selasky 		CL_ASSERT(p_vw);
540*d6b92ffaSHans Petter Selasky 		CL_ASSERT(p_vw->p_mad);
541*d6b92ffaSHans Petter Selasky 
542*d6b92ffaSHans Petter Selasky 		if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
543*d6b92ffaSHans Petter Selasky 			osm_log(p_vend->p_log, OSM_LOG_DEBUG,
544*d6b92ffaSHans Petter Selasky 				"osm_vendor_put: " "Retiring MAD %p.\n",
545*d6b92ffaSHans Petter Selasky 				p_vw->p_mad);
546*d6b92ffaSHans Petter Selasky 		}
547*d6b92ffaSHans Petter Selasky 
548*d6b92ffaSHans Petter Selasky 		free(p_vw->p_mad);
549*d6b92ffaSHans Petter Selasky 		p_vw->p_mad = NULL;
550*d6b92ffaSHans Petter Selasky 
551*d6b92ffaSHans Petter Selasky 		OSM_LOG_EXIT(p_vend->p_log);
552*d6b92ffaSHans Petter Selasky 	}
553*d6b92ffaSHans Petter Selasky }
554*d6b92ffaSHans Petter Selasky 
555*d6b92ffaSHans Petter Selasky /*
556*d6b92ffaSHans Petter Selasky  *  NAME            osm_vendor_local_lid_change
557*d6b92ffaSHans Petter Selasky  *
558*d6b92ffaSHans Petter Selasky  *  DESCRIPTION     Notifies the vendor transport layer that the local address
559*d6b92ffaSHans Petter Selasky  *                  has changed.  This allows the vendor layer to perform
560*d6b92ffaSHans Petter Selasky  *                  housekeeping functions such as address vector updates.
561*d6b92ffaSHans Petter Selasky  */
562*d6b92ffaSHans Petter Selasky 
osm_vendor_local_lid_change(IN osm_bind_handle_t h_bind)563*d6b92ffaSHans Petter Selasky ib_api_status_t osm_vendor_local_lid_change(IN osm_bind_handle_t h_bind)
564*d6b92ffaSHans Petter Selasky {
565*d6b92ffaSHans Petter Selasky 	osm_vendor_t const *p_vend = ((osmv_bind_obj_t *) h_bind)->p_vendor;
566*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
567*d6b92ffaSHans Petter Selasky 
568*d6b92ffaSHans Petter Selasky 	osm_log(p_vend->p_log, OSM_LOG_DEBUG,
569*d6b92ffaSHans Petter Selasky 		"osm_vendor_local_lid_change: " "Change of LID.\n");
570*d6b92ffaSHans Petter Selasky 
571*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
572*d6b92ffaSHans Petter Selasky 
573*d6b92ffaSHans Petter Selasky 	return (IB_SUCCESS);
574*d6b92ffaSHans Petter Selasky 
575*d6b92ffaSHans Petter Selasky }
576*d6b92ffaSHans Petter Selasky 
577*d6b92ffaSHans Petter Selasky /*
578*d6b92ffaSHans Petter Selasky  *  NAME            osm_vendor_set_sm
579*d6b92ffaSHans Petter Selasky  *
580*d6b92ffaSHans Petter Selasky  *  DESCRIPTION     Modifies the port info for the bound port to set the "IS_SM" bit
581*d6b92ffaSHans Petter Selasky  *                  according to the value given (TRUE or FALSE).
582*d6b92ffaSHans Petter Selasky  */
583*d6b92ffaSHans Petter Selasky #if !(defined(OSM_VENDOR_INTF_TS_NO_VAPI) || defined(OSM_VENDOR_INTF_SIM) || defined(OSM_VENDOR_INTF_TS))
osm_vendor_set_sm(IN osm_bind_handle_t h_bind,IN boolean_t is_sm_val)584*d6b92ffaSHans Petter Selasky void osm_vendor_set_sm(IN osm_bind_handle_t h_bind, IN boolean_t is_sm_val)
585*d6b92ffaSHans Petter Selasky {
586*d6b92ffaSHans Petter Selasky 	osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
587*d6b92ffaSHans Petter Selasky 	osm_vendor_t const *p_vend = p_bo->p_vendor;
588*d6b92ffaSHans Petter Selasky 	VAPI_ret_t status;
589*d6b92ffaSHans Petter Selasky 	VAPI_hca_attr_t attr_mod;
590*d6b92ffaSHans Petter Selasky 	VAPI_hca_attr_mask_t attr_mask;
591*d6b92ffaSHans Petter Selasky 
592*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_vend->p_log);
593*d6b92ffaSHans Petter Selasky 
594*d6b92ffaSHans Petter Selasky 	memset(&attr_mod, 0, sizeof(attr_mod));
595*d6b92ffaSHans Petter Selasky 	memset(&attr_mask, 0, sizeof(attr_mask));
596*d6b92ffaSHans Petter Selasky 
597*d6b92ffaSHans Petter Selasky 	attr_mod.is_sm = is_sm_val;
598*d6b92ffaSHans Petter Selasky 	attr_mask = HCA_ATTR_IS_SM;
599*d6b92ffaSHans Petter Selasky 
600*d6b92ffaSHans Petter Selasky 	status =
601*d6b92ffaSHans Petter Selasky 	    VAPI_modify_hca_attr(p_bo->hca_hndl, p_bo->port_num, &attr_mod,
602*d6b92ffaSHans Petter Selasky 				 &attr_mask);
603*d6b92ffaSHans Petter Selasky 	if (status != VAPI_OK) {
604*d6b92ffaSHans Petter Selasky 		osm_log(p_vend->p_log, OSM_LOG_ERROR,
605*d6b92ffaSHans Petter Selasky 			"osm_vendor_set_sm: ERR 7312: "
606*d6b92ffaSHans Petter Selasky 			"Unable set 'IS_SM' bit to:%u in port attributes (%d).\n",
607*d6b92ffaSHans Petter Selasky 			is_sm_val, status);
608*d6b92ffaSHans Petter Selasky 	}
609*d6b92ffaSHans Petter Selasky 
610*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_vend->p_log);
611*d6b92ffaSHans Petter Selasky }
612*d6b92ffaSHans Petter Selasky 
613*d6b92ffaSHans Petter Selasky #endif
614*d6b92ffaSHans Petter Selasky 
615*d6b92ffaSHans Petter Selasky /*
616*d6b92ffaSHans Petter Selasky  *  NAME            __osm_vendor_internal_unbind
617*d6b92ffaSHans Petter Selasky  *
618*d6b92ffaSHans Petter Selasky  *  DESCRIPTION     Destroying a bind:
619*d6b92ffaSHans Petter Selasky  *                    (1) Wait for the completion of the sends in flight
620*d6b92ffaSHans Petter Selasky  *                    (2) Destroy the associated data structures
621*d6b92ffaSHans Petter Selasky  */
622*d6b92ffaSHans Petter Selasky 
__osm_vendor_internal_unbind(osm_bind_handle_t h_bind)623*d6b92ffaSHans Petter Selasky static void __osm_vendor_internal_unbind(osm_bind_handle_t h_bind)
624*d6b92ffaSHans Petter Selasky {
625*d6b92ffaSHans Petter Selasky 	osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
626*d6b92ffaSHans Petter Selasky 	osm_log_t *p_log = p_bo->p_vendor->p_log;
627*d6b92ffaSHans Petter Selasky 
628*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
629*d6b92ffaSHans Petter Selasky 
630*d6b92ffaSHans Petter Selasky 	/* "notifying" all that from now on no new sends can be done */
631*d6b92ffaSHans Petter Selasky 	p_bo->txn_mgr.p_event_wheel->closing = TRUE;
632*d6b92ffaSHans Petter Selasky 
633*d6b92ffaSHans Petter Selasky 	osmv_txn_lock(p_bo);
634*d6b92ffaSHans Petter Selasky 
635*d6b92ffaSHans Petter Selasky 	/*
636*d6b92ffaSHans Petter Selasky 	   the is_closing is set under lock we we know we only need to
637*d6b92ffaSHans Petter Selasky 	   check for it after obtaining the lock
638*d6b92ffaSHans Petter Selasky 	 */
639*d6b92ffaSHans Petter Selasky 	p_bo->is_closing = TRUE;
640*d6b92ffaSHans Petter Selasky 
641*d6b92ffaSHans Petter Selasky 	/* notifying all sleeping rmpp sends to exit */
642*d6b92ffaSHans Petter Selasky 	osmv_txn_abort_rmpp_txns(h_bind);
643*d6b92ffaSHans Petter Selasky 
644*d6b92ffaSHans Petter Selasky 	/* unlock the bo to allow for any residual mads to be dispatched */
645*d6b92ffaSHans Petter Selasky 	osmv_txn_unlock(p_bo);
646*d6b92ffaSHans Petter Selasky 	osm_log(p_log, OSM_LOG_DEBUG,
647*d6b92ffaSHans Petter Selasky 		"__osm_vendor_internal_unbind: destroying transport mgr.. \n");
648*d6b92ffaSHans Petter Selasky 	/* wait for the receiver thread to exit */
649*d6b92ffaSHans Petter Selasky 	osmv_transport_done(h_bind);
650*d6b92ffaSHans Petter Selasky 
651*d6b92ffaSHans Petter Selasky 	/* lock to avoid any collissions while we cleanup the structs */
652*d6b92ffaSHans Petter Selasky 	osmv_txn_lock(p_bo);
653*d6b92ffaSHans Petter Selasky 	osm_log(p_log, OSM_LOG_DEBUG,
654*d6b92ffaSHans Petter Selasky 		"__osm_vendor_internal_unbind: destroying txn mgr.. \n");
655*d6b92ffaSHans Petter Selasky 	osmv_txnmgr_done(h_bind);
656*d6b92ffaSHans Petter Selasky 	osm_log(p_log, OSM_LOG_DEBUG,
657*d6b92ffaSHans Petter Selasky 		"__osm_vendor_internal_unbind: destroying bind lock.. \n");
658*d6b92ffaSHans Petter Selasky 	osmv_txn_unlock(p_bo);
659*d6b92ffaSHans Petter Selasky 
660*d6b92ffaSHans Petter Selasky 	/*
661*d6b92ffaSHans Petter Selasky 	   we intentionally let the p_bo and its lock leak -
662*d6b92ffaSHans Petter Selasky 	   as we did not implement a way to track active bind handles provided to
663*d6b92ffaSHans Petter Selasky 	   the client - and the client might use them
664*d6b92ffaSHans Petter Selasky 
665*d6b92ffaSHans Petter Selasky 	   cl_spinlock_destroy(&p_bo->lock);
666*d6b92ffaSHans Petter Selasky 	   free(p_bo);
667*d6b92ffaSHans Petter Selasky 	 */
668*d6b92ffaSHans Petter Selasky 
669*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
670*d6b92ffaSHans Petter Selasky }
671*d6b92ffaSHans Petter Selasky 
672*d6b92ffaSHans Petter Selasky /*
673*d6b92ffaSHans Petter Selasky  *  NAME            __osmv_get_send_txn
674*d6b92ffaSHans Petter Selasky  *
675*d6b92ffaSHans Petter Selasky  *  DESCRIPTION     Return a transaction object that corresponds to this MAD.
676*d6b92ffaSHans Petter Selasky  *                  Optionally, create it, if the new request (query) is sent or received.
677*d6b92ffaSHans Petter Selasky  */
678*d6b92ffaSHans Petter Selasky 
679*d6b92ffaSHans Petter Selasky static ib_api_status_t
__osmv_get_send_txn(IN osm_bind_handle_t h_bind,IN osm_madw_t * const p_madw,IN boolean_t is_rmpp,IN boolean_t resp_expected,OUT osmv_txn_ctx_t ** pp_txn)680*d6b92ffaSHans Petter Selasky __osmv_get_send_txn(IN osm_bind_handle_t h_bind,
681*d6b92ffaSHans Petter Selasky 		    IN osm_madw_t * const p_madw,
682*d6b92ffaSHans Petter Selasky 		    IN boolean_t is_rmpp,
683*d6b92ffaSHans Petter Selasky 		    IN boolean_t resp_expected, OUT osmv_txn_ctx_t ** pp_txn)
684*d6b92ffaSHans Petter Selasky {
685*d6b92ffaSHans Petter Selasky 	ib_api_status_t ret;
686*d6b92ffaSHans Petter Selasky 	uint64_t tid, key;
687*d6b92ffaSHans Petter Selasky 	osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
688*d6b92ffaSHans Petter Selasky 	ib_mad_t *p_mad = osm_madw_get_mad_ptr(p_madw);
689*d6b92ffaSHans Petter Selasky 
690*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_bo->p_vendor->p_log);
691*d6b92ffaSHans Petter Selasky 	CL_ASSERT(NULL != pp_txn);
692*d6b92ffaSHans Petter Selasky 
693*d6b92ffaSHans Petter Selasky 	key = tid = cl_ntoh64(p_mad->trans_id);
694*d6b92ffaSHans Petter Selasky 	if (TRUE == resp_expected) {
695*d6b92ffaSHans Petter Selasky 		/* Create a unique identifier at the requester side */
696*d6b92ffaSHans Petter Selasky 		key = osmv_txn_uniq_key(tid);
697*d6b92ffaSHans Petter Selasky 	}
698*d6b92ffaSHans Petter Selasky 
699*d6b92ffaSHans Petter Selasky 	/* We must run under a transaction framework */
700*d6b92ffaSHans Petter Selasky 	ret = osmv_txn_lookup(h_bind, key, pp_txn);
701*d6b92ffaSHans Petter Selasky 	if (IB_NOT_FOUND == ret) {
702*d6b92ffaSHans Petter Selasky 		/* Generally, we start a new transaction */
703*d6b92ffaSHans Petter Selasky 		ret = osmv_txn_init(h_bind, tid, key, pp_txn);
704*d6b92ffaSHans Petter Selasky 		if (IB_SUCCESS != ret) {
705*d6b92ffaSHans Petter Selasky 			osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
706*d6b92ffaSHans Petter Selasky 				"__osmv_get_send_txn: ERR 7313: "
707*d6b92ffaSHans Petter Selasky 				"The transaction id=0x%" PRIx64 " failed to init.\n",
708*d6b92ffaSHans Petter Selasky 				tid);
709*d6b92ffaSHans Petter Selasky 			goto get_send_txn_done;
710*d6b92ffaSHans Petter Selasky 		}
711*d6b92ffaSHans Petter Selasky 	} else {
712*d6b92ffaSHans Petter Selasky 		CL_ASSERT(NULL != *pp_txn);
713*d6b92ffaSHans Petter Selasky 		/* The transaction context exists.
714*d6b92ffaSHans Petter Selasky 		 * This is legal only if I am going to return an
715*d6b92ffaSHans Petter Selasky 		 * (RMPP?) reply to an RMPP request sent by the other part
716*d6b92ffaSHans Petter Selasky 		 * (double-sided RMPP transfer)
717*d6b92ffaSHans Petter Selasky 		 */
718*d6b92ffaSHans Petter Selasky 		if (FALSE == is_rmpp
719*d6b92ffaSHans Petter Selasky 		    || FALSE == osmv_txn_is_rmpp_init_by_peer(*pp_txn)) {
720*d6b92ffaSHans Petter Selasky 			osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
721*d6b92ffaSHans Petter Selasky 				"__osmv_get_send_txn: ERR 7314: "
722*d6b92ffaSHans Petter Selasky 				"The transaction id=0x%" PRIx64 " is not unique. Send failed.\n",
723*d6b92ffaSHans Petter Selasky 				tid);
724*d6b92ffaSHans Petter Selasky 
725*d6b92ffaSHans Petter Selasky 			ret = IB_INVALID_SETTING;
726*d6b92ffaSHans Petter Selasky 			goto get_send_txn_done;
727*d6b92ffaSHans Petter Selasky 		}
728*d6b92ffaSHans Petter Selasky 
729*d6b92ffaSHans Petter Selasky 		if (TRUE == resp_expected) {
730*d6b92ffaSHans Petter Selasky 			osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
731*d6b92ffaSHans Petter Selasky 				"__osmv_get_send_txn: ERR 7315: "
732*d6b92ffaSHans Petter Selasky 				"The transaction id=0x%" PRIx64 " can't expect a response. Send failed.\n",
733*d6b92ffaSHans Petter Selasky 				tid);
734*d6b92ffaSHans Petter Selasky 
735*d6b92ffaSHans Petter Selasky 			ret = IB_INVALID_PARAMETER;
736*d6b92ffaSHans Petter Selasky 			goto get_send_txn_done;
737*d6b92ffaSHans Petter Selasky 		}
738*d6b92ffaSHans Petter Selasky 	}
739*d6b92ffaSHans Petter Selasky 
740*d6b92ffaSHans Petter Selasky 	if (TRUE == is_rmpp) {
741*d6b92ffaSHans Petter Selasky 		ret = osmv_txn_init_rmpp_sender(h_bind, *pp_txn, p_madw);
742*d6b92ffaSHans Petter Selasky 		if (IB_SUCCESS != ret) {
743*d6b92ffaSHans Petter Selasky 			osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
744*d6b92ffaSHans Petter Selasky 				"__osmv_get_send_txn: ERR 7316: "
745*d6b92ffaSHans Petter Selasky 				"The transaction id=0x%" PRIx64 " failed to init the rmpp mad. Send failed.\n",
746*d6b92ffaSHans Petter Selasky 				tid);
747*d6b92ffaSHans Petter Selasky 			osmv_txn_done(h_bind, tid, FALSE);
748*d6b92ffaSHans Petter Selasky 			goto get_send_txn_done;
749*d6b92ffaSHans Petter Selasky 		}
750*d6b92ffaSHans Petter Selasky 	}
751*d6b92ffaSHans Petter Selasky 
752*d6b92ffaSHans Petter Selasky 	/* Save a reference to the MAD in the txn context
753*d6b92ffaSHans Petter Selasky 	 * We'll need to match it in two cases:
754*d6b92ffaSHans Petter Selasky 	 *  (1) When the response is returned, if I am the requester
755*d6b92ffaSHans Petter Selasky 	 *  (2) In RMPP retransmissions
756*d6b92ffaSHans Petter Selasky 	 */
757*d6b92ffaSHans Petter Selasky 	osmv_txn_set_madw(*pp_txn, p_madw);
758*d6b92ffaSHans Petter Selasky 
759*d6b92ffaSHans Petter Selasky get_send_txn_done:
760*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_bo->p_vendor->p_log);
761*d6b92ffaSHans Petter Selasky 
762*d6b92ffaSHans Petter Selasky 	return ret;
763*d6b92ffaSHans Petter Selasky }
764*d6b92ffaSHans Petter Selasky 
osm_vendor_set_debug(IN osm_vendor_t * const p_vend,IN int32_t level)765*d6b92ffaSHans Petter Selasky void osm_vendor_set_debug(IN osm_vendor_t * const p_vend, IN int32_t level)
766*d6b92ffaSHans Petter Selasky {
767*d6b92ffaSHans Petter Selasky 
768*d6b92ffaSHans Petter Selasky }
769