[openib-general] [PATCH 2/4] OpenSM: Add optional SA SwitchInfoRecord support

Hal Rosenstock halr at voltaire.com
Wed Dec 27 08:41:25 PST 2006


OpenSM: Add optional SA SwitchInfoRecord support

Signed-off-by: Hal Rosenstock <halr at voltaire.com>

diff --git a/osm/include/opensm/osm_sa_sw_info_record.h b/osm/include/opensm/osm_sa_sw_info_record.h
new file mode 100644
index 0000000..c6b421f
--- /dev/null
+++ b/osm/include/opensm/osm_sa_sw_info_record.h
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2006 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+/*
+ * Abstract:
+ * 	Declaration of osm_sir_rcv_t.
+ *	This object represents the SwitchInfo Receiver object.
+ *	attribute from a switch node.
+ *	This object is part of the OpenSM family of objects.
+ *
+ * Environment:
+ * 	Linux User Mode
+ *
+ */
+
+#ifndef _OSM_SIR_RCV_H_
+#define _OSM_SIR_RCV_H_
+
+#include <complib/cl_passivelock.h>
+#include <opensm/osm_base.h>
+#include <opensm/osm_madw.h>
+#include <opensm/osm_req.h>
+#include <opensm/osm_state_mgr.h>
+#include <opensm/osm_sa_response.h>
+#include <opensm/osm_subnet.h>
+#include <opensm/osm_log.h>
+
+#ifdef __cplusplus
+#  define BEGIN_C_DECLS extern "C" {
+#  define END_C_DECLS   }
+#else /* !__cplusplus */
+#  define BEGIN_C_DECLS
+#  define END_C_DECLS
+#endif /* __cplusplus */
+
+BEGIN_C_DECLS
+
+/****h* OpenSM/Switch Info Receiver
+* NAME
+*	Switch Info Receiver
+*
+* DESCRIPTION
+*	The Switch Info Receiver object encapsulates the information
+*	needed to receive the SwitchInfo attribute from a switch node.
+*
+*	The Switch Info Receiver object is thread safe.
+*
+*	This object should be treated as opaque and should be
+*	manipulated only through the provided functions.
+*
+* AUTHOR
+*	Hal Rosenstock, Voltaire 
+*
+*********/
+
+/****s* OpenSM: Switch Info Receiver/osm_sir_rcv_t
+* NAME
+*	osm_sir_rcv_t
+*
+* DESCRIPTION
+*	Switch Info Receiver structure.
+*
+*	This object should be treated as opaque and should
+*	be manipulated only through the provided functions.
+*
+* SYNOPSIS
+*/
+typedef struct _osm_sir_rcv
+{
+	osm_subn_t				*p_subn;
+	osm_sa_resp_t				*p_resp;
+	osm_mad_pool_t				*p_mad_pool;
+	osm_log_t				*p_log;
+	osm_req_t				*p_req;
+	osm_state_mgr_t				*p_state_mgr;
+	cl_plock_t				*p_lock;
+	cl_qlock_pool_t				pool;
+} osm_sir_rcv_t;
+/*
+* FIELDS
+*	p_subn
+*		Pointer to the Subnet object for this subnet.
+*
+*	p_log
+*		Pointer to the log object.
+*
+*	p_req
+*		Pointer to the Request object.
+*
+*	p_state_mgr
+*		Pointer to the State Manager object.
+*
+*	p_lock
+*		Pointer to the serializing lock.
+*
+* SEE ALSO
+*	Switch Info Receiver object
+*********/
+
+/****f* OpenSM: Switch Info Receiver/osm_sir_rcv_construct
+* NAME
+*	osm_sir_rcv_construct
+*
+* DESCRIPTION
+*	This function constructs a Switch Info Receiver object.
+*
+* SYNOPSIS
+*/
+void osm_sir_rcv_construct(
+	IN osm_sir_rcv_t* const p_ctrl );
+/*
+* PARAMETERS
+*	p_ctrl
+*		[in] Pointer to a Switch Info Receiver object to construct.
+*
+* RETURN VALUE
+*	This function does not return a value.
+*
+* NOTES
+*	Allows calling osm_sir_rcv_init, osm_sir_rcv_destroy,
+*	and osm_sir_rcv_is_inited.
+*
+*	Calling osm_sir_rcv_construct is a prerequisite to calling any other
+*	method except osm_sir_rcv_init.
+*
+* SEE ALSO
+*	Switch Info Receiver object, osm_sir_rcv_init,
+*	osm_sir_rcv_destroy, osm_sir_rcv_is_inited
+*********/
+
+/****f* OpenSM: Switch Info Receiver/osm_sir_rcv_destroy
+* NAME
+*	osm_sir_rcv_destroy
+*
+* DESCRIPTION
+*	The osm_sir_rcv_destroy function destroys the object, releasing
+*	all resources.
+*
+* SYNOPSIS
+*/
+void osm_sir_rcv_destroy(
+	IN osm_sir_rcv_t* const p_ctrl );
+/*
+* PARAMETERS
+*	p_ctrl
+*		[in] Pointer to the object to destroy.
+*
+* RETURN VALUE
+*	This function does not return a value.
+*
+* NOTES
+*	Performs any necessary cleanup of the specified
+*	Switch Info Receiver object.
+*	Further operations should not be attempted on the destroyed object.
+*	This function should only be called after a call to
+*	osm_sir_rcv_construct or osm_sir_rcv_init.
+*
+* SEE ALSO
+*	Switch Info Receiver object, osm_sir_rcv_construct,
+*	osm_sir_rcv_init
+*********/
+
+/****f* OpenSM: Switch Info Receiver/osm_sir_rcv_init
+* NAME
+*	osm_sir_rcv_init
+*
+* DESCRIPTION
+*	The osm_sir_rcv_init function initializes a
+*	Switch Info Receiver object for use.
+*
+* SYNOPSIS
+*/
+ib_api_status_t osm_sir_rcv_init(
+	IN osm_sir_rcv_t* const p_rcv,
+	IN osm_sa_resp_t* const p_resp,
+	IN osm_mad_pool_t* const p_mad_pool,
+	IN osm_subn_t* const p_subn,
+	IN osm_log_t* const p_log,
+	IN cl_plock_t* const p_lock );
+/*
+* PARAMETERS
+*	p_rcv
+*		[in] Pointer to an osm_sir_rcv_t object to initialize.
+*
+*	p_resp
+*		[in] Pointer to the SA Responder object.
+*
+*	p_mad_pool
+*		[in] Pointer to the mad pool.
+*
+*	p_subn
+*		[in] Pointer to the Subnet object for this subnet.
+*
+*	p_log
+*		[in] Pointer to the log object.
+*
+*	p_lock
+*		[in] Pointer to the OpenSM serializing lock.
+*
+* RETURN VALUES
+*	IB_SUCCESS if the Switch Info Receiver object was initialized
+*	successfully.
+*
+* NOTES
+*	Allows calling other Switch Info Receiver methods.
+*
+* SEE ALSO
+*	Switch Info Receiver object, osm_sir_rcv_construct,
+*	osm_sir_rcv_destroy, osm_sir_rcv_is_inited
+*********/
+
+/****f* OpenSM: Switch Info Receiver/osm_sir_rcv_is_inited
+* NAME
+*	osm_sir_rcv_is_inited
+*
+* DESCRIPTION
+*	Indicates if the object has been initialized with osm_sir_rcv_init.
+*
+* SYNOPSIS
+*/
+boolean_t osm_sir_rcv_is_inited(
+	IN const osm_sir_rcv_t* const p_ctrl );
+/*
+* PARAMETERS
+*	p_ctrl
+*		[in] Pointer to an osm_sir_rcv_t object.
+*
+* RETURN VALUES
+*	TRUE if the object was initialized successfully,
+*	FALSE otherwise.
+*
+* NOTES
+*	The osm_sir_rcv_construct or osm_sir_rcv_init must be
+*	called before using this function.
+*
+* SEE ALSO
+*	Switch Info Receiver object, osm_sir_rcv_construct,
+*	osm_sir_rcv_init
+*********/
+
+/****f* OpenSM: Switch Info Receiver/osm_sir_rcv_process
+* NAME
+*	osm_sir_rcv_process
+*
+* DESCRIPTION
+*	Process the SwitchInfo attribute.
+*
+* SYNOPSIS
+*/
+void osm_sir_rcv_process(
+	IN osm_sir_rcv_t* const p_ctrl,
+	IN const osm_madw_t*   const p_madw );
+/*
+* PARAMETERS
+*	p_ctrl
+*		[in] Pointer to an osm_sir_rcv_t object.
+*
+*	p_madw
+*		[in] Pointer to the MAD Wrapper containing the MAD
+*		that contains the node's SwitchInfo attribute.
+*
+* RETURN VALUES
+*	CL_SUCCESS if the SwitchInfo processing was successful.
+*
+* NOTES
+*	This function processes a SwitchInfo attribute.
+*
+* SEE ALSO
+*	Switch Info Receiver, Switch Info Response Controller
+*********/
+
+END_C_DECLS
+
+#endif	/* _OSM_SIR_RCV_H_ */
diff --git a/osm/include/opensm/osm_sa_sw_info_record_ctrl.h b/osm/include/opensm/osm_sa_sw_info_record_ctrl.h
new file mode 100644
index 0000000..b58654f
--- /dev/null
+++ b/osm/include/opensm/osm_sa_sw_info_record_ctrl.h
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+/*
+ * Abstract:
+ * 	Declaration of osm_sir_rcv_ctrl_t.
+ *	This object represents a controller that receives the IBA SwitchInfo
+ *	attribute from a switch node.
+ *	This object is part of the OpenSM family of objects.
+ *
+ * Environment:
+ * 	Linux User Mode
+ *
+ */
+
+#ifndef _OSM_SIR_RCV_CTRL_H_
+#define _OSM_SIR_RCV_CTRL_H_
+
+#include <complib/cl_dispatcher.h>
+#include <opensm/osm_base.h>
+#include <opensm/osm_madw.h>
+#include <opensm/osm_sa_sw_info_record.h>
+#include <opensm/osm_log.h>
+
+#ifdef __cplusplus
+#  define BEGIN_C_DECLS extern "C" {
+#  define END_C_DECLS   }
+#else /* !__cplusplus */
+#  define BEGIN_C_DECLS
+#  define END_C_DECLS
+#endif /* __cplusplus */
+
+BEGIN_C_DECLS
+
+/****h* OpenSM/Switch Info Receive Controller
+* NAME
+*	Switch Info Receive Controller
+*
+* DESCRIPTION
+*	The Switch Info Receive Controller object encapsulates the information
+*	needed to receive the SwitchInfo attribute from a switch node.
+*
+*	The Switch Info Receive Controller object is thread safe.
+*
+*	This object should be treated as opaque and should be
+*	manipulated only through the provided functions.
+*
+* AUTHOR
+*	Hal Rosenstock, Voltaire
+*
+*********/
+
+/****s* OpenSM: Switch Info Receive Controller/osm_sir_rcv_ctrl_t
+* NAME
+*	osm_sir_rcv_ctrl_t
+*
+* DESCRIPTION
+*	Switch Info Receive Controller structure.
+*
+*	This object should be treated as opaque and should
+*	be manipulated only through the provided functions.
+*
+* SYNOPSIS
+*/
+typedef struct _osm_sir_rcv_ctrl
+{
+	osm_sir_rcv_t			*p_rcv;
+	osm_log_t			*p_log;
+	cl_dispatcher_t			*p_disp;
+	cl_disp_reg_handle_t		h_disp;
+} osm_sir_rcv_ctrl_t;
+/*
+* FIELDS
+*	p_rcv
+*		Pointer to the Switch Info Receiver object.
+*
+*	p_log
+*		Pointer to the log object.
+*
+*	p_disp
+*		Pointer to the Dispatcher.
+*
+*	h_disp
+*		Handle returned from dispatcher registration.
+*
+* SEE ALSO
+*	Switch Info Receive Controller object
+*	Switch Info Receiver object
+*********/
+
+/****f* OpenSM: Switch Info Receive Controller/osm_sir_rcv_ctrl_construct
+* NAME
+*	osm_sir_rcv_ctrl_construct
+*
+* DESCRIPTION
+*	This function constructs a Switch Info Receive Controller object.
+*
+* SYNOPSIS
+*/
+void osm_sir_rcv_ctrl_construct(
+	IN osm_sir_rcv_ctrl_t* const p_ctrl );
+/*
+* PARAMETERS
+*	p_ctrl
+*		[in] Pointer to a Switch Info Receive Controller
+*		object to construct.
+*
+* RETURN VALUE
+*	This function does not return a value.
+*
+* NOTES
+*	Allows calling osm_sir_rcv_ctrl_init, osm_sir_rcv_ctrl_destroy,
+*	and osm_sir_rcv_ctrl_is_inited.
+*
+*	Calling osm_sir_rcv_ctrl_construct is a prerequisite to calling any
+*	other method except osm_sir_rcv_ctrl_init.
+*
+* SEE ALSO
+*	Switch Info Receive Controller object, osm_sir_rcv_ctrl_init,
+*	osm_sir_rcv_ctrl_destroy, osm_sir_rcv_ctrl_is_inited
+*********/
+
+/****f* OpenSM: Switch Info Receive Controller/osm_sir_rcv_ctrl_destroy
+* NAME
+*	osm_sir_rcv_ctrl_destroy
+*
+* DESCRIPTION
+*	The osm_sir_rcv_ctrl_destroy function destroys the object, releasing
+*	all resources.
+*
+* SYNOPSIS
+*/
+void osm_sir_rcv_ctrl_destroy(
+	IN osm_sir_rcv_ctrl_t* const p_ctrl );
+/*
+* PARAMETERS
+*	p_ctrl
+*		[in] Pointer to the object to destroy.
+*
+* RETURN VALUE
+*	This function does not return a value.
+*
+* NOTES
+*	Performs any necessary cleanup of the specified
+*	Switch Info Receive Controller object.
+*	Further operations should not be attempted on the destroyed object.
+*	This function should only be called after a call to
+*	osm_sir_rcv_ctrl_construct or osm_sir_rcv_ctrl_init.
+*
+* SEE ALSO
+*	Switch Info Receive Controller object, osm_sir_rcv_ctrl_construct,
+*	osm_sir_rcv_ctrl_init
+*********/
+
+/****f* OpenSM: Switch Info Receive Controller/osm_sir_rcv_ctrl_init
+* NAME
+*	osm_sir_rcv_ctrl_init
+*
+* DESCRIPTION
+*	The osm_sir_rcv_ctrl_init function initializes a
+*	Switch Info Receive Controller object for use.
+*
+* SYNOPSIS
+*/
+ib_api_status_t osm_sir_rcv_ctrl_init(
+	IN osm_sir_rcv_ctrl_t* const p_ctrl,
+	IN osm_sir_rcv_t* const p_rcv,
+	IN osm_log_t* const p_log,
+	IN cl_dispatcher_t* const p_disp );
+/*
+* PARAMETERS
+*	p_ctrl
+*		[in] Pointer to an osm_sir_rcv_ctrl_t object to initialize.
+*
+*	p_rcv
+*		[in] Pointer to an osm_sir_rcv_t object.
+*
+*	p_log
+*		[in] Pointer to the log object.
+*
+*	p_disp
+*		[in] Pointer to the OpenSM central Dispatcher.
+*
+* RETURN VALUES
+*	CL_SUCCESS if the Switch Info Receive Controller object was initialized
+*	successfully.
+*
+* NOTES
+*	Allows calling other Switch Info Receive Controller methods.
+*
+* SEE ALSO
+*	Switch Info Receive Controller object, osm_sir_rcv_ctrl_construct,
+*	osm_sir_rcv_ctrl_destroy, osm_sir_rcv_ctrl_is_inited
+*********/
+
+/****f* OpenSM: Switch Info Receive Controller/osm_sir_rcv_ctrl_is_inited
+* NAME
+*	osm_sir_rcv_ctrl_is_inited
+*
+* DESCRIPTION
+*	Indicates if the object has been initialized with osm_sir_rcv_ctrl_init.
+*
+* SYNOPSIS
+*/
+boolean_t osm_sir_rcv_ctrl_is_inited(
+	IN const osm_sir_rcv_ctrl_t* const p_ctrl );
+/*
+* PARAMETERS
+*	p_ctrl
+*		[in] Pointer to an osm_sir_rcv_ctrl_t object.
+*
+* RETURN VALUES
+*	TRUE if the object was initialized successfully,
+*	FALSE otherwise.
+*
+* NOTES
+*	The osm_sir_rcv_ctrl_construct or osm_sir_rcv_ctrl_init must be
+*	called before using this function.
+*
+* SEE ALSO
+*	Switch Info Receive Controller object, osm_sir_rcv_ctrl_construct,
+*	osm_sir_rcv_ctrl_init
+*********/
+
+END_C_DECLS
+
+#endif	/* _OSM_SIR_RCV_CTRL_H_ */
diff --git a/osm/opensm/osm_sa_sw_info_record.c b/osm/opensm/osm_sa_sw_info_record.c
new file mode 100644
index 0000000..2da30ba
--- /dev/null
+++ b/osm/opensm/osm_sa_sw_info_record.c
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+/*
+ * Abstract:
+ *    Implementation of osm_sir_rcv_t.
+ * This object represents the SwitchInfo Receiver object.
+ * This object is part of the opensm family of objects.
+ *
+ * Environment:
+ *    Linux User Mode
+ *
+ */
+
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <string.h>
+#include <iba/ib_types.h>
+#include <complib/cl_debug.h>
+#include <complib/cl_qlist.h>
+#include <opensm/osm_sa_sw_info_record.h>
+#include <opensm/osm_node.h>
+#include <vendor/osm_vendor_api.h>
+#include <opensm/osm_helper.h>
+#include <opensm/osm_pkey.h>
+
+#define OSM_SIR_RCV_POOL_MIN_SIZE    32
+#define OSM_SIR_RCV_POOL_GROW_SIZE   32
+
+typedef  struct _osm_sir_item
+{
+  cl_pool_item_t           pool_item;
+  ib_switch_info_record_t  rec;
+} osm_sir_item_t;
+
+typedef  struct _osm_sir_search_ctxt
+{
+  const ib_switch_info_record_t* p_rcvd_rec;
+  ib_net64_t               comp_mask;
+  cl_qlist_t*              p_list;
+  osm_sir_rcv_t*           p_rcv;
+  const osm_physp_t*       p_req_physp;
+} osm_sir_search_ctxt_t;
+
+/**********************************************************************
+ **********************************************************************/
+void
+osm_sir_rcv_construct(
+  IN osm_sir_rcv_t* const p_rcv )
+{
+  memset( p_rcv, 0, sizeof(*p_rcv) );
+  cl_qlock_pool_construct( &p_rcv->pool );
+}
+
+/**********************************************************************
+ **********************************************************************/
+void
+osm_sir_rcv_destroy(
+  IN osm_sir_rcv_t* const p_rcv )
+{
+  OSM_LOG_ENTER( p_rcv->p_log, osm_sir_rcv_destroy );
+  cl_qlock_pool_destroy( &p_rcv->pool );
+  OSM_LOG_EXIT( p_rcv->p_log );
+}
+
+/**********************************************************************
+ **********************************************************************/
+ib_api_status_t
+osm_sir_rcv_init(
+  IN osm_sir_rcv_t*        const p_rcv,
+  IN osm_sa_resp_t*        const p_resp,
+  IN osm_mad_pool_t*       const p_mad_pool,
+  IN osm_subn_t*           const p_subn,
+  IN osm_log_t*            const p_log,
+  IN cl_plock_t*           const p_lock )
+{
+  ib_api_status_t          status;
+
+  OSM_LOG_ENTER( p_log, osm_sir_rcv_init );
+
+  osm_sir_rcv_construct( p_rcv );
+
+  p_rcv->p_log = p_log;
+  p_rcv->p_subn = p_subn;
+  p_rcv->p_lock = p_lock;
+  p_rcv->p_resp = p_resp;
+  p_rcv->p_mad_pool = p_mad_pool;
+
+  status = cl_qlock_pool_init( &p_rcv->pool,
+                               OSM_SIR_RCV_POOL_MIN_SIZE,
+                               0,
+                               OSM_SIR_RCV_POOL_GROW_SIZE,
+                               sizeof(osm_sir_item_t),
+                               NULL, NULL, NULL );
+
+  OSM_LOG_EXIT( p_log );
+  return( status );
+}
+
+/**********************************************************************
+ **********************************************************************/
+static ib_api_status_t
+__osm_sir_rcv_new_sir(
+  IN osm_sir_rcv_t*        const p_rcv,
+  IN const osm_switch_t*   const p_sw,
+  IN cl_qlist_t*           const p_list,
+  IN ib_net16_t            const lid )
+{
+  osm_sir_item_t*          p_rec_item;
+  ib_api_status_t          status = IB_SUCCESS;
+
+  OSM_LOG_ENTER( p_rcv->p_log, __osm_sir_rcv_new_sir );
+
+  p_rec_item = (osm_sir_item_t*)cl_qlock_pool_get( &p_rcv->pool );
+  if( p_rec_item == NULL )
+  {
+    osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+             "__osm_sir_rcv_new_sir: ERR 5308: "
+             "cl_qlock_pool_get failed\n" );
+    status = IB_INSUFFICIENT_RESOURCES;
+    goto Exit;
+  }
+
+  if( osm_log_is_active( p_rcv->p_log, OSM_LOG_DEBUG ) )
+  {
+    osm_log( p_rcv->p_log, OSM_LOG_DEBUG,
+             "__osm_sir_rcv_new_sir: "
+             "New SwitchInfoRecord: lid 0x%X\n",
+             cl_ntoh16( lid )
+             );
+  }
+
+  memset( &p_rec_item->rec, 0, sizeof(ib_switch_info_record_t) );
+
+  p_rec_item->rec.lid = lid;
+  p_rec_item->rec.switch_info = p_sw->switch_info;
+
+  cl_qlist_insert_tail( p_list, (cl_list_item_t*)&p_rec_item->pool_item );
+
+ Exit:
+  OSM_LOG_EXIT( p_rcv->p_log );
+  return( status );
+}
+
+/**********************************************************************
+ **********************************************************************/
+static osm_port_t*
+__osm_sir_get_port_by_guid(
+  IN osm_sir_rcv_t*   const p_rcv,
+  IN uint64_t         port_guid )
+{
+  osm_port_t*         p_port;
+
+  CL_PLOCK_ACQUIRE(p_rcv->p_lock);
+
+  p_port = (osm_port_t *)cl_qmap_get(&p_rcv->p_subn->port_guid_tbl,
+                                     port_guid);
+  if (p_port == (osm_port_t *)cl_qmap_end(&p_rcv->p_subn->port_guid_tbl))
+  {
+    osm_log( p_rcv->p_log, OSM_LOG_DEBUG,
+             "__osm_sir_get_port_by_guid ERR 5309: "
+             "Invalid port GUID 0x%016" PRIx64 "\n",
+             port_guid );
+    p_port = NULL;
+  }
+
+  CL_PLOCK_RELEASE(p_rcv->p_lock);
+  return p_port;
+}
+
+/**********************************************************************
+ **********************************************************************/
+static void
+__osm_sir_rcv_create_sir(
+  IN osm_sir_rcv_t*        const p_rcv,
+  IN const osm_switch_t*   const p_sw,
+  IN cl_qlist_t*           const p_list,
+  IN ib_net16_t            const match_lid,
+  IN const osm_physp_t*    const p_req_physp )
+{
+  osm_port_t*              p_port;
+  const osm_physp_t*       p_physp;
+  uint16_t                 match_lid_ho;
+  ib_net16_t               min_lid_ho;
+  ib_net16_t               max_lid_ho;
+
+  OSM_LOG_ENTER( p_rcv->p_log, __osm_sir_rcv_create_sir );
+
+  if( osm_log_is_active( p_rcv->p_log, OSM_LOG_DEBUG ) )
+  {
+    osm_log( p_rcv->p_log, OSM_LOG_DEBUG,
+             "__osm_sir_rcv_create_sir: "
+             "Looking for SwitchInfoRecord with LID: 0x%X\n",
+             cl_ntoh16( match_lid )
+             );
+  }
+
+  /* In switches, the port guid is the node guid. */
+  p_port =
+    __osm_sir_get_port_by_guid( p_rcv, p_sw->p_node->node_info.port_guid );
+  if (! p_port)
+  {
+    osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+             "__osm_sir_rcv_create_sir: ERR 530A: "
+             "Failed to find Port by Node Guid:0x%016" PRIx64
+             "\n",
+             cl_ntoh64( p_sw->p_node->node_info.node_guid )
+             );
+    goto Exit;
+  }
+
+  /* check that the requester physp and the current physp are under
+     the same partition. */
+  p_physp = osm_port_get_default_phys_ptr( p_port );
+  if (! p_physp)
+  {
+    osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+             "__osm_sir_rcv_create_sir: ERR 530B: "
+             "Failed to find default physical Port by Node Guid:0x%016" PRIx64
+             "\n",
+             cl_ntoh64( p_sw->p_node->node_info.node_guid )
+             );
+    goto Exit;
+  }
+  if (! osm_physp_share_pkey( p_rcv->p_log, p_req_physp, p_physp ))
+    goto Exit;
+
+  /* get the port 0 of the switch */
+  osm_port_get_lid_range_ho( p_port, &min_lid_ho, &max_lid_ho );
+
+  match_lid_ho = cl_ntoh16( match_lid );
+  if( match_lid_ho )
+  {
+    /*
+      We validate that the lid belongs to this switch.
+    */
+    if( osm_log_is_active( p_rcv->p_log, OSM_LOG_DEBUG ) )
+    {
+      osm_log( p_rcv->p_log, OSM_LOG_DEBUG,
+               "__osm_sir_rcv_create_sir: "
+               "Comparing LID: 0x%X <= 0x%X <= 0x%X\n",
+               min_lid_ho, match_lid_ho, max_lid_ho
+               );
+    }
+
+    if ( match_lid_ho < min_lid_ho || match_lid_ho > max_lid_ho )
+      goto Exit;
+
+  }
+
+  __osm_sir_rcv_new_sir( p_rcv, p_sw, p_list, osm_port_get_base_lid(p_port) );
+
+Exit:
+  OSM_LOG_EXIT( p_rcv->p_log );
+}
+
+/**********************************************************************
+ **********************************************************************/
+static void
+__osm_sir_rcv_by_comp_mask(
+  IN cl_map_item_t*        const p_map_item,
+  IN void*                 context )
+{
+  const osm_sir_search_ctxt_t* const p_ctxt = (osm_sir_search_ctxt_t *)context;
+  const osm_switch_t*      const p_sw = (osm_switch_t*)p_map_item;
+  const ib_switch_info_record_t* const p_rcvd_rec = p_ctxt->p_rcvd_rec;
+  const osm_physp_t*       const p_req_physp = p_ctxt->p_req_physp;
+  osm_sir_rcv_t*           const p_rcv = p_ctxt->p_rcv;
+  ib_net64_t               const comp_mask = p_ctxt->comp_mask;
+  ib_net16_t               match_lid = 0;
+
+  OSM_LOG_ENTER( p_ctxt->p_rcv->p_log, __osm_sir_rcv_by_comp_mask );
+
+  osm_dump_switch_info(
+    p_ctxt->p_rcv->p_log,
+    &p_sw->switch_info,
+    OSM_LOG_VERBOSE );    
+
+  if( comp_mask & IB_SWIR_COMPMASK_LID )
+    match_lid = p_rcvd_rec->lid;
+
+  __osm_sir_rcv_create_sir( p_rcv, p_sw, p_ctxt->p_list,
+                            match_lid, p_req_physp );
+
+  OSM_LOG_EXIT( p_ctxt->p_rcv->p_log );
+}
+
+/**********************************************************************
+ **********************************************************************/
+void
+osm_sir_rcv_process(
+  IN osm_sir_rcv_t*        const p_rcv,
+  IN const osm_madw_t*     const p_madw )
+{
+  const ib_sa_mad_t*       p_rcvd_mad;
+  const ib_switch_info_record_t*  p_rcvd_rec;
+  ib_switch_info_record_t*        p_resp_rec;
+  cl_qlist_t               rec_list;
+  osm_madw_t*              p_resp_madw;
+  ib_sa_mad_t*             p_resp_sa_mad;
+  uint32_t                 num_rec, pre_trim_num_rec;
+#ifndef VENDOR_RMPP_SUPPORT
+  uint32_t		   trim_num_rec;
+#endif
+  uint32_t                 i;
+  osm_sir_search_ctxt_t    context;
+  osm_sir_item_t*          p_rec_item;
+  ib_api_status_t          status;
+  osm_physp_t*             p_req_physp;
+
+  CL_ASSERT( p_rcv );
+
+  OSM_LOG_ENTER( p_rcv->p_log, osm_sir_rcv_process );
+
+  CL_ASSERT( p_madw );
+
+  p_rcvd_mad = osm_madw_get_sa_mad_ptr( p_madw );
+  p_rcvd_rec = (ib_switch_info_record_t*)ib_sa_mad_get_payload_ptr( p_rcvd_mad );
+
+  CL_ASSERT( p_rcvd_mad->attr_id == IB_MAD_ATTR_SWITCH_INFO_RECORD );
+
+  /* we only support SubnAdmGet and SubnAdmGetTable methods */
+  if ( (p_rcvd_mad->method != IB_MAD_METHOD_GET) &&
+       (p_rcvd_mad->method != IB_MAD_METHOD_GETTABLE) ) {
+    osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+             "osm_sir_rcv_process: ERR 5305: "
+             "Unsupported Method (%s)\n",
+             ib_get_sa_method_str( p_rcvd_mad->method ) );
+    osm_sa_send_error( p_rcv->p_resp, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR );
+    goto Exit;
+  }
+
+  /* update the requester physical port. */
+  p_req_physp = osm_get_physp_by_mad_addr(p_rcv->p_log,
+                                          p_rcv->p_subn,
+                                          osm_madw_get_mad_addr_ptr(p_madw) );
+  if (p_req_physp == NULL)
+  {
+    osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+             "osm_sir_rcv_process: ERR 5304: "
+             "Cannot find requester physical port\n" );
+    goto Exit;
+  }
+
+  if ( osm_log_is_active( p_rcv->p_log, OSM_LOG_DEBUG ) )
+    osm_dump_switch_info_record( p_rcv->p_log, p_rcvd_rec, OSM_LOG_DEBUG );
+
+  cl_qlist_init( &rec_list );
+
+  context.p_rcvd_rec    = p_rcvd_rec;
+  context.p_list        = &rec_list;
+  context.comp_mask     = p_rcvd_mad->comp_mask;
+  context.p_rcv         = p_rcv;
+  context.p_req_physp   = p_req_physp;
+
+  cl_plock_acquire( p_rcv->p_lock );
+
+  /* Go over all switches */
+  cl_qmap_apply_func( &p_rcv->p_subn->sw_guid_tbl,
+                      __osm_sir_rcv_by_comp_mask,
+                      &context );
+
+  cl_plock_release( p_rcv->p_lock );
+
+  num_rec = cl_qlist_count( &rec_list );
+
+  /*
+   * C15-0.1.30:
+   * If we do a SubnAdmGet and got more than one record it is an error !
+   */
+  if ( (p_rcvd_mad->method == IB_MAD_METHOD_GET) && (num_rec > 1) ) {
+    osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+             "osm_sir_rcv_process: ERR 5303: "
+             "Got more than one record for SubnAdmGet (%u)\n",
+             num_rec );
+    osm_sa_send_error( p_rcv->p_resp, p_madw,
+                       IB_SA_MAD_STATUS_TOO_MANY_RECORDS );
+
+    /* need to set the mem free ... */
+    p_rec_item = (osm_sir_item_t*)cl_qlist_remove_head( &rec_list );
+    while( p_rec_item != (osm_sir_item_t*)cl_qlist_end( &rec_list ) )
+    {
+      cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
+      p_rec_item = (osm_sir_item_t*)cl_qlist_remove_head( &rec_list );
+    }
+
+    goto Exit;
+  }
+
+  pre_trim_num_rec = num_rec;
+#ifndef VENDOR_RMPP_SUPPORT
+  /* we limit the number of records to a single packet */
+  trim_num_rec = (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / sizeof(ib_switch_info_record_t);
+  if (trim_num_rec < num_rec)
+  {
+    osm_log( p_rcv->p_log, OSM_LOG_VERBOSE,
+             "osm_sir_rcv_process: "
+             "Number of records:%u trimmed to:%u to fit in one MAD\n",
+             num_rec, trim_num_rec );
+    num_rec = trim_num_rec;
+  }
+#endif
+
+  osm_log( p_rcv->p_log, OSM_LOG_DEBUG,
+           "osm_sir_rcv_process: "
+           "Returning %u records\n", num_rec );
+
+  if ((p_rcvd_mad->method == IB_MAD_METHOD_GET) && (num_rec == 0))
+  {
+    osm_sa_send_error( p_rcv->p_resp, p_madw, IB_SA_MAD_STATUS_NO_RECORDS );
+    goto Exit;
+  }
+
+  /* 
+   * Get a MAD to reply. Address of Mad is in the received mad_wrapper
+   */
+  p_resp_madw = osm_mad_pool_get( p_rcv->p_mad_pool,
+                                  p_madw->h_bind,
+                                  num_rec * sizeof(ib_switch_info_record_t) + IB_SA_MAD_HDR_SIZE,
+                                  &p_madw->mad_addr );
+
+  if( !p_resp_madw )
+  {
+    osm_log(p_rcv->p_log, OSM_LOG_ERROR,
+            "osm_sir_rcv_process: ERR 5306: "
+            "osm_mad_pool_get failed\n" );
+
+    for( i = 0; i < num_rec; i++ )
+    {
+      p_rec_item = (osm_sir_item_t*)cl_qlist_remove_head( &rec_list );
+      cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
+    }
+
+    osm_sa_send_error( p_rcv->p_resp, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES );
+    goto Exit;
+  }
+
+  p_resp_sa_mad = osm_madw_get_sa_mad_ptr( p_resp_madw );
+
+  /*
+    Copy the MAD header back into the response mad.
+    Set the 'R' bit and the payload length,
+    Then copy all records from the list into the response payload.
+  */
+
+  memcpy( p_resp_sa_mad, p_rcvd_mad, IB_SA_MAD_HDR_SIZE );
+  p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
+  /* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
+  p_resp_sa_mad->sm_key = 0;
+  /* Fill in the offset (paylen will be done by the rmpp SAR) */
+  p_resp_sa_mad->attr_offset =
+    ib_get_attr_offset( sizeof(ib_switch_info_record_t) );
+
+  p_resp_rec = (ib_switch_info_record_t*)ib_sa_mad_get_payload_ptr( p_resp_sa_mad );
+
+#ifndef VENDOR_RMPP_SUPPORT
+  /* we support only one packet RMPP - so we will set the first and
+     last flags for gettable */
+  if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
+  {
+    p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
+    p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST | IB_RMPP_FLAG_ACTIVE;
+  }
+#else
+  /* forcefully define the packet as RMPP one */
+  if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
+    p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
+#endif
+
+  for( i = 0; i < pre_trim_num_rec; i++ )
+  {
+    p_rec_item = (osm_sir_item_t*)cl_qlist_remove_head( &rec_list );
+    /* copy only if not trimmed */
+    if (i < num_rec)
+    {
+      *p_resp_rec = p_rec_item->rec;
+    }
+    cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
+    p_resp_rec++;
+  }
+
+  CL_ASSERT( cl_is_qlist_empty( &rec_list ) );
+
+  status = osm_vendor_send( p_resp_madw->h_bind, p_resp_madw, FALSE );
+  if (status != IB_SUCCESS)
+  {
+    osm_log(p_rcv->p_log, OSM_LOG_ERROR,
+            "osm_sir_rcv_process: ERR 5307: "
+            "osm_vendor_send status = %s\n",
+            ib_get_err_str(status));
+    goto Exit;
+  }
+
+ Exit:
+  OSM_LOG_EXIT( p_rcv->p_log );
+}
diff --git a/osm/opensm/osm_sa_sw_info_record_ctrl.c b/osm/opensm/osm_sa_sw_info_record_ctrl.c
new file mode 100644
index 0000000..daf55cc
--- /dev/null
+++ b/osm/opensm/osm_sa_sw_info_record_ctrl.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+/*
+ * Abstract:
+ *    Implementation of osm_sir_rcv_ctrl_t.
+ * This object represents the SwitchInfo Record controller object.
+ * This object is part of the opensm family of objects.
+ *
+ * Environment:
+ *    Linux User Mode
+ *
+ */
+
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <string.h>
+#include <opensm/osm_sa_sw_info_record_ctrl.h>
+#include <opensm/osm_msgdef.h>
+
+/**********************************************************************
+ **********************************************************************/
+void
+__osm_sir_ctrl_disp_callback(
+  IN  void *context,
+  IN  void *p_data )
+{
+  /* ignore return status when invoked via the dispatcher */
+  osm_sir_rcv_process( ((osm_sir_rcv_ctrl_t*)context)->p_rcv,
+                       (osm_madw_t*)p_data );
+}
+
+/**********************************************************************
+ **********************************************************************/
+void
+osm_sir_rcv_ctrl_construct(
+  IN osm_sir_rcv_ctrl_t* const p_ctrl )
+{
+  memset( p_ctrl, 0, sizeof(*p_ctrl) );
+  p_ctrl->h_disp = CL_DISP_INVALID_HANDLE;
+}
+
+/**********************************************************************
+ **********************************************************************/
+void
+osm_sir_rcv_ctrl_destroy(
+  IN osm_sir_rcv_ctrl_t* const p_ctrl )
+{
+  CL_ASSERT( p_ctrl );
+  cl_disp_unregister( p_ctrl->h_disp );
+}
+
+/**********************************************************************
+ **********************************************************************/
+ib_api_status_t
+osm_sir_rcv_ctrl_init(
+  IN osm_sir_rcv_ctrl_t* const p_ctrl,
+  IN osm_sir_rcv_t* const p_rcv,
+  IN osm_log_t* const p_log,
+  IN cl_dispatcher_t* const p_disp )
+{
+  ib_api_status_t status = IB_SUCCESS;
+
+  OSM_LOG_ENTER( p_log, osm_sir_rcv_ctrl_init );
+
+  osm_sir_rcv_ctrl_construct( p_ctrl );
+  p_ctrl->p_log = p_log;
+  p_ctrl->p_rcv = p_rcv;
+  p_ctrl->p_disp = p_disp;
+
+  p_ctrl->h_disp = cl_disp_register(
+    p_disp,
+    OSM_MSG_MAD_SWITCH_INFO_RECORD,
+    __osm_sir_ctrl_disp_callback,
+    p_ctrl );
+
+  if( p_ctrl->h_disp == CL_DISP_INVALID_HANDLE )
+  {
+    osm_log( p_log, OSM_LOG_ERROR,
+             "osm_sir_rcv_ctrl_init: ERR 5301: "
+             "Dispatcher registration failed\n" );
+    status = IB_INSUFFICIENT_RESOURCES;
+    goto Exit;
+  }
+
+ Exit:
+  OSM_LOG_EXIT( p_log );
+  return( status );
+}









More information about the general mailing list