[openib-general] [PATCH] libibsa: userspace SA query and multicast support

Sean Hefty sean.hefty at intel.com
Mon Aug 21 17:34:06 PDT 2006


Add a userspace library to support SA queries and joining IB
multicast groups.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
Index: libibsa/libibsa.spec.in
===================================================================
--- libibsa/libibsa.spec.in	(revision 0)
+++ libibsa/libibsa.spec.in	(revision 0)
@@ -0,0 +1,68 @@
+# $Id: $
+
+%define ver @VERSION@
+%define RELEASE 1
+%define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE}
+
+Summary: Userspace SA client.
+Name: libibsa
+Version: %ver
+Release: %rel%{?dist}
+License: GPL/BSD
+Group: System Environment/Libraries
+BuildRoot: %{_tmppath}/%{name}-%{version}-root
+Source: http://openib.org/downloads/%{name}-%{version}.tar.gz
+Url: http://openib.org/
+
+%description
+Along with the OpenIB kernel drivers, libibsa provides a userspace
+SA client API.
+
+%package devel
+Summary: Development files for the libibsa library
+Group: System Environment/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+Development files for the libibsa library.
+
+%package utils
+Summary: Utilities for the libibsa library
+Group: System Environment/Base
+Requires: %{name} = %{version}-%{release}
+
+%description utils
+Utilities for the libibsa library.
+
+%prep
+%setup -q
+
+%build
+%configure
+make
+
+%install
+make DESTDIR=${RPM_BUILD_ROOT} install
+# remove unpackaged files from the buildroot
+rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
+cd $RPM_BUILD_ROOT%{_libdir}
+mv libibsa.so libibsa.so.%{ver}
+ln -s libibsa.so.%{ver} libibsa.so
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+%{_libdir}/libibsa*.so.*
+%doc AUTHORS COPYING ChangeLog NEWS README
+
+%files devel
+%defattr(-,root,root)
+%{_libdir}/libibsa.so
+%{_includedir}/infiniband/*.h
+
+%files utils
+%defattr(-,root,root)
+%{_bindir}/satest
+%{_bindir}/mchammer
Index: libibsa/include/infiniband/sa_net.h
===================================================================
--- libibsa/include/infiniband/sa_net.h	(revision 0)
+++ libibsa/include/infiniband/sa_net.h	(revision 0)
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2006 Intel Corporation.  All rights reserved.
+ *
+ * This Software is licensed under one of the following licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/cpl.php.
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/bsd-license.php.
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ *    copy of which is available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/gpl-license.php.
+ *
+ * Licensee has the right to choose one of the above licenses.
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ *
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ */
+
+#if !defined(SA_NET_H)
+#define SA_NET_H
+
+#include <asm/byteorder.h>
+
+#include <infiniband/sa.h>
+
+enum {
+	IBV_SA_METHOD_GET		= 0x01,
+	IBV_SA_METHOD_SET		= 0x02,
+	IBV_SA_METHOD_GET_RESP		= 0x81,
+	IBV_SA_METHOD_SEND		= 0x03,
+	IBV_SA_METHOD_TRAP		= 0x05,
+	IBV_SA_METHOD_REPORT		= 0x06,
+	IBV_SA_METHOD_REPORT_RESP	= 0x86,
+	IBV_SA_METHOD_TRAP_REPRESS	= 0x07,
+	IBV_SA_METHOD_GET_TABLE		= 0x12,
+	IBV_SA_METHOD_GET_TABLE_RESP	= 0x92,
+	IBV_SA_METHOD_DELETE		= 0x15,
+	IBV_SA_METHOD_DELETE_RESP	= 0x95,
+	IBV_SA_METHOD_GET_MULTI		= 0x14,
+	IBV_SA_METHOD_GET_MULTI_RESP	= 0x94,
+	IBV_SA_METHOD_GET_TRACE_TBL	= 0x13
+};
+
+enum {
+	IBV_SA_MAD_HEADER_SIZE		= 56,
+	IBV_SA_MAD_DATA_SIZE		= 200
+};
+
+struct ibv_sa_mad {
+	/* common MAD header */
+	uint8_t		base_version;
+	uint8_t		mgmt_class;
+	uint8_t		class_version;
+	uint8_t		r_method;
+	uint16_t	status;
+	uint16_t	class_specific;
+	uint64_t	transaction_id;
+	uint16_t	attribute_id;
+	uint16_t	rsvd1;
+	uint32_t	attribute_modifier;
+	/* RMPP header */
+	uint8_t		rmpp_version;
+	uint8_t		rmpp_type;
+	uint8_t		rmpp_resptime_flags;
+	uint8_t		rmpp_status;
+	uint32_t	rmpp_data1;
+	uint32_t	rmpp_data2;
+	/* SA header */
+	uint32_t	sm_key1;	/* define sm_key for 64-bit alignment */
+	uint32_t	sm_key2;
+	uint16_t	attribute_offset;
+	uint16_t	rsvd2;
+	uint64_t	comp_mask;
+	uint8_t		sa_data[IBV_SA_MAD_DATA_SIZE];
+};
+
+enum {
+	IBV_SA_ATTR_CLASS_PORTINFO	= __constant_cpu_to_be16(0x01),
+	IBV_SA_ATTR_NOTICE		= __constant_cpu_to_be16(0x02),
+	IBV_SA_ATTR_INFORM_INFO		= __constant_cpu_to_be16(0x03),
+	IBV_SA_ATTR_NODE_REC		= __constant_cpu_to_be16(0x11),
+	IBV_SA_ATTR_PORT_INFO_REC	= __constant_cpu_to_be16(0x12),
+	IBV_SA_ATTR_SL2VL_REC		= __constant_cpu_to_be16(0x13),
+	IBV_SA_ATTR_SWITCH_REC		= __constant_cpu_to_be16(0x14),
+	IBV_SA_ATTR_LINEAR_FDB_REC	= __constant_cpu_to_be16(0x15),
+	IBV_SA_ATTR_RANDOM_FDB_REC	= __constant_cpu_to_be16(0x16),
+	IBV_SA_ATTR_MCAST_FDB_REC	= __constant_cpu_to_be16(0x17),
+	IBV_SA_ATTR_SM_INFO_REC		= __constant_cpu_to_be16(0x18),
+	IBV_SA_ATTR_LINK_REC		= __constant_cpu_to_be16(0x20),
+	IBV_SA_ATTR_GUID_INFO_REC	= __constant_cpu_to_be16(0x30),
+	IBV_SA_ATTR_SERVICE_REC		= __constant_cpu_to_be16(0x31),
+	IBV_SA_ATTR_PARTITION_REC	= __constant_cpu_to_be16(0x33),
+	IBV_SA_ATTR_PATH_REC		= __constant_cpu_to_be16(0x35),
+	IBV_SA_ATTR_VL_ARB_REC		= __constant_cpu_to_be16(0x36),
+	IBV_SA_ATTR_MC_MEMBER_REC	= __constant_cpu_to_be16(0x38),
+	IBV_SA_ATTR_TRACE_REC		= __constant_cpu_to_be16(0x39),
+	IBV_SA_ATTR_MULTI_PATH_REC	= __constant_cpu_to_be16(0x3a),
+	IBV_SA_ATTR_SERVICE_ASSOC_REC	= __constant_cpu_to_be16(0x3b),
+	IBV_SA_ATTR_INFORM_INFO_REC	= __constant_cpu_to_be16(0xf3)
+};
+
+/* Length of SA attributes on the wire */
+enum {
+	IBV_SA_ATTR_CLASS_PORTINFO_LEN	= 72,
+	IBV_SA_ATTR_NOTICE_LEN		= 80,
+	IBV_SA_ATTR_INFORM_INFO_LEN	= 36,
+	IBV_SA_ATTR_NODE_REC_LEN	= 108,
+	IBV_SA_ATTR_PORT_INFO_REC_LEN	= 58,
+	IBV_SA_ATTR_SL2VL_REC_LEN	= 16,
+	IBV_SA_ATTR_SWITCH_REC_LEN	= 21,
+	IBV_SA_ATTR_LINEAR_FDB_REC_LEN	= 72,
+	IBV_SA_ATTR_RANDOM_FDB_REC_LEN	= 72,
+	IBV_SA_ATTR_MCAST_FDB_REC_LEN	= 72,
+	IBV_SA_ATTR_SM_INFO_REC_LEN	= 25,
+	IBV_SA_ATTR_LINK_REC_LEN	= 6,
+	IBV_SA_ATTR_GUID_INFO_REC_LEN	= 72,
+	IBV_SA_ATTR_SERVICE_REC_LEN	= 176,
+	IBV_SA_ATTR_PARTITION_REC_LEN	= 72,
+	IBV_SA_ATTR_PATH_REC_LEN	= 64,
+	IBV_SA_ATTR_VL_ARB_REC_LEN	= 72,
+	IBV_SA_ATTR_MC_MEMBER_REC_LEN	= 52,
+	IBV_SA_ATTR_TRACE_REC_LEN	= 46,
+	IBV_SA_ATTR_MULTI_PATH_REC_LEN	= 56,
+	IBV_SA_ATTR_SERVICE_ASSOC_REC_LEN = 80,
+	IBV_SA_ATTR_INFORM_INFO_REC_LEN	= 60
+};
+
+#define IBV_SA_COMP_MASK(n)		__constant_cpu_to_be64(1ull << n)
+
+struct ibv_sa_net_service_rec {
+	uint64_t	service_id;
+	uint8_t		service_gid[16];
+	uint16_t	service_pkey;
+	uint16_t	rsvd;
+	uint32_t	service_lease;
+	uint8_t		service_key[16];
+	uint8_t		service_name[64];
+	uint8_t		service_data8[16];
+	uint16_t	service_data16[8];
+	uint32_t	service_data32[4];
+	uint64_t	service_data64[2];
+};
+
+enum {
+	IBV_SA_SERVICE_REC_SERVICE_ID			= IBV_SA_COMP_MASK(0),
+	IBV_SA_SERVICE_REC_SERVICE_GID			= IBV_SA_COMP_MASK(1),
+	IBV_SA_SERVICE_REC_SERVICE_PKEY			= IBV_SA_COMP_MASK(2),
+	/* reserved:							 3 */
+	IBV_SA_SERVICE_REC_SERVICE_LEASE		= IBV_SA_COMP_MASK(4),
+	IBV_SA_SERVICE_REC_SERVICE_KEY			= IBV_SA_COMP_MASK(5),
+	IBV_SA_SERVICE_REC_SERVICE_NAME			= IBV_SA_COMP_MASK(6),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_0		= IBV_SA_COMP_MASK(7),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_1		= IBV_SA_COMP_MASK(8),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_2		= IBV_SA_COMP_MASK(9),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_3		= IBV_SA_COMP_MASK(10),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_4		= IBV_SA_COMP_MASK(11),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_5		= IBV_SA_COMP_MASK(12),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_6		= IBV_SA_COMP_MASK(13),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_7		= IBV_SA_COMP_MASK(14),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_8		= IBV_SA_COMP_MASK(15),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_9		= IBV_SA_COMP_MASK(16),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_10		= IBV_SA_COMP_MASK(17),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_11		= IBV_SA_COMP_MASK(18),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_12		= IBV_SA_COMP_MASK(19),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_13		= IBV_SA_COMP_MASK(20),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_14		= IBV_SA_COMP_MASK(21),
+	IBV_SA_SERVICE_REC_SERVICE_DATA8_15		= IBV_SA_COMP_MASK(22),
+	IBV_SA_SERVICE_REC_SERVICE_DATA16_0		= IBV_SA_COMP_MASK(23),
+	IBV_SA_SERVICE_REC_SERVICE_DATA16_1		= IBV_SA_COMP_MASK(24),
+	IBV_SA_SERVICE_REC_SERVICE_DATA16_2		= IBV_SA_COMP_MASK(25),
+	IBV_SA_SERVICE_REC_SERVICE_DATA16_3		= IBV_SA_COMP_MASK(26),
+	IBV_SA_SERVICE_REC_SERVICE_DATA16_4		= IBV_SA_COMP_MASK(27),
+	IBV_SA_SERVICE_REC_SERVICE_DATA16_5		= IBV_SA_COMP_MASK(28),
+	IBV_SA_SERVICE_REC_SERVICE_DATA16_6		= IBV_SA_COMP_MASK(29),
+	IBV_SA_SERVICE_REC_SERVICE_DATA16_7		= IBV_SA_COMP_MASK(30),
+	IBV_SA_SERVICE_REC_SERVICE_DATA32_0		= IBV_SA_COMP_MASK(31),
+	IBV_SA_SERVICE_REC_SERVICE_DATA32_1		= IBV_SA_COMP_MASK(32),
+	IBV_SA_SERVICE_REC_SERVICE_DATA32_2		= IBV_SA_COMP_MASK(33),
+	IBV_SA_SERVICE_REC_SERVICE_DATA32_3		= IBV_SA_COMP_MASK(34),
+	IBV_SA_SERVICE_REC_SERVICE_DATA64_0		= IBV_SA_COMP_MASK(35),
+	IBV_SA_SERVICE_REC_SERVICE_DATA64_1		= IBV_SA_COMP_MASK(36)
+};
+
+struct ibv_sa_net_path_rec {
+	uint32_t	rsvd1;
+	uint32_t	rsvd2;
+	uint8_t		dgid[16];
+	uint8_t		sgid[16];
+	uint16_t	dlid;
+	uint16_t	slid;
+	/* RawTraffic: 1:352, Rsvd: 3:353, FlowLabel: 20:356, HopLimit: 8:376 */
+	uint32_t	raw_flow_hop;
+	uint8_t		tclass;
+	/* Reversible: 1:392, NumbPath: 7:393 */
+	uint8_t		reversible_numbpath;
+	uint16_t	pkey;
+	/* Rsvd: 12:416, SL: 4:428 */
+	uint16_t	sl;
+	/* MtuSelector: 2:432, MTU: 6:434 */
+	uint8_t		mtu_info;
+	/* RateSelector: 2:440, Rate: 6:442 */
+	uint8_t		rate_info;
+	/* PacketLifeTimeSelector: 2:448, PacketLifeTime: 6:450 */
+	uint8_t		packetlifetime_info;
+	uint8_t		preference;
+	uint8_t		rsvd3[3];
+};
+
+enum {
+	IBV_SA_PATH_REC_RAW_TRAFFIC_OFFSET		= 352,
+	IBV_SA_PATH_REC_RAW_TRAFFIC_LENGTH		= 1,
+	IBV_SA_PATH_REC_FLOW_LABEL_OFFSET		= 356,
+	IBV_SA_PATH_REC_FLOW_LABEL_LENGTH		= 20,
+	IBV_SA_PATH_REC_HOP_LIMIT_OFFSET		= 376,
+	IBV_SA_PATH_REC_HOP_LIMIT_LENGTH		= 8,
+	IBV_SA_PATH_REC_REVERSIBLE_OFFSET		= 392,
+	IBV_SA_PATH_REC_REVERSIBLE_LENGTH		= 1,
+	IBV_SA_PATH_REC_NUMB_PATH_OFFSET		= 393,
+	IBV_SA_PATH_REC_NUMB_PATH_LENGTH		= 7,
+	IBV_SA_PATH_REC_SL_OFFSET			= 428,
+	IBV_SA_PATH_REC_SL_LENGTH			= 4,
+	IBV_SA_PATH_REC_MTU_SELECTOR_OFFSET		= 324,
+	IBV_SA_PATH_REC_MTU_SELECTOR_LENGTH		= 2,
+	IBV_SA_PATH_REC_MTU_OFFSET			= 434,
+	IBV_SA_PATH_REC_MTU_LENGTH			= 6,
+	IBV_SA_PATH_REC_RATE_SELECTOR_OFFSET		= 440,
+	IBV_SA_PATH_REC_RATE_SELECTOR_LENGTH		= 2,
+	IBV_SA_PATH_REC_RATE_OFFSET			= 442,
+	IBV_SA_PATH_REC_RATE_LENGTH			= 6,
+	IBV_SA_PATH_REC_PACKETLIFE_SELECTOR_OFFSET	= 448,
+	IBV_SA_PATH_REC_PACKETLIFE_SELECTOR_LENGTH	= 2,
+	IBV_SA_PATH_REC_PACKETLIFE_OFFSET		= 450,
+	IBV_SA_PATH_REC_PACKETLIFE_LENGTH		= 6
+};
+
+enum {
+	/* reserved:							 0 */
+	/* reserved:							 1 */
+	IBV_SA_PATH_REC_DGID				= IBV_SA_COMP_MASK(2),
+	IBV_SA_PATH_REC_SGID				= IBV_SA_COMP_MASK(3),
+	IBV_SA_PATH_REC_DLID				= IBV_SA_COMP_MASK(4),
+	IBV_SA_PATH_REC_SLID				= IBV_SA_COMP_MASK(5),
+	IBV_SA_PATH_REC_RAW_TRAFFIC			= IBV_SA_COMP_MASK(6),
+	/* reserved:							 7 */
+	IBV_SA_PATH_REC_FLOW_LABEL			= IBV_SA_COMP_MASK(8),
+	IBV_SA_PATH_REC_HOP_LIMIT			= IBV_SA_COMP_MASK(9),
+	IBV_SA_PATH_REC_TRAFFIC_CLASS			= IBV_SA_COMP_MASK(10),
+	IBV_SA_PATH_REC_REVERSIBLE			= IBV_SA_COMP_MASK(11),
+	IBV_SA_PATH_REC_NUMB_PATH			= IBV_SA_COMP_MASK(12),
+	IBV_SA_PATH_REC_PKEY				= IBV_SA_COMP_MASK(13),
+	/* reserved:							 14 */
+	IBV_SA_PATH_REC_SL				= IBV_SA_COMP_MASK(15),
+	IBV_SA_PATH_REC_MTU_SELECTOR			= IBV_SA_COMP_MASK(16),
+	IBV_SA_PATH_REC_MTU				= IBV_SA_COMP_MASK(17),
+	IBV_SA_PATH_REC_RATE_SELECTOR			= IBV_SA_COMP_MASK(18),
+	IBV_SA_PATH_REC_RATE				= IBV_SA_COMP_MASK(19),
+	IBV_SA_PATH_REC_PACKET_LIFE_TIME_SELECTOR	= IBV_SA_COMP_MASK(20),
+	IBV_SA_PATH_REC_PACKET_LIFE_TIME		= IBV_SA_COMP_MASK(21),
+	IBV_SA_PATH_REC_PREFERENCE			= IBV_SA_COMP_MASK(22)
+};
+
+struct ibv_sa_net_mcmember_rec {
+	uint8_t		mgid[16];
+	uint8_t		port_gid[16];
+	uint32_t	qkey;
+	uint16_t	mlid;
+	/* MtuSelector: 2:304, MTU: 6:306 */
+	uint8_t		mtu_info;
+	uint8_t		tclass;
+	uint16_t	pkey;
+	/* RateSelector: 2:336, Rate: 6:338 */
+	uint8_t		rate_info;
+	/* PacketLifeTimeSelector: 2:344, PacketLifeTime: 6:346 */
+	uint8_t		packetlifetime_info;
+	/* SL: 4:352, FlowLabel: 20:356, HopLimit: 8:376 */
+	uint32_t	sl_flow_hop;
+	/* Scope: 4:384, JoinState: 4:388 */
+	uint8_t		scope_join;
+	/* ProxyJoin: 1:392, rsvd: 7:393 */
+	uint8_t		proxy_join;
+	uint8_t		rsvd[2];
+};
+
+enum {
+	IBV_SA_MCMEMBER_REC_MTU_SELECTOR_OFFSET		= 304,
+	IBV_SA_MCMEMBER_REC_MTU_SELECTOR_LENGTH		= 2,
+	IBV_SA_MCMEMBER_REC_MTU_OFFSET			= 306,
+	IBV_SA_MCMEMBER_REC_MTU_LENGTH			= 6,
+	IBV_SA_MCMEMBER_REC_RATE_SELECTOR_OFFSET	= 336,
+	IBV_SA_MCMEMBER_REC_RATE_SELECTOR_LENGTH	= 2,
+	IBV_SA_MCMEMBER_REC_RATE_OFFSET			= 338,
+	IBV_SA_MCMEMBER_REC_RATE_LENGTH			= 6,
+	IBV_SA_MCMEMBER_REC_PACKETLIFE_SELECTOR_OFFSET	= 344,
+	IBV_SA_MCMEMBER_REC_PACKETLIFE_SELECTOR_LENGTH	= 2,
+	IBV_SA_MCMEMBER_REC_PACKETLIFE_OFFSET		= 346,
+	IBV_SA_MCMEMBER_REC_PACKETLIFE_LENGTH		= 6,
+	IBV_SA_MCMEMBER_REC_SL_OFFSET			= 352,
+	IBV_SA_MCMEMBER_REC_SL_LENGTH			= 4,
+	IBV_SA_MCMEMBER_REC_FLOW_LABEL_OFFSET		= 356,
+	IBV_SA_MCMEMBER_REC_FLOW_LABEL_LENGTH		= 20,
+	IBV_SA_MCMEMBER_REC_HOP_LIMIT_OFFSET		= 376,
+	IBV_SA_MCMEMBER_REC_HOP_LIMIT_LENGTH		= 8,
+	IBV_SA_MCMEMBER_REC_SCOPE_OFFSET		= 384,
+	IBV_SA_MCMEMBER_REC_SCOPE_LENGTH		= 4,
+	IBV_SA_MCMEMBER_REC_JOIN_STATE_OFFSET		= 388,
+	IBV_SA_MCMEMBER_REC_JOIN_STATE_LENGTH		= 4,
+	IBV_SA_MCMEMBER_REC_PROXY_JOIN_OFFSET		= 392,
+	IBV_SA_MCMEMBER_REC_PROXY_JOIN_LENGTH		= 1
+};
+
+enum {
+	IBV_SA_MCMEMBER_REC_MGID			= IBV_SA_COMP_MASK(0),
+	IBV_SA_MCMEMBER_REC_PORT_GID			= IBV_SA_COMP_MASK(1),
+	IBV_SA_MCMEMBER_REC_QKEY			= IBV_SA_COMP_MASK(2),
+	IBV_SA_MCMEMBER_REC_MLID			= IBV_SA_COMP_MASK(3),
+	IBV_SA_MCMEMBER_REC_MTU_SELECTOR		= IBV_SA_COMP_MASK(4),
+	IBV_SA_MCMEMBER_REC_MTU				= IBV_SA_COMP_MASK(5),
+	IBV_SA_MCMEMBER_REC_TRAFFIC_CLASS		= IBV_SA_COMP_MASK(6),
+	IBV_SA_MCMEMBER_REC_PKEY			= IBV_SA_COMP_MASK(7),
+	IBV_SA_MCMEMBER_REC_RATE_SELECTOR		= IBV_SA_COMP_MASK(8),
+	IBV_SA_MCMEMBER_REC_RATE			= IBV_SA_COMP_MASK(9),
+	IBV_SA_MCMEMBER_REC_PACKET_LIFE_TIME_SELECTOR	= IBV_SA_COMP_MASK(10),
+	IBV_SA_MCMEMBER_REC_PACKET_LIFE_TIME		= IBV_SA_COMP_MASK(11),
+	IBV_SA_MCMEMBER_REC_SL				= IBV_SA_COMP_MASK(12),
+	IBV_SA_MCMEMBER_REC_FLOW_LABEL			= IBV_SA_COMP_MASK(13),
+	IBV_SA_MCMEMBER_REC_HOP_LIMIT			= IBV_SA_COMP_MASK(14),
+	IBV_SA_MCMEMBER_REC_SCOPE			= IBV_SA_COMP_MASK(15),
+	IBV_SA_MCMEMBER_REC_JOIN_STATE			= IBV_SA_COMP_MASK(16),
+	IBV_SA_MCMEMBER_REC_PROXY_JOIN			= IBV_SA_COMP_MASK(17)
+};
+
+/*
+ * ibv_sa_pack_attr - Copy an attribute from a host defined structure
+ *   to a packed network structure
+ * ibv_sa_unpack_attr - Copy an attribute from a packed network structure
+ *   to a host defined structure.
+ */
+void ibv_sa_unpack_path_rec(struct ibv_sa_path_rec *rec,
+			    struct ibv_sa_net_path_rec *net_rec);
+void ibv_sa_pack_mcmember_rec(struct ibv_sa_net_mcmember_rec *net_rec,
+			      struct ibv_sa_mcmember_rec *rec);
+void ibv_sa_unpack_mcmember_rec(struct ibv_sa_mcmember_rec *rec,
+				struct ibv_sa_net_mcmember_rec *net_rec);
+
+/**
+ * ibv_sa_get_field - Extract a bit field value from a structure.
+ * @data: Pointer to the start of the structure.
+ * @offset: Bit offset of field from start of structure.
+ * @size: Size of field, in bits.
+ *
+ * The structure must be in network-byte order.  The returned value is in
+ * host-byte order.
+ */
+uint32_t ibv_sa_get_field(void *data, int offset, int size);
+
+/**
+ * ibv_sa_set_field - Set a bit field value in a structure.
+ * @data: Pointer to the start of the structure.
+ * @value: Value to assign to field.
+ * @offset: Bit offset of field from start of structure.
+ * @size: Size of field, in bits.
+ *
+ * The structure must be in network-byte order.  The value to set is in
+ * host-byte order.
+ */
+void ibv_sa_set_field(void *data, uint32_t value, int offset, int size);
+
+#endif /* SA_NET_H */

