|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* This software is available to you under a choice of one of two
|
|
Packit |
13e616 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit |
13e616 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit |
13e616 |
* COPYING in the main directory of this source tree, or the
|
|
Packit |
13e616 |
* OpenIB.org BSD license below:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* Redistribution and use in source and binary forms, with or
|
|
Packit |
13e616 |
* without modification, are permitted provided that the following
|
|
Packit |
13e616 |
* conditions are met:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions of source code must retain the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions in binary form must reproduce the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer in the documentation and/or other materials
|
|
Packit |
13e616 |
* provided with the distribution.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
13e616 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
13e616 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
13e616 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
13e616 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
13e616 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
13e616 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
13e616 |
* SOFTWARE.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#if HAVE_CONFIG_H
|
|
Packit |
13e616 |
# include <config.h>
|
|
Packit |
13e616 |
#endif /* HAVE_CONFIG_H */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <sys/ioctl.h>
|
|
Packit |
13e616 |
#include <stdlib.h>
|
|
Packit |
13e616 |
#include <stddef.h>
|
|
Packit |
13e616 |
#include <sys/types.h>
|
|
Packit |
13e616 |
#include <sys/stat.h>
|
|
Packit |
13e616 |
#include <fcntl.h>
|
|
Packit |
13e616 |
#include <errno.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx_transport.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx_transport_anafa.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx_svc.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_mlx_sender.h>
|
|
Packit |
13e616 |
#include <vendor/osm_pkt_randomizer.h>
|
|
Packit |
13e616 |
#include <vendor/osm_ts_useraccess.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/**
|
|
Packit |
13e616 |
* FORWARD REFERENCES
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
static ib_api_status_t
|
|
Packit |
13e616 |
__osmv_get_send_txn(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN osm_madw_t * const p_madw,
|
|
Packit |
13e616 |
IN boolean_t is_rmpp,
|
|
Packit |
13e616 |
IN boolean_t resp_expected, OUT osmv_txn_ctx_t ** pp_txn);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void __osm_vendor_internal_unbind(osm_bind_handle_t h_bind);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME osm_vendor_new
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION Create and Initialize the osm_vendor_t Object
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_vendor_t *osm_vendor_new(IN osm_log_t * const p_log,
|
|
Packit |
13e616 |
IN const uint32_t timeout)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status;
|
|
Packit |
13e616 |
osm_vendor_t *p_vend;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_vend = malloc(sizeof(*p_vend));
|
|
Packit |
13e616 |
if (p_vend != NULL) {
|
|
Packit |
13e616 |
memset(p_vend, 0, sizeof(*p_vend));
|
|
Packit |
13e616 |
status = osm_vendor_init(p_vend, p_log, timeout);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS) {
|
|
Packit |
13e616 |
osm_vendor_delete(&p_vend);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osm_vendor_new: ERR 7401: "
|
|
Packit |
13e616 |
"Fail to allocate vendor object.\n");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
return (p_vend);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME osm_vendor_delete
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION Delete all the binds behind the vendor + free the vendor object
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_vendor_delete(IN osm_vendor_t ** const pp_vend)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_list_item_t *p_item;
|
|
Packit |
13e616 |
cl_list_obj_t *p_obj;
|
|
Packit |
13e616 |
osm_bind_handle_t bind_h;
|
|
Packit |
13e616 |
osm_log_t *p_log;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER((*pp_vend)->p_log);
|
|
Packit |
13e616 |
p_log = (*pp_vend)->p_log;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* go over the bind handles , unbind them and remove from list */
|
|
Packit |
13e616 |
/* Note that if we reached here due to problem in the init, then
|
|
Packit |
13e616 |
the bind_handles list is not initialized yet */
|
|
Packit |
13e616 |
if ((*pp_vend)->bind_handles.state == CL_INITIALIZED) {
|
|
Packit |
13e616 |
p_item = cl_qlist_remove_head(&((*pp_vend)->bind_handles));
|
|
Packit |
13e616 |
while (p_item != cl_qlist_end(&((*pp_vend)->bind_handles))) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_obj = PARENT_STRUCT(p_item, cl_list_obj_t, list_item);
|
|
Packit |
13e616 |
bind_h = (osm_bind_handle_t *) cl_qlist_obj(p_obj);
|
|
Packit |
13e616 |
osm_log(p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_vendor_delete: unbinding bind_h:%p \n",
|
|
Packit |
13e616 |
bind_h);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
__osm_vendor_internal_unbind(bind_h);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p_obj);
|
|
Packit |
13e616 |
/* removing from list */
|
|
Packit |
13e616 |
p_item =
|
|
Packit |
13e616 |
cl_qlist_remove_head(&((*pp_vend)->bind_handles));
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (NULL != ((*pp_vend)->p_transport_info)) {
|
|
Packit |
13e616 |
free((*pp_vend)->p_transport_info);
|
|
Packit |
13e616 |
(*pp_vend)->p_transport_info = NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* remove the packet randomizer object */
|
|
Packit |
13e616 |
if ((*pp_vend)->run_randomizer == TRUE)
|
|
Packit |
13e616 |
osm_pkt_randomizer_destroy(&((*pp_vend)->p_pkt_randomizer),
|
|
Packit |
13e616 |
p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(*pp_vend);
|
|
Packit |
13e616 |
*pp_vend = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME osm_vendor_init
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION Initialize the vendor object
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osm_vendor_init(IN osm_vendor_t * const p_vend,
|
|
Packit |
13e616 |
IN osm_log_t * const p_log, IN const uint32_t timeout)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit |
13e616 |
char device_file[16];
|
|
Packit |
13e616 |
int device_fd;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_vend->p_log = p_log;
|
|
Packit |
13e616 |
p_vend->resp_timeout = timeout;
|
|
Packit |
13e616 |
p_vend->ttime_timeout = timeout * OSMV_TXN_TIMEOUT_FACTOR;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_vend->p_transport_info = (osmv_TOPSPIN_ANAFA_transport_info_t *)
|
|
Packit |
13e616 |
malloc(sizeof(osmv_TOPSPIN_ANAFA_transport_info_t));
|
|
Packit |
13e616 |
if (!p_vend->p_transport_info) {
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p_vend->p_transport_info, 0,
|
|
Packit |
13e616 |
sizeof(osmv_TOPSPIN_ANAFA_transport_info_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* update the run_randomizer flag */
|
|
Packit |
13e616 |
if (getenv("OSM_PKT_DROP_RATE") != NULL
|
|
Packit |
13e616 |
&& atol(getenv("OSM_PKT_DROP_RATE")) != 0) {
|
|
Packit |
13e616 |
/* if the OSM_PKT_DROP_RATE global variable is defined
|
|
Packit |
13e616 |
to a non-zero value -
|
|
Packit |
13e616 |
then the randomizer should be called.
|
|
Packit |
13e616 |
Need to create the packet randomizer object */
|
|
Packit |
13e616 |
p_vend->run_randomizer = TRUE;
|
|
Packit |
13e616 |
status =
|
|
Packit |
13e616 |
osm_pkt_randomizer_init(&(p_vend->p_pkt_randomizer), p_log);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
p_vend->run_randomizer = FALSE;
|
|
Packit |
13e616 |
p_vend->p_pkt_randomizer = NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* open TopSpin file device */
|
|
Packit |
13e616 |
sprintf(device_file, "/dev/ts_ua0");
|
|
Packit |
13e616 |
device_fd = open("/dev/ts_ua0", O_RDWR);
|
|
Packit |
13e616 |
if (device_fd < 0) {
|
|
Packit |
13e616 |
fprintf(stderr, "Fatal: Fail to open the file:%s(%d)\n",
|
|
Packit |
13e616 |
device_file, errno);
|
|
Packit |
13e616 |
return IB_ERROR;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
((osmv_TOPSPIN_ANAFA_transport_info_t *) p_vend->p_transport_info)->
|
|
Packit |
13e616 |
device_fd = device_fd;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_qlist_init(&p_vend->bind_handles);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
return (IB_SUCCESS);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME osm_vendor_bind
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION Create a new bind object under the vendor object
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_bind_handle_t
|
|
Packit |
13e616 |
osm_vendor_bind(IN osm_vendor_t * const p_vend,
|
|
Packit |
13e616 |
IN osm_bind_info_t * const p_bind_info,
|
|
Packit |
13e616 |
IN osm_mad_pool_t * const p_mad_pool,
|
|
Packit |
13e616 |
IN osm_vend_mad_recv_callback_t mad_recv_callback,
|
|
Packit |
13e616 |
IN osm_vend_mad_send_err_callback_t send_err_callback,
|
|
Packit |
13e616 |
IN void *context)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo;
|
|
Packit |
13e616 |
cl_status_t cl_st;
|
|
Packit |
13e616 |
cl_list_obj_t *p_obj;
|
|
Packit |
13e616 |
uint8_t hca_idx = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (NULL == p_vend || NULL == p_bind_info || NULL == p_mad_pool
|
|
Packit |
13e616 |
|| NULL == mad_recv_callback || NULL == send_err_callback) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osm_vendor_bind: ERR 7402: "
|
|
Packit |
13e616 |
"NULL parameter passed in: p_vend=%p p_bind_info=%p p_mad_pool=%p recv_cb=%p send_err_cb=%p\n",
|
|
Packit |
13e616 |
p_vend, p_bind_info, p_mad_pool, mad_recv_callback,
|
|
Packit |
13e616 |
send_err_callback);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return OSM_BIND_INVALID_HANDLE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_bo = malloc(sizeof(osmv_bind_obj_t));
|
|
Packit |
13e616 |
if (NULL == p_bo) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osm_vendor_bind: ERR 7403: "
|
|
Packit |
13e616 |
"could not allocate the bind object\n");
|
|
Packit |
13e616 |
return OSM_BIND_INVALID_HANDLE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p_bo, 0, sizeof(osmv_bind_obj_t));
|
|
Packit |
13e616 |
p_bo->p_vendor = p_vend;
|
|
Packit |
13e616 |
p_bo->recv_cb = mad_recv_callback;
|
|
Packit |
13e616 |
p_bo->send_err_cb = send_err_callback;
|
|
Packit |
13e616 |
p_bo->cb_context = context;
|
|
Packit |
13e616 |
p_bo->p_osm_pool = p_mad_pool;
|
|
Packit |
13e616 |
p_bo->port_num = 1; /* anafa2 has one port */
|
|
Packit |
13e616 |
p_bo->hca_hndl = 0; /* only one ca on anafa system */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* obtain the hca name and port num from the guid */
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_vendor_bind: "
|
|
Packit |
13e616 |
"Finding CA and Port that owns port guid 0x%" PRIx64 ".\n",
|
|
Packit |
13e616 |
cl_ntoh64(p_bind_info->port_guid));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_bo->is_closing = FALSE;
|
|
Packit |
13e616 |
cl_spinlock_construct(&(p_bo->lock));
|
|
Packit |
13e616 |
cl_st = cl_spinlock_init(&(p_bo->lock));
|
|
Packit |
13e616 |
if (cl_st != CL_SUCCESS) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osm_vendor_bind: ERR 7405: "
|
|
Packit |
13e616 |
"could not initialize the spinlock ...\n");
|
|
Packit |
13e616 |
free(p_bo);
|
|
Packit |
13e616 |
return OSM_BIND_INVALID_HANDLE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_vendor_bind: osmv_txnmgr_init ... \n");
|
|
Packit |
13e616 |
if (osmv_txnmgr_init(&p_bo->txn_mgr, p_vend->p_log, &(p_bo->lock)) !=
|
|
Packit |
13e616 |
IB_SUCCESS) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osm_vendor_bind: ERR 7406: "
|
|
Packit |
13e616 |
"osmv_txnmgr_init failed \n");
|
|
Packit |
13e616 |
cl_spinlock_destroy(&p_bo->lock);
|
|
Packit |
13e616 |
free(p_bo);
|
|
Packit |
13e616 |
return OSM_BIND_INVALID_HANDLE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Do the real job! (Transport-dependent) */
|
|
Packit |
13e616 |
if (IB_SUCCESS !=
|
|
Packit |
13e616 |
osmv_transport_init(p_bind_info, OSMV_ANAFA_ID, hca_idx, p_bo)) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osm_vendor_bind: ERR 7407: "
|
|
Packit |
13e616 |
"osmv_transport_init failed \n");
|
|
Packit |
13e616 |
osmv_txnmgr_done((osm_bind_handle_t) p_bo);
|
|
Packit |
13e616 |
cl_spinlock_destroy(&p_bo->lock);
|
|
Packit |
13e616 |
free(p_bo);
|
|
Packit |
13e616 |
return OSM_BIND_INVALID_HANDLE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* insert bind handle into db */
|
|
Packit |
13e616 |
p_obj = malloc(sizeof(cl_list_obj_t));
|
|
Packit |
13e616 |
if (NULL == p_obj) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osm_vendor_bind: ERR 7408: "
|
|
Packit |
13e616 |
"osm_vendor_bind: could not allocate the list object\n");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osmv_transport_done(p_bo->p_transp_mgr);
|
|
Packit |
13e616 |
osmv_txnmgr_done((osm_bind_handle_t) p_bo);
|
|
Packit |
13e616 |
cl_spinlock_destroy(&p_bo->lock);
|
|
Packit |
13e616 |
free(p_bo);
|
|
Packit |
13e616 |
return OSM_BIND_INVALID_HANDLE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
if (p_obj)
|
|
Packit |
13e616 |
memset(p_obj, 0, sizeof(cl_list_obj_t));
|
|
Packit |
13e616 |
cl_qlist_set_obj(p_obj, p_bo);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_qlist_insert_head(&p_vend->bind_handles, &p_obj->list_item);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return (osm_bind_handle_t) p_bo;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME osm_vendor_unbind
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION Destroy the bind object and remove it from the vendor's list
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_vendor_unbind(IN osm_bind_handle_t h_bind)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
osm_log_t *p_log = p_bo->p_vendor->p_log;
|
|
Packit |
13e616 |
cl_list_obj_t *p_obj;
|
|
Packit |
13e616 |
cl_list_item_t *p_item, *p_item_tmp;
|
|
Packit |
13e616 |
cl_qlist_t *const p_bh_list =
|
|
Packit |
13e616 |
(cl_qlist_t * const)&p_bo->p_vendor->bind_handles;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* go over all the items in the list and remove the specific item */
|
|
Packit |
13e616 |
p_item = cl_qlist_head(&p_bo->p_vendor->bind_handles);
|
|
Packit |
13e616 |
while (p_item != cl_qlist_end(&p_bo->p_vendor->bind_handles)) {
|
|
Packit |
13e616 |
p_obj = PARENT_STRUCT(p_item, cl_list_obj_t, list_item);
|
|
Packit |
13e616 |
if (cl_qlist_obj(p_obj) == h_bind) {
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
p_item_tmp = cl_qlist_next(p_item);
|
|
Packit |
13e616 |
p_item = p_item_tmp;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_item != cl_qlist_end(p_bh_list));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_qlist_remove_item(p_bh_list, p_item);
|
|
Packit |
13e616 |
free(p_obj);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
__osm_vendor_internal_unbind(h_bind);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME osm_vendor_get
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION Allocate the space for a new MAD
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_mad_t *osm_vendor_get(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN const uint32_t mad_size,
|
|
Packit |
13e616 |
IN osm_vend_wrap_t * const p_vw)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_mad_t *p_mad;
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
osm_vendor_t const *p_vend = p_bo->p_vendor;
|
|
Packit |
13e616 |
uint32_t act_mad_size;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_vw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (mad_size < MAD_BLOCK_SIZE) {
|
|
Packit |
13e616 |
/* Stupid, but the applications want that! */
|
|
Packit |
13e616 |
act_mad_size = MAD_BLOCK_SIZE;
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
act_mad_size = mad_size;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* allocate it */
|
|
Packit |
13e616 |
p_mad = (ib_mad_t *) malloc(act_mad_size);
|
|
Packit |
13e616 |
if (p_mad == NULL) {
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osm_vendor_get: ERR 7409: "
|
|
Packit |
13e616 |
"Error Obtaining MAD buffer.\n");
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memset(p_mad, 0, act_mad_size);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_vendor_get: "
|
|
Packit |
13e616 |
"Allocated MAD %p, size = %u.\n", p_mad, act_mad_size);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
p_vw->p_mad = p_mad;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit |
13e616 |
return (p_mad);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME osm_vendor_send
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION Send a MAD buffer (RMPP or simple send).
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* Semantics:
|
|
Packit |
13e616 |
* (1) The RMPP send completes when every segment
|
|
Packit |
13e616 |
* is acknowledged (synchronous)
|
|
Packit |
13e616 |
* (2) The simple send completes when the send completion
|
|
Packit |
13e616 |
* is received (asynchronous)
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t
|
|
Packit |
13e616 |
osm_vendor_send(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN osm_madw_t * const p_madw, IN boolean_t const resp_expected)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t ret = IB_SUCCESS;
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
boolean_t is_rmpp = FALSE, is_rmpp_ds = FALSE;
|
|
Packit |
13e616 |
osmv_txn_ctx_t *p_txn = NULL;
|
|
Packit |
13e616 |
ib_mad_t *p_mad;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (NULL == h_bind || NULL == p_madw ||
|
|
Packit |
13e616 |
NULL == (p_mad = osm_madw_get_mad_ptr(p_madw)) ||
|
|
Packit |
13e616 |
NULL == osm_madw_get_mad_addr_ptr(p_madw)) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return IB_INVALID_PARAMETER;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
is_rmpp = (p_madw->mad_size > MAD_BLOCK_SIZE
|
|
Packit |
13e616 |
|| osmv_mad_is_rmpp(p_mad));
|
|
Packit |
13e616 |
is_rmpp_ds = (TRUE == is_rmpp && TRUE == resp_expected);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Make our operations with the send context atomic */
|
|
Packit |
13e616 |
osmv_txn_lock(p_bo);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (TRUE == p_bo->is_closing) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osm_vendor_send: ERR 7410: "
|
|
Packit |
13e616 |
"The handle %p is being unbound, cannot send.\n",
|
|
Packit |
13e616 |
h_bind);
|
|
Packit |
13e616 |
ret = IB_INTERRUPTED;
|
|
Packit |
13e616 |
goto send_done;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (TRUE == resp_expected || TRUE == is_rmpp) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* We must run under a transaction framework.
|
|
Packit |
13e616 |
* Get the transaction object (old or new) */
|
|
Packit |
13e616 |
ret = __osmv_get_send_txn(h_bind, p_madw, is_rmpp,
|
|
Packit |
13e616 |
resp_expected, &p_txn);
|
|
Packit |
13e616 |
if (IB_SUCCESS != ret) {
|
|
Packit |
13e616 |
goto send_done;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (TRUE == is_rmpp) {
|
|
Packit |
13e616 |
/* Do the job - RMPP!
|
|
Packit |
13e616 |
* The call returns as all the packets are ACK'ed/upon error
|
|
Packit |
13e616 |
* The txn lock will be released each time the function sleeps
|
|
Packit |
13e616 |
* and re-acquired when it wakes up
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
ret = osmv_rmpp_send_madw(h_bind, p_madw, p_txn, is_rmpp_ds);
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Do the job - single MAD!
|
|
Packit |
13e616 |
* The call returns as soon as the MAD is put on the wire
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
ret = osmv_simple_send_madw(h_bind, p_madw, p_txn, FALSE); /* anafa2 */
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (IB_SUCCESS == ret) {
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if ((TRUE == is_rmpp) && (FALSE == is_rmpp_ds)) {
|
|
Packit |
13e616 |
/* For double-sided sends, the txn continues to live */
|
|
Packit |
13e616 |
osmv_txn_done(h_bind, osmv_txn_get_key(p_txn),
|
|
Packit |
13e616 |
FALSE /*not in callback */ );
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (FALSE == resp_expected) {
|
|
Packit |
13e616 |
osm_mad_pool_put(p_bo->p_osm_pool, p_madw);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
if (NULL != p_txn) {
|
|
Packit |
13e616 |
osmv_txn_done(h_bind, osmv_txn_get_key(p_txn),
|
|
Packit |
13e616 |
FALSE /*not in callback */ );
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osm_vendor_send: ERR 7411: failed to send MADW %p\n",
|
|
Packit |
13e616 |
p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (TRUE == resp_expected) {
|
|
Packit |
13e616 |
/* Change the status on the p_madw */
|
|
Packit |
13e616 |
p_madw->status = ret;
|
|
Packit |
13e616 |
/* Only the requester expects the error callback */
|
|
Packit |
13e616 |
p_bo->send_err_cb(p_bo->cb_context, p_madw);
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
/* put back the mad - it is useless ... */
|
|
Packit |
13e616 |
osm_mad_pool_put(p_bo->p_osm_pool, p_madw);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
send_done:
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osmv_txn_unlock(p_bo);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
return ret;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME osm_vendor_put
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION Free the MAD's memory
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void
|
|
Packit |
13e616 |
osm_vendor_put(IN osm_bind_handle_t h_bind, IN osm_vend_wrap_t * const p_vw)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
osm_vendor_t const *p_vend = p_bo->p_vendor;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_vw);
|
|
Packit |
13e616 |
CL_ASSERT(p_vw->p_mad);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_vendor_put: " "Retiring MAD %p.\n", p_vw->p_mad);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
free(p_vw->p_mad);
|
|
Packit |
13e616 |
p_vw->p_mad = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME osm_vendor_local_lid_change
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION Notifies the vendor transport layer that the local address
|
|
Packit |
13e616 |
* has changed. This allows the vendor layer to perform
|
|
Packit |
13e616 |
* housekeeping functions such as address vector updates.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_vendor_local_lid_change(IN osm_bind_handle_t h_bind)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_vendor_t const *p_vend = ((osmv_bind_obj_t *) h_bind)->p_vendor;
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"osm_vendor_local_lid_change: " "Change of LID.\n");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return (IB_SUCCESS);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME osm_vendor_set_sm
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION Modifies the port info for the bound port to set the "IS_SM" bit.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_vendor_set_sm(IN osm_bind_handle_t h_bind, IN boolean_t is_sm_val)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
osm_vendor_t const *p_vend = p_bo->p_vendor;
|
|
Packit |
13e616 |
osmv_TOPSPIN_ANAFA_transport_mgr_t *p_mgr;
|
|
Packit |
13e616 |
int ioctl_ret;
|
|
Packit |
13e616 |
osm_ts_set_port_info_ioctl port_info;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
port_info.port = 0; /* anafa has only 1 port */
|
|
Packit |
13e616 |
port_info.port_info.valid_fields = IB_PORT_IS_SM;
|
|
Packit |
13e616 |
port_info.port_info.is_sm = is_sm_val;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_mgr = (osmv_TOPSPIN_ANAFA_transport_mgr_t *) p_bo->p_transp_mgr;
|
|
Packit |
13e616 |
ioctl_ret = ioctl(p_mgr->device_fd, TS_IB_IOCSPORTINFO, &port_info);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (ioctl_ret < 0) {
|
|
Packit |
13e616 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"osm_vendor_set_sm: ERR 7412: "
|
|
Packit |
13e616 |
"Unable set 'IS_SM' bit to:%u in port attributes (%d). errno=%d\n",
|
|
Packit |
13e616 |
is_sm_val, ioctl_ret, errno);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME __osm_vendor_internal_unbind
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION Destroying a bind:
|
|
Packit |
13e616 |
* (1) Wait for the completion of the sends in flight
|
|
Packit |
13e616 |
* (2) Destroy the associated data structures
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void __osm_vendor_internal_unbind(osm_bind_handle_t h_bind)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
osm_log_t *p_log = p_bo->p_vendor->p_log;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* "notifying" all that from now on no new sends can be done */
|
|
Packit |
13e616 |
p_bo->txn_mgr.p_event_wheel->closing = TRUE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osmv_txn_lock(p_bo);
|
|
Packit |
13e616 |
p_bo->is_closing = TRUE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* notifying all sleeping rmpp sends to exit */
|
|
Packit |
13e616 |
osmv_txn_abort_rmpp_txns(h_bind);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* frees all data in bind handle */
|
|
Packit |
13e616 |
osm_log(p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osm_vendor_internal_unbind: destroying transport mgr.. \n");
|
|
Packit |
13e616 |
osmv_txn_unlock(p_bo);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osmv_transport_done(h_bind);
|
|
Packit |
13e616 |
osm_log(p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osm_vendor_internal_unbind: destroying txn mgr.. \n");
|
|
Packit |
13e616 |
osmv_txn_lock(p_bo);
|
|
Packit |
13e616 |
osmv_txnmgr_done(h_bind);
|
|
Packit |
13e616 |
osm_log(p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"__osm_vendor_internal_unbind: destroying bind lock.. \n");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osmv_txn_unlock(p_bo);
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
we intentionally let the p_bo and its lock leak -
|
|
Packit |
13e616 |
as we did not implement a way to track active bind handles provided to
|
|
Packit |
13e616 |
the client - and the client might use them
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_spinlock_destroy(&p_bo->lock);
|
|
Packit |
13e616 |
free(p_bo);
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* NAME __osmv_get_send_txn
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION Return a transaction object that corresponds to this MAD.
|
|
Packit |
13e616 |
* Optionally, create it, if the new request (query) is sent or received.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static ib_api_status_t
|
|
Packit |
13e616 |
__osmv_get_send_txn(IN osm_bind_handle_t h_bind,
|
|
Packit |
13e616 |
IN osm_madw_t * const p_madw,
|
|
Packit |
13e616 |
IN boolean_t is_rmpp,
|
|
Packit |
13e616 |
IN boolean_t resp_expected, OUT osmv_txn_ctx_t ** pp_txn)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t ret;
|
|
Packit |
13e616 |
uint64_t tid, key;
|
|
Packit |
13e616 |
osmv_bind_obj_t *p_bo = (osmv_bind_obj_t *) h_bind;
|
|
Packit |
13e616 |
ib_mad_t *p_mad = osm_madw_get_mad_ptr(p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
CL_ASSERT(NULL != pp_txn);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
key = tid = cl_ntoh64(p_mad->trans_id);
|
|
Packit |
13e616 |
if (TRUE == resp_expected) {
|
|
Packit |
13e616 |
/* Create a unique identifier at the requester side */
|
|
Packit |
13e616 |
key = osmv_txn_uniq_key(tid);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* We must run under a transaction framework */
|
|
Packit |
13e616 |
ret = osmv_txn_lookup(h_bind, key, pp_txn);
|
|
Packit |
13e616 |
if (IB_NOT_FOUND == ret) {
|
|
Packit |
13e616 |
/* Generally, we start a new transaction */
|
|
Packit |
13e616 |
ret = osmv_txn_init(h_bind, tid, key, pp_txn);
|
|
Packit |
13e616 |
if (IB_SUCCESS != ret) {
|
|
Packit |
13e616 |
goto get_send_txn_done;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
CL_ASSERT(NULL != *pp_txn);
|
|
Packit |
13e616 |
/* The transaction context exists.
|
|
Packit |
13e616 |
* This is legal only if I am going to return an
|
|
Packit |
13e616 |
* (RMPP?) reply to an RMPP request sent by the other part
|
|
Packit |
13e616 |
* (double-sided RMPP transfer)
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (FALSE == is_rmpp
|
|
Packit |
13e616 |
|| FALSE == osmv_txn_is_rmpp_init_by_peer(*pp_txn)) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"__osmv_get_send_txn: ERR 7413: "
|
|
Packit |
13e616 |
"The transaction id=0x%llX is not unique. Send failed.\n",
|
|
Packit |
13e616 |
tid);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ret = IB_INVALID_SETTING;
|
|
Packit |
13e616 |
goto get_send_txn_done;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (TRUE == resp_expected) {
|
|
Packit |
13e616 |
osm_log(p_bo->p_vendor->p_log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"__osmv_get_send_txn: ERR 7414: "
|
|
Packit |
13e616 |
"The transaction id=%llX can\'t expect a response. Send failed.\n",
|
|
Packit |
13e616 |
tid);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ret = IB_INVALID_PARAMETER;
|
|
Packit |
13e616 |
goto get_send_txn_done;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (TRUE == is_rmpp) {
|
|
Packit |
13e616 |
ret = osmv_txn_init_rmpp_sender(h_bind, *pp_txn, p_madw);
|
|
Packit |
13e616 |
if (IB_SUCCESS != ret) {
|
|
Packit |
13e616 |
osmv_txn_done(h_bind, tid, FALSE);
|
|
Packit |
13e616 |
goto get_send_txn_done;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Save a reference to the MAD in the txn context
|
|
Packit |
13e616 |
* We'll need to match it in two cases:
|
|
Packit |
13e616 |
* (1) When the response is returned, if I am the requester
|
|
Packit |
13e616 |
* (2) In RMPP retransmissions
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
osmv_txn_set_madw(*pp_txn, p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
get_send_txn_done:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_bo->p_vendor->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return ret;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_vendor_set_debug(IN osm_vendor_t * const p_vend, IN int32_t level)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
}
|