Blame libvendor/osm_vendor_ibumad.c

Packit 13e616
/*
Packit 13e616
 * Copyright (c) 2004-2009 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
 * Copyright (c) 2009 HNR Consulting. All rights reserved.
Packit 13e616
 * Copyright (c) 2009 Sun Microsystems, Inc. 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
/*
Packit 13e616
 * Abstract:
Packit 13e616
 *    Implementation of osm_vendor_t (for umad).
Packit 13e616
 * This object represents the OpenIB vendor layer.
Packit 13e616
 * This object is part of the opensm family of objects.
Packit 13e616
 *
Packit 13e616
 * Environment:
Packit 13e616
 *    Linux User Mode
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
#ifdef OSM_VENDOR_INTF_OPENIB
Packit 13e616
Packit 13e616
#include <unistd.h>
Packit 13e616
#include <stdlib.h>
Packit 13e616
#include <fcntl.h>
Packit 13e616
#include <errno.h>
Packit 13e616
#include <linux/types.h>	/* for __be64 with older libibumad */
Packit 13e616
Packit 13e616
#include <iba/ib_types.h>
Packit 13e616
#include <complib/cl_qlist.h>
Packit 13e616
#include <complib/cl_math.h>
Packit 13e616
#include <complib/cl_debug.h>
Packit 13e616
#include <opensm/osm_file_ids.h>
Packit 13e616
#define FILE_ID OSM_FILE_VENDOR_IBUMAD_C
Packit 13e616
#include <opensm/osm_madw.h>
Packit 13e616
#include <opensm/osm_log.h>
Packit 13e616
#include <opensm/osm_mad_pool.h>
Packit 13e616
#include <opensm/osm_helper.h>
Packit 13e616
#include <vendor/osm_vendor_api.h>
Packit 13e616
Packit 13e616
/****s* OpenSM: Vendor UMAD/osm_umad_bind_info_t
Packit 13e616
 * NAME
Packit 13e616
 *   osm_umad_bind_info_t
Packit 13e616
 *
Packit 13e616
 * DESCRIPTION
Packit 13e616
 *    Structure containing bind information.
Packit 13e616
 *
Packit 13e616
 * SYNOPSIS
Packit 13e616
 */
Packit 13e616
typedef struct _osm_umad_bind_info {
Packit 13e616
	osm_vendor_t *p_vend;
Packit 13e616
	void *client_context;
Packit 13e616
	osm_mad_pool_t *p_mad_pool;
Packit 13e616
	osm_vend_mad_recv_callback_t mad_recv_callback;
Packit 13e616
	osm_vend_mad_send_err_callback_t send_err_callback;
Packit 13e616
	ib_net64_t port_guid;
Packit 13e616
	int port_id;
Packit 13e616
	int agent_id;
Packit 13e616
	int agent_id1;		/* SMI requires two agents */
Packit 13e616
	int timeout;
Packit 13e616
	int max_retries;
Packit 13e616
} osm_umad_bind_info_t;
Packit 13e616
Packit 13e616
typedef struct _umad_receiver {
Packit 13e616
	pthread_t tid;
Packit 13e616
	osm_vendor_t *p_vend;
Packit 13e616
	osm_log_t *p_log;
Packit 13e616
} umad_receiver_t;
Packit 13e616
Packit 13e616
static void osm_vendor_close_port(osm_vendor_t * const p_vend);
Packit 13e616
Packit 13e616
static void log_send_error(osm_vendor_t * const p_vend, osm_madw_t *p_madw)
Packit 13e616
{
Packit 13e616
	if (p_madw->p_mad->mgmt_class != IB_MCLASS_SUBN_DIR) {
Packit 13e616
		/* LID routed */
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5410: "
Packit 13e616
			"Send completed with error (%s) -- dropping\n"
Packit 13e616
			"\t\t\tClass 0x%x, Method 0x%X, Attr 0x%X, "
Packit 13e616
			"TID 0x%" PRIx64 ", LID %u\n",
Packit 13e616
			ib_get_err_str(p_madw->status),
Packit 13e616
			p_madw->p_mad->mgmt_class, p_madw->p_mad->method,
Packit 13e616
			cl_ntoh16(p_madw->p_mad->attr_id),
Packit 13e616
			cl_ntoh64(p_madw->p_mad->trans_id),
Packit 13e616
			cl_ntoh16(p_madw->mad_addr.dest_lid));
Packit 13e616
	} else {
Packit 13e616
		ib_smp_t *p_smp;
Packit 13e616
Packit 13e616
		/* Direct routed SMP */
Packit 13e616
		p_smp = osm_madw_get_smp_ptr(p_madw);
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5411: "
Packit 13e616
			"DR SMP Send completed with error (%s) -- dropping\n"
Packit 13e616
			"\t\t\tMethod 0x%X, Attr 0x%X, TID 0x%" PRIx64 "\n",
Packit 13e616
			ib_get_err_str(p_madw->status),
Packit 13e616
			p_madw->p_mad->method,
Packit 13e616
			cl_ntoh16(p_madw->p_mad->attr_id),
Packit 13e616
			cl_ntoh64(p_madw->p_mad->trans_id));
Packit 13e616
		osm_dump_smp_dr_path(p_vend->p_log, p_smp, OSM_LOG_ERROR);
Packit 13e616
	}
Packit 13e616
}
Packit 13e616
Packit 13e616
static void clear_madw(osm_vendor_t * p_vend)
Packit 13e616
{
Packit 13e616
	umad_match_t *m, *e, *old_m;
Packit 13e616
	ib_net64_t old_tid;
Packit 13e616
	uint8_t old_mgmt_class;
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(p_vend->p_log);
Packit 13e616
	pthread_mutex_lock(&p_vend->match_tbl_mutex);
Packit 13e616
	for (m = p_vend->mtbl.tbl, e = m + p_vend->mtbl.max; m < e; m++) {
Packit 13e616
		if (m->tid) {
Packit 13e616
			old_m = m;
Packit 13e616
			old_tid = m->tid;
Packit 13e616
			old_mgmt_class = m->mgmt_class;
Packit 13e616
			m->tid = 0;
Packit 13e616
			osm_mad_pool_put(((osm_umad_bind_info_t
Packit 13e616
					   *) ((osm_madw_t *) m->v)->h_bind)->
Packit 13e616
					 p_mad_pool, m->v);
Packit 13e616
			pthread_mutex_unlock(&p_vend->match_tbl_mutex);
Packit 13e616
			OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5401: "
Packit 13e616
				"evicting entry %p (tid was 0x%" PRIx64
Packit 13e616
				" mgmt class 0x%x)\n",
Packit 13e616
				old_m, cl_ntoh64(old_tid), old_mgmt_class);
Packit 13e616
			goto Exit;
Packit 13e616
		}
Packit 13e616
	}
Packit 13e616
	pthread_mutex_unlock(&p_vend->match_tbl_mutex);
Packit 13e616
Packit 13e616
Exit:
Packit 13e616
	OSM_LOG_EXIT(p_vend->p_log);
Packit 13e616
}
Packit 13e616
Packit 13e616
static osm_madw_t *get_madw(osm_vendor_t * p_vend, ib_net64_t * tid,
Packit 13e616
			    uint8_t mgmt_class)
Packit 13e616
{
Packit 13e616
	umad_match_t *m, *e;
Packit 13e616
	ib_net64_t mtid = (*tid & CL_HTON64(0x00000000ffffffffULL));
Packit 13e616
	osm_madw_t *res;
Packit 13e616
Packit 13e616
	/*
Packit 13e616
	 * Since mtid == 0 is the empty key, we should not
Packit 13e616
	 * waste time looking for it
Packit 13e616
	 */
Packit 13e616
	if (mtid == 0 || mgmt_class == 0)
Packit 13e616
		return 0;
Packit 13e616
Packit 13e616
	pthread_mutex_lock(&p_vend->match_tbl_mutex);
Packit 13e616
	for (m = p_vend->mtbl.tbl, e = m + p_vend->mtbl.max; m < e; m++) {
Packit 13e616
		if (m->tid == mtid && m->mgmt_class == mgmt_class) {
Packit 13e616
			m->tid = 0;
Packit 13e616
			m->mgmt_class = 0;
Packit 13e616
			*tid = mtid;
Packit 13e616
			res = m->v;
Packit 13e616
			pthread_mutex_unlock(&p_vend->match_tbl_mutex);
Packit 13e616
			return res;
Packit 13e616
		}
Packit 13e616
	}
Packit 13e616
Packit 13e616
	pthread_mutex_unlock(&p_vend->match_tbl_mutex);
Packit 13e616
	return 0;
Packit 13e616
}
Packit 13e616
Packit 13e616
/*
Packit 13e616
 * If match table full, evict LRU (least recently used) transaction.
Packit 13e616
 * Maintain 2 LRUs: one for SMPs, and one for others (GS).
Packit 13e616
 * Evict LRU GS transaction if one is available and only evict LRU SMP
Packit 13e616
 * transaction if no other choice.
Packit 13e616
 */