Property changes on: libibsa/include/infiniband/sa_net.h
___________________________________________________________________
Name: svn:executable
   + *

Index: libibsa/include/infiniband/sa_client_abi.h
===================================================================
--- libibsa/include/infiniband/sa_client_abi.h	(revision 0)
+++ libibsa/include/infiniband/sa_client_abi.h	(revision 0)
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2006 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.
+ */
+
+#ifndef SA_CLIENT_ABI_H
+#define SA_CLIENT_ABI_H
+
+#include <infiniband/sa_client.h>
+
+/*
+ * This file must be kept in sync with the kernel's version of ib_usa.h
+ */
+
+#define IB_USA_MIN_ABI_VERSION	1
+#define IB_USA_MAX_ABI_VERSION	1
+
+#define IB_USA_EVENT_DATA	256
+
+enum {
+	USA_CMD_SEND_MAD,
+	USA_CMD_GET_EVENT,
+	USA_CMD_GET_DATA,
+	USA_CMD_JOIN_MCAST,
+	USA_CMD_FREE_ID,
+	USA_CMD_GET_MCAST
+};
+
+enum {
+	USA_EVENT_MAD,
+	USA_EVENT_MCAST
+};
+
+struct usa_abi_cmd_hdr {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
+};
+
+struct usa_abi_send_mad {
+	__u64 response;		/* unused - reserved */
+	__u64 uid;
+	__u64 node_guid;
+	__u64 comp_mask;
+	__u64 attr;
+	__u8  port_num;
+	__u8  method;
+	__u16 attr_id;
+	__u32 timeout_ms;
+	__u32 retries;
+};
+
+struct usa_abi_join_mcast {
+	__u64 response;
+	__u64 uid;
+	__u64 node_guid;
+	__u64 comp_mask;
+	__u64 mcmember_rec;
+	__u8  port_num;
+};
+
+struct usa_abi_id_resp {
+	__u32 id;
+};
+
+struct usa_abi_free_resp {
+	__u32 events_reported;
+};
+
+struct usa_abi_free_id {
+	__u64 response;
+	__u32 id;
+};
+
+struct usa_abi_get_event {
+	__u64 response;
+};
+
+struct usa_abi_event_resp {
+	__u64 uid;
+	__u32 id;
+	__u32 event;
+	__u32 status;
+	__u32 data_len;
+	__u8  data[IB_USA_EVENT_DATA];
+};
+
+struct usa_abi_get_data {
+	__u64 response;
+	__u32 id;
+};
+
+struct usa_abi_get_mcast {
+	__u64 response;
+	__u64 node_guid;
+	__u8  mgid[16];
+	__u8  port_num;
+};
+
+#endif /* SA_CLIENT_ABI_H */

