|
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 |
*
|
|
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_sa_mad_ctrl_t.
|
|
Packit |
13e616 |
* This object is part of the SA object.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#if HAVE_CONFIG_H
|
|
Packit |
13e616 |
# include <config.h>
|
|
Packit |
13e616 |
#endif /* HAVE_CONFIG_H */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <string.h>
|
|
Packit |
13e616 |
#include <complib/cl_debug.h>
|
|
Packit |
13e616 |
#include <iba/ib_types.h>
|
|
Packit |
13e616 |
#include <opensm/osm_file_ids.h>
|
|
Packit |
13e616 |
#define FILE_ID OSM_FILE_SA_MAD_CTRL_C
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_api.h>
|
|
Packit |
13e616 |
#include <opensm/osm_sa_mad_ctrl.h>
|
|
Packit |
13e616 |
#include <opensm/osm_msgdef.h>
|
|
Packit |
13e616 |
#include <opensm/osm_helper.h>
|
|
Packit |
13e616 |
#include <opensm/osm_sa.h>
|
|
Packit |
13e616 |
#include <opensm/osm_opensm.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/****f* opensm: SA/sa_mad_ctrl_disp_done_callback
|
|
Packit |
13e616 |
* NAME
|
|
Packit |
13e616 |
* sa_mad_ctrl_disp_done_callback
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
* This function is the Dispatcher callback that indicates
|
|
Packit |
13e616 |
* a received MAD has been processed by the recipient.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* SYNOPSIS
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
static void sa_mad_ctrl_disp_done_callback(IN void *context, IN void *p_data)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_sa_mad_ctrl_t *p_ctrl = context;
|
|
Packit |
13e616 |
osm_madw_t *p_madw = p_data;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_ctrl->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_madw);
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Return the MAD & wrapper to the pool.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_ctrl->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/************/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/****f* opensm: SA/sa_mad_ctrl_process
|
|
Packit |
13e616 |
* NAME
|
|
Packit |
13e616 |
* sa_mad_ctrl_process
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
* This function handles known methods for received MADs.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* SYNOPSIS
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
static void sa_mad_ctrl_process(IN osm_sa_mad_ctrl_t * p_ctrl,
|
|
Packit |
13e616 |
IN osm_madw_t * p_madw,
|
|
Packit |
13e616 |
IN boolean_t is_get_request)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_sa_mad_t *p_sa_mad;
|
|
Packit |
13e616 |
cl_disp_reg_handle_t h_disp;
|
|
Packit |
13e616 |
cl_status_t status;
|
|
Packit |
13e616 |
cl_disp_msgid_t msg_id = CL_DISP_MSGID_NONE;
|
|
Packit |
13e616 |
uint64_t last_dispatched_msg_queue_time_msec;
|
|
Packit |
13e616 |
uint32_t num_messages;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_ctrl->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
If the dispatcher is showing us that it is overloaded
|
|
Packit |
13e616 |
there is no point in placing the request in. We should instead
|
|
Packit |
13e616 |
provide immediate response - IB_RESOURCE_BUSY
|
|
Packit |
13e616 |
But how do we know?
|
|
Packit |
13e616 |
The dispatcher reports back the number of outstanding messages and
|
|
Packit |
13e616 |
the time the last message stayed in the queue.
|
|
Packit |
13e616 |
HACK: Actually, we cannot send a mad from within the receive callback;
|
|
Packit |
13e616 |
thus - we will just drop it.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!is_get_request && p_ctrl->p_set_disp) {
|
|
Packit |
13e616 |
h_disp = p_ctrl->h_set_disp;
|
|
Packit |
13e616 |
goto SKIP_QUEUE_CHECK;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
h_disp = p_ctrl->h_disp;
|
|
Packit |
13e616 |
cl_disp_get_queue_status(h_disp, &num_messages,
|
|
Packit |
13e616 |
&last_dispatched_msg_queue_time_msec);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (num_messages > 1 && p_ctrl->p_subn->opt.max_msg_fifo_timeout &&
|
|
Packit |
13e616 |
last_dispatched_msg_queue_time_msec >
|
|
Packit |
13e616 |
p_ctrl->p_subn->opt.max_msg_fifo_timeout) {
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_INFO,
|
|
Packit |
13e616 |
/* "Responding BUSY status since the dispatcher is already" */
|
|
Packit |
13e616 |
"Dropping MAD since the dispatcher is already"
|
|
Packit |
13e616 |
" overloaded with %u messages and queue time of:"
|
|
Packit |
13e616 |
"%" PRIu64 "[msec]\n",
|
|
Packit |
13e616 |
num_messages, last_dispatched_msg_queue_time_msec);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* send a busy response */
|
|
Packit |
13e616 |
/* osm_sa_send_error(p_ctrl->p_resp, p_madw, IB_RESOURCE_BUSY); */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* return the request to the pool */
|
|
Packit |
13e616 |
osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
SKIP_QUEUE_CHECK:
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Note that attr_id (like the rest of the MAD) is in
|
|
Packit |
13e616 |
network byte order.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
switch (p_sa_mad->attr_id) {
|
|
Packit |
13e616 |
case IB_MAD_ATTR_CLASS_PORT_INFO:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_CLASS_PORT_INFO;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_NODE_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_NODE_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_PORTINFO_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_PORTINFO_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_LINK_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_LINK_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_SMINFO_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_SMINFO_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_SERVICE_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_SERVICE_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_PATH_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_PATH_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_MCMEMBER_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_MCMEMBER_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_INFORM_INFO:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_INFORM_INFO;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_VLARB_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_VL_ARB_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_SLVL_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_SLVL_TBL_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_PKEY_TBL_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_PKEY_TBL_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_LFT_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_LFT_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_GUIDINFO_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_GUIDINFO_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_INFORM_INFO_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_INFORM_INFO_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_SWITCH_INFO_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_SWITCH_INFO_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_ATTR_MFT_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_MFT_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
|
|
Packit |
13e616 |
case IB_MAD_ATTR_MULTIPATH_RECORD:
|
|
Packit |
13e616 |
msg_id = OSM_MSG_MAD_MULTIPATH_RECORD;
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
default:
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A01: "
|
|
Packit |
13e616 |
"Unsupported attribute 0x%X (%s)\n",
|
|
Packit |
13e616 |
cl_ntoh16(p_sa_mad->attr_id),
|
|
Packit |
13e616 |
ib_get_sa_attr_str(p_sa_mad->attr_id));
|
|
Packit |
13e616 |
osm_dump_sa_mad_v2(p_ctrl->p_log, p_sa_mad, FILE_ID, OSM_LOG_ERROR);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (msg_id != CL_DISP_MSGID_NONE) {
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Post this MAD to the dispatcher for asynchronous
|
|
Packit |
13e616 |
processing by the appropriate controller.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Posting Dispatcher message %s\n",
|
|
Packit |
13e616 |
osm_get_disp_msg_str(msg_id));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = cl_disp_post(h_disp, msg_id, p_madw,
|
|
Packit |
13e616 |
sa_mad_ctrl_disp_done_callback, p_ctrl);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (status != CL_SUCCESS) {
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A02: "
|
|
Packit |
13e616 |
"Dispatcher post message failed (%s) for attribute 0x%X (%s)\n",
|
|
Packit |
13e616 |
CL_STATUS_MSG(status),
|
|
Packit |
13e616 |
cl_ntoh16(p_sa_mad->attr_id),
|
|
Packit |
13e616 |
ib_get_sa_attr_str(p_sa_mad->attr_id));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
There is an unknown MAD attribute type for which there is
|
|
Packit |
13e616 |
no recipient. Simply retire the MAD here.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
cl_atomic_inc(&p_ctrl->p_stats->sa_mads_rcvd_unknown);
|
|
Packit |
13e616 |
osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_ctrl->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* PARAMETERS
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* RETURN VALUES
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* NOTES
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* SEE ALSO
|
|
Packit |
13e616 |
*********/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/****f* opensm: SA/sa_mad_ctrl_rcv_callback
|
|
Packit |
13e616 |
* NAME
|
|
Packit |
13e616 |
* sa_mad_ctrl_rcv_callback
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
* This is the callback from the transport layer for received MADs.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* SYNOPSIS
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
static void sa_mad_ctrl_rcv_callback(IN osm_madw_t * p_madw, IN void *context,
|
|
Packit |
13e616 |
IN osm_madw_t * p_req_madw)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_sa_mad_ctrl_t *p_ctrl = context;
|
|
Packit |
13e616 |
ib_sa_mad_t *p_sa_mad;
|
|
Packit |
13e616 |
boolean_t is_get_request = FALSE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_ctrl->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
A MAD was received from the wire, possibly in response to a request.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
cl_atomic_inc(&p_ctrl->p_stats->sa_mads_rcvd);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"%u SA MADs received\n", p_ctrl->p_stats->sa_mads_rcvd);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* C15-0.1.3 requires not responding to any MAD if the SM is
|
|
Packit |
13e616 |
* not in active state!
|
|
Packit |
13e616 |
* We will not respond if the sm_state is not MASTER, or if the
|
|
Packit |
13e616 |
* first_time_master_sweep flag (of the subnet) is TRUE - this
|
|
Packit |
13e616 |
* flag indicates that the master still didn't finish its first
|
|
Packit |
13e616 |
* sweep, so the subnet is not up and stable yet.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (p_ctrl->p_subn->sm_state != IB_SMINFO_STATE_MASTER) {
|
|
Packit |
13e616 |
cl_atomic_inc(&p_ctrl->p_stats->sa_mads_ignored);
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"Received SA MAD while SM not MASTER. MAD ignored\n");
|
|
Packit |
13e616 |
osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
if (p_ctrl->p_subn->first_time_master_sweep == TRUE) {
|
|
Packit |
13e616 |
cl_atomic_inc(&p_ctrl->p_stats->sa_mads_ignored);
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"Received SA MAD while SM in first sweep. MAD ignored\n");
|
|
Packit |
13e616 |
osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (OSM_LOG_IS_ACTIVE_V2(p_ctrl->p_log, OSM_LOG_FRAMES))
|
|
Packit |
13e616 |
osm_dump_sa_mad_v2(p_ctrl->p_log, p_sa_mad, FILE_ID, OSM_LOG_FRAMES);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* C15-0.1.5 - Table 185: SA Header - p884
|
|
Packit |
13e616 |
* SM_key should be either 0 or match the current SM_Key
|
|
Packit |
13e616 |
* otherwise discard the MAD.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (p_sa_mad->sm_key != 0 &&
|
|
Packit |
13e616 |
p_sa_mad->sm_key != p_ctrl->p_subn->opt.sa_key) {
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A04: "
|
|
Packit |
13e616 |
"Non-Zero MAD SM_Key: 0x%" PRIx64 " != SM_Key: 0x%"
|
|
Packit |
13e616 |
PRIx64 "; SA MAD ignored for method 0x%X attribute 0x%X (%s)\n",
|
|
Packit |
13e616 |
cl_ntoh64(p_sa_mad->sm_key),
|
|
Packit |
13e616 |
cl_ntoh64(p_ctrl->p_subn->opt.sa_key),
|
|
Packit |
13e616 |
p_sa_mad->method, cl_ntoh16(p_sa_mad->attr_id),
|
|
Packit |
13e616 |
ib_get_sa_attr_str(p_sa_mad->attr_id));
|
|
Packit |
13e616 |
osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
switch (p_sa_mad->method) {
|
|
Packit |
13e616 |
case IB_MAD_METHOD_REPORT_RESP:
|
|
Packit |
13e616 |
/* we do not really do anything with report responses -
|
|
Packit |
13e616 |
just retire the transaction */
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Received Report Response. Retiring the transaction\n");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_req_madw)
|
|
Packit |
13e616 |
osm_mad_pool_put(p_ctrl->p_mad_pool, p_req_madw);
|
|
Packit |
13e616 |
osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
case IB_MAD_METHOD_GET:
|
|
Packit |
13e616 |
case IB_MAD_METHOD_GETTABLE:
|
|
Packit |
13e616 |
#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
|
|
Packit |
13e616 |
case IB_MAD_METHOD_GETMULTI:
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
is_get_request = TRUE;
|
|
Packit |
13e616 |
case IB_MAD_METHOD_SET:
|
|
Packit |
13e616 |
case IB_MAD_METHOD_DELETE:
|
|
Packit |
13e616 |
/* if we are closing down simply do nothing */
|
|
Packit |
13e616 |
if (osm_exit_flag)
|
|
Packit |
13e616 |
osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
|
|
Packit |
13e616 |
else
|
|
Packit |
13e616 |
sa_mad_ctrl_process(p_ctrl, p_madw, is_get_request);
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
default:
|
|
Packit |
13e616 |
cl_atomic_inc(&p_ctrl->p_stats->sa_mads_rcvd_unknown);
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A05: "
|
|
Packit |
13e616 |
"Unsupported method = 0x%X\n", p_sa_mad->method);
|
|
Packit |
13e616 |
osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_ctrl->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* PARAMETERS
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* RETURN VALUES
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* NOTES
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* SEE ALSO
|
|
Packit |
13e616 |
*********/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/****f* opensm: SA/sa_mad_ctrl_send_err_callback
|
|
Packit |
13e616 |
* NAME
|
|
Packit |
13e616 |
* sa_mad_ctrl_send_err_callback
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* DESCRIPTION
|
|
Packit |
13e616 |
* This is the callback from the transport layer for send errors
|
|
Packit |
13e616 |
* on MADs that were expecting a response.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* SYNOPSIS
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
static void sa_mad_ctrl_send_err_callback(IN void *context,
|
|
Packit |
13e616 |
IN osm_madw_t * p_madw)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_sa_mad_ctrl_t *p_ctrl = context;
|
|
Packit |
13e616 |
cl_status_t status;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_ctrl->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
We should never be here since the SA never originates a request.
|
|
Packit |
13e616 |
Unless we generated a Report(Notice)
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
CL_ASSERT(p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A06: "
|
|
Packit |
13e616 |
"MAD completed in error (%s): "
|
|
Packit |
13e616 |
"%s(%s), attr_mod 0x%x, LID %u, TID 0x%" PRIx64 "\n",
|
|
Packit |
13e616 |
ib_get_err_str(p_madw->status),
|
|
Packit |
13e616 |
ib_get_sa_method_str(p_madw->p_mad->method),
|
|
Packit |
13e616 |
ib_get_sa_attr_str(p_madw->p_mad->attr_id),
|
|
Packit |
13e616 |
cl_ntoh32(p_madw->p_mad->attr_mod),
|
|
Packit |
13e616 |
cl_ntoh16(p_madw->mad_addr.dest_lid),
|
|
Packit |
13e616 |
cl_ntoh64(p_madw->p_mad->trans_id));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_dump_sa_mad_v2(p_ctrl->p_log, osm_madw_get_sa_mad_ptr(p_madw),
|
|
Packit |
13e616 |
FILE_ID, OSM_LOG_ERROR);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
An error occurred. No response was received to a request MAD.
|
|
Packit |
13e616 |
Retire the original request MAD.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (osm_madw_get_err_msg(p_madw) != CL_DISP_MSGID_NONE) {
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Posting Dispatcher message %s\n",
|
|
Packit |
13e616 |
osm_get_disp_msg_str(osm_madw_get_err_msg(p_madw)));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_ctrl->p_set_disp &&
|
|
Packit |
13e616 |
(p_madw->p_mad->method == IB_MAD_METHOD_SET ||
|
|
Packit |
13e616 |
p_madw->p_mad->method == IB_MAD_METHOD_DELETE))
|
|
Packit |
13e616 |
status = cl_disp_post(p_ctrl->h_set_disp,
|
|
Packit |
13e616 |
osm_madw_get_err_msg(p_madw),
|
|
Packit |
13e616 |
p_madw,
|
|
Packit |
13e616 |
sa_mad_ctrl_disp_done_callback,
|
|
Packit |
13e616 |
p_ctrl);
|
|
Packit |
13e616 |
else
|
|
Packit |
13e616 |
status = cl_disp_post(p_ctrl->h_disp,
|
|
Packit |
13e616 |
osm_madw_get_err_msg(p_madw),
|
|
Packit |
13e616 |
p_madw,
|
|
Packit |
13e616 |
sa_mad_ctrl_disp_done_callback,
|
|
Packit |
13e616 |
p_ctrl);
|
|
Packit |
13e616 |
if (status != CL_SUCCESS) {
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A07: "
|
|
Packit |
13e616 |
"Dispatcher post message failed (%s)\n",
|
|
Packit |
13e616 |
CL_STATUS_MSG(status));
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
} else /* No error message was provided, just retire the MAD. */
|
|
Packit |
13e616 |
osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_ctrl->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* PARAMETERS
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* RETURN VALUES
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* NOTES
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* SEE ALSO
|
|
Packit |
13e616 |
*********/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_sa_mad_ctrl_construct(IN osm_sa_mad_ctrl_t * p_ctrl)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
CL_ASSERT(p_ctrl);
|
|
Packit |
13e616 |
memset(p_ctrl, 0, sizeof(*p_ctrl));
|
|
Packit |
13e616 |
p_ctrl->h_disp = CL_DISP_INVALID_HANDLE;
|
|
Packit |
13e616 |
p_ctrl->h_set_disp = CL_DISP_INVALID_HANDLE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_sa_mad_ctrl_destroy(IN osm_sa_mad_ctrl_t * p_ctrl)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
CL_ASSERT(p_ctrl);
|
|
Packit |
13e616 |
cl_disp_unregister(p_ctrl->h_disp);
|
|
Packit |
13e616 |
cl_disp_unregister(p_ctrl->h_set_disp);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_sa_mad_ctrl_init(IN osm_sa_mad_ctrl_t * p_ctrl,
|
|
Packit |
13e616 |
IN osm_sa_t * sa,
|
|
Packit |
13e616 |
IN osm_mad_pool_t * p_mad_pool,
|
|
Packit |
13e616 |
IN osm_vendor_t * p_vendor,
|
|
Packit |
13e616 |
IN osm_subn_t * p_subn,
|
|
Packit |
13e616 |
IN osm_log_t * p_log,
|
|
Packit |
13e616 |
IN osm_stats_t * p_stats,
|
|
Packit |
13e616 |
IN cl_dispatcher_t * p_disp,
|
|
Packit |
13e616 |
IN cl_dispatcher_t * p_set_disp)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_sa_mad_ctrl_construct(p_ctrl);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_ctrl->sa = sa;
|
|
Packit |
13e616 |
p_ctrl->p_log = p_log;
|
|
Packit |
13e616 |
p_ctrl->p_disp = p_disp;
|
|
Packit |
13e616 |
p_ctrl->p_set_disp = p_set_disp;
|
|
Packit |
13e616 |
p_ctrl->p_mad_pool = p_mad_pool;
|
|
Packit |
13e616 |
p_ctrl->p_vendor = p_vendor;
|
|
Packit |
13e616 |
p_ctrl->p_stats = p_stats;
|
|
Packit |
13e616 |
p_ctrl->p_subn = p_subn;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_ctrl->h_disp = cl_disp_register(p_disp, CL_DISP_MSGID_NONE, NULL,
|
|
Packit |
13e616 |
p_ctrl);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_ctrl->h_disp == CL_DISP_INVALID_HANDLE) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 1A08: "
|
|
Packit |
13e616 |
"Dispatcher registration failed\n");
|
|
Packit |
13e616 |
status = IB_INSUFFICIENT_RESOURCES;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_set_disp) {
|
|
Packit |
13e616 |
p_ctrl->h_set_disp =
|
|
Packit |
13e616 |
cl_disp_register(p_set_disp, CL_DISP_MSGID_NONE, NULL,
|
|
Packit |
13e616 |
p_ctrl);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_ctrl->h_set_disp == CL_DISP_INVALID_HANDLE) {
|
|
Packit |
13e616 |
OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 1A0A: "
|
|
Packit |
13e616 |
"SA set dispatcher registration failed\n");
|
|
Packit |
13e616 |
status = IB_INSUFFICIENT_RESOURCES;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_sa_mad_ctrl_bind(IN osm_sa_mad_ctrl_t * p_ctrl,
|
|
Packit |
13e616 |
IN ib_net64_t port_guid)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_bind_info_t bind_info;
|
|
Packit |
13e616 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_ctrl->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_ctrl->h_bind != OSM_BIND_INVALID_HANDLE) {
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A09: "
|
|
Packit |
13e616 |
"Multiple binds not allowed\n");
|
|
Packit |
13e616 |
status = IB_ERROR;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
bind_info.class_version = 2;
|
|
Packit |
13e616 |
bind_info.is_responder = TRUE;
|
|
Packit |
13e616 |
bind_info.is_report_processor = FALSE;
|
|
Packit |
13e616 |
bind_info.is_trap_processor = FALSE;
|
|
Packit |
13e616 |
bind_info.mad_class = IB_MCLASS_SUBN_ADM;
|
|
Packit |
13e616 |
bind_info.port_guid = port_guid;
|
|
Packit |
13e616 |
bind_info.recv_q_size = OSM_SM_DEFAULT_QP1_RCV_SIZE;
|
|
Packit |
13e616 |
bind_info.send_q_size = OSM_SM_DEFAULT_QP1_SEND_SIZE;
|
|
Packit |
13e616 |
bind_info.timeout = p_ctrl->sa->p_subn->opt.transaction_timeout;
|
|
Packit |
13e616 |
bind_info.retries = p_ctrl->sa->p_subn->opt.transaction_retries;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"Binding to port GUID 0x%" PRIx64 "\n", cl_ntoh64(port_guid));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_ctrl->h_bind = osm_vendor_bind(p_ctrl->p_vendor, &bind_info,
|
|
Packit |
13e616 |
p_ctrl->p_mad_pool,
|
|
Packit |
13e616 |
sa_mad_ctrl_rcv_callback,
|
|
Packit |
13e616 |
sa_mad_ctrl_send_err_callback, p_ctrl);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_ctrl->h_bind == OSM_BIND_INVALID_HANDLE) {
|
|
Packit |
13e616 |
status = IB_ERROR;
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A10: "
|
|
Packit |
13e616 |
"Vendor specific bind failed (%s)\n",
|
|
Packit |
13e616 |
ib_get_err_str(status));
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_ctrl->p_log);
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_sa_mad_ctrl_unbind(IN osm_sa_mad_ctrl_t * p_ctrl)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status = IB_SUCCESS;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_ctrl->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_ctrl->h_bind == OSM_BIND_INVALID_HANDLE) {
|
|
Packit |
13e616 |
OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A11: "
|
|
Packit |
13e616 |
"No previous bind\n");
|
|
Packit |
13e616 |
status = IB_ERROR;
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_vendor_unbind(p_ctrl->h_bind);
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_ctrl->p_log);
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|