Packit 13e616
static void
Packit 13e616
put_madw(osm_vendor_t * p_vend, osm_madw_t * p_madw, ib_net64_t tid,
Packit 13e616
	 uint8_t mgmt_class)
Packit 13e616
{
Packit 13e616
	umad_match_t *m, *e, *old_lru, *lru = 0, *lru_smp = 0;
Packit 13e616
	osm_madw_t *p_req_madw;
Packit 13e616
	osm_umad_bind_info_t *p_bind;
Packit 13e616
	ib_net64_t old_tid;
Packit 13e616
	uint32_t oldest = ~0, oldest_smp = ~0;
Packit 13e616
	uint8_t old_mgmt_class;
Packit 13e616
Packit 13e616
	pthread_mutex_lock(&p_vend->match_tbl_mutex);
Packit 13e616
	for (m = p_vend->mtbl.tbl, e = m + p_vend->mtbl.max; m < e; m++) {
Packit 13e616
		if (m->tid == 0 && m->mgmt_class == 0) {
Packit 13e616
			m->tid = tid;
Packit 13e616
			m->mgmt_class = mgmt_class;
Packit 13e616
			m->v = p_madw;
Packit 13e616
			m->version =
Packit 13e616
			    cl_atomic_inc((atomic32_t *) & p_vend->mtbl.
Packit 13e616
					  last_version);
Packit 13e616
			pthread_mutex_unlock(&p_vend->match_tbl_mutex);
Packit 13e616
			return;
Packit 13e616
		}
Packit 13e616
		if (m->mgmt_class == IB_MCLASS_SUBN_DIR ||
Packit 13e616
		    m->mgmt_class == IB_MCLASS_SUBN_LID) {
Packit 13e616
			if (oldest_smp >= m->version) {
Packit 13e616
				oldest_smp = m->version;
Packit 13e616
				lru_smp = m;
Packit 13e616
			}
Packit 13e616
		} else {
Packit 13e616
			if (oldest >= m->version) {
Packit 13e616
				oldest = m->version;
Packit 13e616
				lru = m;
Packit 13e616
			}
Packit 13e616
		}
Packit 13e616
	}
Packit 13e616
Packit 13e616
	if (oldest != ~0) {
Packit 13e616
		old_lru = lru;
Packit 13e616
		old_tid = lru->tid;
Packit 13e616
		old_mgmt_class = lru->mgmt_class;
Packit 13e616
	} else {
Packit 13e616
		CL_ASSERT(oldest_smp != ~0);
Packit 13e616
		old_lru = lru_smp;
Packit 13e616
		old_tid = lru_smp->tid;
Packit 13e616
		old_mgmt_class = lru_smp->mgmt_class;
Packit 13e616
	}
Packit 13e616
	p_req_madw = old_lru->v;
Packit 13e616
	p_bind = p_req_madw->h_bind;
Packit 13e616
	p_req_madw->status = IB_CANCELED;
Packit 13e616
	log_send_error(p_vend, p_req_madw);
Packit 13e616
	pthread_mutex_lock(&p_vend->cb_mutex);
Packit 13e616
	(*p_bind->send_err_callback) (p_bind->client_context, p_req_madw);
Packit 13e616
	pthread_mutex_unlock(&p_vend->cb_mutex);
Packit 13e616
	if (mgmt_class == IB_MCLASS_SUBN_DIR ||
Packit 13e616
	    mgmt_class == IB_MCLASS_SUBN_LID) {
Packit 13e616
		lru_smp->tid = tid;
Packit 13e616
		lru_smp->mgmt_class = mgmt_class;
Packit 13e616
		lru_smp->v = p_madw;
Packit 13e616
		lru_smp->version =
Packit 13e616
		    cl_atomic_inc((atomic32_t *) & p_vend->mtbl.last_version);
Packit 13e616
	} else {
Packit 13e616
		lru->tid = tid;
Packit 13e616
		lru->mgmt_class = mgmt_class;
Packit 13e616
		lru->v = p_madw;
Packit 13e616
		lru->version =
Packit 13e616
		    cl_atomic_inc((atomic32_t *) & p_vend->mtbl.last_version);
Packit 13e616
	}
Packit 13e616
	pthread_mutex_unlock(&p_vend->match_tbl_mutex);
Packit 13e616
	OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5402: "
Packit 13e616
		"evicting entry %p (tid was 0x%" PRIx64
Packit 13e616
		" mgmt class 0x%x)\n", old_lru,
Packit 13e616
		cl_ntoh64(old_tid), old_mgmt_class);
Packit 13e616
}
Packit 13e616
Packit 13e616
static void
Packit 13e616
ib_mad_addr_conv(ib_user_mad_t * umad, osm_mad_addr_t * osm_mad_addr,
Packit 13e616
		 int is_smi)