Property changes on: libibsa/include/infiniband/sa_client_abi.h
___________________________________________________________________
Name: svn:executable
   + *

Index: libibsa/include/infiniband/sa_client.h
===================================================================
--- libibsa/include/infiniband/sa_client.h	(revision 0)
+++ libibsa/include/infiniband/sa_client.h	(revision 0)
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2006 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ *
+ * This Software is licensed under one of the following licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/cpl.php.
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is
+ *    available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/bsd-license.php.
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ *    copy of which is available from the Open Source Initiative, see
+ *    http://www.opensource.org/licenses/gpl-license.php.
+ *
+ * Licensee has the right to choose one of the above licenses.
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ *
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ */
+
+#if !defined(SA_CLIENT_H)
+#define SA_CLIENT_H
+
+#include <infiniband/sa_net.h>
+#include <infiniband/verbs.h>
+
+struct ibv_sa_event_channel {
+	int fd;
+};
+
+enum ibv_sa_event_type {
+	IBV_SA_EVENT_MAD,
+	IBV_SA_EVENT_MULTICAST
+};
+
+struct ibv_sa_event {
+	void *context;
+	enum ibv_sa_event_type event;
+	int status;
+	int attr_count;
+	int attr_size;
+	int attr_offset;
+	uint16_t attr_id;
+	void *attr;
+};
+
+/**
+ * ibv_sa_create_event_channel - Open a channel used to report events.
+ */
+struct ibv_sa_event_channel *ibv_sa_create_event_channel(void);
+
+/**
+ * ibv_sa_destroy_event_channel - Close the event channel.
+ * @channel: The channel to destroy.
+ */
+void ibv_sa_destroy_event_channel(struct ibv_sa_event_channel *channel);
+
+/**
+ * ibv_sa_send_mad - Send a MAD to the SA.
+ * @channel: Event channel to report completion to.
+ * @device: Device to send over.
+ * @port_num: Port number to send over.
+ * @method: MAD method to use in the send.
+ * @attr: Reference to attribute in wire format to send in MAD.
+ * @attr_id: Attribute type identifier.
+ * @comp_mask: Component mask to send in MAD.
+ * @timeout_ms: Time to wait for response, if one is expected.
+ * @retries: Number of times to retry request.
+ * @context: User-defined context associated with request.
+ *
+ * Send a message to the SA.  All values should be in network-byte order.
+ */
+int ibv_sa_send_mad(struct ibv_sa_event_channel *channel,
+		    struct ibv_context *device, uint8_t port_num,
+		    uint8_t method, void *attr, uint16_t attr_id,
+		    uint64_t comp_mask, int timeout_ms, int retries,
+		    void *context);
+
+/**
+ * ibv_sa_get_event - Retrieves the next pending event, if no event is
+ *   pending waits for an event.
+ * @channel: Event channel to check for events.
+ * @event: Allocated information about the next event.
+ *    Event should be freed using ibv_sa_ack_event()
+ */
+int ibv_sa_get_event(struct ibv_sa_event_channel *channel,
+		     struct ibv_sa_event **event);
+
+/**
+ * ibv_sa_ack_event - Free an event.
+ * @event: Event to be released.
+ *
+ * All events which are allocated by ibv_sa_get_event() must be released,
+ * there should be a one-to-one correspondence between successful gets
+ * and acks.
+ */
+int ibv_sa_ack_event(struct ibv_sa_event *event);
+
+/**
+ * ibv_sa_attr_size - Return the length of an SA attribute on the wire.
+ * @attr_id: Attribute identifier, in network-byte order.
+ */
+int ibv_sa_attr_size(uint16_t attr_id);
+
+static inline void *ibv_sa_get_attr(struct ibv_sa_event *event, int index)
+{
+	return event->attr + event->attr_offset * index;
+}
+
+/**
+ * ibv_sa_init_ah_from_path - Initialize address handle attributes.
+ * @device: Source device.
+ * @port_num: Source port number.
+ * @path_rec: Network defined path record.
+ * @ah_attr: Destination address handle attributes.
+ */
+int ibv_sa_init_ah_from_path(struct ibv_context *device, uint8_t port_num,
+			     struct ibv_sa_net_path_rec *path_rec,
+			     struct ibv_ah_attr *ah_attr);
+
+/**
+ * ibv_sa_init_ah_from_mcmember - Initialize address handle attributes.
+ * @device: Source device.
+ * @port_num: Source port number.
+ * @mc_rec: Network defined multicast member record.
+ * @ah_attr: Destination address handle attributes.
+ */
+int ibv_sa_init_ah_from_mcmember(struct ibv_context *device, uint8_t port_num,
+				 struct ibv_sa_net_mcmember_rec *mc_rec,
+				 struct ibv_ah_attr *ah_attr);
+
+struct ibv_sa_multicast;
+
+/**
+ * ibv_sa_join_multicast - Initiates a join request to the specified multicast
+ *   group.
+ * @channel: Event channel to report completion to.
+ * @device: Device to send over.
+ * @port_num: Port number to send over.
+ * @rec: SA multicast member record specifying group attributes.
+ * @comp_mask: Component mask to send in MAD.
+ * @context: User-defined context associated with join.
+ * @multicast: Reference to store multicast pointer.
+ *
+ * This call initiates a multicast join request with the SA for the specified
+ * multicast group.  If the join operation is started successfully, it returns
+ * an ibv_sa_multicast structure that is used to track the multicast operation.
+ * Users must free this structure by calling ibv_sa_free_multicast, even if the
+ * join operation later fails.
+ */
+int ibv_sa_join_multicast(struct ibv_sa_event_channel *channel,
+			  struct ibv_context *device, uint8_t port_num,
+			  struct ibv_sa_net_mcmember_rec *rec,
+			  uint64_t comp_mask, void *context,
+			  struct ibv_sa_multicast **multicast);
+
+/**
+ * ibv_sa_free_multicast - Frees the multicast tracking structure, and releases
+ *    any reference on the multicast group.
+ * @multicast: Multicast tracking structure allocated by ibv_sa_join_multicast.
+ */
+int ibv_sa_free_multicast(struct ibv_sa_multicast *multicast);
+
+/**
+ * ibv_sa_get_mcmember_rec - Looks up a multicast member record by its MGID and
+ *   returns it if found.
+ * @channel: Event channel to issue query on.
+ * @device: Device associated with record.
+ * @port_num: Port number of record.
+ * @mgid: optional MGID of multicast group.
+ * @rec: Location to copy SA multicast member record.
+ *
+ * If an MGID is specified, returns an existing multicast member record if
+ * one is found for the local port.  If no MGID is specified, or the specified
+ * MGID is 0, returns a multicast member record filled in with default values
+ * that may be used to create a new multicast group.
+ */
+int ibv_sa_get_mcmember_rec(struct ibv_sa_event_channel *channel,
+			    struct ibv_context *device, uint8_t port_num,
+			    union ibv_gid *mgid,
+			    struct ibv_sa_net_mcmember_rec *rec);
+
+#endif /* SA_CLIENT_H */

