|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* This software is available to you under a choice of one of two
|
|
Packit Service |
54dbc3 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit Service |
54dbc3 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit Service |
54dbc3 |
* COPYING in the main directory of this source tree, or the
|
|
Packit Service |
54dbc3 |
* OpenIB.org BSD license below:
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* Redistribution and use in source and binary forms, with or
|
|
Packit Service |
54dbc3 |
* without modification, are permitted provided that the following
|
|
Packit Service |
54dbc3 |
* conditions are met:
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* - Redistributions of source code must retain the above
|
|
Packit Service |
54dbc3 |
* copyright notice, this list of conditions and the following
|
|
Packit Service |
54dbc3 |
* disclaimer.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* - Redistributions in binary form must reproduce the above
|
|
Packit Service |
54dbc3 |
* copyright notice, this list of conditions and the following
|
|
Packit Service |
54dbc3 |
* disclaimer in the documentation and/or other materials
|
|
Packit Service |
54dbc3 |
* provided with the distribution.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit Service |
54dbc3 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit Service |
54dbc3 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit Service |
54dbc3 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit Service |
54dbc3 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit Service |
54dbc3 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit Service |
54dbc3 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit Service |
54dbc3 |
* SOFTWARE.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#undef __init
|
|
Packit Service |
54dbc3 |
#if HAVE_CONFIG_H
|
|
Packit Service |
54dbc3 |
# include <config.h>
|
|
Packit Service |
54dbc3 |
#endif /* HAVE_CONFIG_H */
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#include <stdlib.h>
|
|
Packit Service |
54dbc3 |
#include <string.h>
|
|
Packit Service |
54dbc3 |
#include <vendor/osm_vendor_ts.h>
|
|
Packit Service |
54dbc3 |
#include <vendor/osm_vendor_api.h>
|
|
Packit Service |
54dbc3 |
#include <vendor/osm_ts_useraccess.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_subnet.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_opensm.h>
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Since a race can accure on requests. Meaning - a response is received before
|
|
Packit Service |
54dbc3 |
the send_callback is called - we will save both the madw_p and the fact
|
|
Packit Service |
54dbc3 |
whether or not it is a response. A race can occure only on requests that did
|
|
Packit Service |
54dbc3 |
not fail, and then the madw_p will be put back in the pool before the
|
|
Packit Service |
54dbc3 |
callback.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
uint64_t __osm_set_wrid_by_p_madw(IN osm_madw_t * p_madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
uint64_t wrid = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_madw->p_mad);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memcpy(&wrid, &p_madw, sizeof(osm_madw_t *));
|
|
Packit Service |
54dbc3 |
wrid = (wrid << 1) |
|
|
Packit Service |
54dbc3 |
ib_mad_is_response(p_madw->p_mad);
|
|
Packit Service |
54dbc3 |
return wrid;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void
|
|
Packit Service |
54dbc3 |
__osm_set_p_madw_and_resp_by_wrid(IN uint64_t wrid,
|
|
Packit Service |
54dbc3 |
OUT uint8_t * is_resp,
|
|
Packit Service |
54dbc3 |
OUT osm_madw_t ** pp_madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
*is_resp = wrid & 0x0000000000000001;
|
|
Packit Service |
54dbc3 |
wrid = wrid >> 1;
|
|
Packit Service |
54dbc3 |
memcpy(pp_madw, &wrid, sizeof(osm_madw_t *));
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
* TS MAD to OSM ADDRESS VECTOR
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
void
|
|
Packit Service |
54dbc3 |
__osm_ts_conv_mad_rcv_desc_to_osm_addr(IN osm_vendor_t * const p_vend,
|
|
Packit Service |
54dbc3 |
IN struct ib_mad *p_mad,
|
|
Packit Service |
54dbc3 |
IN uint8_t is_smi,
|
|
Packit Service |
54dbc3 |
OUT osm_mad_addr_t * p_mad_addr)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
p_mad_addr->dest_lid = cl_hton16(p_mad->slid);
|
|
Packit Service |
54dbc3 |
p_mad_addr->static_rate = 0; /* HACK - we do not know the rate ! */
|
|
Packit Service |
54dbc3 |
p_mad_addr->path_bits = 0; /* HACK - no way to know in TS */
|
|
Packit Service |
54dbc3 |
if (is_smi) {
|
|
Packit Service |
54dbc3 |
/* SMI */
|
|
Packit Service |
54dbc3 |
p_mad_addr->addr_type.smi.source_lid = cl_hton16(p_mad->slid);
|
|
Packit Service |
54dbc3 |
p_mad_addr->addr_type.smi.port_num = p_mad->port;
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
/* GSI */
|
|
Packit Service |
54dbc3 |
p_mad_addr->addr_type.gsi.remote_qp = p_mad->sqpn;
|
|
Packit Service |
54dbc3 |
p_mad_addr->addr_type.gsi.remote_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
|
|
Packit Service |
54dbc3 |
p_mad_addr->addr_type.gsi.pkey_ix = p_mad->pkey_index;
|
|
Packit Service |
54dbc3 |
p_mad_addr->addr_type.gsi.service_level = 0; /* HACK no way to know */
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_mad_addr->addr_type.gsi.global_route = FALSE; /* HACK no way to know */
|
|
Packit Service |
54dbc3 |
/* copy the GRH data if relevant */
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
if (p_mad_addr->addr_type.gsi.global_route)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
p_mad_addr->addr_type.gsi.grh_info.ver_class_flow =
|
|
Packit Service |
54dbc3 |
ib_grh_set_ver_class_flow(p_rcv_desc->grh.IP_version,
|
|
Packit Service |
54dbc3 |
p_rcv_desc->grh.traffic_class,
|
|
Packit Service |
54dbc3 |
p_rcv_desc->grh.flow_label);
|
|
Packit Service |
54dbc3 |
p_mad_addr->addr_type.gsi.grh_info.hop_limit = p_rcv_desc->grh.hop_limit;
|
|
Packit Service |
54dbc3 |
memcpy(&p_mad_addr->addr_type.gsi.grh_info.src_gid.raw,
|
|
Packit Service |
54dbc3 |
&p_rcv_desc->grh.sgid, sizeof(ib_net64_t));
|
|
Packit Service |
54dbc3 |
memcpy(&p_mad_addr->addr_type.gsi.grh_info.dest_gid.raw,
|
|
Packit Service |
54dbc3 |
p_rcv_desc->grh.dgid, sizeof(ib_net64_t));
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
* OSM ADDR VECTOR TO TS MAD:
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
void
|
|
Packit Service |
54dbc3 |
__osm_ts_conv_osm_addr_to_ts_addr(IN osm_mad_addr_t * p_mad_addr,
|
|
Packit Service |
54dbc3 |
IN uint8_t is_smi, OUT struct ib_mad *p_mad)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* For global destination or Multicast address: */
|
|
Packit Service |
54dbc3 |
p_mad->dlid = cl_ntoh16(p_mad_addr->dest_lid);
|
|
Packit Service |
54dbc3 |
p_mad->sl = 0;
|
|
Packit Service |
54dbc3 |
if (is_smi) {
|
|
Packit Service |
54dbc3 |
p_mad->sqpn = 0;
|
|
Packit Service |
54dbc3 |
p_mad->dqpn = 0;
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
p_mad->sqpn = 1;
|
|
Packit Service |
54dbc3 |
p_mad->dqpn = p_mad_addr->addr_type.gsi.remote_qp;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void __osm_vendor_clear_sm(IN osm_bind_handle_t h_bind)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
|
|
Packit Service |
54dbc3 |
osm_vendor_t *p_vend = p_bind->p_vend;
|
|
Packit Service |
54dbc3 |
VAPI_ret_t status;
|
|
Packit Service |
54dbc3 |
VAPI_hca_attr_t attr_mod;
|
|
Packit Service |
54dbc3 |
VAPI_hca_attr_mask_t attr_mask;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memset(&attr_mod, 0, sizeof(attr_mod));
|
|
Packit Service |
54dbc3 |
memset(&attr_mask, 0, sizeof(attr_mask));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
attr_mod.is_sm = FALSE;
|
|
Packit Service |
54dbc3 |
attr_mask = HCA_ATTR_IS_SM;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status =
|
|
Packit Service |
54dbc3 |
VAPI_modify_hca_attr(p_bind->hca_hndl, p_bind->port_num, &attr_mod,
|
|
Packit Service |
54dbc3 |
&attr_mask);
|
|
Packit Service |
54dbc3 |
if (status != VAPI_OK) {
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"__osm_vendor_clear_sm: ERR 5021: "
|
|
Packit Service |
54dbc3 |
"Unable set 'IS_SM' bit in port attributes (%d).\n",
|
|
Packit Service |
54dbc3 |
status);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
* ANY CONSTRUCTION OF THE osm_vendor_t OBJECT
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
void osm_vendor_construct(IN osm_vendor_t * const p_vend)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
memset(p_vend, 0, sizeof(*p_vend));
|
|
Packit Service |
54dbc3 |
cl_thread_construct(&(p_vend->smi_bind.poller));
|
|
Packit Service |
54dbc3 |
cl_thread_construct(&(p_vend->gsi_bind.poller));
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
* DEALOCATE osm_vendor_t
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
void osm_vendor_destroy(IN osm_vendor_t * const p_vend)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
osm_transaction_mgr_destroy(p_vend);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* Destroy the poller threads */
|
|
Packit Service |
54dbc3 |
/* HACK: can you destroy an un-initialized thread ? */
|
|
Packit Service |
54dbc3 |
pthread_cancel(p_vend->smi_bind.poller.osd.id);
|
|
Packit Service |
54dbc3 |
pthread_cancel(p_vend->gsi_bind.poller.osd.id);
|
|
Packit Service |
54dbc3 |
cl_thread_destroy(&(p_vend->smi_bind.poller));
|
|
Packit Service |
54dbc3 |
cl_thread_destroy(&(p_vend->gsi_bind.poller));
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
DEALLOCATE A POINTER TO osm_vendor_t
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
void osm_vendor_delete(IN osm_vendor_t ** const pp_vend)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
CL_ASSERT(pp_vend);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_vendor_destroy(*pp_vend);
|
|
Packit Service |
54dbc3 |
free(*pp_vend);
|
|
Packit Service |
54dbc3 |
*pp_vend = NULL;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
Initializes the vendor:
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ib_api_status_t
|
|
Packit Service |
54dbc3 |
osm_vendor_init(IN osm_vendor_t * const p_vend,
|
|
Packit Service |
54dbc3 |
IN osm_log_t * const p_log, IN const uint32_t timeout)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_vend->p_log = p_log;
|
|
Packit Service |
54dbc3 |
p_vend->p_transaction_mgr = NULL;
|
|
Packit Service |
54dbc3 |
osm_transaction_mgr_init(p_vend);
|
|
Packit Service |
54dbc3 |
p_vend->timeout = timeout;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* we use the file handle to track the binding */
|
|
Packit Service |
54dbc3 |
p_vend->smi_bind.ul_dev_fd = -1;
|
|
Packit Service |
54dbc3 |
p_vend->gsi_bind.ul_dev_fd = -1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return (status);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
* Create and Initialize osm_vendor_t Object
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
osm_vendor_t *osm_vendor_new(IN osm_log_t * const p_log,
|
|
Packit Service |
54dbc3 |
IN const uint32_t timeout)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_api_status_t status;
|
|
Packit Service |
54dbc3 |
osm_vendor_t *p_vend;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_vend = malloc(sizeof(*p_vend));
|
|
Packit Service |
54dbc3 |
if (p_vend != NULL) {
|
|
Packit Service |
54dbc3 |
memset(p_vend, 0, sizeof(*p_vend));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = osm_vendor_init(p_vend, p_log, timeout);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS) {
|
|
Packit Service |
54dbc3 |
osm_vendor_delete(&p_vend);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"osm_vendor_new: ERR 5007: "
|
|
Packit Service |
54dbc3 |
"Fail to allocate vendor object.\n");
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return (p_vend);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
* TS RCV Thread callback
|
|
Packit Service |
54dbc3 |
* HACK: - we need to make this support arbitrary size mads.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
void
|
|
Packit Service |
54dbc3 |
__osm_ts_rcv_callback(IN osm_ts_bind_info_t * p_bind,
|
|
Packit Service |
54dbc3 |
IN osm_mad_addr_t * p_mad_addr,
|
|
Packit Service |
54dbc3 |
IN uint32_t mad_size, IN void *p_mad)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_api_status_t status;
|
|
Packit Service |
54dbc3 |
osm_madw_t *p_req_madw = NULL;
|
|
Packit Service |
54dbc3 |
osm_madw_t *p_madw;
|
|
Packit Service |
54dbc3 |
osm_vend_wrap_t *p_new_vw;
|
|
Packit Service |
54dbc3 |
ib_mad_t *p_mad_buf;
|
|
Packit Service |
54dbc3 |
osm_log_t *const p_log = p_bind->p_vend->p_log;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* if it is a response MAD we mustbe able to get the request */
|
|
Packit Service |
54dbc3 |
if (ib_mad_is_response((ib_mad_t *) p_mad)) {
|
|
Packit Service |
54dbc3 |
/* can we find a matching madw by this payload TID */
|
|
Packit Service |
54dbc3 |
status =
|
|
Packit Service |
54dbc3 |
osm_transaction_mgr_get_madw_for_tid(p_bind->p_vend,
|
|
Packit Service |
54dbc3 |
(ib_mad_t *) p_mad,
|
|
Packit Service |
54dbc3 |
&p_req_madw);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS) {
|
|
Packit Service |
54dbc3 |
osm_log(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"__osm_ts_rcv_callback: ERR 5008: "
|
|
Packit Service |
54dbc3 |
"Error obtaining request madw by TID (%d).\n",
|
|
Packit Service |
54dbc3 |
status);
|
|
Packit Service |
54dbc3 |
p_req_madw = NULL;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_req_madw == NULL) {
|
|
Packit Service |
54dbc3 |
osm_log(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"__osm_ts_rcv_callback: ERR 5009: "
|
|
Packit Service |
54dbc3 |
"Fail to obtain request madw for receined MAD. Aborting CB.\n");
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* do we have a request ??? */
|
|
Packit Service |
54dbc3 |
if (p_req_madw == NULL) {
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* if not - get new osm_madw and arrange it. */
|
|
Packit Service |
54dbc3 |
/* create the new madw in the pool */
|
|
Packit Service |
54dbc3 |
p_madw = osm_mad_pool_get(p_bind->p_osm_pool,
|
|
Packit Service |
54dbc3 |
(osm_bind_handle_t) p_bind,
|
|
Packit Service |
54dbc3 |
mad_size, p_mad_addr);
|
|
Packit Service |
54dbc3 |
if (p_madw == NULL) {
|
|
Packit Service |
54dbc3 |
osm_log(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"__osm_ts_rcv_callback: ERR 5010: "
|
|
Packit Service |
54dbc3 |
"Error request for a new madw.\n");
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
/* HACK: we cust to avoid the const ??? */
|
|
Packit Service |
54dbc3 |
p_mad_buf = (void *)p_madw->p_mad;
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
/* we have the madw defined during the send and stored in the vend_wrap */
|
|
Packit Service |
54dbc3 |
/* we need to make sure the wrapper is correctly init there */
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_req_madw->vend_wrap.p_resp_madw != 0);
|
|
Packit Service |
54dbc3 |
p_madw = p_req_madw->vend_wrap.p_resp_madw;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_madw->h_bind);
|
|
Packit Service |
54dbc3 |
p_mad_buf =
|
|
Packit Service |
54dbc3 |
osm_vendor_get(p_madw->h_bind, mad_size,
|
|
Packit Service |
54dbc3 |
&p_madw->vend_wrap);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (p_mad_buf == NULL) {
|
|
Packit Service |
54dbc3 |
osm_log(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"__osm_ts_rcv_callback: ERR 5011: "
|
|
Packit Service |
54dbc3 |
"Unable to acquire wire MAD.\n");
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Finally, attach the wire MAD to this wrapper.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
osm_madw_set_mad(p_madw, p_mad_buf);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* init some fields of the vendor wrapper */
|
|
Packit Service |
54dbc3 |
p_new_vw = osm_madw_get_vend_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
p_new_vw->h_bind = p_bind;
|
|
Packit Service |
54dbc3 |
p_new_vw->size = mad_size;
|
|
Packit Service |
54dbc3 |
p_new_vw->p_resp_madw = NULL;
|
|
Packit Service |
54dbc3 |
p_new_vw->p_mad_buf = p_mad_buf;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memcpy(p_new_vw->p_mad_buf, p_mad, mad_size);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* attach the buffer to the wrapper */
|
|
Packit Service |
54dbc3 |
p_madw->p_mad = p_mad_buf;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* we can also make sure we marked the size and bind on the returned madw */
|
|
Packit Service |
54dbc3 |
p_madw->h_bind = p_new_vw->h_bind;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* call the CB */
|
|
Packit Service |
54dbc3 |
(*(osm_vend_mad_recv_callback_t) p_bind->rcv_callback)
|
|
Packit Service |
54dbc3 |
(p_madw, p_bind->client_context, p_req_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
* TS Send callback : invoked after each send
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
void
|
|
Packit Service |
54dbc3 |
__osm_ts_send_callback(IN osm_ts_bind_info_t * bind_info_p,
|
|
Packit Service |
54dbc3 |
IN boolean_t is_resp,
|
|
Packit Service |
54dbc3 |
IN osm_madw_t * madw_p, IN IB_comp_status_t status)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *const p_log = bind_info_p->p_vend->p_log;
|
|
Packit Service |
54dbc3 |
osm_vend_wrap_t *p_vw;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_log(p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"__osm_ts_send_callback: INFO 1008: "
|
|
Packit Service |
54dbc3 |
"Handling Send of MADW:%p Is Resp:%d.\n", madw_p, is_resp);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* we need to handle requests and responses differently */
|
|
Packit Service |
54dbc3 |
if (is_resp) {
|
|
Packit Service |
54dbc3 |
if (status != IB_COMP_SUCCESS) {
|
|
Packit Service |
54dbc3 |
osm_log(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"__osm_ts_send_callback: ERR 5012: "
|
|
Packit Service |
54dbc3 |
"Error Sending Response MADW:%p.\n", madw_p);
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
osm_log(p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"__osm_ts_send_callback: DBG 1008: "
|
|
Packit Service |
54dbc3 |
"Completed Sending Response MADW:%p.\n",
|
|
Packit Service |
54dbc3 |
madw_p);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* if we are a response - we need to clean it up */
|
|
Packit Service |
54dbc3 |
osm_mad_pool_put(bind_info_p->p_osm_pool, madw_p);
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* this call back is invoked on completion of send - error or not */
|
|
Packit Service |
54dbc3 |
if (status != IB_COMP_SUCCESS) {
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_log(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"__osm_ts_send_callback: ERR 5013: "
|
|
Packit Service |
54dbc3 |
"Received an Error from IB_MGT Send (%d).\n",
|
|
Packit Service |
54dbc3 |
status);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_vw = osm_madw_get_vend_ptr(madw_p);
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_vw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
Return any wrappers to the pool that may have been
|
|
Packit Service |
54dbc3 |
pre-emptively allocated to handle a receive.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (p_vw->p_resp_madw) {
|
|
Packit Service |
54dbc3 |
osm_mad_pool_put(bind_info_p->p_osm_pool,
|
|
Packit Service |
54dbc3 |
p_vw->p_resp_madw);
|
|
Packit Service |
54dbc3 |
p_vw->p_resp_madw = NULL;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* invoke the CB */
|
|
Packit Service |
54dbc3 |
(*(osm_vend_mad_send_err_callback_t) bind_info_p->
|
|
Packit Service |
54dbc3 |
send_err_callback)
|
|
Packit Service |
54dbc3 |
(bind_info_p->client_context, madw_p);
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
/* successful request send - do nothing - the response will need the
|
|
Packit Service |
54dbc3 |
out mad */
|
|
Packit Service |
54dbc3 |
osm_log(p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"__osm_ts_send_callback: DBG 1008: "
|
|
Packit Service |
54dbc3 |
"Completed Sending Request MADW:%p.\n", madw_p);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
* Poller thread:
|
|
Packit Service |
54dbc3 |
* Always receive 256byte mads from the devcie file
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
void __osm_vendor_ts_poller(IN void *p_ptr)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
int ts_ret_code;
|
|
Packit Service |
54dbc3 |
struct ib_mad mad;
|
|
Packit Service |
54dbc3 |
osm_mad_addr_t mad_addr;
|
|
Packit Service |
54dbc3 |
osm_ts_bind_info_t *const p_bind = (osm_ts_bind_info_t *) p_ptr;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_bind->p_vend->p_log);
|
|
Packit Service |
54dbc3 |
/* we set the type of cancelation for this thread */
|
|
Packit Service |
54dbc3 |
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
while (1) {
|
|
Packit Service |
54dbc3 |
/* we read one mad at a time and pass it to the read callback function */
|
|
Packit Service |
54dbc3 |
ts_ret_code = read(p_bind->ul_dev_fd, &mad, sizeof(mad));
|
|
Packit Service |
54dbc3 |
if (ts_ret_code != sizeof(mad)) {
|
|
Packit Service |
54dbc3 |
osm_log(p_bind->p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"__osm_vendor_ts_poller: ERR 5003: "
|
|
Packit Service |
54dbc3 |
"error with read, bytes = %d, errno = %d\n",
|
|
Packit Service |
54dbc3 |
ts_ret_code, errno);
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
osm_log(p_bind->p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"__osm_vendor_ts_poller: "
|
|
Packit Service |
54dbc3 |
"MAD QPN:%d SLID:0x%04x class:0x%02x "
|
|
Packit Service |
54dbc3 |
"__osm_vendor_ts_poller:0x%02x attr:0x%04x status:0x%04x "
|
|
Packit Service |
54dbc3 |
"__osm_vendor_ts_poller:0x%016" PRIx64 "\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh32(mad.dqpn),
|
|
Packit Service |
54dbc3 |
cl_ntoh16(mad.slid),
|
|
Packit Service |
54dbc3 |
mad.mgmt_class,
|
|
Packit Service |
54dbc3 |
mad.r_method,
|
|
Packit Service |
54dbc3 |
cl_ntoh16(mad.attribute_id),
|
|
Packit Service |
54dbc3 |
cl_ntoh16(mad.status),
|
|
Packit Service |
54dbc3 |
cl_ntoh64(mad.transaction_id));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* first arrange an address */
|
|
Packit Service |
54dbc3 |
__osm_ts_conv_mad_rcv_desc_to_osm_addr(p_bind->p_vend,
|
|
Packit Service |
54dbc3 |
&mad,
|
|
Packit Service |
54dbc3 |
(((ib_mad_t *) &
|
|
Packit Service |
54dbc3 |
mad)->
|
|
Packit Service |
54dbc3 |
mgmt_class ==
|
|
Packit Service |
54dbc3 |
IB_MCLASS_SUBN_LID)
|
|
Packit Service |
54dbc3 |
||
|
|
Packit Service |
54dbc3 |
(((ib_mad_t *) &
|
|
Packit Service |
54dbc3 |
mad)->
|
|
Packit Service |
54dbc3 |
mgmt_class ==
|
|
Packit Service |
54dbc3 |
IB_MCLASS_SUBN_DIR),
|
|
Packit Service |
54dbc3 |
&mad_addr);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* call the receiver callback */
|
|
Packit Service |
54dbc3 |
/* HACK: this should be replaced with a call to the RMPP Assembly ... */
|
|
Packit Service |
54dbc3 |
__osm_ts_rcv_callback(p_bind, &mad_addr, 256, &mad;;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_bind->p_vend->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
* BINDs a callback (rcv and send error) for a given class and method
|
|
Packit Service |
54dbc3 |
* defined by the given: osm_bind_info_t
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
osm_bind_handle_t
|
|
Packit Service |
54dbc3 |
osm_vendor_bind(IN osm_vendor_t * const p_vend,
|
|
Packit Service |
54dbc3 |
IN osm_bind_info_t * const p_user_bind,
|
|
Packit Service |
54dbc3 |
IN osm_mad_pool_t * const p_mad_pool,
|
|
Packit Service |
54dbc3 |
IN osm_vend_mad_recv_callback_t mad_recv_callback,
|
|
Packit Service |
54dbc3 |
IN osm_vend_mad_send_err_callback_t send_err_callback,
|
|
Packit Service |
54dbc3 |
IN void *context)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_net64_t port_guid;
|
|
Packit Service |
54dbc3 |
osm_ts_bind_info_t *p_bind = NULL;
|
|
Packit Service |
54dbc3 |
VAPI_hca_hndl_t hca_hndl;
|
|
Packit Service |
54dbc3 |
VAPI_hca_id_t hca_id;
|
|
Packit Service |
54dbc3 |
uint32_t port_num;
|
|
Packit Service |
54dbc3 |
ib_api_status_t status;
|
|
Packit Service |
54dbc3 |
int device_fd;
|
|
Packit Service |
54dbc3 |
char device_file[16];
|
|
Packit Service |
54dbc3 |
osm_ts_user_mad_filter filter;
|
|
Packit Service |
54dbc3 |
int ts_ioctl_ret;
|
|
Packit Service |
54dbc3 |
int qpn;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_mad_pool);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
port_guid = p_user_bind->port_guid;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_INFO,
|
|
Packit Service |
54dbc3 |
"osm_vendor_bind: "
|
|
Packit Service |
54dbc3 |
"Binding to port 0x%" PRIx64 ".\n", cl_ntoh64(port_guid));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
switch (p_user_bind->mad_class) {
|
|
Packit Service |
54dbc3 |
case IB_MCLASS_SUBN_LID:
|
|
Packit Service |
54dbc3 |
case IB_MCLASS_SUBN_DIR:
|
|
Packit Service |
54dbc3 |
p_bind = &(p_vend->smi_bind);
|
|
Packit Service |
54dbc3 |
qpn = 0;
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
case IB_MCLASS_SUBN_ADM:
|
|
Packit Service |
54dbc3 |
default:
|
|
Packit Service |
54dbc3 |
p_bind = &(p_vend->gsi_bind);
|
|
Packit Service |
54dbc3 |
qpn = 1;
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* Make sure we did not previously opened the file */
|
|
Packit Service |
54dbc3 |
if (p_bind->ul_dev_fd >= 0) {
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"osm_vendor_bind: ERR 5004: "
|
|
Packit Service |
54dbc3 |
"Already binded to port %u\n", p_bind->port_num);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
We need to figure out what is the TS file name to attach to.
|
|
Packit Service |
54dbc3 |
I guess it is following the index of the port in the table of
|
|
Packit Service |
54dbc3 |
ports.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* obtain the hca name and port num from the guid */
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"osm_vendor_bind: "
|
|
Packit Service |
54dbc3 |
"Finding CA and Port that owns port guid 0x%" PRIx64 ".\n",
|
|
Packit Service |
54dbc3 |
cl_ntoh64(port_guid));
|
|
Packit Service |
54dbc3 |
status =
|
|
Packit Service |
54dbc3 |
osm_vendor_get_guid_ca_and_port(p_vend, port_guid, &hca_hndl,
|
|
Packit Service |
54dbc3 |
&hca_id, &port_num);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS) {
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"osm_vendor_bind: ERR 5005: "
|
|
Packit Service |
54dbc3 |
"Fail to find port number of port guid:0x%016" PRIx64
|
|
Packit Service |
54dbc3 |
"\n", port_guid);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* the file name is just /dev/ts_ua0: */
|
|
Packit Service |
54dbc3 |
strcpy(device_file, "/dev/ts_ua0");
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"osm_vendor_bind: " "Opening TS UL dev file:%s\n", device_file);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* Open the file ... */
|
|
Packit Service |
54dbc3 |
device_fd = open(device_file, O_RDWR);
|
|
Packit Service |
54dbc3 |
if (device_fd < 0) {
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"osm_vendor_bind: ERR 5006: "
|
|
Packit Service |
54dbc3 |
"Fail to open TS UL dev file:%s\n", device_file);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* track this bind request info */
|
|
Packit Service |
54dbc3 |
p_bind->ul_dev_fd = device_fd;
|
|
Packit Service |
54dbc3 |
p_bind->port_num = port_num;
|
|
Packit Service |
54dbc3 |
p_bind->p_vend = p_vend;
|
|
Packit Service |
54dbc3 |
p_bind->client_context = context;
|
|
Packit Service |
54dbc3 |
p_bind->rcv_callback = mad_recv_callback;
|
|
Packit Service |
54dbc3 |
p_bind->send_err_callback = send_err_callback;
|
|
Packit Service |
54dbc3 |
p_bind->p_osm_pool = p_mad_pool;
|
|
Packit Service |
54dbc3 |
p_bind->hca_hndl = hca_hndl;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Create the MAD filter on this file handle.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
filter.port = port_num;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
filter.qpn = qpn;
|
|
Packit Service |
54dbc3 |
filter.mgmt_class = p_user_bind->mad_class;
|
|
Packit Service |
54dbc3 |
filter.direction = TS_IB_MAD_DIRECTION_IN;
|
|
Packit Service |
54dbc3 |
filter.mask =
|
|
Packit Service |
54dbc3 |
TS_IB_MAD_FILTER_DIRECTION |
|
|
Packit Service |
54dbc3 |
TS_IB_MAD_FILTER_PORT |
|
|
Packit Service |
54dbc3 |
TS_IB_MAD_FILTER_QPN | TS_IB_MAD_FILTER_MGMT_CLASS;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ts_ioctl_ret = ioctl(device_fd, TS_IB_IOCSMADFILTADD, &filter);
|
|
Packit Service |
54dbc3 |
if (ts_ioctl_ret < 0) {
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"osm_vendor_bind: ERR 5014: "
|
|
Packit Service |
54dbc3 |
"Fail to register MAD filter with err:%u\n",
|
|
Packit Service |
54dbc3 |
ts_ioctl_ret);
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* Initialize the listener thread for this port */
|
|
Packit Service |
54dbc3 |
status = cl_thread_init(&p_bind->poller,
|
|
Packit Service |
54dbc3 |
__osm_vendor_ts_poller, p_bind,
|
|
Packit Service |
54dbc3 |
"osm ts poller");
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS)
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
return ((osm_bind_handle_t) p_bind);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
Get a mad from the lower level.
|
|
Packit Service |
54dbc3 |
The osm_vend_wrap_t is a wrapper used to connect the mad to the response.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
ib_mad_t *osm_vendor_get(IN osm_bind_handle_t h_bind,
|
|
Packit Service |
54dbc3 |
IN const uint32_t mad_size,
|
|
Packit Service |
54dbc3 |
IN osm_vend_wrap_t * const p_vw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
ib_mad_t *p_mad;
|
|
Packit Service |
54dbc3 |
osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
|
|
Packit Service |
54dbc3 |
osm_vendor_t *p_vend = p_bind->p_vend;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_vw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p_vw->size = mad_size;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* allocate it */
|
|
Packit Service |
54dbc3 |
p_mad = (ib_mad_t *) malloc(p_vw->size);
|
|
Packit Service |
54dbc3 |
if (p_mad == NULL) {
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"osm_vendor_get: ERR 5022: "
|
|
Packit Service |
54dbc3 |
"Error Obtaining MAD buffer.\n");
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memset(p_mad, 0, p_vw->size);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* track locally */
|
|
Packit Service |
54dbc3 |
p_vw->p_mad_buf = p_mad;
|
|
Packit Service |
54dbc3 |
p_vw->h_bind = h_bind;
|
|
Packit Service |
54dbc3 |
p_vw->p_resp_madw = NULL;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"osm_vendor_get: "
|
|
Packit Service |
54dbc3 |
"Acquired MAD %p, size = %u.\n", p_mad, p_vw->size);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
return (p_mad);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
* Return a MAD by providing it's wrapper object.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
void
|
|
Packit Service |
54dbc3 |
osm_vendor_put(IN osm_bind_handle_t h_bind, IN osm_vend_wrap_t * const p_vw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
|
|
Packit Service |
54dbc3 |
osm_vendor_t *p_vend = p_bind->p_vend;
|
|
Packit Service |
54dbc3 |
osm_madw_t *p_madw;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_vw);
|
|
Packit Service |
54dbc3 |
CL_ASSERT(p_vw->p_mad_buf);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (osm_log_get_level(p_vend->p_log) >= OSM_LOG_DEBUG) {
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"osm_vendor_put: " "Retiring MAD %p.\n",
|
|
Packit Service |
54dbc3 |
p_vw->p_mad_buf);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* We moved the removal of the transaction to immediatly after
|
|
Packit Service |
54dbc3 |
* it was looked up.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* free the mad but the wrapper is part of the madw object */
|
|
Packit Service |
54dbc3 |
free(p_vw->p_mad_buf);
|
|
Packit Service |
54dbc3 |
p_vw->p_mad_buf = NULL;
|
|
Packit Service |
54dbc3 |
p_madw = PARENT_STRUCT(p_vw, osm_madw_t, vend_wrap);
|
|
Packit Service |
54dbc3 |
p_madw->p_mad = NULL;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
Actually Send a MAD
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
MADs are buffers of type: struct ib_mad - so they are limited by size.
|
|
Packit Service |
54dbc3 |
This is for internal use by osm_vendor_send and the transaction mgr
|
|
Packit Service |
54dbc3 |
retry too.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
ib_api_status_t
|
|
Packit Service |
54dbc3 |
osm_ts_send_mad(IN osm_ts_bind_info_t * p_bind, IN osm_madw_t * const p_madw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_vendor_t *const p_vend = p_bind->p_vend;
|
|
Packit Service |
54dbc3 |
osm_mad_addr_t *const p_mad_addr = osm_madw_get_mad_addr_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
ib_mad_t *const p_mad = osm_madw_get_mad_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
struct ib_mad ts_mad;
|
|
Packit Service |
54dbc3 |
int ret;
|
|
Packit Service |
54dbc3 |
ib_api_status_t status;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Copy the MAD over to the sent mad
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
memcpy(&ts_mad, p_mad, 256);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* For all sends other than directed route SM MADs,
|
|
Packit Service |
54dbc3 |
* acquire an address vector for the destination.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (p_mad->mgmt_class != IB_MCLASS_SUBN_DIR) {
|
|
Packit Service |
54dbc3 |
__osm_ts_conv_osm_addr_to_ts_addr(p_mad_addr,
|
|
Packit Service |
54dbc3 |
p_mad->mgmt_class ==
|
|
Packit Service |
54dbc3 |
IB_MCLASS_SUBN_LID, &ts_mad);
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
/* is a directed route - we need to construct a permissive address */
|
|
Packit Service |
54dbc3 |
/* we do not need port number since it is part of the mad_hndl */
|
|
Packit Service |
54dbc3 |
ts_mad.dlid = IB_LID_PERMISSIVE;
|
|
Packit Service |
54dbc3 |
ts_mad.slid = IB_LID_PERMISSIVE;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
if ((p_mad->mgmt_class == IB_MCLASS_SUBN_DIR) ||
|
|
Packit Service |
54dbc3 |
(p_mad->mgmt_class == IB_MCLASS_SUBN_LID)) {
|
|
Packit Service |
54dbc3 |
ts_mad.sqpn = 0;
|
|
Packit Service |
54dbc3 |
ts_mad.dqpn = 0;
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
ts_mad.sqpn = 1;
|
|
Packit Service |
54dbc3 |
ts_mad.dqpn = 1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
ts_mad.port = p_bind->port_num;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* send it */
|
|
Packit Service |
54dbc3 |
ret = write(p_bind->ul_dev_fd, &ts_mad, sizeof(ts_mad));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (ret != sizeof(ts_mad)) {
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"osm_ts_send_mad: ERR 5026: "
|
|
Packit Service |
54dbc3 |
"Error sending mad (%d).\n", ret);
|
|
Packit Service |
54dbc3 |
status = IB_ERROR;
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status = IB_SUCCESS;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
return (status);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
Send a MAD through.
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
What is unclear to me is the need for the setting of all the MAD Wrapper
|
|
Packit Service |
54dbc3 |
fields. Seems like the OSM uses these values during it's processing...
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
ib_api_status_t
|
|
Packit Service |
54dbc3 |
osm_vendor_send(IN osm_bind_handle_t h_bind,
|
|
Packit Service |
54dbc3 |
IN osm_madw_t * const p_madw, IN boolean_t const resp_expected)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
|
|
Packit Service |
54dbc3 |
osm_vendor_t *const p_vend = p_bind->p_vend;
|
|
Packit Service |
54dbc3 |
osm_vend_wrap_t *const p_vw = osm_madw_get_vend_ptr(p_madw);
|
|
Packit Service |
54dbc3 |
ib_api_status_t status;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* If a response is expected to this MAD, then preallocate
|
|
Packit Service |
54dbc3 |
* a mad wrapper to contain the wire MAD received in the
|
|
Packit Service |
54dbc3 |
* response. Allocating a wrapper here allows for easier
|
|
Packit Service |
54dbc3 |
* failure paths than after we already received the wire mad.
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (resp_expected == TRUE) {
|
|
Packit Service |
54dbc3 |
/* we track it in the vendor wrapper */
|
|
Packit Service |
54dbc3 |
p_vw->p_resp_madw =
|
|
Packit Service |
54dbc3 |
osm_mad_pool_get_wrapper_raw(p_bind->p_osm_pool);
|
|
Packit Service |
54dbc3 |
if (p_vw->p_resp_madw == NULL) {
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"osm_vendor_send: ERR 5024: "
|
|
Packit Service |
54dbc3 |
"Unable to allocate MAD wrapper.\n");
|
|
Packit Service |
54dbc3 |
status = IB_INSUFFICIENT_RESOURCES;
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* put some minimal info on that wrapper */
|
|
Packit Service |
54dbc3 |
((osm_madw_t *) (p_vw->p_resp_madw))->h_bind = h_bind;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* we also want to track it in the TID based map */
|
|
Packit Service |
54dbc3 |
status = osm_transaction_mgr_insert_madw((osm_bind_handle_t *)
|
|
Packit Service |
54dbc3 |
p_bind, p_madw);
|
|
Packit Service |
54dbc3 |
if (status != IB_SUCCESS) {
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"osm_vendor_send: ERR 5025: "
|
|
Packit Service |
54dbc3 |
"Error inserting request madw by TID (%d).\n",
|
|
Packit Service |
54dbc3 |
status);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
} else
|
|
Packit Service |
54dbc3 |
p_vw->p_resp_madw = NULL;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* do the actual send */
|
|
Packit Service |
54dbc3 |
/* HACK: to be replaced by call to RMPP Segmentation */
|
|
Packit Service |
54dbc3 |
status = osm_ts_send_mad(p_bind, p_madw);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* we do not get an asycn callback so call it ourselves */
|
|
Packit Service |
54dbc3 |
/* this will handle all cleanup if neccessary */
|
|
Packit Service |
54dbc3 |
__osm_ts_send_callback(p_bind, !resp_expected, p_madw, status);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
return (status);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/**********************************************************************
|
|
Packit Service |
54dbc3 |
* the idea here is to change the content of the bind such that it
|
|
Packit Service |
54dbc3 |
* will hold the local address used for sending directed route by the SMA.
|
|
Packit Service |
54dbc3 |
**********************************************************************/
|
|
Packit Service |
54dbc3 |
ib_api_status_t osm_vendor_local_lid_change(IN osm_bind_handle_t h_bind)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_vendor_t *p_vend = ((osm_ts_bind_info_t *) h_bind)->p_vend;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"osm_vendor_local_lid_change: DEBUG 2202: " "Change of LID.\n");
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return (IB_SUCCESS);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void osm_vendor_set_sm(IN osm_bind_handle_t h_bind, IN boolean_t is_sm_val)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_ts_bind_info_t *p_bind = (osm_ts_bind_info_t *) h_bind;
|
|
Packit Service |
54dbc3 |
osm_vendor_t *p_vend = p_bind->p_vend;
|
|
Packit Service |
54dbc3 |
VAPI_ret_t status;
|
|
Packit Service |
54dbc3 |
VAPI_hca_attr_t attr_mod;
|
|
Packit Service |
54dbc3 |
VAPI_hca_attr_mask_t attr_mask;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
memset(&attr_mod, 0, sizeof(attr_mod));
|
|
Packit Service |
54dbc3 |
memset(&attr_mask, 0, sizeof(attr_mask));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
attr_mod.is_sm = is_sm_val;
|
|
Packit Service |
54dbc3 |
attr_mask = HCA_ATTR_IS_SM;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
status =
|
|
Packit Service |
54dbc3 |
VAPI_modify_hca_attr(p_bind->hca_hndl, p_bind->port_num, &attr_mod,
|
|
Packit Service |
54dbc3 |
&attr_mask);
|
|
Packit Service |
54dbc3 |
if (status != VAPI_OK) {
|
|
Packit Service |
54dbc3 |
osm_log(p_vend->p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"osm_vendor_set_sm: ERR 5027: "
|
|
Packit Service |
54dbc3 |
"Unable set 'IS_SM' bit to:%u in port attributes (%d).\n",
|
|
Packit Service |
54dbc3 |
is_sm_val, status);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_vend->p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
void osm_vendor_set_debug(IN osm_vendor_t * const p_vend, IN int32_t level)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
}
|