Packit 13e616
{
Packit 13e616
	ib_mad_addr_t *ib_mad_addr = umad_get_mad_addr(umad);
Packit 13e616
Packit 13e616
	memset(osm_mad_addr, 0, sizeof(osm_mad_addr_t));
Packit 13e616
	osm_mad_addr->dest_lid = ib_mad_addr->lid;
Packit 13e616
	osm_mad_addr->path_bits = ib_mad_addr->path_bits;
Packit 13e616
Packit 13e616
	if (is_smi) {
Packit 13e616
		osm_mad_addr->addr_type.smi.source_lid = osm_mad_addr->dest_lid;
Packit 13e616
		osm_mad_addr->addr_type.smi.port_num = 255;	/* not used */
Packit 13e616
		return;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	osm_mad_addr->addr_type.gsi.remote_qp = ib_mad_addr->qpn;
Packit 13e616
	osm_mad_addr->addr_type.gsi.remote_qkey = ib_mad_addr->qkey;
Packit 13e616
	osm_mad_addr->addr_type.gsi.pkey_ix = umad_get_pkey(umad);
Packit 13e616
	osm_mad_addr->addr_type.gsi.service_level = ib_mad_addr->sl;
Packit 13e616
	if (ib_mad_addr->grh_present) {
Packit 13e616
		osm_mad_addr->addr_type.gsi.global_route = 1;
Packit 13e616
		osm_mad_addr->addr_type.gsi.grh_info.hop_limit = ib_mad_addr->hop_limit;
Packit 13e616
		osm_mad_addr->addr_type.gsi.grh_info.ver_class_flow =
Packit 13e616
			ib_grh_set_ver_class_flow(6,	/* GRH version */
Packit 13e616
						  ib_mad_addr->traffic_class,
Packit 13e616
						  ib_mad_addr->flow_label);
Packit 13e616
		memcpy(&osm_mad_addr->addr_type.gsi.grh_info.dest_gid,
Packit 13e616
		       &ib_mad_addr->gid, 16);
Packit 13e616
	}
Packit 13e616
}
Packit 13e616
Packit 13e616
static void *swap_mad_bufs(osm_madw_t * p_madw, void *umad)
Packit 13e616
{
Packit 13e616
	void *old;
Packit 13e616
Packit 13e616
	old = p_madw->vend_wrap.umad;
Packit 13e616
	p_madw->vend_wrap.umad = umad;
Packit 13e616
	p_madw->p_mad = umad_get_mad(umad);
Packit 13e616
Packit 13e616
	return old;
Packit 13e616
}
Packit 13e616
Packit 13e616
static void unlock_mutex(void *arg)
Packit 13e616
{
Packit 13e616
	pthread_mutex_unlock(arg);
Packit 13e616
}
Packit 13e616
Packit 13e616
static void *umad_receiver(void *p_ptr)
Packit 13e616
{
Packit 13e616
	umad_receiver_t *const p_ur = (umad_receiver_t *) p_ptr;
Packit 13e616
	osm_vendor_t *p_vend = p_ur->p_vend;
Packit 13e616
	osm_umad_bind_info_t *p_bind;
Packit 13e616
	osm_mad_addr_t osm_addr;
Packit 13e616
	osm_madw_t *p_madw, *p_req_madw;
Packit 13e616
	ib_mad_t *p_mad, *p_req_mad;
Packit 13e616
	void *umad = 0;
Packit 13e616
	int mad_agent, length;
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(p_ur->p_log);
Packit 13e616
Packit 13e616
	for (;;) {
Packit 13e616
		if (!umad &&
Packit 13e616
		    !(umad = umad_alloc(1, umad_size() + MAD_BLOCK_SIZE))) {
Packit 13e616
			OSM_LOG(p_ur->p_log, OSM_LOG_ERROR, "ERR 5403: "
Packit 13e616
				"can't alloc MAD sized umad\n");
Packit 13e616
			break;
Packit 13e616
		}
Packit 13e616
Packit 13e616
		length = MAD_BLOCK_SIZE;
Packit 13e616
		if ((mad_agent = umad_recv(p_vend->umad_port_id, umad,
Packit 13e616
					   &length, -1)) < 0) {
Packit 13e616
			if (length <= MAD_BLOCK_SIZE) {
Packit 13e616
				OSM_LOG(p_ur->p_log, OSM_LOG_ERROR, "ERR 5404: "
Packit 13e616
					"recv error on MAD sized umad (%m)\n");
Packit 13e616
				continue;
Packit 13e616
			} else {
Packit 13e616
				umad_free(umad);
Packit 13e616
				/* Need a larger buffer for RMPP */
Packit 13e616
				umad = umad_alloc(1, umad_size() + length);
Packit 13e616
				if (!umad) {
Packit 13e616
					OSM_LOG(p_ur->p_log, OSM_LOG_ERROR,
Packit 13e616
						"ERR 5405: "
Packit 13e616
						"can't alloc umad length %d\n",
Packit 13e616
						length);
Packit 13e616
					continue;
Packit 13e616
				}
Packit 13e616
Packit 13e616
				if ((mad_agent = umad_recv(p_vend->umad_port_id,
Packit 13e616
							   umad, &length,
Packit 13e616
							   -1)) < 0) {
Packit 13e616
					OSM_LOG(p_ur->p_log, OSM_LOG_ERROR,
Packit 13e616
						"ERR 5406: "
Packit 13e616
						"recv error on umad length %d (%m)\n",
Packit 13e616
						length);
Packit 13e616
					continue;
Packit 13e616
				}
Packit 13e616
			}
Packit 13e616
		}
Packit 13e616
Packit 13e616
		if (mad_agent >= OSM_UMAD_MAX_AGENTS ||
Packit 13e616
		    !(p_bind = p_vend->agents[mad_agent])) {
Packit 13e616
			OSM_LOG(p_ur->p_log, OSM_LOG_ERROR, "ERR 5407: "
Packit 13e616
				"invalid mad agent %d - dropping\n", mad_agent);
Packit 13e616
			continue;
Packit 13e616
		}
Packit 13e616
Packit 13e616
		p_mad = (ib_mad_t *) umad_get_mad(umad);
Packit 13e616
Packit 13e616
		ib_mad_addr_conv(umad, &osm_addr,
Packit 13e616
				 p_mad->mgmt_class == IB_MCLASS_SUBN_LID ||
Packit 13e616
				 p_mad->mgmt_class == IB_MCLASS_SUBN_DIR);
Packit 13e616
Packit 13e616
		if (!(p_madw = osm_mad_pool_get(p_bind->p_mad_pool,
Packit 13e616
						(osm_bind_handle_t) p_bind,
Packit 13e616
						MAX(length, MAD_BLOCK_SIZE),
Packit 13e616
						&osm_addr))) {
Packit 13e616
			OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5408: "
Packit 13e616
				"request for a new madw failed -- dropping packet\n");
Packit 13e616
			continue;
Packit 13e616
		}
Packit 13e616
Packit 13e616
		/* Need to fix up MAD size if short RMPP packet */
Packit 13e616
		if (length < MAD_BLOCK_SIZE)
Packit 13e616
			p_madw->mad_size = length;
Packit 13e616
Packit 13e616
		/*
Packit 13e616
		 * Avoid copying by swapping mad buf pointers.
Packit 13e616
		 * Do not use umad after this line of code.
Packit 13e616
		 */
Packit 13e616
		umad = swap_mad_bufs(p_madw, umad);
Packit 13e616
Packit 13e616
		/* if status != 0 then we are handling recv timeout on send */
Packit 13e616
		if (umad_status(p_madw->vend_wrap.umad)) {
Packit 13e616
			if (!(p_req_madw = get_madw(p_vend, &p_mad->trans_id,
Packit 13e616
						    p_mad->mgmt_class))) {
Packit 13e616
				OSM_LOG(p_vend->p_log, OSM_LOG_ERROR,
Packit 13e616
					"ERR 5412: "
Packit 13e616
					"Failed to obtain request madw for timed out MAD"
Packit 13e616
					" (class=0x%X method=0x%X attr=0x%X tid=0x%"PRIx64") -- dropping\n",
Packit 13e616
					p_mad->mgmt_class, p_mad->method,
Packit 13e616
					cl_ntoh16(p_mad->attr_id),
Packit 13e616
					cl_ntoh64(p_mad->trans_id));
Packit 13e616
			} else {
Packit 13e616
				p_req_madw->status = IB_TIMEOUT;
Packit 13e616
				log_send_error(p_vend, p_req_madw);
Packit 13e616
				/* cb frees req_madw */
Packit 13e616
				pthread_mutex_lock(&p_vend->cb_mutex);
Packit 13e616
				pthread_cleanup_push(unlock_mutex,
Packit 13e616
						     &p_vend->cb_mutex);
Packit 13e616
				(*p_bind->send_err_callback) (p_bind->
Packit 13e616
							      client_context,
Packit 13e616
							      p_req_madw);
Packit 13e616
				pthread_cleanup_pop(1);
Packit 13e616
			}
Packit 13e616
Packit 13e616
			osm_mad_pool_put(p_bind->p_mad_pool, p_madw);
Packit 13e616
			continue;
Packit 13e616
		}
Packit 13e616
Packit 13e616
		p_req_madw = 0;
Packit 13e616
		if (ib_mad_is_response(p_mad)) {
Packit 13e616
			p_req_madw = get_madw(p_vend, &p_mad->trans_id,
Packit 13e616
					      p_mad->mgmt_class);
Packit 13e616
			if (PF(!p_req_madw)) {
Packit 13e616
				OSM_LOG(p_vend->p_log, OSM_LOG_ERROR,
Packit 13e616
					"ERR 5413: Failed to obtain request "
Packit 13e616
					"madw for received MAD "
Packit 13e616
					"(class=0x%X method=0x%X attr=0x%X "
Packit 13e616
					"tid=0x%"PRIx64") -- dropping\n",
Packit 13e616
					p_mad->mgmt_class, p_mad->method,
Packit 13e616
					cl_ntoh16(p_mad->attr_id),
Packit 13e616
					cl_ntoh64(p_mad->trans_id));
Packit 13e616
				osm_mad_pool_put(p_bind->p_mad_pool, p_madw);
Packit 13e616
				continue;
Packit 13e616
			}
Packit 13e616
Packit 13e616
			/*
Packit 13e616
			 * Check that request MAD was really a request,
Packit 13e616
			 * and make sure that attribute ID, attribute
Packit 13e616
			 * modifier and transaction ID are the same in
Packit 13e616
			 * request and response.
Packit 13e616
			 *
Packit 13e616
			 * Exception for o15-0.2-1.11:
Packit 13e616
			 * SA response to a SubnAdmGetMulti() containing a
Packit 13e616
			 * MultiPathRecord shall have PathRecord attribute ID.
Packit 13e616
			 */
Packit 13e616
			p_req_mad = osm_madw_get_mad_ptr(p_req_madw);
Packit 13e616
			if (PF(ib_mad_is_response(p_req_mad) ||
Packit 13e616
			       (p_mad->attr_id != p_req_mad->attr_id &&
Packit 13e616
                                !(p_mad->mgmt_class == IB_MCLASS_SUBN_ADM &&
Packit 13e616
                                  p_req_mad->attr_id ==
Packit 13e616
					IB_MAD_ATTR_MULTIPATH_RECORD &&
Packit 13e616
                                  p_mad->attr_id == IB_MAD_ATTR_PATH_RECORD)) ||
Packit 13e616
			       p_mad->attr_mod != p_req_mad->attr_mod ||
Packit 13e616
			       p_mad->trans_id != p_req_mad->trans_id)) {
Packit 13e616
				OSM_LOG(p_vend->p_log, OSM_LOG_ERROR,
Packit 13e616
					"ERR 541A: "
Packit 13e616
					"Response MAD validation failed "
Packit 13e616
					"(request attr=0x%X modif=0x%X "
Packit 13e616
					"tid=0x%"PRIx64", "
Packit 13e616
					"response attr=0x%X modif=0x%X "
Packit 13e616
					"tid=0x%"PRIx64") -- dropping\n",
Packit 13e616
					cl_ntoh16(p_req_mad->attr_id),
Packit 13e616
					cl_ntoh32(p_req_mad->attr_mod),
Packit 13e616
					cl_ntoh64(p_req_mad->trans_id),
Packit 13e616
					cl_ntoh16(p_mad->attr_id),
Packit 13e616
					cl_ntoh32(p_mad->attr_mod),
Packit 13e616
					cl_ntoh64(p_mad->trans_id));
Packit 13e616
				osm_mad_pool_put(p_bind->p_mad_pool, p_madw);
Packit 13e616
				continue;
Packit 13e616
			}
Packit 13e616
		}
Packit 13e616
Packit 13e616
#ifndef VENDOR_RMPP_SUPPORT
Packit 13e616
		if ((p_mad->mgmt_class != IB_MCLASS_SUBN_DIR) &&
Packit 13e616
		    (p_mad->mgmt_class != IB_MCLASS_SUBN_LID) &&
Packit 13e616
		    (ib_rmpp_is_flag_set((ib_rmpp_mad_t *) p_mad,
Packit 13e616
					 IB_RMPP_FLAG_ACTIVE))) {
Packit 13e616
			OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5414: "
Packit 13e616
				"class 0x%x method 0x%x RMPP version %d type "
Packit 13e616
				"%d flags 0x%x received -- dropping\n",
Packit 13e616
				p_mad->mgmt_class, p_mad->method,
Packit 13e616
				((ib_rmpp_mad_t *) p_mad)->rmpp_version,
Packit 13e616
				((ib_rmpp_mad_t *) p_mad)->rmpp_type,
Packit 13e616
				((ib_rmpp_mad_t *) p_mad)->rmpp_flags);
Packit 13e616
			osm_mad_pool_put(p_bind->p_mad_pool, p_madw);
Packit 13e616
			continue;
Packit 13e616
		}
Packit 13e616
#endif
Packit 13e616
Packit 13e616
		/* call the CB */
Packit 13e616
		pthread_mutex_lock(&p_vend->cb_mutex);
Packit 13e616
		pthread_cleanup_push(unlock_mutex, &p_vend->cb_mutex);
Packit 13e616
		(*p_bind->mad_recv_callback) (p_madw, p_bind->client_context,
Packit 13e616
					      p_req_madw);
Packit 13e616
		pthread_cleanup_pop(1);
Packit 13e616
	}