Property changes on: libibsa/include/infiniband/sa_client.h
___________________________________________________________________
Name: svn:executable
   + *

Index: libibsa/AUTHORS
===================================================================
--- libibsa/AUTHORS	(revision 0)
+++ libibsa/AUTHORS	(revision 0)
@@ -0,0 +1 @@
+Sean Hefty		<sean.hefty at intel.com>
Index: libibsa/configure.in
===================================================================
--- libibsa/configure.in	(revision 0)
+++ libibsa/configure.in	(revision 0)
@@ -0,0 +1,50 @@
+dnl Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.57)
+AC_INIT(libibsa, 0.9.0, openib-general at openib.org)
+AC_CONFIG_SRCDIR([src/sa_client.c])
+AC_CONFIG_AUX_DIR(config)
+AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE(libibsa, 0.9.0)
+AC_DISABLE_STATIC
+AM_PROG_LIBTOOL
+
+AC_ARG_ENABLE(libcheck, [  --disable-libcheck      do not test for presence of ib libraries],
+[       if test x$enableval = xno ; then
+                disable_libcheck=yes
+        fi
+])
+
+dnl Checks for programs
+AC_PROG_CC
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_CHECK_SIZEOF(long)
+
+dnl Checks for libraries
+if test "$disable_libcheck" != "yes"
+then
+AC_CHECK_LIB(ibverbs, ibv_get_device_list, [],
+    AC_MSG_ERROR([ibv_get_device_list() not found.  libibsa requires libibverbs.]))
+fi
+
+dnl Checks for header files.
+if test "$disable_libcheck" != "yes"
+then
+AC_CHECK_HEADER(infiniband/verbs.h, [],
+    AC_MSG_ERROR([<infiniband/verbs.h> not found.  Is libibverbs installed?]))
+fi
+AC_HEADER_STDC
+
+AC_CACHE_CHECK(whether ld accepts --version-script, ac_cv_version_script,
+    if test -n "`$LD --help < /dev/null 2>/dev/null | grep version-script`"; then
+        ac_cv_version_script=yes
+    else
+        ac_cv_version_script=no
+    fi)
+
+AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$ac_cv_version_script" = "yes")
+
+AC_CONFIG_FILES([Makefile libibsa.spec])
+AC_OUTPUT
Index: libibsa/INSTALL
===================================================================
Index: libibsa/src/libibsa.map
===================================================================
--- libibsa/src/libibsa.map	(revision 0)
+++ libibsa/src/libibsa.map	(revision 0)
@@ -0,0 +1,21 @@
+IB_SA_1.0 {
+	global:
+		ibv_sa_create_event_channel;
+		ibv_sa_destroy_event_channel;
+		ibv_sa_send_mad;
+		ibv_sa_get_event;
+		ibv_sa_ack_event;
+		ibv_sa_attr_size;
+		ibv_sa_get_attr;
+		ibv_sa_init_ah_from_path;
+		ibv_sa_init_ah_from_mcmember;
+		ibv_sa_join_multicast;
+		ibv_sa_free_multicast;
+		ibv_sa_get_mcmember_rec;
+		ibv_sa_get_field;
+		ibv_sa_set_field;
+		ibv_sa_unpack_path_rec;
+		ibv_sa_pack_mcmember_rec;
+		ibv_sa_unpack_mcmember_rec;
+	local: *;
+};
Index: libibsa/src/sa_client.c
===================================================================
--- libibsa/src/sa_client.c	(revision 0)
+++ libibsa/src/sa_client.c	(revision 0)
@@ -0,0 +1,552 @@
+/*
+ * Copyright (c) 2006 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.
+ *
+ * $Id: cm.c 3453 2005-09-15 21:43:21Z sean.hefty $
+ */
+
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <byteswap.h>
+
+#include <netinet/in.h>
+
+#include <infiniband/driver.h>
+#include <infiniband/sa_client.h>
+#include <infiniband/sa_client_abi.h>
+#include <infiniband/sa_net.h>
+
+#define PFX "libibsa: "
+
+#define container_of(ptr, type, field) \
+	((type *) ((void *) ptr - offsetof(type, field)))
+
+struct sa_event_tracking {
+	uint32_t events_completed;
+	pthread_cond_t cond;
+	pthread_mutex_t	mut;
+};
+
+struct sa_event {
+	struct ibv_sa_event event;
+	struct ibv_sa_event_channel *channel;
+	void *data;
+	struct sa_event_tracking *event_tracking;
+};
+
+struct ibv_sa_multicast {
+	struct ibv_sa_event_channel *channel;
+	void *context;
+	uint32_t id;
+	struct sa_event_tracking event_tracking;
+};
+
+static int abi_ver;
+static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
+
+#define USA_CREATE_MSG_CMD_RESP(msg, cmd, resp, type, size) \
+do {                                        \
+	struct usa_abi_cmd_hdr *hdr;        \
+                                            \
+	size = sizeof(*hdr) + sizeof(*cmd); \
+	msg = alloca(size);                 \
+	if (!msg)                           \
+		return ENOMEM;              \
+	hdr = msg;                          \
+	cmd = msg + sizeof(*hdr);           \
+	hdr->cmd = type;                    \
+	hdr->in  = sizeof(*cmd);            \
+	hdr->out = sizeof(*resp);           \
+	memset(cmd, 0, sizeof(*cmd));       \
+	resp = alloca(sizeof(*resp));       \
+	if (!resp)                          \
+		return ENOMEM;              \
+	cmd->response = (uintptr_t)resp;    \
+} while (0)
+
+#define USA_CREATE_MSG_CMD(msg, cmd, type, size) \
+do {                                        \
+	struct usa_abi_cmd_hdr *hdr;        \
+                                            \
+	size = sizeof(*hdr) + sizeof(*cmd); \
+	msg = alloca(size);                 \
+	if (!msg)                           \
+		return ENOMEM;              \
+	hdr = msg;                          \
+	cmd = msg + sizeof(*hdr);           \
+	hdr->cmd = type;                    \
+	hdr->in  = sizeof(*cmd);            \
+	hdr->out = 0;                       \
+	memset(cmd, 0, sizeof(*cmd));       \
+} while (0)
+
+static int check_abi_version(void)
+{
+	char value[8];
+
+	if (ibv_read_sysfs_file(ibv_get_sysfs_path(),
+				"class/misc/ib_usa/abi_version",
+				value, sizeof value) < 0) {
+		/*
+		 * Older version of Linux do not have class/misc.  To support
+		 * backports, assume the most recent version of the ABI.  If
+		 * we're wrong, we'll simply fail later when calling the ABI.
+		 */
+		abi_ver = IB_USA_MAX_ABI_VERSION;
+		fprintf(stderr, PFX "couldn't read ABI version, assuming: %d\n",
+			abi_ver);
+		return 0;
+	}
+
+	abi_ver = strtol(value, NULL, 10);
+	if (abi_ver < IB_USA_MIN_ABI_VERSION ||
+	    abi_ver > IB_USA_MAX_ABI_VERSION) {
+		fprintf(stderr, PFX "kernel ABI version %d "
+				"doesn't match library version %d.\n",
+				abi_ver, IB_USA_MAX_ABI_VERSION);
+		return -1;
+	}
+	return 0;
+}
+
+static int usa_init(void)
+{
+	int ret = 0;
+
+	pthread_mutex_lock(&mut);
+	if (!abi_ver)
+		ret = check_abi_version();
+	pthread_mutex_unlock(&mut);
+
+	return ret;
+}
+
+struct ibv_sa_event_channel *ibv_sa_create_event_channel(void)
+{
+	struct ibv_sa_event_channel *channel;
+
+	if (usa_init())
+		return NULL;
+
+	channel = malloc(sizeof *channel);
+	if (!channel)
+		return NULL;
+
+	channel->fd = open("/dev/infiniband/ib_usa", O_RDWR);
+	if (channel->fd < 0) {
+		fprintf(stderr, PFX "unable to open /dev/infiniband/ib_usa\n");
+		goto err;
+	}
+	return channel;
+err:
+	free(channel);
+	return NULL;
+}
+
+void ibv_sa_destroy_event_channel(struct ibv_sa_event_channel *channel)
+{
+	close(channel->fd);
+	free(channel);
+}
+
+static int init_event_tracking(struct sa_event_tracking *event_tracking)
+{
+	pthread_mutex_init(&event_tracking->mut, NULL);
+	return pthread_cond_init(&event_tracking->cond, NULL);
+}
+
+static void cleanup_event_tracking(struct sa_event_tracking *event_tracking)
+{
+	pthread_cond_destroy(&event_tracking->cond);
+	pthread_mutex_destroy(&event_tracking->mut);
+}
+
+static void wait_for_events(struct sa_event_tracking *event_tracking,
+			    int events_reported)
+{
+	pthread_mutex_lock(&event_tracking->mut);
+	while (event_tracking->events_completed < events_reported)
+		pthread_cond_wait(&event_tracking->cond, &event_tracking->mut);
+	pthread_mutex_unlock(&event_tracking->mut);
+}
+
+static void complete_event(struct sa_event_tracking *event_tracking)
+{
+	pthread_mutex_lock(&event_tracking->mut);
+	event_tracking->events_completed++;
+	pthread_cond_signal(&event_tracking->cond);
+	pthread_mutex_unlock(&event_tracking->mut);
+}
+
+int ibv_sa_send_mad(struct ibv_sa_event_channel *channel,
+		    struct ibv_context *device, uint8_t port_num,
+		    uint8_t method, void *attr, uint16_t attr_id,
+		    uint64_t comp_mask, int timeout_ms, int retries,
+		    void *context)
+{
+	struct usa_abi_send_mad *cmd;
+	void *msg;
+	int ret, size;
+
+	USA_CREATE_MSG_CMD(msg, cmd, USA_CMD_SEND_MAD, size);
+	cmd->uid = (uintptr_t) context;
+	cmd->node_guid = ibv_get_device_guid(device->device);
+	cmd->comp_mask = comp_mask;
+	cmd->attr = (uintptr_t) attr;
+	cmd->port_num = port_num;
+	cmd->method = method;
+	cmd->attr_id = attr_id;
+	cmd->timeout_ms = timeout_ms;
+	cmd->retries = retries;
+
+	ret = write(channel->fd, msg, size);
+	if (ret != size)
+		return (ret > 0) ? ENODATA : ret;
+
+	return 0;
+}
+
+static void copy_event_attr(struct sa_event *evt,
+			    struct usa_abi_event_resp *resp)
+{
+	struct ibv_sa_mad *mad;
+	int size;
+
+	size = resp->data_len - IBV_SA_MAD_HEADER_SIZE;
+	if (size <= 0)
+		return;
+
+	evt->data = malloc(size);
+	if (!evt->data)
+		return;
+
+	mad = (struct ibv_sa_mad *) resp->data;
+	memcpy(evt->data, mad->sa_data, size);
+	evt->event.attr = evt->data;
+	evt->event.attr_id = mad->attribute_id;
+	evt->event.attr_size = ibv_sa_attr_size(mad->attribute_id);
+	evt->event.attr_offset = ntohs(mad->attribute_offset) * 8;
+	if (evt->event.attr_offset)
+		evt->event.attr_count = size / evt->event.attr_offset;
+}
+
+static int get_event_attr(struct sa_event *evt,
+			  struct usa_abi_event_resp *resp)
+{
+	struct ibv_sa_mad *mad;
+	struct usa_abi_get_data *cmd;
+	void *msg;
+	int ret, size;
+
+	USA_CREATE_MSG_CMD(msg, cmd, USA_CMD_GET_DATA, size);
+	cmd->id = resp->id;
+
+	evt->data = malloc(resp->data_len);
+	if (evt->data) {
+		cmd->response = (uintptr_t) evt->data;
+		((struct usa_abi_cmd_hdr *) msg)->out = resp->data_len;
+	}
+
+	ret = write(evt->channel->fd, msg, size);
+	if (ret != size)
+		return (ret > 0) ? ENODATA : ret;
+
+	mad = (struct ibv_sa_mad *) resp->data;
+	evt->event.attr = evt->data;
+	evt->event.attr_id = mad->attribute_id;
+	evt->event.attr_size = ibv_sa_attr_size(mad->attribute_id);
+	evt->event.attr_offset = ntohs(mad->attribute_offset) * 8;
+	if (evt->event.attr_offset)
+		evt->event.attr_count = (resp->data_len -
+					 IBV_SA_MAD_HEADER_SIZE) /
+					evt->event.attr_offset;
+	return 0;
+}
+
+static void process_mad_event(struct sa_event *evt,
+			      struct usa_abi_event_resp *resp)
+{
+	evt->event.context = (void *) (uintptr_t) resp->uid;
+	if (resp->data_len <= IB_USA_EVENT_DATA)
+		copy_event_attr(evt, resp);
+	else
+		get_event_attr(evt, resp);
+}
+
+static void process_mcast_event(struct sa_event *evt,
+				struct usa_abi_event_resp *resp)
+{
+	struct ibv_sa_multicast *multicast;
+
+	multicast = (void *) (uintptr_t) resp->uid;
+	evt->event.context = multicast->context;
+	evt->event_tracking = &multicast->event_tracking;
+	multicast->id = resp->id;
+
+	evt->data = malloc(IBV_SA_ATTR_MC_MEMBER_REC_LEN);
+	if (!evt->data)
+		return;
+
+	memcpy(evt->data, resp->data, IBV_SA_ATTR_MC_MEMBER_REC_LEN);
+	evt->event.attr = evt->data;
+	evt->event.attr_id = IBV_SA_ATTR_MC_MEMBER_REC;
+	evt->event.attr_size = IBV_SA_ATTR_MC_MEMBER_REC_LEN;
+	evt->event.attr_offset = IBV_SA_ATTR_MC_MEMBER_REC_LEN;
+	evt->event.attr_count = 1;
+}
+
+int ibv_sa_get_event(struct ibv_sa_event_channel *channel,
+		     struct ibv_sa_event **event)
+{
+	struct usa_abi_get_event *cmd;
+	struct usa_abi_event_resp *resp;
+	struct sa_event *evt;
+	void *msg;
+	int ret, size;
+
+	evt = malloc(sizeof *evt);
+	if (!evt)
+		return ENOMEM;
+	memset(evt, 0, sizeof *evt);
+
+	USA_CREATE_MSG_CMD_RESP(msg, cmd, resp, USA_CMD_GET_EVENT, size);
+	ret = write(channel->fd, msg, size);
+	if (ret != size) {
+		ret = (ret > 0) ? ENODATA : ret;
+		goto err;
+	}
+
+	evt->channel = channel;
+	evt->event.event = resp->event;
+	evt->event.status = resp->status;
+
+	switch (resp->event) {
+	case USA_EVENT_MAD:
+		process_mad_event(evt, resp);
+		break;
+	case USA_EVENT_MCAST:
+		process_mcast_event(evt, resp);
+		break;
+	default:
+		break;
+	}
+	
+	*event = &evt->event;
+	return 0;
+err:
+	free(evt);
+	return ret;
+}
+
+int ibv_sa_ack_event(struct ibv_sa_event *event)
+{
+	struct sa_event *evt = container_of(event, struct sa_event, event);
+
+	if (evt->data)
+		free(evt->data);
+
+	if (evt->event_tracking)
+		complete_event(evt->event_tracking);
+
+	free(event);
+	return 0;
+}
+
+int ibv_sa_join_multicast(struct ibv_sa_event_channel *channel,
+			  struct ibv_context *device, uint8_t port_num,
+			  struct ibv_sa_net_mcmember_rec *rec,
+			  uint64_t comp_mask, void *context,
+			  struct ibv_sa_multicast **multicast)
+{
+	struct usa_abi_join_mcast *cmd;
+	struct usa_abi_id_resp *resp;
+	struct ibv_sa_multicast *mcast;
+	void *msg;
+	int ret, size;
+
+	mcast = malloc(sizeof *mcast);
+	if (!mcast)
+		return ENOMEM;
+	memset(mcast, 0, sizeof *mcast);
+
+	mcast->channel = channel;
+	mcast->context = context;
+	ret = init_event_tracking(&mcast->event_tracking);
+	if (ret)
+		goto err;
+
+	USA_CREATE_MSG_CMD_RESP(msg, cmd, resp, USA_CMD_JOIN_MCAST, size);
+	cmd->uid = (uintptr_t) mcast;
+	cmd->node_guid = ibv_get_device_guid(device->device);
+	cmd->comp_mask = comp_mask;
+	cmd->mcmember_rec = (uintptr_t) rec;
+	cmd->port_num = port_num;
+
+	ret = write(channel->fd, msg, size);
+	if (ret != size) {
+		ret = (ret > 0) ? ENODATA : ret;
+		goto err;
+	}
+
+	mcast->id = resp->id;
+	*multicast = mcast;
+	return 0;
+err:
+	cleanup_event_tracking(&mcast->event_tracking);
+	free(mcast);
+	return ret;
+}
+
+int ibv_sa_free_multicast(struct ibv_sa_multicast *multicast)
+{
+	struct usa_abi_free_id *cmd;
+	struct usa_abi_free_resp *resp;
+	void *msg;
+	int ret, size;
+
+	USA_CREATE_MSG_CMD_RESP(msg, cmd, resp, USA_CMD_FREE_ID, size);
+	ret = write(multicast->channel->fd, msg, size);
+	if (ret != size)
+		return (ret > 0) ? ENODATA : ret;
+
+	wait_for_events(&multicast->event_tracking, resp->events_reported);
+
+	cleanup_event_tracking(&multicast->event_tracking);
+	free(multicast);
+	return 0;
+}
+
+int ibv_sa_get_mcmember_rec(struct ibv_sa_event_channel *channel,
+			    struct ibv_context *device, uint8_t port_num,
+			    union ibv_gid *mgid,
+			    struct ibv_sa_net_mcmember_rec *rec)
+{
+	struct usa_abi_get_mcast *cmd;
+	void *msg;
+	int ret, size;
+
+	USA_CREATE_MSG_CMD(msg, cmd, USA_CMD_GET_MCAST, size);
+	cmd->node_guid = ibv_get_device_guid(device->device);
+	cmd->port_num = port_num;
+	cmd->response = (uintptr_t) rec;
+	((struct usa_abi_cmd_hdr *) msg)->out = sizeof *rec;
+	if (mgid)
+		memcpy(cmd->mgid, mgid->raw, sizeof *mgid);
+
+	ret = write(channel->fd, msg, size);
+	if (ret != size)
+		return (ret > 0) ? ENODATA : ret;
+
+	return 0;
+}
+
+static int get_gid_index(struct ibv_context *device, uint8_t port_num,
+			 union ibv_gid *sgid)
+{
+	union ibv_gid gid;
+	int i, ret;
+
+	for (i = 0, ret = 0; !ret; i++) {
+		ret = ibv_query_gid(device, port_num, i, &gid);
+		if (!ret && !memcmp(sgid, &gid, sizeof gid)) {
+			ret = i;
+			break;
+		}
+	}
+	return ret;
+}
+
+int ibv_sa_init_ah_from_path(struct ibv_context *device, uint8_t port_num,
+			     struct ibv_sa_net_path_rec *path_rec,
+			     struct ibv_ah_attr *ah_attr)
+{
+	struct ibv_sa_path_rec rec;
+	int ret;
+
+	ibv_sa_unpack_path_rec(&rec, path_rec);
+
+	memset(ah_attr, 0, sizeof *ah_attr);
+	ah_attr->dlid = ntohs(rec.dlid);
+	ah_attr->sl = rec.sl;
+	ah_attr->src_path_bits = ntohs(rec.slid) & 0x7F;
+	ah_attr->port_num = port_num;
+
+	if (rec.hop_limit > 1) {
+		ah_attr->is_global = 1;
+		ah_attr->grh.dgid = rec.dgid;
+		ret = get_gid_index(device, port_num, &rec.sgid);
+		if (ret < 0)
+			return ret;
+
+		ah_attr->grh.sgid_index = (uint8_t) ret;
+		ah_attr->grh.flow_label = ntohl(rec.flow_label);
+		ah_attr->grh.hop_limit = rec.hop_limit;
+		ah_attr->grh.traffic_class = rec.traffic_class;
+	}
+	return 0;
+}
+
+int ibv_sa_init_ah_from_mcmember(struct ibv_context *device, uint8_t port_num,
+				 struct ibv_sa_net_mcmember_rec *mc_rec,
+				 struct ibv_ah_attr *ah_attr)
+{
+	struct ibv_sa_mcmember_rec rec;
+	int ret;
+
+	ibv_sa_unpack_mcmember_rec(&rec, mc_rec);
+
+	ret = get_gid_index(device, port_num, &rec.port_gid);
+	if (ret < 0)
+		return ret;
+
+	memset(ah_attr, 0, sizeof *ah_attr);
+	ah_attr->dlid = ntohs(rec.mlid);
+	ah_attr->sl = rec.sl;
+	ah_attr->port_num = port_num;
+	ah_attr->static_rate = rec.rate;
+
+	ah_attr->is_global = 1;
+	ah_attr->grh.dgid = rec.mgid;
+
+	ah_attr->grh.sgid_index = (uint8_t) ret;
+	ah_attr->grh.flow_label = ntohl(rec.flow_label);
+	ah_attr->grh.hop_limit = rec.hop_limit;
+	ah_attr->grh.traffic_class = rec.traffic_class;
+	return 0;
+}

