Blame opensm/osm_req.c

Packit Service 54dbc3
/*
Packit Service 54dbc3
 * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
Packit Service 54dbc3
 * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved.
Packit Service 54dbc3
 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
Packit Service 54dbc3
 * Copyright (c) 2009 HNR Consulting. 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
/*
Packit Service 54dbc3
 * Abstract:
Packit Service 54dbc3
 *    Implementation of osm_req_t.
Packit Service 54dbc3
 * This object represents the generic attribute requester.
Packit Service 54dbc3
 * This object is part of the opensm family of objects.
Packit Service 54dbc3
 */
Packit Service 54dbc3
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 <string.h>
Packit Service 54dbc3
#include <iba/ib_types.h>
Packit Service 54dbc3
#include <complib/cl_debug.h>
Packit Service 54dbc3
#include <opensm/osm_file_ids.h>
Packit Service 54dbc3
#define FILE_ID OSM_FILE_REQ_C
Packit Service 54dbc3
#include <opensm/osm_madw.h>
Packit Service 54dbc3
#include <opensm/osm_log.h>
Packit Service 54dbc3
#include <opensm/osm_helper.h>
Packit Service 54dbc3
#include <opensm/osm_mad_pool.h>
Packit Service 54dbc3
#include <opensm/osm_vl15intf.h>
Packit Service 54dbc3
#include <opensm/osm_msgdef.h>
Packit Service 54dbc3
#include <opensm/osm_opensm.h>
Packit Service 54dbc3
#include <opensm/osm_db_pack.h>
Packit Service 54dbc3
Packit Service 54dbc3
/**********************************************************************
Packit Service 54dbc3
  The plock must be held before calling this function.
Packit Service 54dbc3
**********************************************************************/
Packit Service 54dbc3
static ib_net64_t req_determine_mkey(IN osm_sm_t * sm,
Packit Service 54dbc3
				     IN const osm_dr_path_t * p_path)