Packit 13e616
Packit 13e616
	OSM_LOG_EXIT(p_vend->p_log);
Packit 13e616
	return NULL;
Packit 13e616
}
Packit 13e616
Packit 13e616
static int umad_receiver_start(osm_vendor_t * p_vend)
Packit 13e616
{
Packit 13e616
	umad_receiver_t *p_ur = p_vend->receiver;
Packit 13e616
Packit 13e616
	p_ur->p_vend = p_vend;
Packit 13e616
	p_ur->p_log = p_vend->p_log;
Packit 13e616
Packit 13e616
	if (pthread_create(&p_ur->tid, NULL, umad_receiver, p_ur) != 0)
Packit 13e616
		return -1;
Packit 13e616
Packit 13e616
	return 0;
Packit 13e616
}
Packit 13e616
Packit 13e616
static void umad_receiver_stop(umad_receiver_t * p_ur)
Packit 13e616
{
Packit 13e616
	pthread_cancel(p_ur->tid);
Packit 13e616
	pthread_join(p_ur->tid, NULL);
Packit 13e616
	p_ur->tid = 0;
Packit 13e616
	p_ur->p_vend = NULL;
Packit 13e616
	p_ur->p_log = NULL;
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
	char *max = NULL;
Packit 13e616
	int r, n_cas;
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(p_log);
Packit 13e616
Packit 13e616
	p_vend->p_log = p_log;
Packit 13e616
	p_vend->timeout = timeout;
Packit 13e616
	p_vend->max_retries = OSM_DEFAULT_RETRY_COUNT;
Packit 13e616
	pthread_mutex_init(&p_vend->cb_mutex, NULL);
Packit 13e616
	pthread_mutex_init(&p_vend->match_tbl_mutex, NULL);
Packit 13e616
	p_vend->umad_port_id = -1;
Packit 13e616
	p_vend->issmfd = -1;
Packit 13e616
Packit 13e616
	/*
Packit 13e616
	 * Open our instance of UMAD.
Packit 13e616
	 */
Packit 13e616
	if ((r = umad_init()) < 0) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR,
Packit 13e616
			"ERR 5415: Error opening UMAD\n");
Packit 13e616
	}
Packit 13e616
Packit 13e616
	if ((n_cas = umad_get_cas_names(p_vend->ca_names,
Packit 13e616
					OSM_UMAD_MAX_CAS)) < 0) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR,
Packit 13e616
			"ERR 5416: umad_get_cas_names failed\n");
Packit 13e616
		r = n_cas;
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	p_vend->ca_count = n_cas;
Packit 13e616
	p_vend->mtbl.max = DEFAULT_OSM_UMAD_MAX_PENDING;
Packit 13e616
Packit 13e616
	if ((max = getenv("OSM_UMAD_MAX_PENDING")) != NULL) {
Packit 13e616
		int tmp = strtol(max, NULL, 0);
Packit 13e616
		if (tmp > 0)
Packit 13e616
			p_vend->mtbl.max = tmp;
Packit 13e616
		else
Packit 13e616
			OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "Error:"
Packit 13e616
				"OSM_UMAD_MAX_PENDING=%d is invalid\n",
Packit 13e616
				tmp);
Packit 13e616
	}
Packit 13e616
Packit 13e616
	OSM_LOG(p_vend->p_log, OSM_LOG_INFO, "%d pending umads specified\n",
Packit 13e616
		p_vend->mtbl.max);
Packit 13e616
Packit 13e616
	p_vend->mtbl.tbl = calloc(p_vend->mtbl.max, sizeof(*(p_vend->mtbl.tbl)));
Packit 13e616
	if (!p_vend->mtbl.tbl) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "Error:"
Packit 13e616
			"failed to allocate vendor match table\n");
Packit 13e616
		r = IB_INSUFFICIENT_MEMORY;
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
Exit:
Packit 13e616
	OSM_LOG_EXIT(p_log);
Packit 13e616
	return (r);
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
	osm_vendor_t *p_vend = NULL;
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(p_log);
Packit 13e616
Packit 13e616
	if (!timeout) {
Packit 13e616
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5433: "
Packit 13e616
			"transaction timeout cannot be 0\n");
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	p_vend = malloc(sizeof(*p_vend));
Packit 13e616
	if (p_vend == NULL) {
Packit 13e616
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5417: "
Packit 13e616
			"Unable to allocate vendor object\n");
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	memset(p_vend, 0, sizeof(*p_vend));
Packit 13e616
Packit 13e616
	if (osm_vendor_init(p_vend, p_log, timeout) != IB_SUCCESS) {
Packit 13e616
		free(p_vend);
Packit 13e616
		p_vend = NULL;
Packit 13e616
	}
Packit 13e616
Packit 13e616
Exit:
Packit 13e616
	OSM_LOG_EXIT(p_log);
Packit 13e616
	return (p_vend);