Property changes on: libibsa/src/sa_client.c
___________________________________________________________________
Name: svn:executable
   + *

Index: libibsa/src/sa_net.c
===================================================================
--- libibsa/src/sa_net.c	(revision 0)
+++ libibsa/src/sa_net.c	(revision 0)
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2006 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.
+ *
+ * $Id: cm.c 3453 2005-09-15 21:43:21Z sean.hefty $
+ */
+
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <string.h>
+#include <byteswap.h>
+
+#include <netinet/in.h>
+
+#include <infiniband/sa_net.h>
+
+int ibv_sa_attr_size(uint16_t attr_id)
+{
+	int size;
+
+	switch (attr_id) {
+	case IBV_SA_ATTR_CLASS_PORTINFO:
+		size = IBV_SA_ATTR_CLASS_PORTINFO_LEN;
+		break;
+	case IBV_SA_ATTR_NOTICE:
+		size = IBV_SA_ATTR_NOTICE_LEN;
+		break;
+	case IBV_SA_ATTR_INFORM_INFO:
+		size = IBV_SA_ATTR_INFORM_INFO_LEN;
+		break;
+	case IBV_SA_ATTR_NODE_REC:
+		size = IBV_SA_ATTR_NODE_REC_LEN;
+		break;
+	case IBV_SA_ATTR_PORT_INFO_REC:
+		size = IBV_SA_ATTR_PORT_INFO_REC_LEN;
+		break;
+	case IBV_SA_ATTR_SL2VL_REC:
+		size = IBV_SA_ATTR_SL2VL_REC_LEN;
+		break;
+	case IBV_SA_ATTR_SWITCH_REC:
+		size = IBV_SA_ATTR_SWITCH_REC_LEN;
+		break;
+	case IBV_SA_ATTR_LINEAR_FDB_REC:
+		size = IBV_SA_ATTR_LINEAR_FDB_REC_LEN;
+		break;
+	case IBV_SA_ATTR_RANDOM_FDB_REC:
+		size = IBV_SA_ATTR_RANDOM_FDB_REC_LEN;
+		break;
+	case IBV_SA_ATTR_MCAST_FDB_REC:
+		size = IBV_SA_ATTR_MCAST_FDB_REC_LEN;
+		break;
+	case IBV_SA_ATTR_SM_INFO_REC:
+		size = IBV_SA_ATTR_SM_INFO_REC_LEN;
+		break;
+	case IBV_SA_ATTR_LINK_REC:
+		size = IBV_SA_ATTR_LINK_REC_LEN;
+		break;
+	case IBV_SA_ATTR_GUID_INFO_REC:
+		size = IBV_SA_ATTR_GUID_INFO_REC_LEN;
+		break;
+	case IBV_SA_ATTR_SERVICE_REC:
+		size = IBV_SA_ATTR_SERVICE_REC_LEN;
+		break;
+	case IBV_SA_ATTR_PARTITION_REC:
+		size = IBV_SA_ATTR_PARTITION_REC_LEN;
+		break;
+	case IBV_SA_ATTR_PATH_REC:
+		size = IBV_SA_ATTR_PATH_REC_LEN;
+		break;
+	case IBV_SA_ATTR_VL_ARB_REC:
+		size = IBV_SA_ATTR_VL_ARB_REC_LEN;
+		break;
+	case IBV_SA_ATTR_MC_MEMBER_REC:
+		size = IBV_SA_ATTR_MC_MEMBER_REC_LEN;
+		break;
+	case IBV_SA_ATTR_TRACE_REC:
+		size = IBV_SA_ATTR_TRACE_REC_LEN;
+		break;
+	case IBV_SA_ATTR_MULTI_PATH_REC:
+		size = IBV_SA_ATTR_MULTI_PATH_REC_LEN;
+		break;
+	case IBV_SA_ATTR_SERVICE_ASSOC_REC:
+		size = IBV_SA_ATTR_SERVICE_ASSOC_REC_LEN;
+		break;
+	case IBV_SA_ATTR_INFORM_INFO_REC:
+		size = IBV_SA_ATTR_INFORM_INFO_REC_LEN;
+		break;
+	default:
+		size = 0;
+		break;
+	}
+	return size;
+}
+
+uint32_t ibv_sa_get_field(void *data, int offset, int size)
+{
+	uint32_t value, left_offset;
+
+	left_offset = offset & 0x07;
+	if (size <= 8) {
+		value = ((uint8_t *) data)[offset / 8];
+		value = ((value << left_offset) & 0xFF) >> (8 - size);
+	} else if (size <= 16) {
+		value = ntohs(((uint16_t *) data)[offset / 16]);
+		value = ((value << left_offset) & 0xFFFF) >> (16 - size);
+	} else {
+		value = ntohl(((uint32_t *) data)[offset / 32]);
+		value = (value << left_offset) >> (32 - size);
+	}
+	return value;
+}
+
+void ibv_sa_set_field(void *data, uint32_t value, int offset, int size)
+{
+	uint32_t left_value, right_value;
+	uint32_t left_offset, right_offset;
+	uint32_t field_size;
+
+	if (size <= 8)
+		field_size = 8;
+	else if (size <= 16)
+		field_size = 16;
+	else
+		field_size = 32;
+
+	left_offset = offset & 0x07;
+	right_offset = field_size - left_offset - size;
+
+	left_value = left_offset ? ibv_sa_get_field(data, offset - left_offset,
+						    left_offset) : 0;
+	right_value = right_offset ? ibv_sa_get_field(data, offset + size,
+						      right_offset) : 0;
+
+	value = (left_value << (size + right_offset)) |
+		(value << right_offset) | right_value;
+
+	if (field_size == 8)
+		((uint8_t *) data)[offset / 8] = (uint8_t) value;
+	else if (field_size == 16)
+		((uint16_t *) data)[offset / 16] = htons((uint16_t) value);
+	else
+		((uint32_t *) data)[offset / 32] = htonl((uint32_t) value);
+}
+
+void ibv_sa_unpack_path_rec(struct ibv_sa_path_rec *rec,
+			    struct ibv_sa_net_path_rec *net_rec)
+{
+	memcpy(rec->dgid.raw, net_rec->dgid, sizeof net_rec->dgid);
+	memcpy(rec->sgid.raw, net_rec->sgid, sizeof net_rec->sgid);
+	rec->dlid = net_rec->dlid;
+	rec->slid = net_rec->slid;
+
+	rec->raw_traffic = ibv_sa_get_field(net_rec, 352, 1);
+	rec->flow_label = htonl(ibv_sa_get_field(net_rec, 356, 20));
+	rec->hop_limit = (uint8_t) ibv_sa_get_field(net_rec, 376, 8);
+	rec->traffic_class = net_rec->tclass;
+
+	rec->reversible = htonl(ibv_sa_get_field(net_rec, 392, 1));
+	rec->numb_path = (uint8_t) ibv_sa_get_field(net_rec, 393, 7);
+	rec->pkey = net_rec->pkey;
+	rec->sl = (uint8_t) ibv_sa_get_field(net_rec, 428, 4);
+
+	rec->mtu_selector = (uint8_t) ibv_sa_get_field(net_rec, 432, 2);
+	rec->mtu = (uint8_t) ibv_sa_get_field(net_rec, 434, 6);
+
+	rec->rate_selector = (uint8_t) ibv_sa_get_field(net_rec, 440, 2);
+	rec->rate = (uint8_t) ibv_sa_get_field(net_rec, 442, 6);
+
+	rec->packet_life_time_selector = (uint8_t) ibv_sa_get_field(net_rec,
+								    448, 2);
+	rec->packet_life_time = (uint8_t) ibv_sa_get_field(net_rec, 450, 6);
+
+	rec->preference = net_rec->preference;
+}
+
+void ibv_sa_pack_mcmember_rec(struct ibv_sa_net_mcmember_rec *net_rec,
+			      struct ibv_sa_mcmember_rec *rec)
+{
+	memcpy(net_rec->mgid, rec->mgid.raw, sizeof net_rec->mgid);
+	memcpy(net_rec->port_gid, rec->port_gid.raw, sizeof net_rec->port_gid);
+	net_rec->qkey = rec->qkey;
+	net_rec->mlid = rec->mlid;
+
+	ibv_sa_set_field(net_rec, rec->mtu_selector, 304, 2);
+	ibv_sa_set_field(net_rec, rec->mtu, 306, 6);
+
+	net_rec->tclass = rec->traffic_class;
+	net_rec->pkey = rec->pkey;
+
+	ibv_sa_set_field(net_rec, rec->rate_selector, 336, 2);
+	ibv_sa_set_field(net_rec, rec->rate, 338, 6);
+
+	ibv_sa_set_field(net_rec, rec->packet_life_time_selector, 344, 2);
+	ibv_sa_set_field(net_rec, rec->packet_life_time, 346, 6);
+
+	ibv_sa_set_field(net_rec, rec->sl, 352, 4);
+	ibv_sa_set_field(net_rec, ntohl(rec->flow_label), 356, 20);
+	ibv_sa_set_field(net_rec, rec->hop_limit, 376, 8);
+
+	ibv_sa_set_field(net_rec, rec->scope, 384, 4);
+	ibv_sa_set_field(net_rec, rec->join_state, 388, 4);
+
+	ibv_sa_set_field(net_rec, rec->proxy_join, 392, 1);
+}
+
+void ibv_sa_unpack_mcmember_rec(struct ibv_sa_mcmember_rec *rec,
+				struct ibv_sa_net_mcmember_rec *net_rec)
+{
+	memcpy(rec->mgid.raw, net_rec->mgid, sizeof rec->mgid);
+	memcpy(rec->port_gid.raw, net_rec->port_gid, sizeof rec->port_gid);
+	rec->qkey = net_rec->qkey;
+	rec->mlid = net_rec->mlid;
+
+	rec->mtu_selector = (uint8_t) ibv_sa_get_field(net_rec, 304, 2);
+	rec->mtu = (uint8_t) ibv_sa_get_field(net_rec, 306, 6);
+
+	rec->traffic_class = net_rec->tclass;
+	rec->pkey = net_rec->pkey;
+
+	rec->rate_selector = (uint8_t) ibv_sa_get_field(net_rec, 336, 2);
+	rec->rate = (uint8_t) ibv_sa_get_field(net_rec, 338, 6);
+
+	rec->packet_life_time_selector = (uint8_t) ibv_sa_get_field(net_rec,
+								    344, 2);
+	rec->packet_life_time = (uint8_t) ibv_sa_get_field(net_rec, 346, 6);
+
+	rec->sl = (uint8_t) ibv_sa_get_field(net_rec, 352, 4);
+	rec->flow_label = htonl(ibv_sa_get_field(net_rec, 356, 20));
+	rec->hop_limit = ibv_sa_get_field(net_rec, 376, 8);
+
+	rec->scope = (uint8_t) ibv_sa_get_field(net_rec, 384, 4);
+	rec->join_state = (uint8_t) ibv_sa_get_field(net_rec, 388, 4);
+
+	rec->proxy_join = ibv_sa_get_field(net_rec, 392, 1);
+}