Packit Service 54dbc3
{
Packit Service 54dbc3
	osm_node_t *p_node;
Packit Service 54dbc3
	osm_port_t *p_sm_port;
Packit Service 54dbc3
	osm_physp_t *p_physp;
Packit Service 54dbc3
	ib_net64_t dest_port_guid = 0, m_key;
Packit Service 54dbc3
	uint8_t hop;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(sm->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	p_physp = NULL;
Packit Service 54dbc3
Packit Service 54dbc3
	p_sm_port = osm_get_port_by_guid(sm->p_subn, sm->p_subn->sm_port_guid);
Packit Service 54dbc3
Packit Service 54dbc3
	/* hop_count == 0: destination port guid is SM */
Packit Service 54dbc3
	if (p_path->hop_count == 0) {
Packit Service 54dbc3
		dest_port_guid = sm->p_subn->sm_port_guid;
Packit Service 54dbc3
		goto Remote_Guid;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	if (p_sm_port) {
Packit Service 54dbc3
		p_node = p_sm_port->p_node;
Packit Service 54dbc3
		if (osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH)
Packit Service 54dbc3
			p_physp = osm_node_get_physp_ptr(p_node, p_path->path[1]);
Packit Service 54dbc3
		else
Packit Service 54dbc3
			p_physp = p_sm_port->p_physp;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	/* hop_count == 1: outgoing physp is SM physp */
Packit Service 54dbc3
	for (hop = 2; p_physp && hop <= p_path->hop_count; hop++) {
Packit Service 54dbc3
		p_physp = p_physp->p_remote_physp;
Packit Service 54dbc3
		if (!p_physp)
Packit Service 54dbc3
			break;
Packit Service 54dbc3
		p_node = p_physp->p_node;
Packit Service 54dbc3
		p_physp = osm_node_get_physp_ptr(p_node, p_path->path[hop]);
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	/* At this point, p_physp points at the outgoing physp on the
Packit Service 54dbc3
	   last hop, or NULL if we don't know it.
Packit Service 54dbc3
	*/
Packit Service 54dbc3
	if (!p_physp) {
Packit Service 54dbc3
		OSM_LOG(sm->p_log, OSM_LOG_ERROR,
Packit Service 54dbc3
			"ERR 1107: Outgoing physp is null on non-hop_0!\n");
Packit Service 54dbc3
		osm_dump_dr_path_v2(sm->p_log, p_path, FILE_ID, OSM_LOG_ERROR);
Packit Service 54dbc3
		dest_port_guid = 0;
Packit Service 54dbc3
		goto Remote_Guid;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	if (p_physp->p_remote_physp) {
Packit Service 54dbc3
		dest_port_guid = p_physp->p_remote_physp->port_guid;
Packit Service 54dbc3
		goto Remote_Guid;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Target port guid unknown, "
Packit Service 54dbc3
		"using persistent DB\n");
Packit Service 54dbc3
	if (!osm_db_neighbor_get(sm->p_subn->p_neighbor,
Packit Service 54dbc3
				 cl_ntoh64(p_physp->port_guid),
Packit Service 54dbc3
				 p_physp->port_num,
Packit Service 54dbc3
				 &dest_port_guid, NULL)) {
Packit Service 54dbc3
		dest_port_guid = cl_hton64(dest_port_guid);
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
Remote_Guid:
Packit Service 54dbc3
	if (dest_port_guid) {
Packit Service 54dbc3
		if (!osm_db_guid2mkey_get(sm->p_subn->p_g2m,
Packit Service 54dbc3
					  cl_ntoh64(dest_port_guid), &m_key)) {
Packit Service 54dbc3
			m_key = cl_hton64(m_key);
Packit Service 54dbc3
			OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
Packit Service 54dbc3
				"Found mkey for guid 0x%"
Packit Service 54dbc3
				PRIx64 "\n", cl_ntoh64(dest_port_guid));
Packit Service 54dbc3
		} else {
Packit Service 54dbc3
			OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
Packit Service 54dbc3
				"Target port mkey unknown, using default\n");
Packit Service 54dbc3
			m_key = sm->p_subn->opt.m_key;
Packit Service 54dbc3
		}
Packit Service 54dbc3
	} else {
Packit Service 54dbc3
		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
Packit Service 54dbc3
			"Target port guid unknown, using default\n");
Packit Service 54dbc3
		m_key = sm->p_subn->opt.m_key;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_EXIT(sm->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	return m_key;
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
/**********************************************************************
Packit Service 54dbc3
  The plock must be held before calling this function.
Packit Service 54dbc3
**********************************************************************/
Packit Service 54dbc3
ib_api_status_t osm_req_get(IN osm_sm_t * sm, IN const osm_dr_path_t * p_path,
Packit Service 54dbc3
			    IN ib_net16_t attr_id, IN ib_net32_t attr_mod,
Packit Service 54dbc3
			    IN boolean_t find_mkey, IN ib_net64_t m_key,
Packit Service 54dbc3
			    IN uint32_t timeout, IN cl_disp_msgid_t err_msg,
Packit Service 54dbc3
			    IN const osm_madw_context_t * p_context)
Packit Service 54dbc3
{
Packit Service 54dbc3
	osm_madw_t *p_madw;
Packit Service 54dbc3
	ib_api_status_t status = IB_SUCCESS;
Packit Service 54dbc3
	ib_net64_t m_key_calc;
Packit Service 54dbc3
	ib_net64_t tid;
Packit Service 54dbc3
Packit Service 54dbc3
	CL_ASSERT(sm);
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(sm->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	CL_ASSERT(p_path);
Packit Service 54dbc3
	CL_ASSERT(attr_id);
Packit Service 54dbc3
Packit Service 54dbc3
	/* do nothing if we are exiting ... */
Packit Service 54dbc3
	if (osm_exit_flag)
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
Packit Service 54dbc3
	/* p_context may be NULL. */
Packit Service 54dbc3
Packit Service 54dbc3
	p_madw = osm_mad_pool_get(sm->p_mad_pool, sm->mad_ctrl.h_bind,
Packit Service 54dbc3
				  MAD_BLOCK_SIZE, NULL);
Packit Service 54dbc3
	if (p_madw == NULL) {
Packit Service 54dbc3
		OSM_LOG(sm->p_log, OSM_LOG_ERROR,
Packit Service 54dbc3
			"ERR 1101: Unable to acquire MAD\n");
Packit Service 54dbc3
		status = IB_INSUFFICIENT_RESOURCES;
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	tid = cl_hton64((uint64_t) cl_atomic_inc(&sm->sm_trans_id)
Packit Service 54dbc3
						 & (uint64_t)(0xFFFFFFFF));
Packit Service 54dbc3
	if (tid == 0)
Packit Service 54dbc3
		tid = cl_hton64((uint64_t) cl_atomic_inc(&sm->sm_trans_id)
Packit Service 54dbc3
							 & (uint64_t)(0xFFFFFFFF));
Packit Service 54dbc3
Packit Service 54dbc3
	if (sm->p_subn->opt.m_key_lookup == TRUE) {
Packit Service 54dbc3
		if (find_mkey == TRUE)
Packit Service 54dbc3
			m_key_calc = req_determine_mkey(sm, p_path);
Packit Service 54dbc3
		else
Packit Service 54dbc3
			m_key_calc = m_key;
Packit Service 54dbc3
	} else
Packit Service 54dbc3
		m_key_calc = sm->p_subn->opt.m_key;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
Packit Service 54dbc3
		"Getting %s (0x%X), modifier 0x%X, TID 0x%" PRIx64
Packit Service 54dbc3
		", MKey 0x%016" PRIx64 "\n",
Packit Service 54dbc3
		ib_get_sm_attr_str(attr_id), cl_ntoh16(attr_id),
Packit Service 54dbc3
		cl_ntoh32(attr_mod), cl_ntoh64(tid), cl_ntoh64(m_key_calc));
Packit Service 54dbc3
Packit Service 54dbc3
	ib_smp_init_new(osm_madw_get_smp_ptr(p_madw), IB_MAD_METHOD_GET,
Packit Service 54dbc3
			tid, attr_id, attr_mod, p_path->hop_count,
Packit Service 54dbc3
			m_key_calc, p_path->path,
Packit Service 54dbc3
			IB_LID_PERMISSIVE, IB_LID_PERMISSIVE);
Packit Service 54dbc3
Packit Service 54dbc3
	p_madw->mad_addr.dest_lid = IB_LID_PERMISSIVE;
Packit Service 54dbc3
	p_madw->mad_addr.addr_type.smi.source_lid = IB_LID_PERMISSIVE;
Packit Service 54dbc3
	p_madw->resp_expected = TRUE;
Packit Service 54dbc3
	p_madw->timeout = timeout;
Packit Service 54dbc3
	p_madw->fail_msg = err_msg;
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Fill in the mad wrapper context for the recipient.
Packit Service 54dbc3
	   In this case, the only thing the recipient needs is the
Packit Service 54dbc3
	   guid value.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
Packit Service 54dbc3
	if (p_context)
Packit Service 54dbc3
		p_madw->context = *p_context;
Packit Service 54dbc3
Packit Service 54dbc3
	osm_vl15_post(sm->p_vl15, p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
Exit:
Packit Service 54dbc3
	OSM_LOG_EXIT(sm->p_log);
Packit Service 54dbc3
	return status;
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
/**********************************************************************
Packit Service 54dbc3
  The plock must be held before calling this function.
Packit Service 54dbc3
**********************************************************************/
Packit Service 54dbc3
osm_madw_t *osm_prepare_req_set(IN osm_sm_t * sm, IN const osm_dr_path_t * p_path,
Packit Service 54dbc3
				IN const uint8_t * p_payload,
Packit Service 54dbc3
				IN size_t payload_size,
Packit Service 54dbc3
				IN ib_net16_t attr_id, IN ib_net32_t attr_mod,
Packit Service 54dbc3
				IN boolean_t find_mkey, IN ib_net64_t m_key,
Packit Service 54dbc3
				IN uint32_t timeout,
Packit Service 54dbc3
				IN cl_disp_msgid_t err_msg,
Packit Service 54dbc3
				IN const osm_madw_context_t * p_context)
Packit Service 54dbc3
{
Packit Service 54dbc3
	osm_madw_t *p_madw = NULL;
Packit Service 54dbc3
	ib_net64_t m_key_calc;
Packit Service 54dbc3
	ib_net64_t tid;
Packit Service 54dbc3
Packit Service 54dbc3
	CL_ASSERT(sm);
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG_ENTER(sm->p_log);
Packit Service 54dbc3
Packit Service 54dbc3
	CL_ASSERT(p_path);
Packit Service 54dbc3
	CL_ASSERT(attr_id);
Packit Service 54dbc3
	CL_ASSERT(p_payload);
Packit Service 54dbc3
Packit Service 54dbc3
	/* do nothing if we are exiting ... */
Packit Service 54dbc3
	if (osm_exit_flag)
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
Packit Service 54dbc3
	/* p_context may be NULL. */
Packit Service 54dbc3
Packit Service 54dbc3
	p_madw = osm_mad_pool_get(sm->p_mad_pool, sm->mad_ctrl.h_bind,
Packit Service 54dbc3
				  MAD_BLOCK_SIZE, NULL);
Packit Service 54dbc3
	if (p_madw == NULL) {
Packit Service 54dbc3
		OSM_LOG(sm->p_log, OSM_LOG_ERROR,
Packit Service 54dbc3
			"ERR 1102: Unable to acquire MAD\n");
Packit Service 54dbc3
		goto Exit;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	tid = cl_hton64((uint64_t) cl_atomic_inc(&sm->sm_trans_id)
Packit Service 54dbc3
						 & (uint64_t)(0xFFFFFFFF));
Packit Service 54dbc3
	if (tid == 0)
Packit Service 54dbc3
		tid = cl_hton64((uint64_t) cl_atomic_inc(&sm->sm_trans_id)
Packit Service 54dbc3
							 & (uint64_t)(0xFFFFFFFF));
Packit Service 54dbc3
Packit Service 54dbc3
	if (sm->p_subn->opt.m_key_lookup == TRUE) {
Packit Service 54dbc3
		if (find_mkey == TRUE)
Packit Service 54dbc3
			m_key_calc = req_determine_mkey(sm, p_path);
Packit Service 54dbc3
		else
Packit Service 54dbc3
			m_key_calc = m_key;
Packit Service 54dbc3
	} else
Packit Service 54dbc3
		m_key_calc = sm->p_subn->opt.m_key;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
Packit Service 54dbc3
		"Setting %s (0x%X), modifier 0x%X, TID 0x%" PRIx64
Packit Service 54dbc3
		", MKey 0x%016" PRIx64 "\n",
Packit Service 54dbc3
		ib_get_sm_attr_str(attr_id), cl_ntoh16(attr_id),
Packit Service 54dbc3
		cl_ntoh32(attr_mod), cl_ntoh64(tid), cl_ntoh64(m_key_calc));
Packit Service 54dbc3
Packit Service 54dbc3
	ib_smp_init_new(osm_madw_get_smp_ptr(p_madw), IB_MAD_METHOD_SET,
Packit Service 54dbc3
			tid, attr_id, attr_mod, p_path->hop_count,
Packit Service 54dbc3
			m_key_calc, p_path->path,
Packit Service 54dbc3
			IB_LID_PERMISSIVE, IB_LID_PERMISSIVE);
Packit Service 54dbc3
Packit Service 54dbc3
	p_madw->mad_addr.dest_lid = IB_LID_PERMISSIVE;
Packit Service 54dbc3
	p_madw->mad_addr.addr_type.smi.source_lid = IB_LID_PERMISSIVE;
Packit Service 54dbc3
	p_madw->resp_expected = TRUE;
Packit Service 54dbc3
	p_madw->timeout = timeout;
Packit Service 54dbc3
	p_madw->fail_msg = err_msg;
Packit Service 54dbc3
Packit Service 54dbc3
	/*
Packit Service 54dbc3
	   Fill in the mad wrapper context for the recipient.
Packit Service 54dbc3
	   In this case, the only thing the recipient needs is the
Packit Service 54dbc3
	   guid value.
Packit Service 54dbc3
	 */
Packit Service 54dbc3
Packit Service 54dbc3
	if (p_context)
Packit Service 54dbc3
		p_madw->context = *p_context;
Packit Service 54dbc3
Packit Service 54dbc3
	memcpy(osm_madw_get_smp_ptr(p_madw)->data, p_payload, payload_size);
Packit Service 54dbc3
Packit Service 54dbc3
Exit:
Packit Service 54dbc3
	OSM_LOG_EXIT(sm->p_log);
Packit Service 54dbc3
	return p_madw;
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
void osm_send_req_mad(IN osm_sm_t * sm, IN osm_madw_t *p_madw)
Packit Service 54dbc3
{
Packit Service 54dbc3
	CL_ASSERT(p_madw);
Packit Service 54dbc3
	CL_ASSERT(sm);
Packit Service 54dbc3
Packit Service 54dbc3
	osm_vl15_post(sm->p_vl15, p_madw);
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
/**********************************************************************
Packit Service 54dbc3
  The plock MAY or MAY NOT be held before calling this function.
Packit Service 54dbc3
**********************************************************************/
Packit Service 54dbc3
ib_api_status_t osm_req_set(IN osm_sm_t * sm, IN const osm_dr_path_t * p_path,
Packit Service 54dbc3
			    IN const uint8_t * p_payload,
Packit Service 54dbc3
			    IN size_t payload_size,
Packit Service 54dbc3
			    IN ib_net16_t attr_id, IN ib_net32_t attr_mod,
Packit Service 54dbc3
			    IN boolean_t find_mkey, IN ib_net64_t m_key,
Packit Service 54dbc3
			    IN uint32_t timeout,
Packit Service 54dbc3
			    IN cl_disp_msgid_t err_msg,
Packit Service 54dbc3
			    IN const osm_madw_context_t * p_context)
Packit Service 54dbc3
{
Packit Service 54dbc3
	osm_madw_t *p_madw;
Packit Service 54dbc3
	ib_api_status_t status = IB_SUCCESS;
Packit Service 54dbc3
Packit Service 54dbc3
	p_madw = osm_prepare_req_set(sm, p_path, p_payload, payload_size, attr_id,
Packit Service 54dbc3
				     attr_mod, find_mkey, m_key, timeout, err_msg, p_context);
Packit Service 54dbc3
	if (p_madw == NULL)
Packit Service 54dbc3
		status = IB_INSUFFICIENT_RESOURCES;
Packit Service 54dbc3
	else
Packit Service 54dbc3
		osm_send_req_mad(sm, p_madw);
Packit Service 54dbc3
Packit Service 54dbc3
	return status;
Packit Service 54dbc3
}
Packit Service 54dbc3
Packit Service 54dbc3
int osm_send_trap144(osm_sm_t * sm, ib_net16_t local)
Packit Service 54dbc3
{
Packit Service 54dbc3
	osm_madw_t *madw;
Packit Service 54dbc3
	ib_smp_t *smp;
Packit Service 54dbc3
	ib_mad_notice_attr_t *ntc;
Packit Service 54dbc3
	osm_port_t *port, *smport;
Packit Service 54dbc3
	ib_port_info_t *pi;
Packit Service 54dbc3
Packit Service 54dbc3
	port = osm_get_port_by_guid(sm->p_subn, sm->p_subn->sm_port_guid);
Packit Service 54dbc3
	if (!port) {
Packit Service 54dbc3
		OSM_LOG(sm->p_log, OSM_LOG_ERROR,
Packit Service 54dbc3
			"ERR 1104: cannot find SM port by guid 0x%" PRIx64 "\n",
Packit Service 54dbc3
			cl_ntoh64(sm->p_subn->sm_port_guid));
Packit Service 54dbc3
		return -1;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	pi = &port->p_physp->port_info;
Packit Service 54dbc3
Packit Service 54dbc3
	/* don't bother with sending trap when SMA supports this */
Packit Service 54dbc3
	if (!local &&
Packit Service 54dbc3
	    pi->capability_mask&(IB_PORT_CAP_HAS_TRAP|IB_PORT_CAP_HAS_CAP_NTC))
Packit Service 54dbc3
		return 0;
Packit Service 54dbc3
Packit Service 54dbc3
	smport = osm_get_port_by_guid(sm->p_subn, sm->master_sm_guid);
Packit Service 54dbc3
	if (!smport) {
Packit Service 54dbc3
		OSM_LOG(sm->p_log, OSM_LOG_ERROR,
Packit Service 54dbc3
			"ERR 1106: cannot find master SM port by guid 0x%" PRIx64 "\n",
Packit Service 54dbc3
			cl_ntoh64(sm->master_sm_guid));
Packit Service 54dbc3
		return -1;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	madw = osm_mad_pool_get(sm->p_mad_pool,
Packit Service 54dbc3
				osm_sm_mad_ctrl_get_bind_handle(&sm->mad_ctrl),
Packit Service 54dbc3
				MAD_BLOCK_SIZE, NULL);
Packit Service 54dbc3
	if (madw == NULL) {
Packit Service 54dbc3
		OSM_LOG(sm->p_log, OSM_LOG_ERROR,
Packit Service 54dbc3
			"ERR 1105: Unable to acquire MAD\n");
Packit Service 54dbc3
		return -1;
Packit Service 54dbc3
	}
Packit Service 54dbc3
Packit Service 54dbc3
	madw->mad_addr.dest_lid = smport->p_physp->port_info.base_lid;
Packit Service 54dbc3
	madw->mad_addr.addr_type.smi.source_lid = pi->base_lid;
Packit Service 54dbc3
	madw->resp_expected = TRUE;
Packit Service 54dbc3
	madw->fail_msg = CL_DISP_MSGID_NONE;
Packit Service 54dbc3
Packit Service 54dbc3
	smp = osm_madw_get_smp_ptr(madw);
Packit Service 54dbc3
	memset(smp, 0, sizeof(*smp));
Packit Service 54dbc3
Packit Service 54dbc3
	smp->base_ver = 1;
Packit Service 54dbc3
	smp->mgmt_class = IB_MCLASS_SUBN_LID;
Packit Service 54dbc3
	smp->class_ver = 1;
Packit Service 54dbc3
	smp->method = IB_MAD_METHOD_TRAP;
Packit Service 54dbc3
	smp->trans_id = cl_hton64((uint64_t) cl_atomic_inc(&sm->sm_trans_id)
Packit Service 54dbc3
							   & (uint64_t)(0xFFFFFFFF));
Packit Service 54dbc3
	if (smp->trans_id == 0)
Packit Service 54dbc3
		smp->trans_id = cl_hton64((uint64_t) cl_atomic_inc(&sm->sm_trans_id)
Packit Service 54dbc3
								   & (uint64_t)(0xFFFFFFFF));
Packit Service 54dbc3
Packit Service 54dbc3
	smp->attr_id = IB_MAD_ATTR_NOTICE;
Packit Service 54dbc3
Packit Service 54dbc3
	ntc = (ib_mad_notice_attr_t *) smp->data;
Packit Service 54dbc3
Packit Service 54dbc3
	ntc->generic_type = 0x80 | IB_NOTICE_TYPE_INFO;
Packit Service 54dbc3
	ib_notice_set_prod_type_ho(ntc, osm_node_get_type(port->p_node));
Packit Service 54dbc3
	ntc->g_or_v.generic.trap_num = cl_hton16(SM_LOCAL_CHANGES_TRAP); /* 144 */
Packit Service 54dbc3
	ntc->issuer_lid = pi->base_lid;
Packit Service 54dbc3
	ntc->data_details.ntc_144.lid = pi->base_lid;
Packit Service 54dbc3
	ntc->data_details.ntc_144.local_changes = local ?
Packit Service 54dbc3
	    TRAP_144_MASK_OTHER_LOCAL_CHANGES : 0;
Packit Service 54dbc3
	ntc->data_details.ntc_144.new_cap_mask = pi->capability_mask;
Packit Service 54dbc3
	ntc->data_details.ntc_144.change_flgs = local;
Packit Service 54dbc3
Packit Service 54dbc3
	OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
Packit Service 54dbc3
		"Sending Trap 144, TID 0x%" PRIx64 " to SM lid %u\n",
Packit Service 54dbc3
		cl_ntoh64(smp->trans_id), cl_ntoh16(madw->mad_addr.dest_lid));
Packit Service 54dbc3
Packit Service 54dbc3
	osm_vl15_post(sm->p_vl15, madw);
Packit Service 54dbc3
Packit Service 54dbc3
	return 0;
Packit Service 54dbc3
}