Packit 13e616
}
Packit 13e616
Packit 13e616
void osm_vendor_delete(IN osm_vendor_t ** const pp_vend)
Packit 13e616
{
Packit 13e616
	osm_vendor_close_port(*pp_vend);
Packit 13e616
Packit 13e616
	clear_madw(*pp_vend);
Packit 13e616
	/* make sure all ports are closed */
Packit 13e616
	umad_done();
Packit 13e616
Packit 13e616
	pthread_mutex_destroy(&(*pp_vend)->cb_mutex);
Packit 13e616
	pthread_mutex_destroy(&(*pp_vend)->match_tbl_mutex);
Packit 13e616
	free((*pp_vend)->mtbl.tbl);
Packit 13e616
	free(*pp_vend);
Packit 13e616
	*pp_vend = NULL;
Packit 13e616
}
Packit 13e616
Packit 13e616
ib_api_status_t
Packit 13e616
osm_vendor_get_all_port_attr(IN osm_vendor_t * const p_vend,
Packit 13e616
			     IN ib_port_attr_t * const p_attr_array,
Packit 13e616
			     IN uint32_t * const p_num_ports)
Packit 13e616
{
Packit 13e616
	umad_ca_t ca;
Packit 13e616
	ib_port_attr_t *attr = p_attr_array;
Packit 13e616
	unsigned done = 0;
Packit 13e616
	int r = 0, i, j, k;
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(p_vend->p_log);
Packit 13e616
Packit 13e616
	CL_ASSERT(p_vend && p_num_ports);
Packit 13e616
Packit 13e616
	if (!*p_num_ports) {
Packit 13e616
		r = IB_INVALID_PARAMETER;
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5418: "
Packit 13e616
			"Ports in should be > 0\n");
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	if (!p_attr_array) {
Packit 13e616
		r = IB_INSUFFICIENT_MEMORY;
Packit 13e616
		*p_num_ports = 0;
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	for (i = 0; i < p_vend->ca_count && !done; i++) {
Packit 13e616
		/* For each CA, retrieve the port attributes */
Packit 13e616
		if (umad_get_ca(p_vend->ca_names[i], &ca) == 0) {
Packit 13e616
			if (ca.node_type < 1 || ca.node_type > 3)
Packit 13e616
				continue;
Packit 13e616
			for (j = 0; j <= ca.numports; j++) {
Packit 13e616
				if (!ca.ports[j])
Packit 13e616
					continue;
Packit 13e616
				attr->port_guid = ca.ports[j]->port_guid;
Packit 13e616
				attr->lid = ca.ports[j]->base_lid;
Packit 13e616
				attr->port_num = ca.ports[j]->portnum;
Packit 13e616
				attr->sm_lid = ca.ports[j]->sm_lid;
Packit 13e616
				attr->sm_sl = ca.ports[j]->sm_sl;
Packit 13e616
				attr->link_state = ca.ports[j]->state;
Packit 13e616
				if (attr->num_pkeys && attr->p_pkey_table) {
Packit 13e616
					if (attr->num_pkeys > ca.ports[j]->pkeys_size)
Packit 13e616
						attr->num_pkeys = ca.ports[j]->pkeys_size;
Packit 13e616
					for (k = 0; k < attr->num_pkeys; k++)
Packit 13e616
						attr->p_pkey_table[k] =
Packit 13e616
							cl_hton16(ca.ports[j]->pkeys[k]);
Packit 13e616
				}
Packit 13e616
				attr->num_pkeys = ca.ports[j]->pkeys_size;
Packit 13e616
				if (attr->num_gids && attr->p_gid_table) {
Packit 13e616
					attr->p_gid_table[0].unicast.prefix = cl_hton64(ca.ports[j]->gid_prefix);
Packit 13e616
					attr->p_gid_table[0].unicast.interface_id = cl_hton64(ca.ports[j]->port_guid);
Packit 13e616
					attr->num_gids = 1;
Packit 13e616
				}
Packit 13e616
				attr++;
Packit 13e616
				if (attr - p_attr_array > *p_num_ports) {
Packit 13e616
					done = 1;
Packit 13e616
					break;
Packit 13e616
				}
Packit 13e616
			}
Packit 13e616
			umad_release_ca(&ca);
Packit 13e616
		}
Packit 13e616
	}
Packit 13e616
Packit 13e616
	*p_num_ports = attr - p_attr_array;
Packit 13e616
Packit 13e616
Exit:
Packit 13e616
	OSM_LOG_EXIT(p_vend->p_log);
Packit 13e616
	return r;
Packit 13e616
}
Packit 13e616
Packit 13e616
static int
Packit 13e616
osm_vendor_open_port(IN osm_vendor_t * const p_vend,
Packit 13e616
		     IN const ib_net64_t port_guid)
Packit 13e616
{
Packit 13e616
	__be64 portguids[OSM_UMAD_MAX_PORTS_PER_CA + 1];
Packit 13e616
	umad_ca_t umad_ca;
Packit 13e616
	int i = 0, umad_port_id = -1;
Packit 13e616
	char *name;
Packit 13e616
	int ca, r;
Packit 13e616
Packit 13e616
	CL_ASSERT(p_vend);
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(p_vend->p_log);
Packit 13e616
Packit 13e616
	if (p_vend->umad_port_id >= 0) {
Packit 13e616
		umad_port_id = p_vend->umad_port_id;
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	if (!port_guid) {
Packit 13e616
		name = NULL;
Packit 13e616
		i = 0;
Packit 13e616
		goto _found;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	for (ca = 0; ca < p_vend->ca_count; ca++) {
Packit 13e616
		if ((r = umad_get_ca_portguids(p_vend->ca_names[ca], portguids,
Packit 13e616
					       OSM_UMAD_MAX_PORTS_PER_CA + 1)) < 0) {
Packit 13e616
#ifdef __WIN__
Packit 13e616
			OSM_LOG(p_vend->p_log, OSM_LOG_VERBOSE,
Packit 13e616
#else
Packit 13e616
			OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5421: "
Packit 13e616
#endif
Packit 13e616
				"Unable to get CA %s port guids (%s)\n",
Packit 13e616
				p_vend->ca_names[ca], strerror(r));
Packit 13e616
			continue;
Packit 13e616
		}
Packit 13e616
		for (i = 0; i < r; i++)
Packit 13e616
			if (port_guid == portguids[i]) {
Packit 13e616
				name = p_vend->ca_names[ca];
Packit 13e616
				goto _found;
Packit 13e616
			}
Packit 13e616
	}
Packit 13e616
Packit 13e616
	/*
Packit 13e616
	 * No local CA owns this guid!
Packit 13e616
	 */
Packit 13e616
	OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5422: "
Packit 13e616
		"Unable to find requested CA guid 0x%" PRIx64 "\n",
Packit 13e616
		cl_ntoh64(port_guid));
Packit 13e616
	goto Exit;
Packit 13e616
Packit 13e616
_found:
Packit 13e616
	/* Validate that node is an IB node type (not iWARP) */
Packit 13e616
	if (umad_get_ca(name, &umad_ca) < 0) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 542A: "
Packit 13e616
			"umad_get_ca() failed\n");
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	if (umad_ca.node_type < 1 || umad_ca.node_type > 3) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 542D: "
Packit 13e616
			"Type %d of node \'%s\' is not an IB node type\n",
Packit 13e616
			umad_ca.node_type, umad_ca.ca_name);
Packit 13e616
		fprintf(stderr,
Packit 13e616
			"Type %d of node \'%s\' is not an IB node type\n",
Packit 13e616
			umad_ca.node_type, umad_ca.ca_name);
Packit 13e616
		umad_release_ca(&umad_ca);
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
	umad_release_ca(&umad_ca);
Packit 13e616
Packit 13e616
	/* Port found, try to open it */
Packit 13e616
	if (umad_get_port(name, i, &p_vend->umad_port) < 0) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 542B: "
Packit 13e616
			"umad_get_port() failed\n");
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	if ((umad_port_id = umad_open_port(p_vend->umad_port.ca_name,
Packit 13e616
					   p_vend->umad_port.portnum)) < 0) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 542C: "
Packit 13e616
			"umad_open_port() failed\n");
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	p_vend->umad_port_id = umad_port_id;
Packit 13e616
Packit 13e616
	/* start receiver thread */
Packit 13e616
	if (!(p_vend->receiver = calloc(1, sizeof(umad_receiver_t)))) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5423: "