Property changes on: libibsa/src/sa_net.c
___________________________________________________________________
Name: svn:executable
   + *

Index: libibsa/ChangeLog
===================================================================
Index: libibsa/COPYING
===================================================================
--- libibsa/COPYING	(revision 0)
+++ libibsa/COPYING	(revision 0)
@@ -0,0 +1,378 @@
+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 the
+OpenIB.org BSD license or the GNU General Public License (GPL) Version
+2, both included below.
+
+Copyright (c) 2005 Intel Corporation.  All rights reserved.
+
+==================================================================
+
+		       OpenIB.org BSD license
+
+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.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+==================================================================
+
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: libibsa/Makefile.am
===================================================================
--- libibsa/Makefile.am	(revision 0)
+++ libibsa/Makefile.am	(revision 0)
@@ -0,0 +1,40 @@
+# $Id: Makefile.am 3373 2005-09-12 16:34:20Z roland $
+INCLUDES = -I$(srcdir)/include
+
+AM_CFLAGS = -g -Wall -D_GNU_SOURCE
+
+ibsalibdir = $(libdir)
+
+ibsalib_LTLIBRARIES = src/libibsa.la
+
+src_ibsa_la_CFLAGS = -g -Wall -D_GNU_SOURCE
+
+if HAVE_LD_VERSION_SCRIPT
+    ibsa_version_script = -Wl,--version-script=$(srcdir)/src/libibsa.map
+else
+    ibsa_version_script =
+endif
+
+src_libibsa_la_SOURCES = src/sa_client.c src/sa_net.c
+src_libibsa_la_LDFLAGS = -avoid-version $(ibsa_version_script)
+
+bin_PROGRAMS = examples/satest examples/mchammer
+examples_satest_SOURCES = examples/satest.c
+examples_satest_LDADD = $(top_builddir)/src/libibsa.la
+examples_mchammer_SOURCES = examples/mchammer.c
+examples_mchammer_LDADD = $(top_builddir)/src/libibsa.la
+
+libibsaincludedir = $(includedir)/infiniband
+
+libibsainclude_HEADERS = include/infiniband/sa_client_abi.h \
+			 include/infiniband/sa_client.h \
+			 include/infiniband/sa_net.h
+
+EXTRA_DIST = include/infiniband/sa_client_abi.h \
+	     include/infiniband/sa_client.h \
+	     include/infiniband/sa_net.h \
+	     src/libibsa.map \
+	     libibsa.spec.in
+
+dist-hook: libibsa.spec
+	cp libibsa.spec $(distdir)
Index: libibsa/autogen.sh
===================================================================
--- libibsa/autogen.sh	(revision 0)
+++ libibsa/autogen.sh	(revision 0)
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+set -x
+aclocal -I config
+libtoolize --force --copy
+autoheader
+automake --foreign --add-missing --copy
+autoconf