Packit 13e616
			"Unable to alloc receiver struct\n");
Packit 13e616
		umad_close_port(umad_port_id);
Packit 13e616
		umad_release_port(&p_vend->umad_port);
Packit 13e616
		p_vend->umad_port.port_guid = 0;
Packit 13e616
		p_vend->umad_port_id = umad_port_id = -1;
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
	if (umad_receiver_start(p_vend) != 0) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5420: "
Packit 13e616
			"umad_receiver_init failed\n");
Packit 13e616
		umad_close_port(umad_port_id);
Packit 13e616
		umad_release_port(&p_vend->umad_port);
Packit 13e616
		p_vend->umad_port.port_guid = 0;
Packit 13e616
		p_vend->umad_port_id = umad_port_id = -1;
Packit 13e616
	}
Packit 13e616
Packit 13e616
Exit:
Packit 13e616
	OSM_LOG_EXIT(p_vend->p_log);
Packit 13e616
	return umad_port_id;
Packit 13e616
}
Packit 13e616
Packit 13e616
static void osm_vendor_close_port(osm_vendor_t * const p_vend)
Packit 13e616
{
Packit 13e616
	umad_receiver_t *p_ur;
Packit 13e616
	int i;
Packit 13e616
Packit 13e616
	p_ur = p_vend->receiver;
Packit 13e616
	p_vend->receiver = NULL;
Packit 13e616
	if (p_ur) {
Packit 13e616
		umad_receiver_stop(p_ur);
Packit 13e616
		free(p_ur);
Packit 13e616
	}
Packit 13e616
Packit 13e616
	if (p_vend->umad_port_id >= 0) {
Packit 13e616
		for (i = 0; i < OSM_UMAD_MAX_AGENTS; i++)
Packit 13e616
			if (p_vend->agents[i])
Packit 13e616
				umad_unregister(p_vend->umad_port_id, i);
Packit 13e616
		umad_close_port(p_vend->umad_port_id);
Packit 13e616
		umad_release_port(&p_vend->umad_port);
Packit 13e616
		p_vend->umad_port.port_guid = 0;
Packit 13e616
		p_vend->umad_port_id = -1;
Packit 13e616
	}
Packit 13e616
}
Packit 13e616
Packit 13e616
static int set_bit(int nr, void *method_mask)
Packit 13e616
{
Packit 13e616
	long mask, *addr = method_mask;
Packit 13e616
	int retval;
Packit 13e616
Packit 13e616
	addr += nr / (8 * sizeof(long));
Packit 13e616
	mask = 1L << (nr % (8 * sizeof(long)));
Packit 13e616
	retval = (mask & *addr) != 0;
Packit 13e616
	*addr |= mask;
Packit 13e616
	return retval;
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_user_bind,
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
	ib_net64_t port_guid;
Packit 13e616
	osm_umad_bind_info_t *p_bind = 0;
Packit 13e616
	long method_mask[16 / sizeof(long)];
Packit 13e616
	int umad_port_id;
Packit 13e616
	uint8_t rmpp_version;
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(p_vend->p_log);
Packit 13e616
Packit 13e616
	CL_ASSERT(p_user_bind);
Packit 13e616
	CL_ASSERT(p_mad_pool);
Packit 13e616
	CL_ASSERT(mad_recv_callback);
Packit 13e616
	CL_ASSERT(send_err_callback);
Packit 13e616
Packit 13e616
	port_guid = p_user_bind->port_guid;
Packit 13e616
Packit 13e616
	OSM_LOG(p_vend->p_log, OSM_LOG_INFO,
Packit 13e616
		"Mgmt class 0x%02x binding to port GUID 0x%" PRIx64 "\n",
Packit 13e616
		p_user_bind->mad_class, cl_ntoh64(port_guid));
Packit 13e616
Packit 13e616
	if ((umad_port_id = osm_vendor_open_port(p_vend, port_guid)) < 0) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5424: "
Packit 13e616
			"Unable to open port 0x%" PRIx64 "\n",
Packit 13e616
			cl_ntoh64(port_guid));
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	if (umad_get_issm_path(p_vend->umad_port.ca_name,
Packit 13e616
			       p_vend->umad_port.portnum,
Packit 13e616
			       p_vend->issm_path,
Packit 13e616
			       sizeof(p_vend->issm_path)) < 0) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 542E: "
Packit 13e616
			"Cannot resolve issm path for port %s:%u\n",
Packit 13e616
			p_vend->umad_port.ca_name, p_vend->umad_port.portnum);
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	if (!(p_bind = malloc(sizeof(*p_bind)))) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5425: "
Packit 13e616
			"Unable to allocate internal bind object\n");
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	memset(p_bind, 0, sizeof(*p_bind));
Packit 13e616
	p_bind->p_vend = p_vend;
Packit 13e616
	p_bind->port_id = umad_port_id;
Packit 13e616
	p_bind->client_context = context;
Packit 13e616
	p_bind->mad_recv_callback = mad_recv_callback;
Packit 13e616
	p_bind->send_err_callback = send_err_callback;
Packit 13e616
	p_bind->p_mad_pool = p_mad_pool;
Packit 13e616
	p_bind->port_guid = port_guid;
Packit 13e616
	p_bind->timeout = p_user_bind->timeout ? p_user_bind->timeout :
Packit 13e616
			  p_vend->timeout;
Packit 13e616
	p_bind->max_retries = p_user_bind->retries ? p_user_bind->retries :
Packit 13e616
			      p_vend->max_retries;
Packit 13e616
Packit 13e616
	memset(method_mask, 0, sizeof method_mask);
Packit 13e616
	if (p_user_bind->is_responder) {
Packit 13e616
		set_bit(IB_MAD_METHOD_GET, &method_mask);
Packit 13e616
		set_bit(IB_MAD_METHOD_SET, &method_mask);
Packit 13e616
		if (p_user_bind->mad_class == IB_MCLASS_SUBN_ADM) {
Packit 13e616
			set_bit(IB_MAD_METHOD_GETTABLE, &method_mask);
Packit 13e616
			set_bit(IB_MAD_METHOD_DELETE, &method_mask);
Packit 13e616
#ifdef DUAL_SIDED_RMPP
Packit 13e616
			set_bit(IB_MAD_METHOD_GETMULTI, &method_mask);
Packit 13e616
#endif
Packit 13e616
			/* Add in IB_MAD_METHOD_GETTRACETABLE */
Packit 13e616
			/* when supported by OpenSM */
Packit 13e616
		}
Packit 13e616
	}
Packit 13e616
	if (p_user_bind->is_report_processor)
Packit 13e616
		set_bit(IB_MAD_METHOD_REPORT, &method_mask);
Packit 13e616
	if (p_user_bind->is_trap_processor) {
Packit 13e616
		set_bit(IB_MAD_METHOD_TRAP, &method_mask);
Packit 13e616
		set_bit(IB_MAD_METHOD_TRAP_REPRESS, &method_mask);
Packit 13e616
	}
Packit 13e616
#ifndef VENDOR_RMPP_SUPPORT
Packit 13e616
	rmpp_version = 0;
Packit 13e616
#else
Packit 13e616
	/* If SA class, set rmpp_version */
Packit 13e616
	if (p_user_bind->mad_class == IB_MCLASS_SUBN_ADM)
Packit 13e616
		rmpp_version = 1;
Packit 13e616
	else
Packit 13e616
		rmpp_version = 0;
Packit 13e616
#endif
Packit 13e616
Packit 13e616
	if ((p_bind->agent_id = umad_register(p_vend->umad_port_id,
Packit 13e616
					      p_user_bind->mad_class,
Packit 13e616
					      p_user_bind->class_version,
Packit 13e616
					      rmpp_version, method_mask)) < 0) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5426: "
Packit 13e616
			"Unable to register class %u version %u\n",
Packit 13e616
			p_user_bind->mad_class, p_user_bind->class_version);
Packit 13e616
		free(p_bind);
Packit 13e616
		p_bind = 0;
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	if (p_bind->agent_id >= OSM_UMAD_MAX_AGENTS ||
Packit 13e616
	    p_vend->agents[p_bind->agent_id]) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5427: "
Packit 13e616
			"bad agent id %u or duplicate agent for class %u vers %u\n",
Packit 13e616
			p_bind->agent_id, p_user_bind->mad_class,
Packit 13e616
			p_user_bind->class_version);
Packit 13e616
		free(p_bind);
Packit 13e616
		p_bind = 0;
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	p_vend->agents[p_bind->agent_id] = p_bind;
Packit 13e616
Packit 13e616
	/* If Subn Directed Route class, register Subn LID routed class */
Packit 13e616
	if (p_user_bind->mad_class == IB_MCLASS_SUBN_DIR) {
Packit 13e616
		if ((p_bind->agent_id1 = umad_register(p_vend->umad_port_id,
Packit 13e616
						       IB_MCLASS_SUBN_LID,
Packit 13e616
						       p_user_bind->
Packit 13e616
						       class_version, 0,
Packit 13e616
						       method_mask)) < 0) {
Packit 13e616
			OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5428: "
Packit 13e616
				"Unable to register class 1 version %u\n",
Packit 13e616
				p_user_bind->class_version);
Packit 13e616
			free(p_bind);
Packit 13e616
			p_bind = 0;
Packit 13e616
			goto Exit;
Packit 13e616
		}
Packit 13e616
Packit 13e616
		if (p_bind->agent_id1 >= OSM_UMAD_MAX_AGENTS ||
Packit 13e616
		    p_vend->agents[p_bind->agent_id1]) {
Packit 13e616
			OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5429: "
Packit 13e616
				"bad agent id %u or duplicate agent for class 1 vers %u\n",
Packit 13e616
				p_bind->agent_id1, p_user_bind->class_version);
Packit 13e616
			free(p_bind);
Packit 13e616
			p_bind = 0;
Packit 13e616
			goto Exit;
Packit 13e616
		}
Packit 13e616
Packit 13e616
		p_vend->agents[p_bind->agent_id1] = p_bind;
Packit 13e616
	}
Packit 13e616
Packit 13e616
Exit:
Packit 13e616
	OSM_LOG_EXIT(p_vend->p_log);
Packit 13e616
	return ((osm_bind_handle_t) p_bind);
Packit 13e616
}
Packit 13e616
Packit 13e616
static void
Packit 13e616
__osm_vendor_recv_dummy_cb(IN osm_madw_t * p_madw,
Packit 13e616
			   IN void *bind_context, IN osm_madw_t * p_req_madw)
Packit 13e616
{
Packit 13e616
#ifdef _DEBUG_
Packit 13e616
	fprintf(stderr,
Packit 13e616
		"__osm_vendor_recv_dummy_cb: Ignoring received MAD after osm_vendor_unbind\n");
Packit 13e616
#endif
Packit 13e616
}
Packit 13e616
Packit 13e616
static void
Packit 13e616
__osm_vendor_send_err_dummy_cb(IN void *bind_context,
Packit 13e616
			       IN osm_madw_t * p_req_madw)
Packit 13e616
{
Packit 13e616
#ifdef _DEBUG_
Packit 13e616
	fprintf(stderr,
Packit 13e616
		"__osm_vendor_send_err_dummy_cb: Ignoring send error after osm_vendor_unbind\n");
Packit 13e616
#endif
Packit 13e616
}
Packit 13e616
Packit 13e616
void osm_vendor_unbind(IN osm_bind_handle_t h_bind)
Packit 13e616
{
Packit 13e616
	osm_umad_bind_info_t *p_bind = (osm_umad_bind_info_t *) h_bind;
Packit 13e616
	osm_vendor_t *p_vend = p_bind->p_vend;
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(p_vend->p_log);
Packit 13e616
Packit 13e616
	pthread_mutex_lock(&p_vend->cb_mutex);
Packit 13e616
	p_bind->mad_recv_callback = __osm_vendor_recv_dummy_cb;
Packit 13e616
	p_bind->send_err_callback = __osm_vendor_send_err_dummy_cb;
Packit 13e616
	pthread_mutex_unlock(&p_vend->cb_mutex);
Packit 13e616
Packit 13e616
	OSM_LOG_EXIT(p_vend->p_log);
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
	osm_umad_bind_info_t *p_bind = (osm_umad_bind_info_t *) h_bind;
Packit 13e616
	osm_vendor_t *p_vend = p_bind->p_vend;
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(p_vend->p_log);
Packit 13e616
Packit 13e616
	OSM_LOG(p_vend->p_log, OSM_LOG_DEBUG,
Packit 13e616
		"Acquiring UMAD for p_madw = %p, size = %u\n", p_vw, mad_size);
Packit 13e616
	CL_ASSERT(p_vw);
Packit 13e616
	p_vw->size = mad_size;
Packit 13e616
	p_vw->umad = umad_alloc(1, mad_size + umad_size());
Packit 13e616
Packit 13e616
	/* track locally */
Packit 13e616
	p_vw->h_bind = h_bind;
Packit 13e616
Packit 13e616
	OSM_LOG(p_vend->p_log, OSM_LOG_DEBUG,
Packit 13e616
		"Acquired UMAD %p, size = %u\n", p_vw->umad, p_vw->size);
Packit 13e616
Packit 13e616
	OSM_LOG_EXIT(p_vend->p_log);
Packit 13e616
	return (p_vw->umad ? umad_get_mad(p_vw->umad) : NULL);
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
	osm_umad_bind_info_t *p_bind = (osm_umad_bind_info_t *) h_bind;
Packit 13e616
	osm_vendor_t *p_vend = p_bind->p_vend;
Packit 13e616
	osm_madw_t *p_madw;
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(p_vend->p_log);
Packit 13e616
Packit 13e616
	CL_ASSERT(p_vw);
Packit 13e616
Packit 13e616
	OSM_LOG(p_vend->p_log, OSM_LOG_DEBUG, "Retiring UMAD %p\n", p_vw->umad);
Packit 13e616
Packit 13e616
	/*
Packit 13e616
	 * We moved the removal of the transaction to immediately after
Packit 13e616
	 * it was looked up.
Packit 13e616
	 */
Packit 13e616
Packit 13e616
	/* free the mad but the wrapper is part of the madw object */
Packit 13e616
	umad_free(p_vw->umad);
Packit 13e616
	p_vw->umad = 0;
Packit 13e616
	p_madw = PARENT_STRUCT(p_vw, osm_madw_t, vend_wrap);
Packit 13e616
	p_madw->p_mad = NULL;
Packit 13e616
Packit 13e616
	OSM_LOG_EXIT(p_vend->p_log);
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
	osm_umad_bind_info_t *const p_bind = h_bind;
Packit 13e616
	osm_vendor_t *const p_vend = p_bind->p_vend;
Packit 13e616
	osm_vend_wrap_t *const p_vw = osm_madw_get_vend_ptr(p_madw);
Packit 13e616
	osm_mad_addr_t *const p_mad_addr = osm_madw_get_mad_addr_ptr(p_madw);
Packit 13e616
	ib_mad_t *const p_mad = osm_madw_get_mad_ptr(p_madw);
Packit 13e616
	ib_sa_mad_t *const p_sa = (ib_sa_mad_t *) p_mad;
Packit 13e616
	ib_mad_addr_t mad_addr;
Packit 13e616
	int ret = -1;
Packit 13e616
	int __attribute__((__unused__)) is_rmpp = 0;
Packit 13e616
	uint32_t sent_mad_size, timeout = 0;
Packit 13e616
	uint64_t tid;
Packit 13e616
#ifndef VENDOR_RMPP_SUPPORT
Packit 13e616
	uint32_t paylen = 0;
Packit 13e616
#endif
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(p_vend->p_log);
Packit 13e616
Packit 13e616
	CL_ASSERT(p_vw->h_bind == h_bind);
Packit 13e616
	CL_ASSERT(p_mad == umad_get_mad(p_vw->umad));
Packit 13e616
Packit 13e616
	if (p_mad->mgmt_class == IB_MCLASS_SUBN_DIR) {
Packit 13e616
		umad_set_addr_net(p_vw->umad, 0xffff, 0, 0, 0);
Packit 13e616
		umad_set_grh(p_vw->umad, NULL);
Packit 13e616
		goto Resp;
Packit 13e616
	}
Packit 13e616
	if (p_mad->mgmt_class == IB_MCLASS_SUBN_LID) {
Packit 13e616
		umad_set_addr_net(p_vw->umad, p_mad_addr->dest_lid, 0, 0, 0);
Packit 13e616
		umad_set_grh(p_vw->umad, NULL);
Packit 13e616
		goto Resp;
Packit 13e616
	}
Packit 13e616
	/* GS classes */
Packit 13e616
	umad_set_addr_net(p_vw->umad, p_mad_addr->dest_lid,
Packit 13e616
			  p_mad_addr->addr_type.gsi.remote_qp,
Packit 13e616
			  p_mad_addr->addr_type.gsi.service_level,
Packit 13e616
			  IB_QP1_WELL_KNOWN_Q_KEY);
Packit 13e616
	if (p_mad_addr->addr_type.gsi.global_route) {
Packit 13e616
		mad_addr.grh_present = 1;
Packit 13e616
		mad_addr.gid_index = 0;
Packit 13e616
		mad_addr.hop_limit = p_mad_addr->addr_type.gsi.grh_info.hop_limit;
Packit 13e616
		ib_grh_get_ver_class_flow(p_mad_addr->addr_type.gsi.grh_info.ver_class_flow,
Packit 13e616
					  NULL, &mad_addr.traffic_class,
Packit 13e616
					  &mad_addr.flow_label);
Packit 13e616
		memcpy(&mad_addr.gid, &p_mad_addr->addr_type.gsi.grh_info.dest_gid, 16);
Packit 13e616
		umad_set_grh(p_vw->umad, &mad_addr);
Packit 13e616
	} else
Packit 13e616
		umad_set_grh(p_vw->umad, NULL);
Packit 13e616
	umad_set_pkey(p_vw->umad, p_mad_addr->addr_type.gsi.pkey_ix);
Packit 13e616
	if (ib_class_is_rmpp(p_mad->mgmt_class)) {	/* RMPP GS classes */
Packit 13e616
		if (!ib_rmpp_is_flag_set((ib_rmpp_mad_t *) p_sa,
Packit 13e616
					 IB_RMPP_FLAG_ACTIVE)) {
Packit 13e616
			/* Clear RMPP header when RMPP not ACTIVE */
Packit 13e616
			p_sa->rmpp_version = 0;
Packit 13e616
			p_sa->rmpp_type = 0;
Packit 13e616
			p_sa->rmpp_flags = 0;
Packit 13e616
			p_sa->rmpp_status = 0;
Packit 13e616
#ifdef VENDOR_RMPP_SUPPORT
Packit 13e616
		} else
Packit 13e616
			is_rmpp = 1;
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_DEBUG, "RMPP %d length %d\n",
Packit 13e616
			ib_rmpp_is_flag_set((ib_rmpp_mad_t *) p_sa,
Packit 13e616
					    IB_RMPP_FLAG_ACTIVE),
Packit 13e616
			p_madw->mad_size);
Packit 13e616
#else
Packit 13e616
		} else {
Packit 13e616
			p_sa->rmpp_version = 1;
Packit 13e616
			p_sa->seg_num = cl_ntoh32(1);	/* first DATA is seg 1 */
Packit 13e616
			p_sa->rmpp_flags |= (uint8_t) 0x70;	/* RRespTime of 14 (high 5 bits) */
Packit 13e616
			p_sa->rmpp_status = 0;
Packit 13e616
			paylen = p_madw->mad_size - IB_SA_MAD_HDR_SIZE;
Packit 13e616
			paylen += (IB_SA_MAD_HDR_SIZE - MAD_RMPP_HDR_SIZE);
Packit 13e616
			p_sa->paylen_newwin = cl_ntoh32(paylen);
Packit 13e616
		}