Property changes on: libibsa/autogen.sh
___________________________________________________________________
Name: svn:executable
   + *

Index: libibsa/NEWS
===================================================================
Index: libibsa/README
===================================================================
--- libibsa/README	(revision 0)
+++ libibsa/README	(revision 0)
@@ -0,0 +1,16 @@
+This README is for userspace SA client library.
+
+Building
+
+To make this directory, run:
+./autogen.sh && ./configure && make && make install
+
+Typically the autogen and configure steps only need be done the first
+time unless configure.in or Makefile.am changes.
+
+Libraries are installed by default at /usr/local/lib.
+
+Device files
+
+The userspace SA client uses a single device file under misc devices
+regardless of the number of adapters or ports present.
Index: libibsa/examples/satest.c
===================================================================
--- libibsa/examples/satest.c	(revision 0)
+++ libibsa/examples/satest.c	(revision 0)
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2006 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.
+ *
+ * $Id$
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <byteswap.h>
+#include <netinet/in.h>
+
+#include <infiniband/sa_client.h>
+#include <infiniband/sa_net.h>
+
+/*
+ * To execute:
+ * satest slid dlid
+ */
+
+struct ibv_context *verbs;
+struct ibv_sa_event_channel *channel;
+uint16_t slid;
+uint16_t dlid;
+
+static int init(void)
+{
+	struct ibv_device **dev_list;
+	int ret = 0;
+
+	dev_list = ibv_get_device_list(NULL);
+	if (!dev_list[0])
+		return -1;
+
+	verbs = ibv_open_device(dev_list[0]);
+	ibv_free_device_list(dev_list);
+	if (!verbs)
+		return -1;
+
+	channel = ibv_sa_create_event_channel();
+	if (!channel) {
+		printf("ibv_sa_create_event_channel failed\n");
+		ibv_close_device(verbs);
+		ret = 1;
+	}
+
+	return ret;
+}
+
+static void cleanup(void)
+{
+	ibv_sa_destroy_event_channel(channel);
+	ibv_close_device(verbs);
+}
+
+static int query_one_path(struct ibv_sa_net_path_rec *path_rec)
+{
+	struct ibv_sa_event *event;
+	int ret;
+
+	path_rec->slid = slid;
+	path_rec->dlid = dlid;
+	ibv_sa_set_field(path_rec, 1, IBV_SA_PATH_REC_NUMB_PATH_OFFSET,
+			 IBV_SA_PATH_REC_NUMB_PATH_LENGTH);
+	ret = ibv_sa_send_mad(channel, verbs, 1, IBV_SA_METHOD_GET,
+			      path_rec, IBV_SA_ATTR_PATH_REC,
+			      IBV_SA_PATH_REC_SLID |
+			      IBV_SA_PATH_REC_DLID |
+			      IBV_SA_PATH_REC_NUMB_PATH, 3000, 3, NULL);
+	if (ret) {
+		printf("query_one_path ibv_sa_send_mad failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = ibv_sa_get_event(channel, &event);
+	if (ret) {
+		printf("query_one_path ibv_sa_get_event failed: %d\n", ret);
+		return ret;
+	}
+
+	if (event->status) {
+		printf("query_one_path: status = %d\n", event->status);
+		ret = event->status;
+		goto out;
+	}
+
+	memcpy(path_rec, event->attr, event->attr_size);
+out:
+	ibv_sa_ack_event(event);
+	return ret;
+}
+
+static int query_many_paths(struct ibv_sa_event **event)
+{
+	struct ibv_sa_net_path_rec path_rec;
+	int ret;
+
+	path_rec.slid = slid;
+	ret = ibv_sa_send_mad(channel, verbs, 1, IBV_SA_METHOD_GET_TABLE,
+			      &path_rec, IBV_SA_ATTR_PATH_REC,
+			      IBV_SA_PATH_REC_SLID, 3000, 3, NULL);
+	if (ret) {
+		printf("query_many_paths ibv_sa_send_mad failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = ibv_sa_get_event(channel, event);
+	if (ret) {
+		printf("query_many_paths ibv_sa_get_event failed: %d\n", ret);
+		return ret;
+	}
+
+	if ((*event)->status) {
+		printf("query_many_paths: status = %d\n", (*event)->status);
+		ret = (*event)->status;
+		goto err;
+	}
+
+	return 0;
+err:
+	ibv_sa_ack_event(*event);
+	return ret;
+}
+
+static int verify_paths(struct ibv_sa_net_path_rec *path_rec,
+			struct ibv_sa_event *event)
+{
+	struct ibv_sa_net_path_rec *rec;
+	int i, ret = -1;
+
+	if (path_rec->slid != slid || path_rec->dlid != dlid) {
+		printf("path_rec slid or dlid does not match request\n");
+		return -1;
+	}
+
+	for (i = 0; i < event->attr_count; i++) {
+		rec = ibv_sa_get_attr(event, i);
+
+		if (rec->slid != slid) {
+			printf("rec slid does not match request\n");
+			return -1;
+		}
+
+		if (path_rec->dlid == rec->dlid &&
+		    !memcmp(path_rec, rec, sizeof *rec))
+			ret = 0;
+	}
+
+	if (ret)
+		printf("path_rec not found in returned list\n");
+
+	return ret;
+}
+
+static int run_path_query(void)
+{
+	struct ibv_sa_net_path_rec path_rec;
+	struct ibv_sa_event *event;
+	int ret;
+
+	ret = query_one_path(&path_rec);
+	if (ret)
+		return ret;
+
+	ret = query_many_paths(&event);
+	if (ret)
+		return ret;
+
+	ret = verify_paths(&path_rec, event);
+
+	ibv_sa_ack_event(event);
+	return ret;
+}
+
+int main(int argc, char **argv)
+{
+	int ret;
+
+	if (argc != 3) {
+		printf("usage: %s slid dlid\n", argv[0]);
+		exit(1);
+	}
+
+	slid = htons((uint16_t) atoi(argv[1]));
+	dlid = htons((uint16_t) atoi(argv[2]));
+
+	if (init())
+		exit(1);
+
+	ret = run_path_query();
+
+	printf("test complete\n");
+	cleanup();
+	printf("return status %d\n", ret);
+	return ret;
+}

Property changes on: libibsa/examples/satest.c
___________________________________________________________________
Name: svn:executable
   + *

Index: libibsa/examples/mchammer.c
===================================================================
--- libibsa/examples/mchammer.c	(revision 0)
+++ libibsa/examples/mchammer.c	(revision 0)
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2006 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.
+ *
+ * $Id$
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <byteswap.h>
+#include <netinet/in.h>
+#include <unistd.h>
+
+#include <infiniband/sa_client.h>
+#include <infiniband/sa_net.h>
+
+/*
+ * To execute:
+ * mchammer {r | s}
+ */
+
+struct ibv_context	*verbs;
+struct ibv_pd		*pd;
+struct ibv_cq		*cq;
+struct ibv_qp		*qp;
+struct ibv_mr		*mr;
+void			*msgs;
+
+static int message_count = 10;
+static int message_size = 100;
+static int sender;
+
+static int post_recvs(void)
+{
+	struct ibv_recv_wr recv_wr, *recv_failure;
+	struct ibv_sge sge;
+	int i, ret = 0;
+
+	if (!message_count)
+		return 0;
+
+	recv_wr.next = NULL;
+	recv_wr.sg_list = &sge;
+	recv_wr.num_sge = 1;
+
+	sge.length = message_size + sizeof(struct ibv_grh);;
+	sge.lkey = mr->lkey;
+	sge.addr = (uintptr_t) msgs;
+
+	for (i = 0; i < message_count && !ret; i++ ) {
+		ret = ibv_post_recv(qp, &recv_wr, &recv_failure);
+		if (ret) {
+			printf("failed to post receives: %d\n", ret);
+			break;
+		}
+	}
+	return ret;
+}
+
+static int create_qp(void)
+{
+	struct ibv_qp_init_attr init_qp_attr;
+	struct ibv_qp_attr qp_attr;
+	int ret;
+
+	memset(&init_qp_attr, 0, sizeof init_qp_attr);
+	init_qp_attr.cap.max_send_wr = message_count ? message_count : 1;
+	init_qp_attr.cap.max_recv_wr = message_count ? message_count : 1;
+	init_qp_attr.cap.max_send_sge = 1;
+	init_qp_attr.cap.max_recv_sge = 1;
+	init_qp_attr.qp_type = IBV_QPT_UD;
+	init_qp_attr.send_cq = cq;
+	init_qp_attr.recv_cq = cq;
+	qp = ibv_create_qp(pd, &init_qp_attr);
+	if (!qp) {
+		printf("unable to create QP\n");
+		return -1;
+	}
+
+	qp_attr.qp_state = IBV_QPS_INIT;
+	qp_attr.pkey_index = 0;
+	qp_attr.port_num = 1;
+	qp_attr.qkey = 0x01234567;
+	ret = ibv_modify_qp(qp, &qp_attr, IBV_QP_STATE | IBV_QP_PKEY_INDEX |
+					  IBV_QP_PORT | IBV_QP_QKEY);
+	if (ret) {
+		printf("failed to modify QP to INIT\n");
+		goto err;
+	}
+
+	qp_attr.qp_state = IBV_QPS_RTR;
+	ret = ibv_modify_qp(qp, &qp_attr, IBV_QP_STATE);
+	if (ret) {
+		printf("failed to modify QP to RTR\n");
+		goto err;
+	}
+
+	qp_attr.qp_state = IBV_QPS_RTS;
+	qp_attr.sq_psn = 0;
+	ret = ibv_modify_qp(qp, &qp_attr, IBV_QP_STATE | IBV_QP_SQ_PSN);
+	if (ret) {
+		printf("failed to modify QP to RTS\n");
+		goto err;
+	}
+	return 0;
+err:
+	ibv_destroy_qp(qp);
+	return ret;
+}
+
+static int create_messages(void)
+{
+	if (!message_size)
+		message_count = 0;
+
+	if (!message_count)
+		return 0;
+
+	msgs = malloc(message_size + sizeof(struct ibv_grh));
+	if (!msgs) {
+		printf("failed message allocation\n");
+		return -1;
+	}
+	mr = ibv_reg_mr(pd, msgs, message_size + sizeof(struct ibv_grh),
+			IBV_ACCESS_LOCAL_WRITE);
+	if (!mr) {
+		printf("failed to reg MR\n");
+		free(msgs);
+		return -1;
+	}
+	return 0;
+}
+
+static void destroy_messages(void)
+{
+	if (!message_count)
+		return;
+
+	ibv_dereg_mr(mr);
+	free(msgs);
+}
+
+static int init(void)
+{
+	struct ibv_device **dev_list;
+	int ret;
+
+	dev_list = ibv_get_device_list(NULL);
+	if (!dev_list[0])
+		return -1;
+
+	verbs = ibv_open_device(dev_list[0]);
+	ibv_free_device_list(dev_list);
+	if (!verbs)
+		return -1;
+
+	pd = ibv_alloc_pd(verbs);
+	if (!pd) {
+		printf("unable to alloc PD\n");
+		return -1;
+	}
+
+	ret = create_messages();
+	if (ret) {
+		printf("unable to create test messages\n");
+		goto err1;
+	}
+
+	cq = ibv_create_cq(verbs, message_count, NULL, NULL, 0);
+	if (!cq) {
+		printf("unable to create CQ\n");
+		ret = -1;
+		goto err2;
+	}
+
+	ret = create_qp();
+	if (ret) {
+		printf("unable to create QP\n");
+		goto err3;
+	}
+	return 0;
+
+err3:
+	ibv_destroy_cq(cq);
+err2:
+	destroy_messages();
+err1:
+	ibv_dealloc_pd(pd);
+	return -1;
+}
+
+static void cleanup(void)
+{
+	ibv_destroy_qp(qp);
+	ibv_destroy_cq(cq);
+	destroy_messages();
+	ibv_dealloc_pd(pd);
+	ibv_close_device(verbs);
+}
+
+static int send_msgs(struct ibv_ah *ah)
+{
+	struct ibv_send_wr send_wr, *bad_send_wr;
+	struct ibv_sge sge;
+	int i, ret = 0;
+
+	send_wr.next = NULL;
+	send_wr.sg_list = &sge;
+	send_wr.num_sge = 1;
+	send_wr.opcode = IBV_WR_SEND;
+	send_wr.send_flags = 0;
+
+	send_wr.wr.ud.ah = ah;
+	send_wr.wr.ud.remote_qpn = 0xFFFFFF;
+	send_wr.wr.ud.remote_qkey = 0x01234567;
+
+	sge.length = message_size;
+	sge.lkey = mr->lkey;
+	sge.addr = (uintptr_t) msgs;
+
+	for (i = 0; i < message_count && !ret; i++) {
+		ret = ibv_post_send(qp, &send_wr, &bad_send_wr);
+		if (ret) 
+			printf("failed to post sends: %d\n", ret);
+	}
+	return ret;
+}
+
+static int poll_cq(void)
+{
+	struct ibv_wc wc[8];
+	int done, ret;
+
+	for (done = 0; done < message_count; done += ret) {
+		ret = ibv_poll_cq(cq, 8, wc);
+		if (ret < 0) {
+			printf("failed polling CQ: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int run(void)
+{
+	struct ibv_sa_event_channel *channel;
+	struct ibv_sa_multicast	*mcast;
+	struct ibv_sa_event *event;
+	struct ibv_sa_net_mcmember_rec mc_rec, *rec;
+	struct ibv_ah_attr ah_attr;
+	struct ibv_ah *ah;
+	uint64_t comp_mask;
+	int ret;
+
+	channel = ibv_sa_create_event_channel();
+	if (!channel) {
+		printf("ibv_sa_create_event_channel failed\n");
+		return -1;
+	}
+
+	ret = ibv_sa_get_mcmember_rec(channel, verbs, 1, NULL, &mc_rec);
+	if (ret) {
+		printf("ibv_sa_get_mcmember_rec failed\n");
+		goto out1;
+	}
+
+	printf("joining multicast group\n");
+	mc_rec.mgid[0] = 0xFF;	/* multicast GID */
+	mc_rec.mgid[1] = 0x12;	/* not permanent (7:4), link-local (3:0) */
+	strcpy(&mc_rec.mgid[2], "7471"); /* our GID */
+	mc_rec.qkey = htonl(0x01234567);
+	comp_mask = IBV_SA_MCMEMBER_REC_MGID | IBV_SA_MCMEMBER_REC_PORT_GID |
+		    IBV_SA_MCMEMBER_REC_PKEY | IBV_SA_MCMEMBER_REC_JOIN_STATE |
+		    IBV_SA_MCMEMBER_REC_QKEY | IBV_SA_MCMEMBER_REC_SL |
+		    IBV_SA_MCMEMBER_REC_FLOW_LABEL |
+		    IBV_SA_MCMEMBER_REC_TRAFFIC_CLASS;
+	ret = ibv_sa_join_multicast(channel, verbs, 1, &mc_rec,
+				    comp_mask, NULL, &mcast);
+	if (ret) {
+		printf("ibv_sa_join_multicast failed\n");
+		goto out1;
+	}
+
+	ret = ibv_sa_get_event(channel, &event);
+	if (ret) {
+		printf("ibv_sa_get_event failed\n");
+		goto out2;
+	}
+
+	if (event->status) {
+		printf("join failed: %d\n", event->status);
+		ret = event->status;
+		goto out3;
+	}
+
+	rec = (struct ibv_sa_net_mcmember_rec *) event->attr;
+	ibv_sa_init_ah_from_mcmember(verbs, 1, rec, &ah_attr);
+	ah = ibv_create_ah(pd, &ah_attr);
+	if (!ah) {
+		printf("ibv_create_ah failed\n");
+		ret = -1;
+		goto out3;
+	}
+
+	ret = ibv_attach_mcast(qp, (union ibv_gid *) rec->mgid,
+			       htons(rec->mlid));
+	if (ret) {
+		printf("ibv_attach_mcast failed\n");
+		goto out4;
+	}
+
+	/*
+	 * Pause to give SM chance to configure switches.  We don't want to
+	 * handle reliability issue in this simple test program.
+	 */
+	sleep(2);
+
+	if (sender) {
+		printf("initiating data transfers\n");
+		ret = send_msgs(ah);
+		sleep(1);
+	} else {
+		printf("receiving data transfers\n");
+		ret = post_recvs();
+		if (!ret)
+			ret = poll_cq();
+	}
+	printf("data transfers complete\n");
+
+	ibv_detach_mcast(qp, (union ibv_gid *) rec->mgid, htons(rec->mlid));
+out4:
+	ibv_destroy_ah(ah);
+out3:
+	ibv_sa_ack_event(event);
+out2:
+	ibv_sa_free_multicast(mcast);
+out1:
+	ibv_sa_destroy_event_channel(channel);
+	return ret;
+}
+
+int main(int argc, char **argv)
+{
+	int ret;
+
+	if (argc != 2) {
+		printf("usage: %s {r | s}\n", argv[0]);
+		exit(1);
+	}
+
+	sender = (argv[1][0] == 's');
+	if (init())
+		exit(1);
+
+	ret = run();
+
+	printf("test complete\n");
+	cleanup();
+	printf("return status %d\n", ret);
+	return ret;
+}

Property changes on: libibsa/examples/mchammer.c
___________________________________________________________________
Name: svn:executable
   + *






More information about the general mailing list