Packit 13e616
#endif
Packit 13e616
	}
Packit 13e616
Packit 13e616
Resp:
Packit 13e616
	if (resp_expected)
Packit 13e616
		put_madw(p_vend, p_madw, p_mad->trans_id, p_mad->mgmt_class);
Packit 13e616
Packit 13e616
#ifdef VENDOR_RMPP_SUPPORT
Packit 13e616
	sent_mad_size = p_madw->mad_size;
Packit 13e616
#else
Packit 13e616
	sent_mad_size = is_rmpp ? p_madw->mad_size - IB_SA_MAD_HDR_SIZE :
Packit 13e616
	    p_madw->mad_size;
Packit 13e616
#endif
Packit 13e616
	tid = cl_ntoh64(p_mad->trans_id);
Packit 13e616
	if (resp_expected) {
Packit 13e616
		if (p_madw->timeout)
Packit 13e616
			timeout = p_madw->timeout;
Packit 13e616
		else
Packit 13e616
			timeout = p_bind->timeout;
Packit 13e616
	}
Packit 13e616
	if ((ret = umad_send(p_bind->port_id, p_bind->agent_id, p_vw->umad,
Packit 13e616
			     sent_mad_size, timeout,
Packit 13e616
			     p_bind->max_retries)) < 0) {
Packit 13e616
		OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5430: "
Packit 13e616
			"Send p_madw = %p of size %d, Class 0x%x, Method 0x%X, "
Packit 13e616
			"Attr 0x%X, TID 0x%" PRIx64 " failed %d (%m)\n",
Packit 13e616
			p_madw, sent_mad_size, p_mad->mgmt_class,
Packit 13e616
			p_mad->method, cl_ntoh16(p_mad->attr_id), tid, ret);
Packit 13e616
		if (resp_expected) {
Packit 13e616
			get_madw(p_vend, &p_mad->trans_id,
Packit 13e616
				 p_mad->mgmt_class);	/* remove from aging table */
Packit 13e616
			p_madw->status = IB_ERROR;
Packit 13e616
			pthread_mutex_lock(&p_vend->cb_mutex);
Packit 13e616
			(*p_bind->send_err_callback) (p_bind->client_context, p_madw);	/* cb frees madw */
Packit 13e616
			pthread_mutex_unlock(&p_vend->cb_mutex);
Packit 13e616
		} else
Packit 13e616
			osm_mad_pool_put(p_bind->p_mad_pool, p_madw);
Packit 13e616
		goto Exit;
Packit 13e616
	}
Packit 13e616
Packit 13e616
	if (!resp_expected)
Packit 13e616
		osm_mad_pool_put(p_bind->p_mad_pool, p_madw);
Packit 13e616
Packit 13e616
	OSM_LOG(p_vend->p_log, OSM_LOG_DEBUG, "Completed sending %s TID 0x%" PRIx64 "\n",
Packit 13e616
		resp_expected ? "request" : "response or unsolicited", tid);
Packit 13e616
Exit:
Packit 13e616
	OSM_LOG_EXIT(p_vend->p_log);
Packit 13e616
	return (ret);
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_umad_bind_info_t *p_bind = (osm_umad_bind_info_t *) h_bind;
Packit 13e616
	osm_vendor_t *p_vend = p_bind->p_vend;
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(p_vend->p_log);
Packit 13e616
	;
Packit 13e616
	OSM_LOG_EXIT(p_vend->p_log);
Packit 13e616
	return (0);
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
	osm_umad_bind_info_t *p_bind = (osm_umad_bind_info_t *) h_bind;
Packit 13e616
	osm_vendor_t *p_vend = p_bind->p_vend;
Packit 13e616
Packit 13e616
	OSM_LOG_ENTER(p_vend->p_log);
Packit 13e616
	if (TRUE == is_sm_val) {
Packit 13e616
		p_vend->issmfd = open(p_vend->issm_path, O_NONBLOCK);
Packit 13e616
		if (p_vend->issmfd < 0) {
Packit 13e616
			OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5431: "
Packit 13e616
				"setting IS_SM capmask: cannot open file "
Packit 13e616
				"\'%s\': %s\n",
Packit 13e616
				p_vend->issm_path, strerror(errno));
Packit 13e616
			p_vend->issmfd = -1;
Packit 13e616
		}
Packit 13e616
	} else if (p_vend->issmfd != -1) {
Packit 13e616
		if (0 != close(p_vend->issmfd))
Packit 13e616
			OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5432: "
Packit 13e616
				"clearing IS_SM capmask: cannot close: %s\n",
Packit 13e616
				strerror(errno));
Packit 13e616
		p_vend->issmfd = -1;
Packit 13e616
	}
Packit 13e616
	OSM_LOG_EXIT(p_vend->p_log);
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
	umad_debug(level);
Packit 13e616
}
Packit 13e616
Packit 13e616
#endif				/* OSM_VENDOR_INTF_OPENIB */