[ofw] [PATCH] Update libibmad and infiniband-diags

Smith, Stan stan.smith at intel.com
Mon Aug 8 12:57:00 PDT 2011


Do the git commits imply SVN commits?

Since you are likely one of the 'few' who use git for windows projects, it is not a burden on the rest of the Windows IB project members to force everyone else to refer to the git trees for changes and/or an explanation of the bigger picture of what/how things have changed?

Does opensm still build?

We 'really' need to separate out from ib_types.h the diags/MAD/opensm issues into separate header files...the kitchen sink is rather larger and continues to grow. :-(

Stan.

>-----Original Message-----
>From: ofw-bounces at lists.openfabrics.org [mailto:ofw-bounces at lists.openfabrics.org] On Behalf Of Hefty, Sean
>Sent: Monday, August 08, 2011 12:34 PM
>To: ofw at lists.openfabrics.org
>Subject: [ofw] [PATCH] Update libibmad and infiniband-diags
>
>Update libibmad to commit 818fcb2260ea0308e09ad434acb76691d25ff95d and
>ib-diags to commit a817e38e5275dcf75404af19b8592c03f4822118
>
>This results in all diags needing a dependency on ibal for ib_get_err_str() and
>adds one new executable, ibcacheedit.  For a separate breakout of changes, refer
>to the git trees.
>
>Signed-off-by: Sean Hefty <sean.hefty at intel.com>
>---
>trunk/inc/iba/ib_types.h                           |    2
> .../tools/infiniband-diags/include/ibdiag_common.h |   55 ++
> .../infiniband-diags/include/windows/config.h      |    3
> trunk/tools/infiniband-diags/src/dirs              |    1
> trunk/tools/infiniband-diags/src/ibaddr.c          |    5
> trunk/tools/infiniband-diags/src/ibaddr/SOURCES    |    1
> .../tools/infiniband-diags/src/ibcacheedit/SOURCES |   28 +
> .../src/ibcacheedit/ibcacheedit.rc                 |   47 ++
> .../infiniband-diags/src/ibcacheedit/makefile      |    7
> trunk/tools/infiniband-diags/src/ibdiag_common.c   |  193 ++++++++
> trunk/tools/infiniband-diags/src/iblinkinfo.c      |  416 +++++++++++++++--
> .../tools/infiniband-diags/src/iblinkinfo/SOURCES  |    1
> trunk/tools/infiniband-diags/src/ibnetdiscover.c   |   69 +++
> .../infiniband-diags/src/ibnetdiscover/SOURCES     |    1
> trunk/tools/infiniband-diags/src/ibping.c          |    2
> trunk/tools/infiniband-diags/src/ibping/SOURCES    |    1
> trunk/tools/infiniband-diags/src/ibportstate.c     |    6
> .../tools/infiniband-diags/src/ibportstate/SOURCES |    1
> trunk/tools/infiniband-diags/src/ibqueryerrors.c   |  491 ++++++++++++++++----
> .../infiniband-diags/src/ibqueryerrors/SOURCES     |    1
> trunk/tools/infiniband-diags/src/ibroute.c         |   10
> trunk/tools/infiniband-diags/src/ibroute/SOURCES   |    1
> trunk/tools/infiniband-diags/src/ibsendtrap.c      |    5
> .../tools/infiniband-diags/src/ibsendtrap/SOURCES  |    1
> trunk/tools/infiniband-diags/src/ibstat.c          |   17 -
> trunk/tools/infiniband-diags/src/ibstat/SOURCES    |    1
> trunk/tools/infiniband-diags/src/ibsysstat/SOURCES |    1
> trunk/tools/infiniband-diags/src/ibtracert.c       |   14 -
> trunk/tools/infiniband-diags/src/ibtracert/SOURCES |    1
> .../infiniband-diags/src/mcm_rereg_test/SOURCES    |    1
> trunk/tools/infiniband-diags/src/perfquery.c       |  301 +++++++++++-
> trunk/tools/infiniband-diags/src/perfquery/SOURCES |    1
> trunk/tools/infiniband-diags/src/saquery.c         |  405 ++++++----------
> trunk/tools/infiniband-diags/src/sminfo.c          |    3
> trunk/tools/infiniband-diags/src/sminfo/SOURCES    |    1
> trunk/tools/infiniband-diags/src/smpdump/SOURCES   |    1
> trunk/tools/infiniband-diags/src/smpquery.c        |   48 +-
> trunk/tools/infiniband-diags/src/smpquery/SOURCES  |    1
> trunk/tools/infiniband-diags/src/vendstat.c        |    1
> trunk/tools/infiniband-diags/src/vendstat/SOURCES  |    1
> trunk/ulp/libibmad/include/infiniband/mad.h        |  355 ++++++++++++++
> trunk/ulp/libibmad/include/infiniband/mad_osd.h    |    1
> trunk/ulp/libibmad/src/dump.c                      |  207 ++++++++
> trunk/ulp/libibmad/src/fields.c                    |  364 +++++++++++++--
> trunk/ulp/libibmad/src/gs.c                        |   23 +
> trunk/ulp/libibmad/src/ibmad_exports.src           |  167 +++++--
> trunk/ulp/libibmad/src/libibmad.map                |   19 +
> trunk/ulp/libibmad/src/mad.c                       |   19 -
> trunk/ulp/libibmad/src/register.c                  |    2
> trunk/ulp/libibmad/src/rpc.c                       |   34 +
> trunk/ulp/libibmad/src/serv.c                      |    2
> trunk/ulp/libibmad/src/smp.c                       |   41 +-
> trunk/ulp/libibmad/src/vendor.c                    |   17 -
> .../libibnetdisc/include/infiniband/ibnetdisc.h    |   22 +
> .../include/infiniband/ibnetdisc_osd.h             |   41 ++
> trunk/ulp/libibnetdisc/src/chassis.c               |  275 ++++++++++-
> trunk/ulp/libibnetdisc/src/chassis.h               |    6
> trunk/ulp/libibnetdisc/src/ibnetdisc.c             |  213 ++++++---
> trunk/ulp/libibnetdisc/src/ibnetdisc_cache.c       |   19 +
> trunk/ulp/libibnetdisc/src/ibnetdisc_exports.src   |    5
> trunk/ulp/libibnetdisc/src/internal.h              |    1
> trunk/ulp/opensm/user/opensm/osm_helper.c          |    4
> 62 files changed, 3282 insertions(+), 701 deletions(-)
> create mode 100644 trunk/tools/infiniband-diags/src/ibcacheedit/SOURCES
> create mode 100644 trunk/tools/infiniband-diags/src/ibcacheedit/ibcacheedit.rc
> create mode 100644 trunk/tools/infiniband-diags/src/ibcacheedit/makefile
> create mode 100644 trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc_osd.h
>
>diff --git a/trunk/inc/iba/ib_types.h b/trunk/inc/iba/ib_types.h
>index 665bdad..21781d5 100644
>--- a/trunk/inc/iba/ib_types.h
>+++ b/trunk/inc/iba/ib_types.h
>@@ -6228,7 +6228,7 @@ typedef struct _ib_portinfo_record
> {
> 	ib_net16_t		lid;
> 	uint8_t			port_num;
>-	uint8_t			resv;
>+	uint8_t			options;
> 	ib_port_info_t	port_info;
>
> }	PACK_SUFFIX ib_portinfo_record_t;
>diff --git a/trunk/tools/infiniband-diags/include/ibdiag_common.h b/trunk/tools/infiniband-diags/include/ibdiag_common.h
>index 9b2add7..57bde20 100644
>--- a/trunk/tools/infiniband-diags/include/ibdiag_common.h
>+++ b/trunk/tools/infiniband-diags/include/ibdiag_common.h
>@@ -1,6 +1,10 @@
> /*
>  * Copyright (c) 2006-2007 The Regents of the University of California.
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>+ * Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved.
>+ * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
>+ * Copyright (c) 2009 HNR Consulting. All rights reserved.
>+ * Copyright (c) 2011 Lawrence Livermore National Security. 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
>@@ -35,6 +39,7 @@
> #ifndef _IBDIAG_COMMON_H_
> #define _IBDIAG_COMMON_H_
>
>+#include <infiniband/iba/ib_types.h>
> #include <infiniband/mad.h>
>
> extern int ibverbose;
>@@ -57,6 +62,11 @@ extern int ibd_timeout;
> } while (0)
> #define IBERROR(fmt, ...) iberror(__FUNCTION__, fmt, ## __VA_ARGS__)
>
>+/* not all versions of ib_types.h will have this define */
>+#ifndef IB_PM_PC_XMIT_WAIT_SUP
>+#define IB_PM_PC_XMIT_WAIT_SUP (CL_HTON16(((uint16_t)1)<<12))
>+#endif
>+
> struct ibdiag_opt {
> 	const char *name;
> 	char letter;
>@@ -75,4 +85,49 @@ extern int ibdiag_process_opts(int argc, char *const argv[], void *context,
> extern void ibdiag_show_usage();
> extern void iberror(const char *fn, char *msg, ...);
>
>+/* define an SA query structure to be common
>+ * This is by no means optimal but it moves the saquery functionality out of
>+ * the saquery tool and provides it to other utilities.
>+ */
>+struct bind_handle {
>+	int fd, agent;
>+	ib_portid_t dport;
>+	struct ibmad_port *srcport;
>+};
>+typedef struct bind_handle * bind_handle_t;
>+bind_handle_t sa_get_bind_handle(void);
>+void sa_free_bind_handle(bind_handle_t h);
>+
>+struct sa_query_result {
>+	uint32_t status;
>+	unsigned result_cnt;
>+	void *p_result_madw;
>+};
>+int sa_query(struct bind_handle *h, uint8_t method,
>+	     uint16_t attr, uint32_t mod, uint64_t comp_mask, uint64_t sm_key,
>+	     void *data, struct sa_query_result *result);
>+void sa_free_result_mad(struct sa_query_result *result);
>+void *sa_get_query_rec(void *mad, unsigned i);
>+void sa_report_err(int status);
>+
>+#define cl_hton8(x) (x)
>+#define CHECK_AND_SET_VAL(val, size, comp_with, target, name, mask) \
>+	if ((int##size##_t) val != (int##size##_t) comp_with) { \
>+		target = cl_hton##size((uint##size##_t) val); \
>+		comp_mask |= IB_##name##_COMPMASK_##mask; \
>+	}
>+
>+#define CHECK_AND_SET_GID(val, target, name, mask) \
>+	if (valid_gid(&(val))) { \
>+		memcpy(&(target), &(val), sizeof(val)); \
>+		comp_mask |= IB_##name##_COMPMASK_##mask; \
>+	}
>+
>+#define CHECK_AND_SET_VAL_AND_SEL(val, target, name, mask, sel) \
>+	if (val) { \
>+		target = val; \
>+		comp_mask |= IB_##name##_COMPMASK_##mask##sel; \
>+		comp_mask |= IB_##name##_COMPMASK_##mask; \
>+	}
>+
> #endif				/* _IBDIAG_COMMON_H_ */
>diff --git a/trunk/tools/infiniband-diags/include/windows/config.h b/trunk/tools/infiniband-diags/include/windows/config.h
>index c6365bf..3a46b6f 100644
>--- a/trunk/tools/infiniband-diags/include/windows/config.h
>+++ b/trunk/tools/infiniband-diags/include/windows/config.h
>@@ -37,4 +37,7 @@
> #include <_errno.h>
> #include <_string.h>
>
>+#define IBDIAG_CONFIG_PATH "."
>+#define UINT16_MAX 0xffffffff
>+
> #endif /* _CONFIG_H_ */
>diff --git a/trunk/tools/infiniband-diags/src/dirs b/trunk/tools/infiniband-diags/src/dirs
>index 822f325..c36a414 100644
>--- a/trunk/tools/infiniband-diags/src/dirs
>+++ b/trunk/tools/infiniband-diags/src/dirs
>@@ -1,5 +1,6 @@
> DIRS = \
> 	ibaddr		\
>+	ibcacheedit	\
> 	iblinkinfo	\
> 	ibnetdiscover	\
> 	ibping		\
>diff --git a/trunk/tools/infiniband-diags/src/ibaddr.c b/trunk/tools/infiniband-diags/src/ibaddr.c
>index 6e17458..397ef77 100644
>--- a/trunk/tools/infiniband-diags/src/ibaddr.c
>+++ b/trunk/tools/infiniband-diags/src/ibaddr.c
>@@ -1,5 +1,6 @@
> /*
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>+ * Copyright (c) 2011 Mellanox Technologies LTD.  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
>@@ -52,8 +53,8 @@ static int ib_resolve_addr(ib_portid_t * portid, int portnum, int show_lid,
> 			   int show_gid)
> {
> 	char gid_str[INET6_ADDRSTRLEN];
>-	uint8_t portinfo[64];
>-	uint8_t nodeinfo[64];
>+	uint8_t portinfo[IB_SMP_DATA_SIZE] = { 0 };
>+	uint8_t nodeinfo[IB_SMP_DATA_SIZE] = { 0 };
> 	uint64_t guid, prefix;
> 	ibmad_gid_t gid;
> 	int lmc;
>diff --git a/trunk/tools/infiniband-diags/src/ibaddr/SOURCES b/trunk/tools/infiniband-diags/src/ibaddr/SOURCES
>index f7462a5..91a22fb 100644
>--- a/trunk/tools/infiniband-diags/src/ibaddr/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/ibaddr/SOURCES
>@@ -21,6 +21,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H /DUSE_INET
> TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
> 	$(SDK_LIB_PATH)\ws2_32.lib		\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib	\
> 	$(TARGETPATH)\*\libibnetdisc.lib
>diff --git a/trunk/tools/infiniband-diags/src/ibcacheedit/SOURCES b/trunk/tools/infiniband-diags/src/ibcacheedit/SOURCES
>new file mode 100644
>index 0000000..c00ddb9
>--- /dev/null
>+++ b/trunk/tools/infiniband-diags/src/ibcacheedit/SOURCES
>@@ -0,0 +1,28 @@
>+TARGETNAME = ibcacheedit
>+TARGETPATH = ..\..\..\..\bin\user\obj$(BUILD_ALT_DIR)
>+TARGETTYPE = PROGRAM
>+
>+UMTYPE = console
>+UMENTRY = main
>+
>+USE_MSVCRT = 1
>+
>+SOURCES = ..\ibcacheedit.c ..\ibdiag_common.c ..\ibdiag_windows.c ibcacheedit.rc
>+
>+INCLUDES = ..\..\include;..\..\include\windows;\
>+		   ..\..\..\..\ulp\libibnetdisc\include;\
>+		   ..\..\..\..\ulp\libibmad\include;\
>+		   ..\..\..\..\ulp\libibumad\include;\
>+		   ..\..\..\..\inc;..\..\..\..\inc\user;\
>+		   ..\..\..\..\inc\user\linux;
>+
>+C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
>+
>+TARGETLIBS = \
>+	$(SDK_LIB_PATH)\kernel32.lib	\
>+	$(TARGETPATH)\*\ibal.lib		\
>+	$(TARGETPATH)\*\libibmad.lib	\
>+	$(TARGETPATH)\*\libibumad.lib	\
>+	$(TARGETPATH)\*\libibnetdisc.lib
>+
>+MSC_WARNING_LEVEL = /W3 /WX /wd4007
>diff --git a/trunk/tools/infiniband-diags/src/ibcacheedit/ibcacheedit.rc b/trunk/tools/infiniband-diags/src/ibcacheedit/ibcacheedit.rc
>new file mode 100644
>index 0000000..c358cda
>--- /dev/null
>+++ b/trunk/tools/infiniband-diags/src/ibcacheedit/ibcacheedit.rc
>@@ -0,0 +1,47 @@
>+/*
>+ * Copyright (c) 2011 Intel Corporation.  All rights reserved.
>+ *
>+ * This software is available to you under 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 <oib_ver.h>
>+
>+#define VER_FILETYPE			VFT_APP
>+#define VER_FILESUBTYPE			VFT2_UNKNOWN
>+
>+#ifdef DBG
>+#define VER_FILEDESCRIPTION_STR	"Edit InfiniBand Diagnostic Cache Information (Debug)"
>+#else
>+#define VER_FILEDESCRIPTION_STR	"Edit InfiniBand Diagnostic Cache Information"
>+#endif
>+
>+#define VER_INTERNALNAME_STR		"ibcacheedit.exe"
>+#define VER_ORIGINALFILENAME_STR	"ibcacheedit.exe"
>+
>+#include <common.ver>
>diff --git a/trunk/tools/infiniband-diags/src/ibcacheedit/makefile b/trunk/tools/infiniband-diags/src/ibcacheedit/makefile
>new file mode 100644
>index 0000000..a0c0627
>--- /dev/null
>+++ b/trunk/tools/infiniband-diags/src/ibcacheedit/makefile
>@@ -0,0 +1,7 @@
>+#
>+# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source
>+# file to this component.  This file merely indirects to the real make file
>+# that is shared by all the driver components of the OpenIB Windows project.
>+#
>+
>+!INCLUDE ..\..\..\..\inc\openib.def
>diff --git a/trunk/tools/infiniband-diags/src/ibdiag_common.c b/trunk/tools/infiniband-diags/src/ibdiag_common.c
>index 99861f1..e7e1590 100644
>--- a/trunk/tools/infiniband-diags/src/ibdiag_common.c
>+++ b/trunk/tools/infiniband-diags/src/ibdiag_common.c
>@@ -1,6 +1,10 @@
> /*
>  * Copyright (c) 2006-2007 The Regents of the University of California.
>  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
>+ * Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved.
>+ * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
>+ * Copyright (c) 2009 HNR Consulting. All rights reserved.
>+ * Copyright (c) 2011 Lawrence Livermore National Security. 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
>@@ -47,6 +51,7 @@
> #include <ctype.h>
> #include <config.h>
> #include <getopt.h>
>+#include <limits.h>
>
> #include <infiniband/umad.h>
> #include <infiniband/mad.h>
>@@ -138,7 +143,8 @@ void ibdiag_show_usage()
>
> static int process_opt(int ch, char *optarg)
> {
>-	int val;
>+	char *endp;
>+	long val;
>
> 	switch (ch) {
> 	case 'h':
>@@ -175,9 +181,16 @@ static int process_opt(int ch, char *optarg)
> 		ibd_dest_type = IB_DEST_GUID;
> 		break;
> 	case 't':
>-		val = strtoul(optarg, 0, 0);
>-		madrpc_set_timeout(val);
>-		ibd_timeout = val;
>+		errno = 0;
>+		val = strtol(optarg, &endp, 0);
>+		if (errno || (endp && *endp != '\0') || val <= 0 ||
>+		    val > INT_MAX)
>+			IBERROR("Invalid timeout \"%s\".  Timeout requires a "
>+				"positive integer value < %d.", optarg, INT_MAX);
>+		else {
>+			madrpc_set_timeout((int)val);
>+			ibd_timeout = (int)val;
>+		}
> 		break;
> 	case 's':
> 		/* srcport is not required when resolving via IB_DEST_LID */
>@@ -328,3 +341,175 @@ void iberror(const char *fn, char *msg, ...)
>
> 	exit(-1);
> }
>+
>+/* define a common SA query structure
>+ * This is by no means optimal but it moves the saquery functionality out of
>+ * the saquery tool and provides it to other utilities.
>+ */
>+bind_handle_t sa_get_bind_handle(void)
>+{
>+	struct ibmad_port * srcport;
>+	bind_handle_t handle;
>+	int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
>+
>+	srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
>+	if (!srcport) {
>+		IBWARN("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
>+		return (NULL);
>+	}
>+
>+	handle = calloc(1, sizeof(*handle));
>+	if (!handle)
>+		IBPANIC("calloc failed");
>+
>+	ib_resolve_smlid_via(&handle->dport, ibd_timeout, srcport);
>+	if (!handle->dport.lid) {
>+		IBWARN("No SM found.");
>+		free(handle);
>+		return (NULL);
>+	}
>+
>+	handle->dport.qp = 1;
>+	if (!handle->dport.qkey)
>+		handle->dport.qkey = IB_DEFAULT_QP1_QKEY;
>+
>+	handle->srcport = srcport;
>+	handle->fd = mad_rpc_portid(srcport);
>+	handle->agent = umad_register(handle->fd, IB_SA_CLASS, 2, 1, NULL);
>+
>+	return handle;
>+}
>+
>+void sa_free_bind_handle(bind_handle_t h)
>+{
>+	umad_unregister(h->fd, h->agent);
>+	mad_rpc_close_port(h->srcport);
>+	free(h);
>+}
>+
>+int sa_query(bind_handle_t h, uint8_t method,
>+		    uint16_t attr, uint32_t mod, uint64_t comp_mask,
>+		    uint64_t sm_key, void *data, struct sa_query_result *result)
>+{
>+	ib_rpc_t rpc;
>+	void *umad, *mad;
>+	int ret, offset, len = 256;
>+
>+	memset(&rpc, 0, sizeof(rpc));
>+	rpc.mgtclass = IB_SA_CLASS;
>+	rpc.method = method;
>+	rpc.attr.id = attr;
>+	rpc.attr.mod = mod;
>+	rpc.mask = comp_mask;
>+	rpc.datasz = IB_SA_DATA_SIZE;
>+	rpc.dataoffs = IB_SA_DATA_OFFS;
>+
>+	umad = calloc(1, len + umad_size());
>+	if (!umad)
>+		IBPANIC("cannot alloc mem for umad: %s\n", strerror(errno));
>+
>+	mad_build_pkt(umad, &rpc, &h->dport, NULL, data);
>+
>+	mad_set_field64(umad_get_mad(umad), 0, IB_SA_MKEY_F, sm_key);
>+
>+	if (ibdebug > 1)
>+		xdump(stdout, "SA Request:\n", umad_get_mad(umad), len);
>+
>+	ret = umad_send(h->fd, h->agent, umad, len, ibd_timeout, 0);
>+	if (ret < 0) {
>+		IBWARN("umad_send failed: attr %u: %s\n",
>+			attr, strerror(errno));
>+		free(umad);
>+		return (IB_ERROR);
>+	}
>+
>+recv_mad:
>+	ret = umad_recv(h->fd, umad, &len, ibd_timeout);
>+	if (ret < 0) {
>+		if (errno == ENOSPC) {
>+			umad = realloc(umad, umad_size() + len);
>+			goto recv_mad;
>+		}
>+		IBWARN("umad_recv failed: attr 0x%x: %s\n", attr,
>+			strerror(errno));
>+		free(umad);
>+		return (IB_ERROR);
>+	}
>+
>+	if ((ret = umad_status(umad)))
>+		return ret;
>+
>+	mad = umad_get_mad(umad);
>+
>+	if (ibdebug > 1)
>+		xdump(stdout, "SA Response:\n", mad, len);
>+
>+	method = (uint8_t) mad_get_field(mad, 0, IB_MAD_METHOD_F);
>+	offset = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);
>+	result->status = mad_get_field(mad, 0, IB_MAD_STATUS_F);
>+	result->p_result_madw = mad;
>+	if (result->status != IB_SA_MAD_STATUS_SUCCESS)
>+		result->result_cnt = 0;
>+	else if (method != IB_MAD_METHOD_GET_TABLE)
>+		result->result_cnt = 1;
>+	else if (!offset)
>+		result->result_cnt = 0;
>+	else
>+		result->result_cnt = (len - IB_SA_DATA_OFFS) / (offset << 3);
>+
>+	return 0;
>+}
>+
>+void sa_free_result_mad(struct sa_query_result *result)
>+{
>+	if (result->p_result_madw) {
>+		free((uint8_t *) result->p_result_madw - umad_size());
>+		result->p_result_madw = NULL;
>+	}
>+}
>+
>+void *sa_get_query_rec(void *mad, unsigned i)
>+{
>+	int offset = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);
>+	return (uint8_t *) mad + IB_SA_DATA_OFFS + i * (offset << 3);
>+}
>+
>+static const char *ib_sa_error_str[] = {
>+	"SA_NO_ERROR",
>+	"SA_ERR_NO_RESOURCES",
>+	"SA_ERR_REQ_INVALID",
>+	"SA_ERR_NO_RECORDS",
>+	"SA_ERR_TOO_MANY_RECORDS",
>+	"SA_ERR_REQ_INVALID_GID",
>+	"SA_ERR_REQ_INSUFFICIENT_COMPONENTS",
>+	"SA_ERR_REQ_DENIED",
>+	"SA_ERR_STATUS_PRIO_SUGGESTED",
>+	"SA_ERR_UNKNOWN"
>+};
>+
>+#define ARR_SIZE(a) (sizeof(a)/sizeof((a)[0]))
>+#define SA_ERR_UNKNOWN (ARR_SIZE(ib_sa_error_str) - 1)
>+
>+static inline const char *ib_sa_err_str(IN uint8_t status)
>+{
>+	if (status > SA_ERR_UNKNOWN)
>+		status = SA_ERR_UNKNOWN;
>+	return (ib_sa_error_str[status]);
>+}
>+
>+void sa_report_err(int status)
>+{
>+	int st = status & 0xff;
>+	char sm_err_str[64] = { 0 };
>+	char sa_err_str[64] = { 0 };
>+
>+	if (st)
>+		sprintf(sm_err_str, " SM(%s)", ib_get_err_str(st));
>+
>+	st = status >> 8;
>+	if (st)
>+		sprintf(sa_err_str, " SA(%s)", ib_sa_err_str((uint8_t) st));
>+
>+	fprintf(stderr, "ERROR: Query result returned 0x%04x, %s%s\n",
>+		status, sm_err_str, sa_err_str);
>+}
>diff --git a/trunk/tools/infiniband-diags/src/iblinkinfo.c b/trunk/tools/infiniband-diags/src/iblinkinfo.c
>index d0c9b13..c07d33e 100644
>--- a/trunk/tools/infiniband-diags/src/iblinkinfo.c
>+++ b/trunk/tools/infiniband-diags/src/iblinkinfo.c
>@@ -2,6 +2,7 @@
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>  * Copyright (c) 2007 Xsigo Systems Inc.  All rights reserved.
>  * Copyright (c) 2008 Lawrence Livermore National Lab.  All rights reserved.
>+ * Copyright (c) 2010,2011 Mellanox Technologies LTD.  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
>@@ -53,9 +54,20 @@
>
> #include "ibdiag_common.h"
>
>+#define DIFF_FLAG_PORT_CONNECTION  0x01
>+#define DIFF_FLAG_PORT_STATE       0x02
>+#define DIFF_FLAG_LID              0x04
>+#define DIFF_FLAG_NODE_DESCRIPTION 0x08
>+
>+#define DIFF_FLAG_DEFAULT (DIFF_FLAG_PORT_CONNECTION | DIFF_FLAG_PORT_STATE)
>+
> static char *node_name_map_file = NULL;
> static nn_map_t *node_name_map = NULL;
> static char *load_cache_file = NULL;
>+static char *diff_cache_file = NULL;
>+static unsigned diffcheck_flags = DIFF_FLAG_DEFAULT;
>+static char *filterdownports_cache_file = NULL;
>+static ibnd_fabric_t *filterdownports_fabric = NULL;
>
> static uint64_t guid = 0;
> static char *guid_str = NULL;
>@@ -65,7 +77,6 @@ static int all = 0;
> static int down_links_only = 0;
> static int line_mode = 0;
> static int add_sw_settings = 0;
>-static int print_port_guids = 0;
>
> static unsigned int get_max(unsigned int num)
> {
>@@ -107,7 +118,31 @@ void get_msg(char *width_msg, char *speed_msg, int msg_size, ibnd_port_t * port)
> 				      buf, 64, &max_speed));
> }
>
>-void print_port(ibnd_node_t * node, ibnd_port_t * port)
>+int filterdownport_check(ibnd_node_t * node, ibnd_port_t * port)
>+{
>+	ibnd_node_t *fsw;
>+	ibnd_port_t *fport;
>+	int fistate;
>+
>+	fsw = ibnd_find_node_guid(filterdownports_fabric, node->guid);
>+
>+	if (!fsw)
>+		return 0;
>+
>+	if (port->portnum > fsw->numports)
>+		return 0;
>+
>+	fport = fsw->ports[port->portnum];
>+
>+	if (!fport)
>+		return 0;
>+
>+	fistate = mad_get_field(fport->info, 0, IB_PORT_STATE_F);
>+
>+	return (fistate == IB_LINK_DOWN) ? 1 : 0;
>+}
>+
>+void print_port(ibnd_node_t * node, ibnd_port_t * port, char *out_prefix)
> {
> 	char width[64], speed[64], state[64], physstate[64];
> 	char remote_guid_str[256];
>@@ -133,6 +168,11 @@ void print_port(ibnd_node_t * node, ibnd_port_t * port)
> 	width_msg[0] = '\0';
> 	speed_msg[0] = '\0';
>
>+	if (istate == IB_LINK_DOWN
>+	    && filterdownports_fabric
>+	    && filterdownport_check(node, port))
>+		return;
>+
> 	/* C14-24.2.1 states that a down port allows for invalid data to be
> 	 * returned for all PortInfo components except PortState and
> 	 * PortPhysicalState */
>@@ -176,14 +216,9 @@ void print_port(ibnd_node_t * node, ibnd_port_t * port)
> 		get_msg(width_msg, speed_msg, 256, port);
>
> 		if (line_mode) {
>-			if (print_port_guids)
>-				snprintf(remote_guid_str, 256,
>-					 "0x%016" PRIx64 " ",
>-					 port->remoteport->guid);
>-			else
>-				snprintf(remote_guid_str, 256,
>-					 "0x%016" PRIx64 " ",
>-					 port->remoteport->node->guid);
>+			snprintf(remote_guid_str, 256,
>+				 "0x%016" PRIx64 " ",
>+				 port->remoteport->guid);
> 		}
>
> 		snprintf(remote_str, 256, "%s%6d %4d[%2s] \"%s\" (%s %s)\n",
>@@ -204,21 +239,64 @@ void print_port(ibnd_node_t * node, ibnd_port_t * port)
> 	if (line_mode) {
> 		char *remap = remap_node_name(node_name_map, node->guid,
> 					      node->nodedesc);
>-		printf("0x%016" PRIx64 " \"%30s\" ", node->guid, remap);
>+		printf("%s0x%016" PRIx64 " \"%30s\" ",
>+		       out_prefix ? out_prefix : "",
>+		       port->guid, remap);
> 		free(remap);
> 	} else
>-		printf("      ");
>+		printf("%s      ", out_prefix ? out_prefix : "");
>+
>+	if (port->node->type != IB_NODE_SWITCH) {
>+		if (!line_mode)
>+			printf("0x%016" PRIx64 " ", port->guid);
>+
>+		printf("%6d %4d[%2s] ==%s==>  %s",
>+			port->base_lid,
>+			port->portnum, ext_port_str, link_str, remote_str);
>+	} else
>+		printf("%6d %4d[%2s] ==%s==>  %s",
>+			node->smalid, port->portnum, ext_port_str,
>+			link_str, remote_str);
>+}
>+
>+static inline const char *nodetype_str(ibnd_node_t * node)
>+{
>+	switch (node->type) {
>+	case IB_NODE_SWITCH:
>+		return "Switch";
>+	case IB_NODE_CA:
>+		return "CA";
>+	case IB_NODE_ROUTER:
>+		return "Router";
>+	}
>+	return "??";
>+}
>
>-	printf("%6d %4d[%2s] ==%s==>  %s",
>-	       node->smalid, port->portnum, ext_port_str, link_str, remote_str);
>+void print_node_header(ibnd_node_t *node, int *out_header_flag,
>+			char *out_prefix)
>+{
>+	if ((!out_header_flag || !(*out_header_flag)) && !line_mode) {
>+		char *remap =
>+			remap_node_name(node_name_map, node->guid, node->nodedesc);
>+		if (node->type == IB_NODE_SWITCH)
>+			printf("%s%s: 0x%016" PRIx64 " %s:\n",
>+				out_prefix ? out_prefix : "",
>+				nodetype_str(node),
>+				node->ports[0]->guid, remap);
>+		else
>+			printf("%s%s: %s:\n",
>+				out_prefix ? out_prefix : "",
>+				nodetype_str(node), remap);
>+		(*out_header_flag)++;
>+		free(remap);
>+	}
> }
>
>-void print_switch(ibnd_node_t * node, void *user_data)
>+void print_node(ibnd_node_t * node, void *user_data)
> {
> 	int i = 0;
> 	int head_print = 0;
>-	char *remap =
>-	    remap_node_name(node_name_map, node->guid, node->nodedesc);
>+	char *out_prefix = (char *)user_data;
>
> 	for (i = 1; i <= node->numports; i++) {
> 		ibnd_port_t *port = node->ports[i];
>@@ -227,20 +305,192 @@ void print_switch(ibnd_node_t * node, void *user_data)
> 		if (!down_links_only ||
> 		    mad_get_field(port->info, 0,
> 				  IB_PORT_STATE_F) == IB_LINK_DOWN) {
>-			if (!head_print && !line_mode) {
>-				printf("Switch 0x%016" PRIx64 " %s:\n",
>-				       node->guid, remap);
>-				head_print = 1;
>-			}
>-			print_port(node, port);
>+			print_node_header(node, &head_print, out_prefix);
>+			print_port(node, port, out_prefix);
> 		}
> 	}
>-	free(remap);
>+}
>+
>+struct iter_diff_data {
>+        uint32_t diff_flags;
>+        ibnd_fabric_t *fabric1;
>+        ibnd_fabric_t *fabric2;
>+        char *fabric1_prefix;
>+        char *fabric2_prefix;
>+};
>+
>+void diff_node_ports(ibnd_node_t * fabric1_node, ibnd_node_t * fabric2_node,
>+		       int *head_print, struct iter_diff_data *data)
>+{
>+	int i = 0;
>+
>+	for (i = 1; i <= fabric1_node->numports; i++) {
>+		ibnd_port_t *fabric1_port, *fabric2_port;
>+		int output_diff = 0;
>+
>+		fabric1_port = fabric1_node->ports[i];
>+		fabric2_port = fabric2_node->ports[i];
>+
>+		if (!fabric1_port && !fabric2_port)
>+			continue;
>+
>+		if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION) {
>+			if ((fabric1_port && !fabric2_port)
>+			    || (!fabric1_port && fabric2_port)
>+			    || (fabric1_port->remoteport
>+				&& !fabric2_port->remoteport)
>+			    || (!fabric1_port->remoteport
>+				&& fabric2_port->remoteport)
>+			    || (fabric1_port->remoteport
>+				&& fabric2_port->remoteport
>+				&& fabric1_port->remoteport->guid !=
>+				fabric2_port->remoteport->guid))
>+				output_diff++;
>+		}
>+
>+		/* if either fabric1_port or fabric2_port NULL, should be
>+		 * handled by port connection diff code
>+		 */
>+		if (data->diff_flags & DIFF_FLAG_PORT_STATE
>+		    && fabric1_port
>+		    && fabric2_port) {
>+			int state1, state2;
>+
>+			state1 = mad_get_field(fabric1_port->info, 0,
>+					       IB_PORT_STATE_F);
>+			state2 = mad_get_field(fabric2_port->info, 0,
>+					       IB_PORT_STATE_F);
>+
>+			if (state1 != state2)
>+				output_diff++;
>+		}
>+
>+		if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
>+		    && data->diff_flags & DIFF_FLAG_LID
>+		    && fabric1_port && fabric2_port
>+		    && fabric1_port->remoteport && fabric2_port->remoteport
>+		    && fabric1_port->remoteport->base_lid != fabric2_port->remoteport->base_lid)
>+			output_diff++;
>+
>+		if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
>+		    && data->diff_flags & DIFF_FLAG_NODE_DESCRIPTION
>+		    && fabric1_port && fabric2_port
>+		    && fabric1_port->remoteport && fabric2_port->remoteport
>+		    && memcmp(fabric1_port->remoteport->node->nodedesc,
>+			      fabric2_port->remoteport->node->nodedesc,
>+			      IB_SMP_DATA_SIZE))
>+			output_diff++;
>+
>+		if (output_diff && fabric1_port) {
>+			print_node_header(fabric1_node,
>+					    head_print,
>+					    NULL);
>+			print_port(fabric1_node,
>+				   fabric1_port,
>+				   data->fabric1_prefix);
>+		}
>+
>+		if (output_diff && fabric2_port) {
>+			print_node_header(fabric1_node,
>+					    head_print,
>+					    NULL);
>+			print_port(fabric2_node,
>+				   fabric2_port,
>+				   data->fabric2_prefix);
>+		}
>+	}
>+}
>+
>+void diff_node_iter(ibnd_node_t * fabric1_node, void *iter_user_data)
>+{
>+	struct iter_diff_data *data = iter_user_data;
>+	ibnd_node_t *fabric2_node;
>+	int head_print = 0;
>+
>+	DEBUG("DEBUG: fabric1_node %p\n", fabric1_node);
>+
>+	fabric2_node = ibnd_find_node_guid(data->fabric2, fabric1_node->guid);
>+	if (!fabric2_node)
>+		print_node(fabric1_node, data->fabric1_prefix);
>+	else if (data->diff_flags &
>+		 (DIFF_FLAG_PORT_CONNECTION | DIFF_FLAG_PORT_STATE
>+		  | DIFF_FLAG_LID | DIFF_FLAG_NODE_DESCRIPTION)) {
>+
>+		if ((fabric1_node->type == IB_NODE_SWITCH
>+		     && data->diff_flags & DIFF_FLAG_LID
>+		     && fabric1_node->smalid != fabric2_node->smalid) ||
>+		    (data->diff_flags & DIFF_FLAG_NODE_DESCRIPTION
>+		     && memcmp(fabric1_node->nodedesc, fabric2_node->nodedesc,
>+			       IB_SMP_DATA_SIZE))) {
>+			print_node_header(fabric1_node,
>+					    NULL,
>+					    data->fabric1_prefix);
>+			print_node_header(fabric2_node,
>+					    NULL,
>+					    data->fabric2_prefix);
>+			head_print++;
>+		}
>+
>+		if (fabric1_node->numports != fabric2_node->numports) {
>+			print_node_header(fabric1_node,
>+					    &head_print,
>+					    NULL);
>+			printf("%snumports = %d\n", data->fabric1_prefix,
>+			       fabric1_node->numports);
>+			printf("%snumports = %d\n", data->fabric2_prefix,
>+			       fabric2_node->numports);
>+			return;
>+		}
>+
>+		diff_node_ports(fabric1_node, fabric2_node,
>+				  &head_print, data);
>+	}
>+}
>+
>+int diff_node(ibnd_node_t * node, ibnd_fabric_t * orig_fabric,
>+		ibnd_fabric_t * new_fabric)
>+{
>+	struct iter_diff_data iter_diff_data;
>+
>+	iter_diff_data.diff_flags = diffcheck_flags;
>+	iter_diff_data.fabric1 = orig_fabric;
>+	iter_diff_data.fabric2 = new_fabric;
>+	iter_diff_data.fabric1_prefix = "< ";
>+	iter_diff_data.fabric2_prefix = "> ";
>+	if (node)
>+		diff_node_iter(node, &iter_diff_data);
>+	else
>+		ibnd_iter_nodes(orig_fabric, diff_node_iter, &iter_diff_data);
>+
>+	/* Do opposite diff to find existence of node types
>+	 * in new_fabric but not in orig_fabric.
>+	 *
>+	 * In this diff, we don't need to check port connections,
>+	 * port state, lids, or node descriptions since it has already
>+	 * been done (i.e. checks are only done when guid exists on both
>+	 * orig and new).
>+	 */
>+	iter_diff_data.diff_flags = diffcheck_flags & ~DIFF_FLAG_PORT_CONNECTION;
>+	iter_diff_data.diff_flags &= ~DIFF_FLAG_PORT_STATE;
>+	iter_diff_data.diff_flags &= ~DIFF_FLAG_LID;
>+	iter_diff_data.diff_flags &= ~DIFF_FLAG_NODE_DESCRIPTION;
>+	iter_diff_data.fabric1 = new_fabric;
>+	iter_diff_data.fabric2 = orig_fabric;
>+	iter_diff_data.fabric1_prefix = "> ";
>+	iter_diff_data.fabric2_prefix = "< ";
>+	if (node)
>+		diff_node_iter(node, &iter_diff_data);
>+	else
>+		ibnd_iter_nodes(new_fabric, diff_node_iter, &iter_diff_data);
>+
>+	return 0;
> }
>
> static int process_opt(void *context, int ch, char *optarg)
> {
> 	struct ibnd_config *cfg = context;
>+	char *p;
>+
> 	switch (ch) {
> 	case 1:
> 		node_name_map_file = strdup(optarg);
>@@ -248,7 +498,34 @@ static int process_opt(void *context, int ch, char *optarg)
> 	case 2:
> 		load_cache_file = strdup(optarg);
> 		break;
>+	case 3:
>+		diff_cache_file = strdup(optarg);
>+		break;
>+	case 4:
>+		diffcheck_flags = 0;
>+		p = strtok(optarg, ",");
>+		while (p) {
>+			if (!strcasecmp(p, "port"))
>+				diffcheck_flags |= DIFF_FLAG_PORT_CONNECTION;
>+			else if (!strcasecmp(p, "state"))
>+				diffcheck_flags |= DIFF_FLAG_PORT_STATE;
>+			else if (!strcasecmp(p, "lid"))
>+				diffcheck_flags |= DIFF_FLAG_LID;
>+			else if (!strcasecmp(p, "nodedesc"))
>+				diffcheck_flags |= DIFF_FLAG_NODE_DESCRIPTION;
>+			else {
>+				fprintf(stderr, "invalid diff check key: %s\n",
>+					p);
>+				return -1;
>+			}
>+			p = strtok(NULL, ",");
>+		}
>+		break;
>+	case 5:
>+		filterdownports_cache_file = strdup(optarg);
>+		break;
> 	case 'S':
>+	case 'G':
> 		guid_str = optarg;
> 		guid = (uint64_t) strtoull(guid_str, 0, 0);
> 		break;
>@@ -270,9 +547,6 @@ static int process_opt(void *context, int ch, char *optarg)
> 	case 'p':
> 		add_sw_settings = 1;
> 		break;
>-	case 'g':
>-		print_port_guids = 1;
>-		break;
> 	case 'R':		/* nop */
> 		break;
> 	case 'o':
>@@ -291,6 +565,7 @@ int main(int argc, char **argv)
> 	int rc = 0;
> 	int resolved = -1;
> 	ibnd_fabric_t *fabric = NULL;
>+	ibnd_fabric_t *diff_fabric = NULL;
> 	struct ibmad_port *ibmad_port;
> 	ib_portid_t port_id = { 0 };
> 	int mgmt_classes[3] =
>@@ -298,23 +573,29 @@ int main(int argc, char **argv)
>
> 	const struct ibdiag_opt opts[] = {
> 		{"node-name-map", 1, 1, "<file>", "node name map file"},
>-		{"switch", 'S', 1, "<switch_guid>",
>-		 "query only <switch_guid> (hex format)"},
>+		{"switch", 'S', 1, "<port_guid>",
>+		 "start partial scan at the port specified by <port_guid> (hex format)"},
>+		{"port-guid", 'G', 1, "<port_guid>",
>+		 "(same as -S)"},
> 		{"Direct", 'D', 1, "<dr_path>",
>-		 "query only node specified by <dr_path>"},
>+		 "start partial scan at the port specified by <dr_path>"},
> 		{"all", 'a', 0, NULL,
>-		 "print all switches found in a partial fabric scan"},
>+		 "print all nodes found in a partial fabric scan"},
> 		{"hops", 'n', 1, "<hops>",
> 		 "Number of hops to include away from specified node"},
> 		{"down", 'd', 0, NULL, "print only down links"},
> 		{"line", 'l', 0, NULL,
> 		 "(line mode) print all information for each link on a single line"},
> 		{"additional", 'p', 0, NULL,
>-		 "print additional switch settings (PktLifeTime, HoqLife, VLStallCount)"},
>-		{"portguids", 'g', 0, NULL,
>-		 "print port guids instead of node guids"},
>+		 "print additional port settings (PktLifeTime, HoqLife, VLStallCount)"},
> 		{"load-cache", 2, 1, "<file>",
> 		 "filename of ibnetdiscover cache to load"},
>+		{"diff", 3, 1, "<file>",
>+		 "filename of ibnetdiscover cache to diff"},
>+		{"diffcheck", 4, 1, "<key(s)>",
>+		 "specify checks to execute for --diff"},
>+		{"filterdownports", 5, 1, "<file>",
>+		 "filename of ibnetdiscover cache to filter downports"},
> 		{"outstanding_smps", 'o', 1, NULL,
> 		 "specify the number of outstanding SMP's which should be "
> 		 "issued during the scan"},
>@@ -355,7 +636,7 @@ int main(int argc, char **argv)
> 		     ib_resolve_portid_str_via(&port_id, dr_path,
> 					       IB_DEST_DRPATH, NULL,
> 					       ibmad_port)) < 0)
>-			IBWARN("Failed to resolve %s; attempting full scan\n",
>+			IBWARN("Failed to resolve %s; attempting full scan",
> 			       dr_path);
> 	} else if (guid_str) {
> 		if ((resolved =
>@@ -365,17 +646,28 @@ int main(int argc, char **argv)
> 			       guid_str);
> 	}
>
>+	if (diff_cache_file &&
>+	    !(diff_fabric = ibnd_load_fabric(diff_cache_file, 0)))
>+		IBERROR("loading cached fabric for diff failed\n");
>+
>+	if (filterdownports_cache_file &&
>+	    !(filterdownports_fabric = ibnd_load_fabric(filterdownports_cache_file, 0)))
>+		IBERROR("loading cached fabric for filterdownports failed\n");
>+
> 	if (load_cache_file) {
> 		if ((fabric = ibnd_load_fabric(load_cache_file, 0)) == NULL) {
> 			fprintf(stderr, "loading cached fabric failed\n");
> 			exit(1);
> 		}
> 	} else {
>-		if (resolved >= 0 &&
>-		    !(fabric =
>-		      ibnd_discover_fabric(ibd_ca, ibd_ca_port, &port_id, &config)))
>-			IBWARN("Single node discover failed;"
>-			       " attempting full scan\n");
>+		if (resolved >= 0) {
>+			if (!config.max_hops)
>+				config.max_hops = 1;
>+			if (!(fabric =
>+			    ibnd_discover_fabric(ibd_ca, ibd_ca_port, &port_id, &config)))
>+				IBWARN("Partial fabric scan failed;"
>+				       " attempting full scan\n");
>+		}
>
> 		if (!fabric &&
> 		    !(fabric = ibnd_discover_fabric(ibd_ca, ibd_ca_port, NULL, &config))) {
>@@ -386,31 +678,45 @@ int main(int argc, char **argv)
> 	}
>
> 	if (!all && guid_str) {
>-		ibnd_node_t *sw = ibnd_find_node_guid(fabric, guid);
>-		if (sw)
>-			print_switch(sw, NULL);
>+		ibnd_port_t *p = ibnd_find_port_guid(fabric, guid);
>+		if (p) {
>+			ibnd_node_t *n = p->node;
>+			if (diff_fabric)
>+				diff_node(n, diff_fabric, fabric);
>+			else
>+				print_node(n, NULL);
>+		}
> 		else
>-			fprintf(stderr, "Failed to find switch: %s\n",
>-				guid_str);
>+			fprintf(stderr, "Failed to find port: %s\n", guid_str);
> 	} else if (!all && dr_path) {
>-		ibnd_node_t *sw = NULL;
>-		uint8_t ni[IB_SMP_DATA_SIZE];
>+		ibnd_port_t *p = NULL;
>+		uint8_t ni[IB_SMP_DATA_SIZE] = { 0 };
>
> 		if (!smp_query_via(ni, &port_id, IB_ATTR_NODE_INFO, 0,
> 				   ibd_timeout, ibmad_port))
> 			return -1;
>-		mad_decode_field(ni, IB_NODE_GUID_F, &(guid));
>+		mad_decode_field(ni, IB_NODE_PORT_GUID_F, &(guid));
>
>-		sw = ibnd_find_node_guid(fabric, guid);
>-		if (sw)
>-			print_switch(sw, NULL);
>+		p = ibnd_find_port_guid(fabric, guid);
>+		if (p) {
>+			ibnd_node_t *n = p->node;
>+			if (diff_fabric)
>+				diff_node(n, diff_fabric, fabric);
>+			else
>+				print_node(n, NULL);
>+		}
> 		else
>-			fprintf(stderr, "Failed to find switch: %s\n", dr_path);
>-	} else
>-		ibnd_iter_nodes_type(fabric, print_switch, IB_NODE_SWITCH,
>-				     NULL);
>+			fprintf(stderr, "Failed to find port: %s\n", dr_path);
>+	} else {
>+		if (diff_fabric)
>+			diff_node(NULL, diff_fabric, fabric);
>+		else
>+			ibnd_iter_nodes(fabric, print_node, NULL);
>+	}
>
> 	ibnd_destroy_fabric(fabric);
>+	if (diff_fabric)
>+		ibnd_destroy_fabric(diff_fabric);
>
> close_port:
> 	close_node_name_map(node_name_map);
>diff --git a/trunk/tools/infiniband-diags/src/iblinkinfo/SOURCES b/trunk/tools/infiniband-diags/src/iblinkinfo/SOURCES
>index e864598..2761041 100644
>--- a/trunk/tools/infiniband-diags/src/iblinkinfo/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/iblinkinfo/SOURCES
>@@ -22,6 +22,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
> TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
> 	$(TARGETPATH)\*\complib.lib		\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib	\
> 	$(TARGETPATH)\*\libibnetdisc.lib
>diff --git a/trunk/tools/infiniband-diags/src/ibnetdiscover.c b/trunk/tools/infiniband-diags/src/ibnetdiscover.c
>index 347e7b2..59304b6 100644
>--- a/trunk/tools/infiniband-diags/src/ibnetdiscover.c
>+++ b/trunk/tools/infiniband-diags/src/ibnetdiscover.c
>@@ -77,6 +77,7 @@ static char *diff_cache_file = NULL;
> static unsigned diffcheck_flags = DIFF_FLAG_DEFAULT;
>
> static int report_max_hops = 0;
>+static int full_info;
>
> /**
>  * Define our own conversion functions to maintain compatibility with the old
>@@ -214,7 +215,9 @@ void out_ids(ibnd_node_t * node, int group, char *chname, char *out_prefix)
> 			fprintf(f, " slot %d",
> 				node->ports[1]->remoteport->portnum);
> 	}
>-	fprintf(f, "\n");
>+	if (sysimgguid ||
>+	    (group && node->chassis && node->chassis->chassisnum))
>+		fprintf(f, "\n");
> }
>
> uint64_t out_chassis(ibnd_fabric_t * fabric, unsigned char chassisnum)
>@@ -364,6 +367,9 @@ void out_switch_port(ibnd_port_t * port, int group, char *out_prefix)
> 		port->remoteport->base_lid,
> 		dump_linkwidth_compat(iwidth), dump_linkspeed_compat(ispeed));
>
>+	if (full_info)
>+		fprintf(f, " s=%d w=%d", ispeed, iwidth);
>+
> 	if (ibnd_is_xsigo_tca(port->remoteport->guid))
> 		fprintf(f, " slot %d", port->portnum);
> 	else if (ibnd_is_xsigo_hca(port->remoteport->guid))
>@@ -397,13 +403,17 @@ void out_ca_port(ibnd_port_t * port, int group, char *out_prefix)
> 				       port->remoteport->node->guid,
> 				       port->remoteport->node->nodedesc);
>
>-	fprintf(f, "\t\t# lid %d lmc %d \"%s\" lid %d %s%s\n",
>+	fprintf(f, "\t\t# lid %d lmc %d \"%s\" lid %d %s%s",
> 		port->base_lid, port->lmc, rem_nodename,
> 		port->remoteport->node->type == IB_NODE_SWITCH ?
> 		port->remoteport->node->smalid :
> 		port->remoteport->base_lid,
> 		dump_linkwidth_compat(iwidth), dump_linkspeed_compat(ispeed));
>
>+	if (full_info)
>+		fprintf(f, " s=%d w=%d", ispeed, iwidth);
>+	fprintf(f, "\n");
>+
> 	free(rem_nodename);
> }
>
>@@ -616,6 +626,8 @@ void dump_ports_report(ibnd_node_t * node, void *user_data)
> {
> 	int p = 0;
> 	ibnd_port_t *port = NULL;
>+	char *nodename = NULL;
>+	char *rem_nodename = NULL;
>
> 	/* for each port */
> 	for (p = node->numports, port = node->ports[p]; p > 0;
>@@ -627,6 +639,9 @@ void dump_ports_report(ibnd_node_t * node, void *user_data)
> 		    mad_get_field(port->info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F);
> 		ispeed =
> 		    mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F);
>+		nodename = remap_node_name(node_name_map,
>+					   port->node->guid,
>+					   port->node->nodedesc);
> 		fprintf(stdout, "%2s %5d %2d 0x%016" PRIx64 " %s %s",
> 			ports_nt_str_compat(node),
> 			node->type ==
>@@ -634,7 +649,10 @@ void dump_ports_report(ibnd_node_t * node, void *user_data)
> 			port->portnum, port->guid,
> 			dump_linkwidth_compat(iwidth),
> 			dump_linkspeed_compat(ispeed));
>-		if (port->remoteport)
>+		if (port->remoteport) {
>+			rem_nodename = remap_node_name(node_name_map,
>+					      port->remoteport->node->guid,
>+					      port->remoteport->node->nodedesc);
> 			fprintf(stdout,
> 				" - %2s %5d %2d 0x%016" PRIx64
> 				" ( '%s' - '%s' )\n",
>@@ -643,10 +661,12 @@ void dump_ports_report(ibnd_node_t * node, void *user_data)
> 				port->remoteport->node->smalid :
> 				port->remoteport->base_lid,
> 				port->remoteport->portnum,
>-				port->remoteport->guid, port->node->nodedesc,
>-				port->remoteport->node->nodedesc);
>-		else
>-			fprintf(stdout, "%36s'%s'\n", "", port->node->nodedesc);
>+				port->remoteport->guid, nodename, rem_nodename);
>+			free(rem_nodename);
>+		} else
>+			fprintf(stdout, "%36s'%s'\n", "", nodename);
>+
>+		free(nodename);
> 	}
> }
>
>@@ -714,6 +734,37 @@ static void diff_ports(ibnd_node_t * fabric1_node, ibnd_node_t * fabric2_node,
> 			fabric2_out++;
> 		}
>
>+		if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
>+		    && data->diff_flags & DIFF_FLAG_NODE_DESCRIPTION
>+		    && fabric1_port && fabric2_port
>+		    && fabric1_port->remoteport && fabric2_port->remoteport
>+		    && memcmp(fabric1_port->remoteport->node->nodedesc,
>+			      fabric2_port->remoteport->node->nodedesc,
>+			      IB_SMP_DATA_SIZE)) {
>+			fabric1_out++;
>+			fabric2_out++;
>+		}
>+
>+		if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
>+		    && data->diff_flags & DIFF_FLAG_NODE_DESCRIPTION
>+		    && fabric1_port && fabric2_port
>+		    && fabric1_port->remoteport && fabric2_port->remoteport
>+		    && memcmp(fabric1_port->remoteport->node->nodedesc,
>+			      fabric2_port->remoteport->node->nodedesc,
>+			      IB_SMP_DATA_SIZE)) {
>+			fabric1_out++;
>+			fabric2_out++;
>+		}
>+
>+		if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
>+		    && data->diff_flags & DIFF_FLAG_LID
>+		    && fabric1_port && fabric2_port
>+		    && fabric1_port->remoteport && fabric2_port->remoteport
>+		    && fabric1_port->remoteport->base_lid != fabric2_port->remoteport->base_lid) {
>+			fabric1_out++;
>+			fabric2_out++;
>+		}
>+
> 		if (fabric1_out) {
> 			diff_iter_out_header(fabric1_node, data,
> 					     out_header_flag);
>@@ -895,6 +946,9 @@ static int process_opt(void *context, int ch, char *optarg)
> 	case 's':
> 		cfg->show_progress = 1;
> 		break;
>+	case 'f':
>+		full_info = 1;
>+		break;
> 	case 'l':
> 		list = LIST_CA_NODE | LIST_SWITCH_NODE | LIST_ROUTER_NODE;
> 		break;
>@@ -933,6 +987,7 @@ int main(int argc, char **argv)
> 	ibnd_fabric_t *diff_fabric = NULL;
>
> 	const struct ibdiag_opt opts[] = {
>+		{"full", 'f', 0, NULL, "show full information (ports' speed and width)"},
> 		{"show", 's', 0, NULL, "show more information"},
> 		{"list", 'l', 0, NULL, "list of connected nodes"},
> 		{"grouping", 'g', 0, NULL, "show grouping"},
>diff --git a/trunk/tools/infiniband-diags/src/ibnetdiscover/SOURCES b/trunk/tools/infiniband-diags/src/ibnetdiscover/SOURCES
>index 22bfc67..86eae18 100644
>--- a/trunk/tools/infiniband-diags/src/ibnetdiscover/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/ibnetdiscover/SOURCES
>@@ -22,6 +22,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
> TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
> 	$(TARGETPATH)\*\complib.lib		\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib	\
> 	$(TARGETPATH)\*\libibnetdisc.lib
>diff --git a/trunk/tools/infiniband-diags/src/ibping.c b/trunk/tools/infiniband-diags/src/ibping.c
>index dafab1c..016679d 100644
>--- a/trunk/tools/infiniband-diags/src/ibping.c
>+++ b/trunk/tools/infiniband-diags/src/ibping.c
>@@ -138,7 +138,7 @@ static uint64_t minrtt = ~0ull, maxrtt, total_rtt;
> static uint64_t start, total_time, replied, lost, ntrans;
> static ib_portid_t portid = { 0 };
>
>-void __cdecl report(int sig)
>+void report(int sig)
> {
> 	total_time = cl_get_time_stamp() - start;
>
>diff --git a/trunk/tools/infiniband-diags/src/ibping/SOURCES b/trunk/tools/infiniband-diags/src/ibping/SOURCES
>index 341f589..12d3a5e 100644
>--- a/trunk/tools/infiniband-diags/src/ibping/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/ibping/SOURCES
>@@ -21,6 +21,7 @@ TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
> 	$(SDK_LIB_PATH)\ws2_32.lib		\
> 	$(TARGETPATH)\*\complib.lib		\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib
>
>diff --git a/trunk/tools/infiniband-diags/src/ibportstate.c b/trunk/tools/infiniband-diags/src/ibportstate.c
>index 499dabc..1f0f42e 100644
>--- a/trunk/tools/infiniband-diags/src/ibportstate.c
>+++ b/trunk/tools/infiniband-diags/src/ibportstate.c
>@@ -1,5 +1,6 @@
> /*
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>+ * Copyright (c) 2011 Mellanox Technologies LTD.  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
>@@ -125,7 +126,7 @@ static void show_port_info(ib_portid_t * dest, uint8_t * data, int portnum)
> 	char buf[2048];
> 	char val[64];
>
>-	mad_dump_portstates(buf, sizeof buf, data, sizeof data);
>+	mad_dump_portstates(buf, sizeof buf, data, sizeof *data);
> 	mad_decode_field(data, IB_PORT_LID_F, val);
> 	mad_dump_field(IB_PORT_LID_F, buf + strlen(buf),
> 		       sizeof buf - strlen(buf), val);
>@@ -247,7 +248,7 @@ int main(int argc, char **argv)
> 	int peerlocalportnum, peerlwe, peerlws, peerlwa, peerlse, peerlss,
> 	    peerlsa;
> 	int peerwidth, peerspeed;
>-	uint8_t data[IB_SMP_DATA_SIZE];
>+	uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
> 	ib_portid_t peerportid = { 0 };
> 	int portnum = 0;
> 	ib_portid_t selfportid = { 0 };
>@@ -356,6 +357,7 @@ int main(int argc, char **argv)
> 		printf("Initial %s PortInfo:\n", is_switch ? "Switch" : "CA");
> 	else
> 		printf("%s PortInfo:\n", is_switch ? "Switch" : "CA");
>+	memset(data, 0, sizeof(data));
> 	get_port_info(&portid, data, portnum);
> 	show_port_info(&portid, data, portnum);
>
>diff --git a/trunk/tools/infiniband-diags/src/ibportstate/SOURCES b/trunk/tools/infiniband-diags/src/ibportstate/SOURCES
>index 1fa9adc..851e77f 100644
>--- a/trunk/tools/infiniband-diags/src/ibportstate/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/ibportstate/SOURCES
>@@ -19,6 +19,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
>
> TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib
>
>diff --git a/trunk/tools/infiniband-diags/src/ibqueryerrors.c b/trunk/tools/infiniband-diags/src/ibqueryerrors.c
>index f04e47f..4677db4 100644
>--- a/trunk/tools/infiniband-diags/src/ibqueryerrors.c
>+++ b/trunk/tools/infiniband-diags/src/ibqueryerrors.c
>@@ -3,6 +3,7 @@
>  * Copyright (c) 2007 Xsigo Systems Inc.  All rights reserved.
>  * Copyright (c) 2008 Lawrence Livermore National Lab.  All rights reserved.
>  * Copyright (c) 2009 HNR Consulting.  All rights reserved.
>+ * Copyright (c) 2011 Mellanox Technologies LTD.  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
>@@ -61,9 +62,10 @@ static nn_map_t *node_name_map = NULL;
> static char *load_cache_file = NULL;
>
> int data_counters = 0;
>+int data_counters_only = 0;
> int port_config = 0;
>-uint64_t node_guid = 0;
>-char *node_guid_str = NULL;
>+uint64_t port_guid = 0;
>+char *port_guid_str = NULL;
> #define SUP_MAX 64
> int sup_total = 0;
> enum MAD_FIELDS suppressed_fields[SUP_MAX];
>@@ -76,6 +78,88 @@ unsigned clear_errors = 0, clear_counts = 0, details = 0;
> #define PRINT_ROUTER 0x4
> #define PRINT_ALL 0xFF		/* all nodes default flag */
>
>+struct {
>+	int nodes_checked;
>+	int bad_nodes;
>+	int ports_checked;
>+	int bad_ports;
>+} summary = { 0 };
>+
>+#define DEF_THRES_FILE IBDIAG_CONFIG_PATH"/error_thresholds"
>+static char *threshold_file = DEF_THRES_FILE;
>+
>+/* define a "packet" with threshold values in it */
>+uint8_t thresholds[1204] = { 0 };
>+char * threshold_str = "";
>+
>+static void set_thres(char *name, uint32_t val)
>+{
>+	int f;
>+	int n;
>+	char tmp[256];
>+	for (f = IB_PC_FIRST_F; f <= IB_PC_LAST_F; f++) {
>+		if (strcmp(name, mad_field_name(f)) == 0) {
>+			mad_encode_field(thresholds, f, &val);
>+			snprintf(tmp, 255, "[%s = %u]", name, val);
>+			threshold_str = realloc(threshold_str,
>+					strlen(threshold_str)+strlen(tmp)+1);
>+			if (!threshold_str) {
>+				fprintf(stderr, "Failed to allocate memory: "
>+					"%s\n", strerror(errno));
>+				exit(1);
>+			}
>+			n = strlen(threshold_str);
>+			strcpy(threshold_str+n, tmp);
>+		}
>+	}
>+}
>+
>+static void set_thresholds(char *threshold_file)
>+{
>+	char buf[1024];
>+	int val = 0;
>+	FILE *thresf = fopen(threshold_file, "r");
>+	char *p_prefix, *p_last;
>+	char *name;
>+	char *val_str;
>+	char str[64];
>+
>+	if (!thresf)
>+		return;
>+
>+	snprintf(str, 63, "Thresholds: ");
>+	threshold_str = malloc(strlen(str)+1);
>+	if (!threshold_str) {
>+		fprintf(stderr, "Failed to allocate memory: %s\n",
>+			strerror(errno));
>+		exit(1);
>+	}
>+	strcpy(threshold_str, str);
>+	while (fgets(buf, sizeof buf, thresf) != NULL) {
>+		p_prefix = strtok_r(buf, "\n", &p_last);
>+		if (!p_prefix)
>+			continue; /* ignore blank lines */
>+
>+		if (*p_prefix == '#')
>+			continue; /* ignore comment lines */
>+
>+		name = strtok_r(p_prefix, "=", &p_last);
>+		val_str = strtok_r(NULL, "\n", &p_last);
>+
>+		val = strtoul(val_str, NULL, 0);
>+		set_thres(name, val);
>+	}
>+
>+	fclose(thresf);
>+}
>+
>+static int exceeds_threshold(int field, unsigned val)
>+{
>+	uint32_t thres = 0;
>+	mad_decode_field(thresholds, field, &thres);
>+	return (val > thres);
>+}
>+
> static unsigned int get_max(unsigned int num)
> {
> 	unsigned r = 0;		// r will be lg(num)
>@@ -175,7 +259,7 @@ static void print_port_config(char *node_name, ibnd_node_t * node, int portnum)
>
> 		snprintf(remote_str, 256,
> 			 "0x%016" PRIx64 " %6d %4d[%2s] \"%s\" (%s %s)\n",
>-			 port->remoteport->node->guid,
>+			 port->remoteport->guid,
> 			 port->remoteport->base_lid ? port->remoteport->
> 			 base_lid : port->remoteport->node->smalid,
> 			 port->remoteport->portnum, ext_port_str, rem_node_name,
>@@ -211,12 +295,22 @@ static int suppress(enum MAD_FIELDS field)
> static void report_suppressed(void)
> {
> 	int i = 0;
>-	printf("Suppressing:");
>+	printf("## Suppresed:");
> 	for (i = 0; i < sup_total; i++)
> 		printf(" %s", mad_field_name(suppressed_fields[i]));
> 	printf("\n");
> }
>
>+static void print_summary(void)
>+{
>+	printf("\n## Summary: %d nodes checked, %d bad nodes found\n",
>+		summary.nodes_checked, summary.bad_nodes);
>+	printf("##          %d ports checked, %d ports have errors beyond threshold\n",
>+		summary.ports_checked, summary.bad_ports);
>+	printf("## %s\n", threshold_str);
>+	report_suppressed();
>+}
>+
> static int query_and_dump(char *buf, size_t size, ib_portid_t * portid,
> 			  ibnd_node_t * node, char *node_name, int portnum,
> 			  const char *attr_name, uint16_t attr_id,
>@@ -245,9 +339,9 @@ static int query_and_dump(char *buf, size_t size, ib_portid_t * portid,
> 	return n;
> }
>
>-static void print_results(ib_portid_t * portid, char *node_name,
>-			  ibnd_node_t * node, uint8_t * pc, int portnum,
>-			  int *header_printed)
>+static int print_results(ib_portid_t * portid, char *node_name,
>+			 ibnd_node_t * node, uint8_t * pc, int portnum,
>+			 int *header_printed, uint8_t *pce, uint16_t cap_mask)
> {
> 	char buf[1024];
> 	char *str = buf;
>@@ -263,65 +357,91 @@ static void print_results(ib_portid_t * portid, char *node_name,
> 			continue;
>
> 		mad_decode_field(pc, i, (void *)&val);
>-		if (val)
>+		if (exceeds_threshold(i, val)) {
> 			n += snprintf(str + n, 1024 - n, " [%s == %u]",
> 				      mad_field_name(i), val);
>
>-		/* If there are PortXmitDiscards, get details (if supported) */
>-		if (i == IB_PC_XMT_DISCARDS_F && details && val) {
>-			n += query_and_dump(str + n, sizeof(buf) - n, portid,
>-					    node, node_name, portnum,
>-					    "PortXmitDiscardDetails",
>-					    IB_GSI_PORT_XMIT_DISCARD_DETAILS,
>-					    IB_PC_RCV_LOCAL_PHY_ERR_F,
>-					    IB_PC_RCV_ERR_LAST_F);
>-			/* If there are PortRcvErrors, get details (if supported) */
>-		} else if (i == IB_PC_ERR_RCV_F && details && val) {
>-			n += query_and_dump(str + n, sizeof(buf) - n, portid,
>-					    node, node_name, portnum,
>-					    "PortRcvErrorDetails",
>-					    IB_GSI_PORT_RCV_ERROR_DETAILS,
>-					    IB_PC_XMT_INACT_DISC_F,
>-					    IB_PC_XMT_DISC_LAST_F);
>+			/* If there are PortXmitDiscards, get details (if supported) */
>+			if (i == IB_PC_XMT_DISCARDS_F && details) {
>+				n += query_and_dump(str + n, sizeof(buf) - n, portid,
>+						    node, node_name, portnum,
>+						    "PortXmitDiscardDetails",
>+						    IB_GSI_PORT_XMIT_DISCARD_DETAILS,
>+						    IB_PC_RCV_LOCAL_PHY_ERR_F,
>+						    IB_PC_RCV_ERR_LAST_F);
>+				/* If there are PortRcvErrors, get details (if supported) */
>+			} else if (i == IB_PC_ERR_RCV_F && details) {
>+				n += query_and_dump(str + n, sizeof(buf) - n, portid,
>+						    node, node_name, portnum,
>+						    "PortRcvErrorDetails",
>+						    IB_GSI_PORT_RCV_ERROR_DETAILS,
>+						    IB_PC_XMT_INACT_DISC_F,
>+						    IB_PC_XMT_DISC_LAST_F);
>+			}
> 		}
> 	}
>
> 	if (!suppress(IB_PC_XMT_WAIT_F)) {
> 		mad_decode_field(pc, IB_PC_XMT_WAIT_F, (void *)&val);
>-		if (val)
>+		if (exceeds_threshold(IB_PC_XMT_WAIT_F, val))
> 			n += snprintf(str + n, 1024 - n, " [%s == %u]",
> 				      mad_field_name(IB_PC_XMT_WAIT_F), val);
> 	}
>
> 	/* if we found errors. */
> 	if (n != 0) {
>-		if (data_counters)
>-			for (i = IB_PC_XMT_BYTES_F; i <= IB_PC_RCV_PKTS_F; i++) {
>+		if (data_counters) {
>+			uint8_t *pkt = pc;
>+			int start_field = IB_PC_XMT_BYTES_F;
>+			int end_field = IB_PC_RCV_PKTS_F;
>+
>+			if (pce) {
>+				pkt = pce;
>+				start_field = IB_PC_EXT_XMT_BYTES_F;
>+				if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED)
>+					end_field = IB_PC_EXT_RCV_MPKTS_F;
>+				else
>+					end_field = IB_PC_EXT_RCV_PKTS_F;
>+			}
>+
>+			for (i = start_field; i <= end_field; i++) {
> 				uint64_t val64 = 0;
>-				mad_decode_field(pc, i, (void *)&val64);
>+				mad_decode_field(pkt, i, (void *)&val64);
> 				if (val64)
> 					n += snprintf(str + n, 1024 - n,
>-						      " [%s == %" PRIu64 "]",
>-						      mad_field_name(i), val64);
>+						" [%s == %" PRIu64 "]",
>+						mad_field_name(i), val64);
> 			}
>+		}
>
> 		if (!*header_printed) {
>-			printf("Errors for 0x%" PRIx64 " \"%s\"\n", node->guid,
>-			       node_name);
>+			if (node->type == IB_NODE_SWITCH)
>+				printf("Errors for 0x%" PRIx64 " \"%s\"\n",
>+					node->ports[0]->guid, node_name);
>+			else
>+				printf("Errors for \"%s\"\n", node_name);
> 			*header_printed = 1;
>+			summary.bad_nodes++;
> 		}
>
>-		printf("   GUID 0x%" PRIx64 " port %d:%s\n", node->guid,
>-		       portnum, str);
>-		if (port_config)
>+		if (portnum == 0xFF)
>+			printf("   GUID 0x%" PRIx64 " port ALL:%s\n",
>+			       node->ports[0]->guid, str);
>+		else
>+			printf("   GUID 0x%" PRIx64 " port %d:%s\n",
>+			       node->ports[portnum]->guid, portnum, str);
>+		if (portnum != 0xFF && port_config)
> 			print_port_config(node_name, node, portnum);
>+
>+		summary.bad_ports++;
> 	}
>+	return (n);
> }
>
> static int query_cap_mask(ib_portid_t * portid, char *node_name, int portnum,
> 			  uint16_t * cap_mask)
> {
>-	uint8_t pc[1024];
>+	uint8_t pc[1024] = { 0 };
> 	uint16_t rc_cap_mask;
>
> 	/* PerfMgt ClassPortInfo is a required attribute */
>@@ -335,63 +455,192 @@ static int query_cap_mask(ib_portid_t * portid, char *node_name, int portnum,
> 	/* ClassPortInfo should be supported as part of libibmad */
> 	memcpy(&rc_cap_mask, pc + 2, sizeof(rc_cap_mask));	/* CapabilityMask */
>
>-	*cap_mask = ntohs(rc_cap_mask);
>+	*cap_mask = rc_cap_mask;
> 	return 0;
> }
>
>-static void print_port(ib_portid_t * portid, uint16_t cap_mask, char *node_name,
>-		       ibnd_node_t * node, int portnum, int *header_printed)
>+static int print_data_cnts(ib_portid_t * portid, uint16_t cap_mask,
>+			   char *node_name, ibnd_node_t * node, int portnum,
>+			   int *header_printed)
>+{
>+	uint8_t pc[1024];
>+	int i;
>+	int start_field = IB_PC_XMT_BYTES_F;
>+	int end_field = IB_PC_RCV_PKTS_F;
>+
>+	memset(pc, 0, 1024);
>+
>+	if (cap_mask & (IB_PM_EXT_WIDTH_SUPPORTED | IB_PM_EXT_WIDTH_NOIETF_SUP)) {
>+		if (!pma_query_via(pc, portid, portnum, ibd_timeout,
>+				   IB_GSI_PORT_COUNTERS_EXT, ibmad_port)) {
>+			IBWARN("IB_GSI_PORT_COUNTERS_EXT query failed on %s, %s port %d",
>+			       node_name, portid2str(portid), portnum);
>+			return (1);
>+		}
>+		start_field = IB_PC_EXT_XMT_BYTES_F;
>+		if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED)
>+			end_field = IB_PC_EXT_RCV_MPKTS_F;
>+		else
>+			end_field = IB_PC_EXT_RCV_PKTS_F;
>+	} else {
>+		if (!pma_query_via(pc, portid, portnum, ibd_timeout,
>+				   IB_GSI_PORT_COUNTERS, ibmad_port)) {
>+			IBWARN("IB_GSI_PORT_COUNTERS query failed on %s, %s port %d",
>+			       node_name, portid2str(portid), portnum);
>+			return (1);
>+		}
>+		start_field = IB_PC_XMT_BYTES_F;
>+		end_field = IB_PC_RCV_PKTS_F;
>+	}
>+
>+	if (!*header_printed) {
>+		printf("Data Counters for 0x%" PRIx64 " \"%s\"\n", node->guid,
>+		       node_name);
>+		*header_printed = 1;
>+	}
>+
>+	if (portnum == 0xFF)
>+		printf("   GUID 0x%" PRIx64 " port ALL:", node->guid);
>+	else
>+		printf("   GUID 0x%" PRIx64 " port %d:",
>+		       node->guid, portnum);
>+
>+	for (i = start_field; i <= end_field; i++) {
>+		uint64_t val64 = 0;
>+		mad_decode_field(pc, i, (void *)&val64);
>+		printf(" [%s == %" PRIu64 "]", mad_field_name(i), val64);
>+	}
>+	printf("\n");
>+
>+	if (portnum != 0xFF && port_config)
>+		print_port_config(node_name, node, portnum);
>+
>+	return (0);
>+}
>+
>+static int print_errors(ib_portid_t * portid, uint16_t cap_mask,
>+			char *node_name, ibnd_node_t * node, int portnum,
>+			int *header_printed)
> {
> 	uint8_t pc[1024];
>+	uint8_t pce[1024];
>+	uint8_t *pc_ext = NULL;
>
> 	memset(pc, 0, 1024);
>+	memset(pce, 0, 1024);
>
> 	if (!pma_query_via(pc, portid, portnum, ibd_timeout,
> 			   IB_GSI_PORT_COUNTERS, ibmad_port)) {
> 		IBWARN("IB_GSI_PORT_COUNTERS query failed on %s, %s port %d",
> 		       node_name, portid2str(portid), portnum);
>-		return;
>+		return (0);
>+	}
>+
>+	if (cap_mask & (IB_PM_EXT_WIDTH_SUPPORTED | IB_PM_EXT_WIDTH_NOIETF_SUP)) {
>+		if (!pma_query_via(pce, portid, portnum, ibd_timeout,
>+		    IB_GSI_PORT_COUNTERS_EXT, ibmad_port)) {
>+			IBWARN("IB_GSI_PORT_COUNTERS_EXT query failed on %s, %s port %d",
>+			       node_name, portid2str(portid), portnum);
>+			return (0);
>+		}
>+		pc_ext = pce;
> 	}
>-	if (!(cap_mask & 0x1000)) {
>+
>+	if (!(cap_mask & IB_PM_PC_XMIT_WAIT_SUP)) {
> 		/* if PortCounters:PortXmitWait not supported clear this counter */
> 		uint32_t foo = 0;
> 		mad_encode_field(pc, IB_PC_XMT_WAIT_F, &foo);
> 	}
>-	print_results(portid, node_name, node, pc, portnum, header_printed);
>+	return (print_results(portid, node_name, node, pc, portnum,
>+			      header_printed, pc_ext, cap_mask));
>+}
>+
>+uint8_t *reset_pc_ext(void *rcvbuf, ib_portid_t * dest,
>+		      int port, unsigned mask, unsigned timeout,
>+		      const struct ibmad_port * srcport)
>+{
>+	ib_rpc_t rpc = { 0 };
>+	int lid = dest->lid;
>+
>+	DEBUG("lid %u port %d mask 0x%x", lid, port, mask);
>+
>+	if (lid == -1) {
>+		IBWARN("only lid routed is supported");
>+		return NULL;
>+	}
>+
>+	if (!mask)
>+		mask = ~0;
>+
>+	rpc.mgtclass = IB_PERFORMANCE_CLASS;
>+	rpc.method = IB_MAD_METHOD_SET;
>+	rpc.attr.id = IB_GSI_PORT_COUNTERS_EXT;
>+
>+	memset(rcvbuf, 0, IB_MAD_SIZE);
>+
>+	/* Same for attribute IDs */
>+	mad_set_field(rcvbuf, 0, IB_PC_EXT_PORT_SELECT_F, port);
>+	mad_set_field(rcvbuf, 0, IB_PC_EXT_COUNTER_SELECT_F, mask);
>+	rpc.attr.mod = 0;
>+	rpc.timeout = timeout;
>+	rpc.datasz = IB_PC_DATA_SZ;
>+	rpc.dataoffs = IB_PC_DATA_OFFS;
>+	if (!dest->qp)
>+		dest->qp = 1;
>+	if (!dest->qkey)
>+		dest->qkey = IB_DEFAULT_QP1_QKEY;
>+
>+	return mad_rpc(srcport, &rpc, dest, rcvbuf, rcvbuf);
> }
>
> static void clear_port(ib_portid_t * portid, uint16_t cap_mask,
> 		       char *node_name, int port)
> {
>-	uint8_t pc[1024];
>+	uint8_t pc[1024] = { 0 };
> 	/* bits defined in Table 228 PortCounters CounterSelect and
> 	 * CounterSelect2
> 	 */
> 	uint32_t mask = 0;
>
>-	if (!clear_errors && !clear_counts)
>-		return;
>-
> 	if (clear_errors) {
> 		mask |= 0xFFF;
>-		if (cap_mask & 0x1000)
>+		if (cap_mask & IB_PM_PC_XMIT_WAIT_SUP)
> 			mask |= 0x10000;
> 	}
> 	if (clear_counts)
> 		mask |= 0xF000;
>
>-	if (!performance_reset_via(pc, portid, port, mask, ibd_timeout,
>-				   IB_GSI_PORT_COUNTERS, ibmad_port))
>-		IBERROR("Failed to reset errors %s port %d", node_name, port);
>+	if (mask)
>+		if (!performance_reset_via(pc, portid, port, mask, ibd_timeout,
>+					   IB_GSI_PORT_COUNTERS, ibmad_port))
>+			IBERROR("Failed to reset errors %s port %d", node_name,
>+				port);
>
>-	if (details && clear_errors) {
>+	if (clear_errors && details) {
>+		memset(pc, 0, 1024);
> 		performance_reset_via(pc, portid, port, 0xf, ibd_timeout,
> 				      IB_GSI_PORT_XMIT_DISCARD_DETAILS,
> 				      ibmad_port);
>+		memset(pc, 0, 1024);
> 		performance_reset_via(pc, portid, port, 0x3f, ibd_timeout,
> 				      IB_GSI_PORT_RCV_ERROR_DETAILS,
> 				      ibmad_port);
> 	}
>+
>+	if (clear_counts &&
>+	    (cap_mask &
>+	     (IB_PM_EXT_WIDTH_SUPPORTED | IB_PM_EXT_WIDTH_NOIETF_SUP))) {
>+		if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED)
>+			mask = 0xFF;
>+		else
>+			mask = 0x0F;
>+
>+		if (!reset_pc_ext(pc, portid, port, mask, ibd_timeout,
>+		    ibmad_port))
>+			IBERROR("Failed to reset extended data counters %s, "
>+				"%s port %d", node_name, portid2str(portid),
>+				port);
>+	}
> }
>
> void print_node(ibnd_node_t * node, void *user_data)
>@@ -425,28 +674,67 @@ void print_node(ibnd_node_t * node, void *user_data)
>
> 	node_name = remap_node_name(node_name_map, node->guid, node->nodedesc);
>
>-	for (p = startport; p <= node->numports; p++) {
>-		if (node->ports[p]) {
>-			if (node->type == IB_NODE_SWITCH)
>-				ib_portid_set(&portid, node->smalid, 0, 0);
>-			else
>-				ib_portid_set(&portid, node->ports[p]->base_lid,
>+	if (node->type == IB_NODE_SWITCH) {
>+		ib_portid_set(&portid, node->smalid, 0, 0);
>+		p = 0;
>+	} else {
>+		for (p = 1; p <= node->numports; p++) {
>+			if (node->ports[p]) {
>+				ib_portid_set(&portid,
>+					      node->ports[p]->base_lid,
> 					      0, 0);
>+				break;
>+			}
>+		}
>+	}
>
>-			if (query_cap_mask(&portid, node_name, p, &cap_mask) <
>-			    0)
>-				continue;
>-
>-			if (cap_mask & 0x100)
>-				all_port_sup = 1;
>+	if ((query_cap_mask(&portid, node_name, p, &cap_mask) == 0) &&
>+	    (cap_mask & IB_PM_ALL_PORT_SELECT))
>+		all_port_sup = 1;
>+
>+	if (data_counters_only) {
>+		for (p = startport; p <= node->numports; p++) {
>+			if (node->ports[p]) {
>+				if (node->type == IB_NODE_SWITCH)
>+					ib_portid_set(&portid, node->smalid, 0, 0);
>+				else
>+					ib_portid_set(&portid, node->ports[p]->base_lid,
>+						      0, 0);
>+
>+				print_data_cnts(&portid, cap_mask, node_name, node, p,
>+						&header_printed);
>+				summary.ports_checked++;
>+				if (!all_port_sup)
>+					clear_port(&portid, cap_mask, node_name, p);
>+			}
>+		}
>+	} else {
>+		if (all_port_sup)
>+			if (!print_errors(&portid, cap_mask, node_name, node,
>+					  0xFF, &header_printed)) {
>+				summary.ports_checked += node->numports;
>+				goto clear;
>+			}
>
>-			print_port(&portid, cap_mask, node_name, node, p,
>-				   &header_printed);
>-			if (!all_port_sup)
>-				clear_port(&portid, cap_mask, node_name, p);
>+		for (p = startport; p <= node->numports; p++) {
>+			if (node->ports[p]) {
>+				if (node->type == IB_NODE_SWITCH)
>+					ib_portid_set(&portid, node->smalid, 0, 0);
>+				else
>+					ib_portid_set(&portid, node->ports[p]->base_lid,
>+						      0, 0);
>+
>+				print_errors(&portid, cap_mask, node_name, node, p,
>+					     &header_printed);
>+				summary.ports_checked++;
>+				if (!all_port_sup)
>+					clear_port(&portid, cap_mask, node_name, p);
>+			}
> 		}
> 	}
>
>+clear:
>+	summary.nodes_checked++;
> 	if (all_port_sup)
> 		clear_port(&portid, cap_mask, node_name, 0xFF);
>
>@@ -512,10 +800,16 @@ static int process_opt(void *context, int ch, char *optarg)
> 	case 7:
> 		load_cache_file = strdup(optarg);
> 		break;
>+	case 8:
>+		threshold_file = strdup(optarg);
>+		break;
>+	case 9:
>+		data_counters_only = 1;
>+		break;
> 	case 'G':
> 	case 'S':
>-		node_guid_str = optarg;
>-		node_guid = strtoull(optarg, 0, 0);
>+		port_guid_str = optarg;
>+		port_guid = strtoull(optarg, 0, 0);
> 		break;
> 	case 'D':
> 		dr_path = strdup(optarg);
>@@ -559,20 +853,24 @@ int main(int argc, char **argv)
> 		{"suppress-common", 'c', 0, NULL,
> 		 "suppress some of the common counters"},
> 		{"node-name-map", 1, 1, "<file>", "node name map file"},
>-		{"node-guid", 'G', 1, "<node_guid>", "query only <node_guid>"},
>-		{"", 'S', 1, "<node_guid>",
>+		{"port-guid", 'G', 1, "<port_guid>",
>+		 "report the node containing the port specified by <port_guid>"},
>+		{"", 'S', 1, "<port_guid>",
> 		 "Same as \"-G\" for backward compatibility"},
> 		{"Direct", 'D', 1, "<dr_path>",
>-		 "query only switch specified by <dr_path>"},
>+		 "report the node containing the port specified by <dr_path>"},
> 		{"report-port", 'r', 0, NULL,
>-		 "report port configuration information"},
>+		 "report port link information"},
>+		{"threshold-file", 8, 1, NULL,
>+		 "specify an alternate threshold file, default: " DEF_THRES_FILE},
> 		{"GNDN", 'R', 0, NULL,
> 		 "(This option is obsolete and does nothing)"},
>-		{"data", 2, 0, NULL, "include the data counters in the output"},
>+		{"data", 2, 0, NULL, "include data counters for ports with errors"},
> 		{"switch", 3, 0, NULL, "print data for switches only"},
> 		{"ca", 4, 0, NULL, "print data for CA's only"},
> 		{"router", 5, 0, NULL, "print data for routers only"},
> 		{"details", 6, 0, NULL, "include transmit discard details"},
>+		{"counters", 9, 0, NULL, "print data counters only"},
> 		{"clear-errors", 'k', 0, NULL,
> 		 "Clear error counters after read"},
> 		{"clear-counts", 'K', 0, NULL,
>@@ -619,13 +917,13 @@ int main(int argc, char **argv)
> 					       NULL, ibmad_port)) < 0)
> 			IBWARN("Failed to resolve %s; attempting full scan",
> 			       dr_path);
>-	} else if (node_guid_str) {
>+	} else if (port_guid_str) {
> 		if ((resolved =
>-		     ib_resolve_portid_str_via(&portid, node_guid_str,
>+		     ib_resolve_portid_str_via(&portid, port_guid_str,
> 					       IB_DEST_GUID, ibd_sm_id,
> 					       ibmad_port)) < 0)
> 			IBWARN("Failed to resolve %s; attempting full scan",
>-			       node_guid_str);
>+			       port_guid_str);
> 	}
>
> 	if (load_cache_file) {
>@@ -634,11 +932,14 @@ int main(int argc, char **argv)
> 			exit(1);
> 		}
> 	} else {
>-		if (resolved >= 0 &&
>-		    !(fabric = ibnd_discover_fabric(ibd_ca, ibd_ca_port,
>+		if (resolved >= 0) {
>+			if (!config.max_hops)
>+				config.max_hops = 1;
>+			if (!(fabric = ibnd_discover_fabric(ibd_ca, ibd_ca_port,
> 						    &portid, &config)))
>-			IBWARN("Single node discover failed;"
>-			       " attempting full scan");
>+				IBWARN("Single node discover failed;"
>+				       " attempting full scan");
>+		}
>
> 		if (!fabric && !(fabric = ibnd_discover_fabric(ibd_ca,
> 							       ibd_ca_port,
>@@ -650,34 +951,36 @@ int main(int argc, char **argv)
> 		}
> 	}
>
>-	report_suppressed();
>+	set_thresholds(threshold_file);
>
>-	if (node_guid_str) {
>-		ibnd_node_t *node = ibnd_find_node_guid(fabric, node_guid);
>-		if (node)
>-			print_node(node, NULL);
>+	if (port_guid_str) {
>+		ibnd_port_t *port = ibnd_find_port_guid(fabric, port_guid);
>+		if (port)
>+			print_node(port->node, NULL);
> 		else
> 			fprintf(stderr, "Failed to find node: %s\n",
>-				node_guid_str);
>+				port_guid_str);
> 	} else if (dr_path) {
>-		ibnd_node_t *node = ibnd_find_node_dr(fabric, dr_path);
>-		uint8_t ni[IB_SMP_DATA_SIZE];
>+		ibnd_port_t *port = ibnd_find_port_dr(fabric, dr_path);
>+		uint8_t ni[IB_SMP_DATA_SIZE] = { 0 };
>
> 		if (!smp_query_via(ni, &portid, IB_ATTR_NODE_INFO, 0,
> 				   ibd_timeout, ibmad_port)) {
> 			rc = -1;
> 			goto destroy_fabric;
> 		}
>-		mad_decode_field(ni, IB_NODE_GUID_F, &(node_guid));
>+		mad_decode_field(ni, IB_NODE_PORT_GUID_F, &(port_guid));
>
>-		node = ibnd_find_node_guid(fabric, node_guid);
>-		if (node)
>-			print_node(node, NULL);
>-		else
>+		port = ibnd_find_port_guid(fabric, port_guid);
>+		if (port) {
>+			print_node(port->node, NULL);
>+		} else
> 			fprintf(stderr, "Failed to find node: %s\n", dr_path);
> 	} else
> 		ibnd_iter_nodes(fabric, print_node, NULL);
>
>+	print_summary();
>+
> destroy_fabric:
> 	ibnd_destroy_fabric(fabric);
>
>diff --git a/trunk/tools/infiniband-diags/src/ibqueryerrors/SOURCES b/trunk/tools/infiniband-diags/src/ibqueryerrors/SOURCES
>index 8c529dd..ab323bc 100644
>--- a/trunk/tools/infiniband-diags/src/ibqueryerrors/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/ibqueryerrors/SOURCES
>@@ -22,6 +22,7 @@ TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
> 	$(SDK_LIB_PATH)\ws2_32.lib		\
> 	$(TARGETPATH)\*\complib.lib		\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib	\
> 	$(TARGETPATH)\*\libibnetdisc.lib
>diff --git a/trunk/tools/infiniband-diags/src/ibroute.c b/trunk/tools/infiniband-diags/src/ibroute.c
>index b765c84..7339218 100644
>--- a/trunk/tools/infiniband-diags/src/ibroute.c
>+++ b/trunk/tools/infiniband-diags/src/ibroute.c
>@@ -1,6 +1,6 @@
> /*
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>- * Copyright (c) 2009 Mellanox Technologies LTD.  All rights reserved.
>+ * Copyright (c) 2009-2011 Mellanox Technologies LTD.  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
>@@ -130,7 +130,7 @@ int dump_mlid(char *str, int strlen, unsigned mlid, unsigned nports,
> 	return i * 2;
> }
>
>-uint16_t mft[16][IB_MLIDS_IN_BLOCK];
>+uint16_t mft[16][IB_MLIDS_IN_BLOCK] = { { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0}, { 0 }, { 0 } };
>
> char *dump_multicast_tables(ib_portid_t * portid, unsigned startlid,
> 			    unsigned endlid)
>@@ -303,9 +303,9 @@ int dump_lid(char *str, int strlen, int lid, int valid)
>
> char *dump_unicast_tables(ib_portid_t * portid, int startlid, int endlid)
> {
>-	char lft[IB_SMP_DATA_SIZE];
>-	char nd[IB_SMP_DATA_SIZE];
>-	uint8_t sw[IB_SMP_DATA_SIZE];
>+	char lft[IB_SMP_DATA_SIZE] = { 0 };
>+	char nd[IB_SMP_DATA_SIZE] = { 0 };
>+	uint8_t sw[IB_SMP_DATA_SIZE] = { 0 };
> 	char str[200], *s;
> 	uint64_t nodeguid;
> 	int block, i, e, top;
>diff --git a/trunk/tools/infiniband-diags/src/ibroute/SOURCES b/trunk/tools/infiniband-diags/src/ibroute/SOURCES
>index 5e7763d..26bf224 100644
>--- a/trunk/tools/infiniband-diags/src/ibroute/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/ibroute/SOURCES
>@@ -21,6 +21,7 @@ TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
> 	$(SDK_LIB_PATH)\ws2_32.lib		\
> 	$(TARGETPATH)\*\complib.lib		\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib
>
>diff --git a/trunk/tools/infiniband-diags/src/ibsendtrap.c b/trunk/tools/infiniband-diags/src/ibsendtrap.c
>index 1b91595..618706b 100644
>--- a/trunk/tools/infiniband-diags/src/ibsendtrap.c
>+++ b/trunk/tools/infiniband-diags/src/ibsendtrap.c
>@@ -2,6 +2,7 @@
>  * Copyright (c) 2008 Lawrence Livermore National Security
>  * Copyright (c) 2008-2009 Voltaire Inc.  All rights reserved.
>  * Copyright (c) 2009 HNR Consulting.  All rights reserved.
>+ * Copyright (c) 2011 Mellanox Technologies LTD.  All rights reserved.
>  *
>  * Produced at Lawrence Livermore National Laboratory.
>  * Written by Ira Weiny <weiny2 at llnl.gov>.
>@@ -56,7 +57,7 @@ int error_port = 1;
> static uint16_t get_node_type(ib_portid_t * port)
> {
> 	uint16_t node_type = IB_NODE_TYPE_CA;
>-	uint8_t data[IB_SMP_DATA_SIZE];
>+	uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
>
> 	if (smp_query_via(data, port, IB_ATTR_NODE_INFO, 0, 0, srcport))
> 		node_type = (uint16_t) mad_get_field(data, 0, IB_NODE_TYPE_F);
>@@ -65,7 +66,7 @@ static uint16_t get_node_type(ib_portid_t * port)
>
> static uint32_t get_cap_mask(ib_portid_t * port)
> {
>-	uint8_t data[IB_SMP_DATA_SIZE];
>+	uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
> 	uint32_t cap_mask = 0;
>
> 	if (smp_query_via(data, port, IB_ATTR_PORT_INFO, 0, 0, srcport))
>diff --git a/trunk/tools/infiniband-diags/src/ibsendtrap/SOURCES b/trunk/tools/infiniband-diags/src/ibsendtrap/SOURCES
>index 6ebf711..51b9ddd 100644
>--- a/trunk/tools/infiniband-diags/src/ibsendtrap/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/ibsendtrap/SOURCES
>@@ -19,6 +19,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
>
> TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib
>
>diff --git a/trunk/tools/infiniband-diags/src/ibstat.c b/trunk/tools/infiniband-diags/src/ibstat.c
>index c44d8c4..92fcd0f 100644
>--- a/trunk/tools/infiniband-diags/src/ibstat.c
>+++ b/trunk/tools/infiniband-diags/src/ibstat.c
>@@ -72,10 +72,9 @@ static void ca_dump(umad_ca_t * ca)
> 	printf("\tNumber of ports: %d\n", ca->numports);
> 	printf("\tFirmware version: %s\n", ca->fw_ver);
> 	printf("\tHardware version: %s\n", ca->hw_ver);
>-	printf("\tNode GUID: 0x%016llx\n",
>-	       (long long unsigned)ntohll(ca->node_guid));
>-	printf("\tSystem image GUID: 0x%016llx\n",
>-	       (long long unsigned)ntohll(ca->system_guid));
>+	printf("\tNode GUID: 0x%016" PRIx64 "\n", ntohll(ca->node_guid));
>+	printf("\tSystem image GUID: 0x%016" PRIx64 "\n",
>+	       ntohll(ca->system_guid));
> }
>
> static char *port_state_str[] = {
>@@ -115,16 +114,17 @@ static int port_dump(umad_port_t * port, int alone)
> 	       (unsigned)port->state <=
> 	       4 ? port_state_str[port->state] : "???");
> 	printf("%sPhysical state: %s\n", pre,
>-	       (unsigned)port->state <=
>+	       (unsigned)port->phys_state <=
> 	       7 ? port_phy_state_str[port->phys_state] : "???");
> 	printf("%sRate: %d\n", pre, port->rate);
> 	printf("%sBase lid: %d\n", pre, port->base_lid);
> 	printf("%sLMC: %d\n", pre, port->lmc);
> 	printf("%sSM lid: %d\n", pre, port->sm_lid);
> 	printf("%sCapability mask: 0x%08x\n", pre, ntohl(port->capmask));
>-	printf("%sPort GUID: 0x%016llx\n", pre,
>-	       (long long unsigned)ntohll(port->port_guid));
>+	printf("%sPort GUID: 0x%016" PRIx64 "\n", pre, ntohll(port->port_guid));
>+#ifdef HAVE_UMAD_PORT_LINK_LAYER
> 	printf("%sLink layer: %s\n", pre, port->link_layer);
>+#endif
> 	return 0;
> }
>
>@@ -182,8 +182,7 @@ static int ports_list(char names[][UMAD_CA_NAME_LEN], int n)
>
> 	for (i = 0; i < found; i++)
> 		if (guids[i])
>-			printf("0x%016llx\n",
>-			       (long long unsigned)ntohll(guids[i]));
>+			printf("0x%016" PRIx64 "\n", ntohll(guids[i]));
> 	return found;
> }
>
>diff --git a/trunk/tools/infiniband-diags/src/ibstat/SOURCES b/trunk/tools/infiniband-diags/src/ibstat/SOURCES
>index 03c809c..599e656 100644
>--- a/trunk/tools/infiniband-diags/src/ibstat/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/ibstat/SOURCES
>@@ -20,6 +20,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
> TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
> 	$(SDK_LIB_PATH)\ws2_32.lib		\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib
>
>diff --git a/trunk/tools/infiniband-diags/src/ibsysstat/SOURCES b/trunk/tools/infiniband-diags/src/ibsysstat/SOURCES
>index d1add5c..f7c92f5 100644
>--- a/trunk/tools/infiniband-diags/src/ibsysstat/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/ibsysstat/SOURCES
>@@ -20,6 +20,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
> TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
> 	$(SDK_LIB_PATH)\ws2_32.lib		\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib
>
>diff --git a/trunk/tools/infiniband-diags/src/ibtracert.c b/trunk/tools/infiniband-diags/src/ibtracert.c
>index 80694f2..c9f511b 100644
>--- a/trunk/tools/infiniband-diags/src/ibtracert.c
>+++ b/trunk/tools/infiniband-diags/src/ibtracert.c
>@@ -1,6 +1,7 @@
> /*
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>  * Copyright (c) 2009 HNR Consulting.  All rights reserved.
>+ * Copyright (c) 2010,2011 Mellanox Technologies LTD.  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
>@@ -118,9 +119,11 @@ static int get_node(Node * node, Port * port, ib_portid_t * portid)
> 	void *pi = port->portinfo, *ni = node->nodeinfo, *nd = node->nodedesc;
> 	char *s, *e;
>
>+	memset(ni, 0, sizeof(node->nodeinfo));
> 	if (!smp_query_via(ni, portid, IB_ATTR_NODE_INFO, 0, timeout, srcport))
> 		return -1;
>
>+	memset(nd, 0, sizeof(node->nodedesc));
> 	if (!smp_query_via(nd, portid, IB_ATTR_NODE_DESC, 0, timeout, srcport))
> 		return -1;
>
>@@ -131,6 +134,7 @@ static int get_node(Node * node, Port * port, ib_portid_t * portid)
> 			*s = ' ';
> 	}
>
>+	memset(pi, 0, sizeof(port->portinfo));
> 	if (!smp_query_via(pi, portid, IB_ATTR_PORT_INFO, 0, timeout, srcport))
> 		return -1;
>
>@@ -153,6 +157,7 @@ static int switch_lookup(Switch * sw, ib_portid_t * portid, int lid)
> {
> 	void *si = sw->switchinfo, *fdb = sw->fdb;
>
>+	memset(si, 0, sizeof(sw->switchinfo));
> 	if (!smp_query_via(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout,
> 			   srcport))
> 		return -1;
>@@ -163,6 +168,7 @@ static int switch_lookup(Switch * sw, ib_portid_t * portid, int lid)
> 	if (lid >= sw->linearcap && lid > sw->linearFDBtop)
> 		return -1;
>
>+	memset(fdb, 0, sizeof(sw->fdb));
> 	if (!smp_query_via(fdb, portid, IB_ATTR_LINEARFORWTBL, lid / 64,
> 			   timeout, srcport))
> 		return -1;
>@@ -382,7 +388,7 @@ static int insert_node(Node * new)
>
> static int get_port(Port * port, int portnum, ib_portid_t * portid)
> {
>-	char portinfo[64];
>+	char portinfo[64] = { 0 };
> 	void *pi = portinfo;
>
> 	port->portnum = portnum;
>@@ -445,6 +451,7 @@ static int switch_mclookup(Node * node, ib_portid_t * portid, int mlid,
>
> 	memset(map, 0, 256);
>
>+	memset(si, 0, sizeof(sw.switchinfo));
> 	if (!smp_query_via(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout,
> 			   srcport))
> 		return -1;
>@@ -460,6 +467,7 @@ static int switch_mclookup(Node * node, ib_portid_t * portid, int mlid,
> 	maxsets = (node->numports + 15) / 16;	/* round up */
>
> 	for (set = 0; set < maxsets; set++) {
>+		memset(mdb, 0, sizeof(mdb));
> 		if (!smp_query_via(mdb, portid, IB_ATTR_MULTICASTFORWTBL,
> 				   block | (set << 28), timeout, srcport))
> 			return -1;
>@@ -685,7 +693,7 @@ free_name:
>
> static int resolve_lid(ib_portid_t * portid, const void *srcport)
> {
>-	uint8_t portinfo[64];
>+	uint8_t portinfo[64] = { 0 };
> 	uint16_t lid;
>
> 	if (!smp_query_via(portinfo, portid, IB_ATTR_PORT_INFO, 0, 0, srcport))
>@@ -749,7 +757,7 @@ int main(int argc, char **argv)
> 		NULL,
> 	};
>
>-	ibdiag_process_opts(argc, argv, NULL, NULL, opts, process_opt,
>+	ibdiag_process_opts(argc, argv, NULL, "D", opts, process_opt,
> 			    usage_args, usage_examples);
>
> 	f = stdout;
>diff --git a/trunk/tools/infiniband-diags/src/ibtracert/SOURCES b/trunk/tools/infiniband-diags/src/ibtracert/SOURCES
>index 65f8c0d..63c9982 100644
>--- a/trunk/tools/infiniband-diags/src/ibtracert/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/ibtracert/SOURCES
>@@ -21,6 +21,7 @@ TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
> 	$(SDK_LIB_PATH)\ws2_32.lib		\
> 	$(TARGETPATH)\*\complib.lib		\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib
>
>diff --git a/trunk/tools/infiniband-diags/src/mcm_rereg_test/SOURCES b/trunk/tools/infiniband-diags/src/mcm_rereg_test/SOURCES
>index d026c0e..65b2fa5 100644
>--- a/trunk/tools/infiniband-diags/src/mcm_rereg_test/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/mcm_rereg_test/SOURCES
>@@ -19,6 +19,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
>
> TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib
>
>diff --git a/trunk/tools/infiniband-diags/src/perfquery.c b/trunk/tools/infiniband-diags/src/perfquery.c
>index 07a9226..0ea68aa 100644
>--- a/trunk/tools/infiniband-diags/src/perfquery.c
>+++ b/trunk/tools/infiniband-diags/src/perfquery.c
>@@ -2,6 +2,7 @@
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>  * Copyright (c) 2007 Xsigo Systems Inc.  All rights reserved.
>  * Copyright (c) 2009 HNR Consulting.  All rights reserved.
>+ * Copyright (c) 2011 Mellanox Technologies LTD.  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
>@@ -45,6 +46,7 @@
>
> #include <infiniband/umad.h>
> #include <infiniband/mad.h>
>+#include <infiniband/iba/ib_types.h>
>
> #include "ibdiag_common.h"
>
>@@ -186,7 +188,8 @@ static void aggregate_perfcounters(void)
> 	aggregate_32bit(&perf_count.xmtwait, val);
> }
>
>-static void output_aggregate_perfcounters(ib_portid_t * portid)
>+static void output_aggregate_perfcounters(ib_portid_t * portid,
>+					  uint16_t cap_mask)
> {
> 	char buf[1024];
> 	uint32_t val = ALL_PORTS;
>@@ -220,11 +223,11 @@ static void output_aggregate_perfcounters(ib_portid_t * portid)
>
> 	mad_dump_perfcounters(buf, sizeof buf, pc, sizeof pc);
>
>-	printf("# Port counters: %s port %d\n%s", portid2str(portid), ALL_PORTS,
>-	       buf);
>+	printf("# Port counters: %s port %d (CapMask: 0x%02X)\n%s",
>+	       portid2str(portid), ALL_PORTS, ntohs(cap_mask), buf);
> }
>
>-static void aggregate_perfcounters_ext(void)
>+static void aggregate_perfcounters_ext(uint16_t cap_mask)
> {
> 	uint32_t val;
> 	uint64_t val64;
>@@ -241,21 +244,27 @@ static void aggregate_perfcounters_ext(void)
> 	aggregate_64bit(&perf_count_ext.portxmitpkts, val64);
> 	mad_decode_field(pc, IB_PC_EXT_RCV_PKTS_F, &val64);
> 	aggregate_64bit(&perf_count_ext.portrcvpkts, val64);
>-	mad_decode_field(pc, IB_PC_EXT_XMT_UPKTS_F, &val64);
>-	aggregate_64bit(&perf_count_ext.portunicastxmitpkts, val64);
>-	mad_decode_field(pc, IB_PC_EXT_RCV_UPKTS_F, &val64);
>-	aggregate_64bit(&perf_count_ext.portunicastrcvpkts, val64);
>-	mad_decode_field(pc, IB_PC_EXT_XMT_MPKTS_F, &val64);
>-	aggregate_64bit(&perf_count_ext.portmulticastxmitpkits, val64);
>-	mad_decode_field(pc, IB_PC_EXT_RCV_MPKTS_F, &val64);
>-	aggregate_64bit(&perf_count_ext.portmulticastrcvpkts, val64);
>+
>+	if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED) {
>+		mad_decode_field(pc, IB_PC_EXT_XMT_UPKTS_F, &val64);
>+		aggregate_64bit(&perf_count_ext.portunicastxmitpkts, val64);
>+		mad_decode_field(pc, IB_PC_EXT_RCV_UPKTS_F, &val64);
>+		aggregate_64bit(&perf_count_ext.portunicastrcvpkts, val64);
>+		mad_decode_field(pc, IB_PC_EXT_XMT_MPKTS_F, &val64);
>+		aggregate_64bit(&perf_count_ext.portmulticastxmitpkits, val64);
>+		mad_decode_field(pc, IB_PC_EXT_RCV_MPKTS_F, &val64);
>+		aggregate_64bit(&perf_count_ext.portmulticastrcvpkts, val64);
>+	}
> }
>
>-static void output_aggregate_perfcounters_ext(ib_portid_t * portid)
>+static void output_aggregate_perfcounters_ext(ib_portid_t * portid,
>+					      uint16_t cap_mask)
> {
> 	char buf[1024];
> 	uint32_t val = ALL_PORTS;
>
>+	memset(buf, 0, 1024);
>+
> 	/* set port_select to 255 to emulate AllPortSelect */
> 	mad_encode_field(pc, IB_PC_EXT_PORT_SELECT_F, &val);
> 	mad_encode_field(pc, IB_PC_EXT_COUNTER_SELECT_F,
>@@ -267,19 +276,22 @@ static void output_aggregate_perfcounters_ext(ib_portid_t * portid)
> 	mad_encode_field(pc, IB_PC_EXT_XMT_PKTS_F,
> 			 &perf_count_ext.portxmitpkts);
> 	mad_encode_field(pc, IB_PC_EXT_RCV_PKTS_F, &perf_count_ext.portrcvpkts);
>-	mad_encode_field(pc, IB_PC_EXT_XMT_UPKTS_F,
>-			 &perf_count_ext.portunicastxmitpkts);
>-	mad_encode_field(pc, IB_PC_EXT_RCV_UPKTS_F,
>-			 &perf_count_ext.portunicastrcvpkts);
>-	mad_encode_field(pc, IB_PC_EXT_XMT_MPKTS_F,
>-			 &perf_count_ext.portmulticastxmitpkits);
>-	mad_encode_field(pc, IB_PC_EXT_RCV_MPKTS_F,
>-			 &perf_count_ext.portmulticastrcvpkts);
>+
>+	if (cap_mask & IB_PM_EXT_WIDTH_SUPPORTED) {
>+		mad_encode_field(pc, IB_PC_EXT_XMT_UPKTS_F,
>+				 &perf_count_ext.portunicastxmitpkts);
>+		mad_encode_field(pc, IB_PC_EXT_RCV_UPKTS_F,
>+				 &perf_count_ext.portunicastrcvpkts);
>+		mad_encode_field(pc, IB_PC_EXT_XMT_MPKTS_F,
>+				 &perf_count_ext.portmulticastxmitpkits);
>+		mad_encode_field(pc, IB_PC_EXT_RCV_MPKTS_F,
>+				 &perf_count_ext.portmulticastrcvpkts);
>+	}
>
> 	mad_dump_perfcounters_ext(buf, sizeof buf, pc, sizeof pc);
>
>-	printf("# Port extended counters: %s port %d\n%s", portid2str(portid),
>-	       ALL_PORTS, buf);
>+	printf("# Port extended counters: %s port %d (CapMask: 0x%02X)\n%s",
>+	       portid2str(portid), ALL_PORTS, ntohs(cap_mask), buf);
> }
>
> static void dump_perfcounters(int extended, int timeout, uint16_t cap_mask,
>@@ -288,10 +300,11 @@ static void dump_perfcounters(int extended, int timeout, uint16_t cap_mask,
> 	char buf[1024];
>
> 	if (extended != 1) {
>+		memset(pc, 0, sizeof(pc));
> 		if (!pma_query_via(pc, portid, port, timeout,
> 				   IB_GSI_PORT_COUNTERS, srcport))
> 			IBERROR("perfquery");
>-		if (!(cap_mask & 0x1000)) {
>+		if (!(cap_mask & IB_PM_PC_XMIT_WAIT_SUP)) {
> 			/* if PortCounters:PortXmitWait not supported clear this counter */
> 			VERBOSE("PortXmitWait not indicated"
> 				" so ignore this counter");
>@@ -304,19 +317,24 @@ static void dump_perfcounters(int extended, int timeout, uint16_t cap_mask,
> 		else
> 			mad_dump_fields(buf, sizeof buf, pc, sizeof pc,
> 							IB_PC_FIRST_F,
>-							(cap_mask & 0x1000)?IB_PC_LAST_F:(IB_PC_RCV_PKTS_F+1));
>+							(cap_mask &
>IB_PM_PC_XMIT_WAIT_SUP)?IB_PC_LAST_F:(IB_PC_RCV_PKTS_F+1));
>
> 	} else {
>-		if (!(cap_mask & 0x200))	/* 1.2 errata: bit 9 is extended counter support */
>+		/* 1.2 errata: bit 9 is extended counter support
>+		 * bit 10 is extended counter NoIETF
>+		 */
>+		if (!(cap_mask & IB_PM_EXT_WIDTH_SUPPORTED) &&
>+		    !(cap_mask & IB_PM_EXT_WIDTH_NOIETF_SUP))
> 			IBWARN
>-			    ("PerfMgt ClassPortInfo 0x%x extended counters not indicated\n",
>-			     cap_mask);
>+			    ("PerfMgt ClassPortInfo 0x%x; No extended counter support indicated\n",
>+			     ntohs(cap_mask));
>
>+		memset(pc, 0, sizeof(pc));
> 		if (!pma_query_via(pc, portid, port, timeout,
> 				   IB_GSI_PORT_COUNTERS_EXT, srcport))
> 			IBERROR("perfextquery");
> 		if (aggregate)
>-			aggregate_perfcounters_ext();
>+			aggregate_perfcounters_ext(cap_mask);
> 		else
> 			mad_dump_perfcounters_ext(buf, sizeof buf, pc,
> 						  sizeof pc);
>@@ -324,17 +342,20 @@ static void dump_perfcounters(int extended, int timeout, uint16_t cap_mask,
>
> 	if (!aggregate) {
> 		if (extended)
>-			printf("# Port extended counters: %s port %d\n%s",
>-			       portid2str(portid), port, buf);
>+			printf("# Port extended counters: %s port %d "
>+			       "(CapMask: 0x%02X)\n%s",
>+			       portid2str(portid), port, ntohs(cap_mask), buf);
> 		else
>-			printf("# Port counters: %s port %d\n%s",
>-			       portid2str(portid), port, buf);
>+			printf("# Port counters: %s port %d "
>+			       "(CapMask: 0x%02X)\n%s",
>+			       portid2str(portid), port, ntohs(cap_mask), buf);
> 	}
> }
>
> static void reset_counters(int extended, int timeout, int mask,
> 			   ib_portid_t * portid, int port)
> {
>+	memset(pc, 0, sizeof(pc));
> 	if (extended != 1) {
> 		if (!performance_reset_via(pc, portid, port, mask, timeout,
> 					   IB_GSI_PORT_COUNTERS, srcport))
>@@ -347,7 +368,9 @@ static void reset_counters(int extended, int timeout, int mask,
> }
>
> static int reset, reset_only, all_ports, loop_ports, port, extended, xmt_sl,
>-    rcv_sl, xmt_disc, rcv_err, smpl_ctl;
>+    rcv_sl, xmt_disc, rcv_err, smpl_ctl, oprcvcounters, flowctlcounters,
>+    vloppackets, vlopdata, vlxmitflowctlerrors, vlxmitcounters, swportvlcong,
>+    rcvcc, slrcvfecn, slrcvbecn, xmitcc, vlxmittimecc;
>
> static void common_func(ib_portid_t * portid, int port_num, int mask,
> 			unsigned query, unsigned reset,
>@@ -357,6 +380,7 @@ static void common_func(ib_portid_t * portid, int port_num, int mask,
> 	char buf[1024];
>
> 	if (query) {
>+		memset(pc, 0, sizeof(pc));
> 		if (!pma_query_via(pc, portid, port_num, ibd_timeout, attr,
> 				   srcport))
> 			IBERROR("cannot query %s", name);
>@@ -367,6 +391,7 @@ static void common_func(ib_portid_t * portid, int port_num, int mask,
> 		       portid2str(portid), port_num, buf);
> 	}
>
>+	memset(pc, 0, sizeof(pc));
> 	if (reset && !performance_reset_via(pc, portid, port, mask, ibd_timeout,
> 					    attr, srcport))
> 		IBERROR("cannot reset %s", name);
>@@ -400,10 +425,95 @@ static void rcv_err_query(ib_portid_t * portid, int port, int mask)
> 		    mad_dump_perfcounters_rcv_err);
> }
>
>+static void oprcvcounters_query(ib_portid_t * portid, int port, int mask)
>+{
>+	common_func(portid, port, mask, !reset_only, (reset_only || reset),
>+		    "PortOpRcvCounters", IB_GSI_PORT_PORT_OP_RCV_COUNTERS,
>+		    mad_dump_perfcounters_port_op_rcv_counters);
>+}
>+
>+static void flowctlcounters_query(ib_portid_t * portid, int port, int mask)
>+{
>+	common_func(portid, port, mask, !reset_only, (reset_only || reset),
>+		    "PortFlowCtlCounters", IB_GSI_PORT_PORT_FLOW_CTL_COUNTERS,
>+		    mad_dump_perfcounters_port_flow_ctl_counters);
>+}
>+
>+static void vloppackets_query(ib_portid_t * portid, int port, int mask)
>+{
>+	common_func(portid, port, mask, !reset_only, (reset_only || reset),
>+		    "PortVLOpPackets", IB_GSI_PORT_PORT_VL_OP_PACKETS,
>+		    mad_dump_perfcounters_port_vl_op_packet);
>+}
>+
>+static void vlopdata_query(ib_portid_t * portid, int port, int mask)
>+{
>+	common_func(portid, port, mask, !reset_only, (reset_only || reset),
>+		    "PortVLOpData", IB_GSI_PORT_PORT_VL_OP_DATA,
>+		    mad_dump_perfcounters_port_vl_op_data);
>+}
>+
>+static void vlxmitflowctlerrors_query(ib_portid_t * portid, int port, int mask)
>+{
>+	common_func(portid, port, mask, !reset_only, (reset_only || reset),
>+		    "PortVLXmitFlowCtlUpdateErrors", IB_GSI_PORT_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS,
>+		    mad_dump_perfcounters_port_vl_xmit_flow_ctl_update_errors);
>+}
>+
>+static void vlxmitcounters_query(ib_portid_t * portid, int port, int mask)
>+{
>+	common_func(portid, port, mask, !reset_only, (reset_only || reset),
>+		    "PortVLXmitWaitCounters", IB_GSI_PORT_PORT_VL_XMIT_WAIT_COUNTERS,
>+		    mad_dump_perfcounters_port_vl_xmit_wait_counters);
>+}
>+
>+static void swportvlcong_query(ib_portid_t * portid, int port, int mask)
>+{
>+	common_func(portid, port, mask, !reset_only, (reset_only || reset),
>+		    "SwPortVLCongestion", IB_GSI_SW_PORT_VL_CONGESTION,
>+		    mad_dump_perfcounters_sw_port_vl_congestion);
>+}
>+
>+static void rcvcc_query(ib_portid_t * portid, int port, int mask)
>+{
>+	common_func(portid, port, mask, !reset_only, (reset_only || reset),
>+		    "PortRcvConCtrl", IB_GSI_PORT_RCV_CON_CTRL,
>+		    mad_dump_perfcounters_rcv_con_ctrl);
>+}
>+
>+static void slrcvfecn_query(ib_portid_t * portid, int port, int mask)
>+{
>+	common_func(portid, port, mask, !reset_only, (reset_only || reset),
>+		    "PortSLRcvFECN", IB_GSI_PORT_SL_RCV_FECN,
>+		    mad_dump_perfcounters_sl_rcv_fecn);
>+}
>+
>+static void slrcvbecn_query(ib_portid_t * portid, int port, int mask)
>+{
>+	common_func(portid, port, mask, !reset_only, (reset_only || reset),
>+		    "PortSLRcvBECN", IB_GSI_PORT_SL_RCV_BECN,
>+		    mad_dump_perfcounters_sl_rcv_becn);
>+}
>+
>+static void xmitcc_query(ib_portid_t * portid, int port, int mask)
>+{
>+	common_func(portid, port, mask, !reset_only, (reset_only || reset),
>+		    "PortXmitConCtrl", IB_GSI_PORT_XMIT_CON_CTRL,
>+		    mad_dump_perfcounters_xmit_con_ctrl);
>+}
>+
>+static void vlxmittimecc_query(ib_portid_t * portid, int port, int mask)
>+{
>+	common_func(portid, port, mask, !reset_only, (reset_only || reset),
>+		    "PortVLXmitTimeCong", IB_GSI_PORT_VL_XMIT_TIME_CONG,
>+		    mad_dump_perfcounters_vl_xmit_time_cong);
>+}
>+
> void dump_portsamples_control(ib_portid_t * portid, int port)
> {
> 	char buf[1024];
>
>+	memset(pc, 0, sizeof(pc));
> 	if (!pma_query_via(pc, portid, port, ibd_timeout,
> 			   IB_GSI_PORT_SAMPLES_CONTROL, srcport))
> 		IBERROR("sampctlquery");
>@@ -434,6 +544,42 @@ static int process_opt(void *context, int ch, char *optarg)
> 	case 'c':
> 		smpl_ctl = 1;
> 		break;
>+	case 1:
>+		oprcvcounters = 1;
>+		break;
>+	case 2:
>+		flowctlcounters = 1;
>+		break;
>+	case 3:
>+		vloppackets = 1;
>+		break;
>+	case 4:
>+		vlopdata = 1;
>+		break;
>+	case 5:
>+		vlxmitflowctlerrors = 1;
>+		break;
>+	case 6:
>+		vlxmitcounters = 1;
>+		break;
>+	case 7:
>+		swportvlcong = 1;
>+		break;
>+	case 8:
>+		rcvcc = 1;
>+		break;
>+	case 9:
>+		slrcvfecn = 1;
>+		break;
>+	case 10:
>+		slrcvbecn = 1;
>+		break;
>+	case 11:
>+		xmitcc = 1;
>+		break;
>+	case 12:
>+		vlxmittimecc = 1;
>+		break;
> 	case 'a':
> 		all_ports++;
> 		port = ALL_PORTS;
>@@ -463,7 +609,7 @@ int main(int argc, char **argv)
> 	uint16_t cap_mask;
> 	int all_ports_loop = 0;
> 	int node_type, num_ports = 0;
>-	uint8_t data[IB_SMP_DATA_SIZE];
>+	uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
> 	int start_port = 1;
> 	int enhancedport0;
> 	int i;
>@@ -474,6 +620,18 @@ int main(int argc, char **argv)
> 		{"rcvsl", 'S', 0, NULL, "show Rcv SL port counters"},
> 		{"xmtdisc", 'D', 0, NULL, "show Xmt Discard Details"},
> 		{"rcverr", 'E', 0, NULL, "show Rcv Error Details"},
>+		{"oprcvcounters", 1, 0, NULL, "show Rcv Counters per Op code"},
>+		{"flowctlcounters", 2, 0, NULL, "show flow control counters"},
>+		{"vloppackets", 3, 0, NULL, "show packets received per Op code per VL"},
>+		{"vlopdata", 4, 0, NULL, "show data received per Op code per VL"},
>+		{"vlxmitflowctlerrors", 5, 0, NULL, "show flow control update errors per VL"},
>+		{"vlxmitcounters", 6, 0, NULL, "show ticks waiting to transmit counters per VL"},
>+		{"swportvlcong", 7, 0, NULL, "show sw port VL congestion"},
>+		{"rcvcc", 8, 0, NULL, "show Rcv congestion control counters"},
>+		{"slrcvfecn", 9, 0, NULL, "show SL Rcv FECN counters"},
>+		{"slrcvbecn", 10, 0, NULL, "show SL Rcv BECN counters"},
>+		{"xmitcc", 11, 0, NULL, "show Xmit congestion control counters"},
>+		{"vlxmittimecc", 12, 0, NULL, "show VL Xmit Time congestion control counters"},
> 		{"smplctl", 'c', 0, NULL, "show samples control"},
> 		{"all_ports", 'a', 0, NULL, "show aggregated counters"},
> 		{"loop_ports", 'l', 0, NULL, "iterate through each port"},
>@@ -522,13 +680,13 @@ int main(int argc, char **argv)
> 	}
>
> 	/* PerfMgt ClassPortInfo is a required attribute */
>+	memset(pc, 0, sizeof(pc));
> 	if (!pma_query_via(pc, &portid, port, ibd_timeout, CLASS_PORT_INFO,
> 			   srcport))
> 		IBERROR("classportinfo query");
> 	/* ClassPortInfo should be supported as part of libibmad */
> 	memcpy(&cap_mask, pc + 2, sizeof(cap_mask));	/* CapabilityMask */
>-	cap_mask = ntohs(cap_mask);
>-	if (!(cap_mask & 0x100)) {	/* bit 8 is AllPortSelect */
>+	if (!(cap_mask & IB_PM_ALL_PORT_SELECT)) {	/* bit 8 is AllPortSelect */
> 		if (!all_ports && port == ALL_PORTS)
> 			IBERROR("AllPortSelect not supported");
> 		if (all_ports)
>@@ -555,11 +713,72 @@ int main(int argc, char **argv)
> 		goto done;
> 	}
>
>+	if (oprcvcounters) {
>+		oprcvcounters_query(&portid, port, mask);
>+		goto done;
>+	}
>+
>+	if (flowctlcounters) {
>+		flowctlcounters_query(&portid, port, mask);
>+		goto done;
>+	}
>+
>+	if (vloppackets) {
>+		vloppackets_query(&portid, port, mask);
>+		goto done;
>+	}
>+
>+	if (vlopdata) {
>+		vlopdata_query(&portid, port, mask);
>+		goto done;
>+	}
>+
>+	if (vlxmitflowctlerrors) {
>+		vlxmitflowctlerrors_query(&portid, port, mask);
>+		goto done;
>+	}
>+
>+	if (vlxmitcounters) {
>+		vlxmitcounters_query(&portid, port, mask);
>+		goto done;
>+	}
>+
>+	if (swportvlcong) {
>+		swportvlcong_query(&portid, port, mask);
>+		goto done;
>+	}
>+
>+	if (rcvcc) {
>+		rcvcc_query(&portid, port, mask);
>+		goto done;
>+	}
>+
>+	if (slrcvfecn) {
>+		slrcvfecn_query(&portid, port, mask);
>+		goto done;
>+	}
>+
>+	if (slrcvbecn) {
>+		slrcvbecn_query(&portid, port, mask);
>+		goto done;
>+	}
>+
>+	if (xmitcc) {
>+		xmitcc_query(&portid, port, mask);
>+		goto done;
>+	}
>+
>+	if (vlxmittimecc) {
>+		vlxmittimecc_query(&portid, port, mask);
>+		goto done;
>+	}
>+
> 	if (smpl_ctl) {
> 		dump_portsamples_control(&portid, port);
> 		goto done;
> 	}
>
>+
> 	if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) {
> 		if (smp_query_via(data, &portid, IB_ATTR_NODE_INFO, 0, 0,
> 				  srcport) < 0)
>@@ -593,9 +812,11 @@ int main(int argc, char **argv)
> 						       && !loop_ports));
> 		if (all_ports_loop && !loop_ports) {
> 			if (extended != 1)
>-				output_aggregate_perfcounters(&portid);
>+				output_aggregate_perfcounters(&portid,
>+							      cap_mask);
> 			else
>-				output_aggregate_perfcounters_ext(&portid);
>+				output_aggregate_perfcounters_ext(&portid,
>+								  cap_mask);
> 		}
> 	} else
> 		dump_perfcounters(extended, ibd_timeout, cap_mask, &portid,
>@@ -605,7 +826,7 @@ int main(int argc, char **argv)
> 		goto done;
>
> do_reset:
>-	if (argc <= 2 && !extended && (cap_mask & 0x1000))
>+	if (argc <= 2 && !extended && (cap_mask & IB_PM_PC_XMIT_WAIT_SUP))
> 		mask |= (1 << 16);	/* reset portxmitwait */
>
> 	if (all_ports_loop || (loop_ports && (all_ports || port == ALL_PORTS))) {
>diff --git a/trunk/tools/infiniband-diags/src/perfquery/SOURCES b/trunk/tools/infiniband-diags/src/perfquery/SOURCES
>index 7e0079b..c71dfac 100644
>--- a/trunk/tools/infiniband-diags/src/perfquery/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/perfquery/SOURCES
>@@ -20,6 +20,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
> TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
> 	$(SDK_LIB_PATH)\ws2_32.lib		\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib
>
>diff --git a/trunk/tools/infiniband-diags/src/saquery.c b/trunk/tools/infiniband-diags/src/saquery.c
>index 5e9a5ad..f82772f 100644
>--- a/trunk/tools/infiniband-diags/src/saquery.c
>+++ b/trunk/tools/infiniband-diags/src/saquery.c
>@@ -1,7 +1,7 @@
> /*
>  * Copyright (c) 2006,2007 The Regents of the University of California.
>  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
>- * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
>+ * Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved.
>  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
>  * Copyright (c) 2009 HNR Consulting. All rights reserved.
>  *
>@@ -48,7 +48,6 @@
> #include <ctype.h>
> #include <string.h>
> #include <errno.h>
>-#include <assert.h>
>
> #define _GNU_SOURCE
> #include <getopt.h>
>@@ -60,19 +59,6 @@
>
> #include "ibdiag_common.h"
>
>-struct bind_handle {
>-	int fd, agent;
>-	ib_portid_t dport;
>-};
>-
>-struct query_res {
>-	int status;
>-	unsigned result_cnt;
>-	void *p_result_madw;
>-};
>-
>-typedef struct bind_handle *bind_handle_t;
>-
> struct query_params {
> 	ib_gid_t sgid, dgid, gid, mgid;
> 	uint16_t slid, dlid, mlid;
>@@ -106,7 +92,6 @@ static uint64_t smkey = 1;
>  */
> #define MAX_PORTS (8)
> #define DEFAULT_SA_TIMEOUT_MS (1000)
>-static struct query_res result;
>
> enum {
> 	ALL,
>@@ -124,119 +109,6 @@ int requested_lid_flag = 0;
> uint64_t requested_guid = 0;
> int requested_guid_flag = 0;
>
>-#define SA_ERR_UNKNOWN IB_SA_MAD_STATUS_PRIO_SUGGESTED
>-
>-const char *ib_sa_error_str[] = {
>-	"SA_NO_ERROR",
>-	"SA_ERR_NO_RESOURCES",
>-	"SA_ERR_REQ_INVALID",
>-	"SA_ERR_NO_RECORDS",
>-	"SA_ERR_TOO_MANY_RECORDS",
>-	"SA_ERR_REQ_INVALID_GID",
>-	"SA_ERR_REQ_INSUFFICIENT_COMPONENTS",
>-	"SA_ERR_REQ_DENIED",
>-	"SA_ERR_STATUS_PRIO_SUGGESTED",
>-	"SA_ERR_UNKNOWN"
>-};
>-
>-static inline const char *ib_sa_err_str(IN uint8_t status)
>-{
>-	if (status > SA_ERR_UNKNOWN)
>-		status = SA_ERR_UNKNOWN;
>-	return (ib_sa_error_str[status]);
>-}
>-
>-static inline void report_err(int status)
>-{
>-	int st = status & 0xff;
>-	char sm_err_str[64] = { 0 };
>-	char sa_err_str[64] = { 0 };
>-
>-	if (st)
>-		sprintf(sm_err_str, " SM(%s)", ib_get_err_str(st));
>-
>-	st = status >> 8;
>-	if (st)
>-		sprintf(sa_err_str, " SA(%s)", ib_sa_err_str((uint8_t) st));
>-
>-	fprintf(stderr, "ERROR: Query result returned 0x%04x, %s%s\n",
>-		status, sm_err_str, sa_err_str);
>-}
>-
>-static int sa_query(struct bind_handle *h, uint8_t method,
>-		    uint16_t attr, uint32_t mod, uint64_t comp_mask,
>-		    uint64_t sm_key, void *data)
>-{
>-	ib_rpc_t rpc;
>-	void *umad, *mad;
>-	int ret, offset, len = 256;
>-
>-	memset(&rpc, 0, sizeof(rpc));
>-	rpc.mgtclass = IB_SA_CLASS;
>-	rpc.method = method;
>-	rpc.attr.id = attr;
>-	rpc.attr.mod = mod;
>-	rpc.mask = comp_mask;
>-	rpc.datasz = IB_SA_DATA_SIZE;
>-	rpc.dataoffs = IB_SA_DATA_OFFS;
>-
>-	umad = calloc(1, len + umad_size());
>-	if (!umad)
>-		IBPANIC("cannot alloc mem for umad: %s\n", strerror(errno));
>-
>-	mad_build_pkt(umad, &rpc, &h->dport, NULL, data);
>-
>-	mad_set_field64(umad_get_mad(umad), 0, IB_SA_MKEY_F, sm_key);
>-
>-	if (ibdebug > 1)
>-		xdump(stdout, "SA Request:\n", umad_get_mad(umad), len);
>-
>-	ret = umad_send(h->fd, h->agent, umad, len, ibd_timeout, 0);
>-	if (ret < 0)
>-		IBPANIC("umad_send failed: attr %u: %s\n",
>-			attr, strerror(errno));
>-
>-recv_mad:
>-	ret = umad_recv(h->fd, umad, &len, ibd_timeout);
>-	if (ret < 0) {
>-		if (errno == ENOSPC) {
>-			umad = realloc(umad, umad_size() + len);
>-			goto recv_mad;
>-		}
>-		IBPANIC("umad_recv failed: attr 0x%x: %s\n", attr,
>-			strerror(errno));
>-	}
>-
>-	if ((ret = umad_status(umad)))
>-		return ret;
>-
>-	mad = umad_get_mad(umad);
>-
>-	if (ibdebug > 1)
>-		xdump(stdout, "SA Response:\n", mad, len);
>-
>-	method = (uint8_t) mad_get_field(mad, 0, IB_MAD_METHOD_F);
>-	offset = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);
>-	result.status = mad_get_field(mad, 0, IB_MAD_STATUS_F);
>-	result.p_result_madw = mad;
>-	if (result.status)
>-		result.result_cnt = 0;
>-	else if (method != IB_MAD_METHOD_GET_TABLE)
>-		result.result_cnt = 1;
>-	else if (!offset)
>-		result.result_cnt = 0;
>-	else
>-		result.result_cnt = (len - IB_SA_DATA_OFFS) / (offset << 3);
>-
>-	return 0;
>-}
>-
>-static void *get_query_rec(void *mad, unsigned i)
>-{
>-	int offset = mad_get_field(mad, 0, IB_SA_ATTROFFS_F);
>-	return (uint8_t *) mad + IB_SA_DATA_OFFS + i * (offset << 3);
>-}
>-
> static unsigned valid_gid(ib_gid_t * gid)
> {
> 	ib_gid_t zero_gid;
>@@ -418,7 +290,7 @@ static void dump_portinfo_record(void *data)
>
> static void dump_one_portinfo_record(void *data)
> {
>-	char buf[2048], buf2[4096];
>+	char buf[2300], buf2[4096];
> 	ib_portinfo_record_t *pir = data;
> 	ib_port_info_t *pi = &pir->port_info;
>
>@@ -428,9 +300,9 @@ static void dump_one_portinfo_record(void *data)
> 	       "\tRID:\n"
> 	       "\t\tEndPortLid..............%u\n"
> 	       "\t\tPortNum.................%u\n"
>-	       "\t\tReserved................0x%x\n"
>+	       "\t\tOptions.................0x%x\n"
> 	       "\tPortInfo dump:\n\t\t%s",
>-	       cl_ntoh16(pir->lid), pir->port_num, pir->resv, buf2);
>+	       cl_ntoh16(pir->lid), pir->port_num, pir->options, buf2);
> }
>
> static void dump_one_mcmember_record(void *data)
>@@ -461,7 +333,7 @@ static void dump_one_mcmember_record(void *data)
> 	       inet_ntop(AF_INET6, mr->port_gid.raw, gid, sizeof(gid)),
> 	       cl_ntoh32(mr->qkey), cl_ntoh16(mr->mlid), mr->mtu, mr->tclass,
> 	       cl_ntoh16(mr->pkey), mr->rate, mr->pkt_life, sl,
>-	       cl_ntoh32(flow), hop, scope, join, mr->proxy_join);
>+	       flow, hop, scope, join, mr->proxy_join);
> }
>
> static void dump_multicast_group_record(void *data)
>@@ -482,11 +354,11 @@ static void dump_multicast_group_record(void *data)
> 	       p_mcmr->mtu, cl_ntoh16(p_mcmr->pkey), p_mcmr->rate, sl);
> }
>
>-static void dump_multicast_member_record(void *data)
>+static void dump_multicast_member_record(ib_member_rec_t *p_mcmr,
>+					 struct sa_query_result *nr_result)
> {
> 	char gid_str[INET6_ADDRSTRLEN];
> 	char gid_str2[INET6_ADDRSTRLEN];
>-	ib_member_rec_t *p_mcmr = data;
> 	uint16_t mlid = cl_ntoh16(p_mcmr->mlid);
> 	unsigned i = 0;
> 	char *node_name = "<unknown>";
>@@ -495,8 +367,8 @@ static void dump_multicast_member_record(void *data)
> 	 * this port gid interface id.
> 	 * This gives us a node name to print, if available.
> 	 */
>-	for (i = 0; i < result.result_cnt; i++) {
>-		ib_node_record_t *nr = get_query_rec(result.p_result_madw, i);
>+	for (i = 0; i < nr_result->result_cnt; i++) {
>+		ib_node_record_t *nr = sa_get_query_rec(nr_result->p_result_madw, i);
> 		if (nr->node_info.port_guid ==
> 		    p_mcmr->port_gid.unicast.interface_id) {
> 			node_name =
>@@ -781,6 +653,31 @@ static void dump_one_lft_record(void *data)
> 	printf("\n");
> }
>
>+static void dump_one_guidinfo_record(void *data)
>+{
>+	ib_guidinfo_record_t *gir = data;
>+	printf("GUIDInfo Record dump:\n"
>+	       "\t\tLID........................%u\n"
>+	       "\t\tBlock......................%u\n"
>+	       "\t\tGUID 0.....................0x%016" PRIx64 "\n"
>+	       "\t\tGUID 1.....................0x%016" PRIx64 "\n"
>+	       "\t\tGUID 2.....................0x%016" PRIx64 "\n"
>+	       "\t\tGUID 3.....................0x%016" PRIx64 "\n"
>+	       "\t\tGUID 4.....................0x%016" PRIx64 "\n"
>+	       "\t\tGUID 5.....................0x%016" PRIx64 "\n"
>+	       "\t\tGUID 6.....................0x%016" PRIx64 "\n"
>+	       "\t\tGUID 7.....................0x%016" PRIx64 "\n",
>+	       cl_ntoh16(gir->lid), gir->block_num,
>+	       cl_ntoh64(gir->guid_info.guid[0]),
>+	       cl_ntoh64(gir->guid_info.guid[1]),
>+	       cl_ntoh64(gir->guid_info.guid[2]),
>+	       cl_ntoh64(gir->guid_info.guid[3]),
>+	       cl_ntoh64(gir->guid_info.guid[4]),
>+	       cl_ntoh64(gir->guid_info.guid[5]),
>+	       cl_ntoh64(gir->guid_info.guid[6]),
>+	       cl_ntoh64(gir->guid_info.guid[7]));
>+}
>+
> static void dump_one_mft_record(void *data)
> {
> 	ib_mft_record_t *mftr = data;
>@@ -788,53 +685,48 @@ static void dump_one_mft_record(void *data)
> 	unsigned block = cl_ntoh16(mftr->position_block_num) &
> 	    IB_MCAST_BLOCK_ID_MASK_HO;
> 	int i;
>+	unsigned offset;
>+
> 	printf("MFT Record dump:\n"
> 	       "\t\tLID........................%u\n"
> 	       "\t\tPosition...................%u\n"
> 	       "\t\tBlock......................%u\n"
> 	       "\t\tMFT:\n\t\tMLID\tPort Mask\n",
> 	       cl_ntoh16(mftr->lid), position, block);
>+	offset = IB_LID_MCAST_START_HO + block * 32;
> 	for (i = 0; i < IB_MCAST_BLOCK_SIZE; i++)
>-		printf("\t\t0x%x\t0x%x\n",
>-		       IB_LID_MCAST_START_HO + block * 64 + i,
>-		       cl_ntoh16(mftr->mft[i]));
>+		printf("\t\t0x%04x\t0x%04x\n",
>+		       offset + i, cl_ntoh16(mftr->mft[i]));
> 	printf("\n");
> }
>
>-static void dump_results(struct query_res *r, void (*dump_func) (void *))
>+static void dump_results(struct sa_query_result *r, void (*dump_func) (void *))
> {
> 	unsigned i;
> 	for (i = 0; i < r->result_cnt; i++) {
>-		void *data = get_query_rec(r->p_result_madw, i);
>+		void *data = sa_get_query_rec(r->p_result_madw, i);
> 		dump_func(data);
> 	}
> }
>
>-static void return_mad(void)
>-{
>-	if (result.p_result_madw) {
>-		free((uint8_t *) result.p_result_madw - umad_size());
>-		result.p_result_madw = NULL;
>-	}
>-}
>-
> /**
>  * Get any record(s)
>  */
> static int get_any_records(bind_handle_t h,
> 			   uint16_t attr_id, uint32_t attr_mod,
>-			   ib_net64_t comp_mask, void *attr, uint64_t sm_key)
>+			   ib_net64_t comp_mask, void *attr, uint64_t sm_key,
>+			   struct sa_query_result *result)
> {
> 	int ret = sa_query(h, IB_MAD_METHOD_GET_TABLE, attr_id, attr_mod,
>-			   cl_ntoh64(comp_mask), sm_key, attr);
>+			   cl_ntoh64(comp_mask), sm_key, attr, result);
> 	if (ret) {
> 		fprintf(stderr, "Query SA failed: %s\n", ib_get_err_str(ret));
> 		return ret;
> 	}
>
>-	if (result.status != IB_SUCCESS) {
>-		report_err(result.status);
>-		return result.status;
>+	if (result->status != IB_SA_MAD_STATUS_SUCCESS) {
>+		sa_report_err(result->status);
>+		return EIO;
> 	}
>
> 	return ret;
>@@ -845,33 +737,37 @@ static int get_and_dump_any_records(bind_handle_t h, uint16_t attr_id,
> 				    void *attr, uint64_t sm_key,
> 				    void (*dump_func) (void *))
> {
>+	struct sa_query_result result;
> 	int ret = get_any_records(h, attr_id, attr_mod, comp_mask, attr,
>-				  sm_key);
>+				  sm_key, &result);
> 	if (ret)
> 		return ret;
>
> 	dump_results(&result, dump_func);
>-
>+	sa_free_result_mad(&result);
> 	return 0;
> }
>
> /**
>  * Get all the records available for requested query type.
>  */
>-static int get_all_records(bind_handle_t h, uint16_t attr_id, int trusted)
>+static int get_all_records(bind_handle_t h, uint16_t attr_id, int trusted,
>+			   struct sa_query_result *result)
> {
>-	return get_any_records(h, attr_id, 0, 0, NULL, trusted ? smkey : 0);
>+	return get_any_records(h, attr_id, 0, 0, NULL, trusted ? smkey : 0,
>+			       result);
> }
>
> static int get_and_dump_all_records(bind_handle_t h, uint16_t attr_id,
> 				    int trusted, void (*dump_func) (void *))
> {
>-	int ret = get_all_records(h, attr_id, 0);
>+	struct sa_query_result result;
>+	int ret = get_all_records(h, attr_id, 0, &result);
> 	if (ret)
> 		return ret;
>
> 	dump_results(&result, dump_func);
>-	return_mad();
>+	sa_free_result_mad(&result);
> 	return ret;
> }
>
>@@ -884,24 +780,27 @@ static int get_lid_from_name(bind_handle_t h, const char *name, uint16_t * lid)
> 	ib_node_info_t *p_ni = NULL;
> 	unsigned i;
> 	int ret;
>+	struct sa_query_result result;
>
>-	ret = get_all_records(h, IB_SA_ATTR_NODERECORD, 0);
>+	ret = get_all_records(h, IB_SA_ATTR_NODERECORD, 0, &result);
> 	if (ret)
> 		return ret;
>
>+	ret = IB_NOT_FOUND;
> 	for (i = 0; i < result.result_cnt; i++) {
>-		node_record = get_query_rec(result.p_result_madw, i);
>+		node_record = sa_get_query_rec(result.p_result_madw, i);
> 		p_ni = &(node_record->node_info);
> 		if (name
> 		    && strncmp(name, (char *)node_record->node_desc.description,
> 			       sizeof(node_record->node_desc.description)) ==
> 		    0) {
> 			*lid = cl_ntoh16(node_record->lid);
>+			ret = IB_SUCCESS;
> 			break;
> 		}
> 	}
>-	return_mad();
>-	return 0;
>+	sa_free_result_mad(&result);
>+	return ret;
> }
>
> static uint16_t get_lid(bind_handle_t h, const char *name)
>@@ -910,12 +809,22 @@ static uint16_t get_lid(bind_handle_t h, const char *name)
>
> 	if (!name)
> 		return 0;
>-	if (isalpha(name[0]))
>-		assert(get_lid_from_name(h, name, &rc_lid) == IB_SUCCESS);
>-	else
>-		rc_lid = (uint16_t) atoi(name);
>-	if (rc_lid == 0)
>-		fprintf(stderr, "Failed to find lid for \"%s\"\n", name);
>+	if (isalpha(name[0])) {
>+		if (get_lid_from_name(h, name, &rc_lid) != IB_SUCCESS) {
>+			fprintf(stderr, "Failed to find lid for \"%s\"\n", name);
>+			exit(EINVAL);
>+		}
>+	} else {
>+		long val;
>+		errno = 0;
>+		val = strtol(name, NULL, 0);
>+		if (errno != 0 || val <= 0 || val > UINT16_MAX) {
>+			fprintf(stderr, "Invalid lid specified: \"%s\"\n", name);
>+			exit(EINVAL);
>+		}
>+		rc_lid = (uint16_t)val;
>+	}
>+
> 	return rc_lid;
> }
>
>@@ -959,30 +868,11 @@ static int parse_lid_and_ports(bind_handle_t h,
> 	return 0;
> }
>
>-#define cl_hton8(x) (x)
>-#define CHECK_AND_SET_VAL(val, size, comp_with, target, name, mask) \
>-	if ((int##size##_t) val != (int##size##_t) comp_with) { \
>-		target = cl_hton##size((uint##size##_t) val); \
>-		comp_mask |= IB_##name##_COMPMASK_##mask; \
>-	}
>-
>-#define CHECK_AND_SET_GID(val, target, name, mask) \
>-	if (valid_gid(&(val))) { \
>-		memcpy(&(target), &(val), sizeof(val)); \
>-		comp_mask |= IB_##name##_COMPMASK_##mask; \
>-	}
>-
>-#define CHECK_AND_SET_VAL_AND_SEL(val, target, name, mask, sel) \
>-	if (val) { \
>-		target = val; \
>-		comp_mask |= IB_##name##_COMPMASK_##mask##sel; \
>-		comp_mask |= IB_##name##_COMPMASK_##mask; \
>-	}
>-
> /*
>  * Get the portinfo records available with IsSM or IsSMdisabled CapabilityMask bit on.
>  */
>-static int get_issm_records(bind_handle_t h, ib_net32_t capability_mask)
>+static int get_issm_records(bind_handle_t h, ib_net32_t capability_mask,
>+			    struct sa_query_result *result)
> {
> 	ib_portinfo_record_t attr;
>
>@@ -990,15 +880,16 @@ static int get_issm_records(bind_handle_t h, ib_net32_t capability_mask)
> 	attr.port_info.capability_mask = capability_mask;
>
> 	return get_any_records(h, IB_SA_ATTR_PORTINFORECORD, 1 << 31,
>-			       IB_PIR_COMPMASK_CAPMASK, &attr, 0);
>+			       IB_PIR_COMPMASK_CAPMASK, &attr, 0, result);
> }
>
> static int print_node_records(bind_handle_t h)
> {
> 	unsigned i;
> 	int ret;
>+	struct sa_query_result result;
>
>-	ret = get_all_records(h, IB_SA_ATTR_NODERECORD, 0);
>+	ret = get_all_records(h, IB_SA_ATTR_NODERECORD, 0, &result);
> 	if (ret)
> 		return ret;
>
>@@ -1008,7 +899,7 @@ static int print_node_records(bind_handle_t h)
> 	}
> 	for (i = 0; i < result.result_cnt; i++) {
> 		ib_node_record_t *node_record;
>-		node_record = get_query_rec(result.p_result_madw, i);
>+		node_record = sa_get_query_rec(result.p_result_madw, i);
> 		if (node_print_desc == ALL_DESC) {
> 			print_node_desc(node_record);
> 		} else if (node_print_desc == NAME_OF_LID) {
>@@ -1027,31 +918,34 @@ static int print_node_records(bind_handle_t h)
> 					    node_desc.description)) == 0)) {
> 				print_node_record(node_record);
> 				if (node_print_desc == UNIQUE_LID_ONLY) {
>-					return_mad();
>+					sa_free_result_mad(&result);
> 					exit(0);
> 				}
> 			}
> 		}
> 	}
>-	return_mad();
>+	sa_free_result_mad(&result);
> 	return ret;
> }
>
> static int get_print_class_port_info(bind_handle_t h)
> {
>+	struct sa_query_result result;
> 	int ret = sa_query(h, IB_MAD_METHOD_GET, CLASS_PORT_INFO, 0, 0,
>-			   0, NULL);
>+			   0, NULL, &result);
> 	if (ret) {
> 		fprintf(stderr, "ERROR: Query SA failed: %s\n",
> 			ib_get_err_str(ret));
> 		return ret;
> 	}
>-	if (result.status != IB_SUCCESS) {
>-		report_err(result.status);
>-		return (result.status);
>+	if (result.status != IB_SA_MAD_STATUS_SUCCESS) {
>+		sa_report_err(result.status);
>+		ret = EIO;
>+		goto Exit;
> 	}
> 	dump_results(&result, dump_class_port_info);
>-	return_mad();
>+Exit:
>+	sa_free_result_mad(&result);
> 	return ret;
> }
>
>@@ -1089,52 +983,58 @@ static int query_path_records(const struct query_cmd *q, bind_handle_t h,
> 					&pr, 0, dump_path_record);
> }
>
>-static ib_api_status_t print_issm_records(bind_handle_t h)
>+static int print_issm_records(bind_handle_t h)
> {
>-	ib_api_status_t status;
>+	struct sa_query_result result;
>+	int ret = 0;
>
> 	/* First, get IsSM records */
>-	status = get_issm_records(h, IB_PORT_CAP_IS_SM);
>-	if (status != IB_SUCCESS)
>-		return (status);
>+	ret = get_issm_records(h, IB_PORT_CAP_IS_SM, &result);
>+	if (ret != 0)
>+		return (ret);
>
> 	printf("IsSM ports\n");
> 	dump_results(&result, dump_portinfo_record);
>-	return_mad();
>+	sa_free_result_mad(&result);
>
> 	/* Now, get IsSMdisabled records */
>-	status = get_issm_records(h, IB_PORT_CAP_SM_DISAB);
>-	if (status != IB_SUCCESS)
>-		return (status);
>+	ret = get_issm_records(h, IB_PORT_CAP_SM_DISAB, &result);
>+	if (ret != 0)
>+		return (ret);
>
> 	printf("\nIsSMdisabled ports\n");
> 	dump_results(&result, dump_portinfo_record);
>-	return_mad();
>+	sa_free_result_mad(&result);
>
>-	return (status);
>+	return (ret);
> }
>
> static int print_multicast_member_records(bind_handle_t h)
> {
>-	struct query_res mc_group_result;
>+	struct sa_query_result mc_group_result;
>+	struct sa_query_result nr_result;
> 	int ret;
>+	unsigned i;
>
>-	ret = get_all_records(h, IB_SA_ATTR_MCRECORD, 1);
>+	ret = get_all_records(h, IB_SA_ATTR_MCRECORD, 1, &mc_group_result);
> 	if (ret)
> 		return ret;
>
>-	mc_group_result = result;
>-
>-	ret = get_all_records(h, IB_SA_ATTR_NODERECORD, 0);
>+	ret = get_all_records(h, IB_SA_ATTR_NODERECORD, 0, &nr_result);
> 	if (ret)
> 		goto return_mc;
>
>-	dump_results(&mc_group_result, dump_multicast_member_record);
>-	return_mad();
>+	for (i = 0; i < mc_group_result.result_cnt; i++) {
>+		ib_member_rec_t *rec = (ib_member_rec_t *)
>+				sa_get_query_rec(mc_group_result.p_result_madw,
>+					      i);
>+		dump_multicast_member_record(rec, &nr_result);
>+	}
>+
>+	sa_free_result_mad(&nr_result);
>
> return_mc:
>-	if (mc_group_result.p_result_madw)
>-		free((uint8_t *) mc_group_result.p_result_madw - umad_size());
>+	sa_free_result_mad(&mc_group_result);
>
> 	return ret;
> }
>@@ -1337,6 +1237,25 @@ static int query_lft_records(const struct query_cmd *q, bind_handle_t h,
> 					&lftr, 0, dump_one_lft_record);
> }
>
>+static int query_guidinfo_records(const struct query_cmd *q, bind_handle_t h,
>+				  struct query_params *p, int argc, char *argv[])
>+{
>+	ib_guidinfo_record_t gir;
>+	ib_net64_t comp_mask = 0;
>+	int lid = 0, block = -1;
>+
>+	if (argc > 0)
>+		parse_lid_and_ports(h, argv[0], &lid, &block, NULL);
>+
>+	memset(&gir, 0, sizeof(gir));
>+	CHECK_AND_SET_VAL(lid, 16, 0, gir.lid, GIR, LID);
>+	CHECK_AND_SET_VAL(block, 8, -1, gir.block_num, GIR, BLOCKNUM);
>+
>+	return get_and_dump_any_records(h, IB_SA_ATTR_GUIDINFORECORD, 0,
>+					comp_mask, &gir, 0,
>+					dump_one_guidinfo_record);
>+}
>+
> static int query_mft_records(const struct query_cmd *q, bind_handle_t h,
> 			     struct query_params *p, int argc, char *argv[])
> {
>@@ -1359,37 +1278,6 @@ static int query_mft_records(const struct query_cmd *q, bind_handle_t h,
> 					&mftr, 0, dump_one_mft_record);
> }
>
>-static bind_handle_t get_bind_handle(void)
>-{
>-	static struct ibmad_port *srcport;
>-	static struct bind_handle handle;
>-	int mgmt_classes[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
>-
>-	srcport = mad_rpc_open_port(ibd_ca, ibd_ca_port, mgmt_classes, 2);
>-	if (!srcport)
>-		IBERROR("Failed to open '%s' port '%d'", ibd_ca, ibd_ca_port);
>-
>-	ib_resolve_smlid_via(&handle.dport, ibd_timeout, srcport);
>-	if (!handle.dport.lid)
>-		IBPANIC("No SM found.");
>-
>-	handle.dport.qp = 1;
>-	if (!handle.dport.qkey)
>-		handle.dport.qkey = IB_DEFAULT_QP1_QKEY;
>-
>-	handle.fd = mad_rpc_portid(srcport);
>-	handle.agent = umad_register(handle.fd, IB_SA_CLASS, 2, 1, NULL);
>-
>-	return &handle;
>-}
>-
>-static void clean_up(struct bind_handle *h)
>-{
>-	umad_unregister(h->fd, h->agent);
>-	umad_close_port(h->fd);
>-	umad_done();
>-}
>-
> static const struct query_cmd query_cmds[] = {
> 	{"ClassPortInfo", "CPI", CLASS_PORT_INFO,
> 	 NULL, query_class_port_info},
>@@ -1417,6 +1305,8 @@ static const struct query_cmd query_cmds[] = {
> 	 "[[lid]/[block]]", query_lft_records},
> 	{"MFTRecord", "MFTR", IB_SA_ATTR_MFTRECORD,
> 	 "[[mlid]/[position]/[block]]", query_mft_records},
>+	{"GUIDInfoRecord", "GIR", IB_SA_ATTR_GUIDINFORECORD,
>+	 "[[lid]/[block]]", query_guidinfo_records},
> 	{0}
> };
>
>@@ -1639,7 +1529,7 @@ int main(int argc, char **argv)
> 	bind_handle_t h;
> 	struct query_params params;
> 	const struct query_cmd *q;
>-	ib_api_status_t status;
>+	int status;
> 	int n;
>
> 	const struct ibdiag_opt opts[] = {
>@@ -1784,7 +1674,10 @@ int main(int argc, char **argv)
> 		ibdiag_show_usage();
> 	}
>
>-	h = get_bind_handle();
>+	h = sa_get_bind_handle();
>+	if (!h)
>+		IBPANIC("Failed to bind to the SA");
>+
> 	node_name_map = open_node_name_map(node_name_map_file);
>
> 	if (src_lid && *src_lid)
>@@ -1821,7 +1714,7 @@ int main(int argc, char **argv)
>
> 	if (src_lid)
> 		free(src_lid);
>-	clean_up(h);
>+	sa_free_bind_handle(h);
> 	close_node_name_map(node_name_map);
> 	return (status);
> }
>diff --git a/trunk/tools/infiniband-diags/src/sminfo.c b/trunk/tools/infiniband-diags/src/sminfo.c
>index ef13911..b02906f 100644
>--- a/trunk/tools/infiniband-diags/src/sminfo.c
>+++ b/trunk/tools/infiniband-diags/src/sminfo.c
>@@ -1,5 +1,6 @@
> /*
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>+ * Copyright (c) 2011 Mellanox Technologies LTD.  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
>@@ -46,7 +47,7 @@
>
> #include "ibdiag_common.h"
>
>-static uint8_t sminfo[1024];
>+static uint8_t sminfo[1024] = { 0 };
>
> struct ibmad_port *srcport;
>
>diff --git a/trunk/tools/infiniband-diags/src/sminfo/SOURCES b/trunk/tools/infiniband-diags/src/sminfo/SOURCES
>index 9596c16..0910bf0 100644
>--- a/trunk/tools/infiniband-diags/src/sminfo/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/sminfo/SOURCES
>@@ -19,6 +19,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
>
> TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib
>
>diff --git a/trunk/tools/infiniband-diags/src/smpdump/SOURCES b/trunk/tools/infiniband-diags/src/smpdump/SOURCES
>index 8e308ce..d8f7d6d 100644
>--- a/trunk/tools/infiniband-diags/src/smpdump/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/smpdump/SOURCES
>@@ -20,6 +20,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
> TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
> 	$(SDK_LIB_PATH)\ws2_32.lib		\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib
>
>diff --git a/trunk/tools/infiniband-diags/src/smpquery.c b/trunk/tools/infiniband-diags/src/smpquery.c
>index a1559e8..6753ba9 100644
>--- a/trunk/tools/infiniband-diags/src/smpquery.c
>+++ b/trunk/tools/infiniband-diags/src/smpquery.c
>@@ -1,5 +1,6 @@
> /*
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>+ * Copyright (c) 2011 Mellanox Technologies LTD.  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
>@@ -62,7 +63,7 @@ typedef struct match_rec {
> } match_rec_t;
>
> static op_fn_t node_desc, node_info, port_info, switch_info, pkey_table,
>-    sl2vl_table, vlarb_table, guid_info;
>+    sl2vl_table, vlarb_table, guid_info, mlnx_ext_port_info;
>
> static const match_rec_t match_tbl[] = {
> 	{"NodeInfo", "NI", node_info},
>@@ -73,6 +74,7 @@ static const match_rec_t match_tbl[] = {
> 	{"SL2VLTable", "SL2VL", sl2vl_table, 1},
> 	{"VLArbitration", "VLArb", vlarb_table, 1},
> 	{"GUIDInfo", "GI", guid_info},
>+	{"MlnxExtPortInfo", "MEPI", mlnx_ext_port_info, 1},
> 	{0}
> };
>
>@@ -84,8 +86,8 @@ static char *node_desc(ib_portid_t * dest, char **argv, int argc)
> {
> 	int node_type, l;
> 	uint64_t node_guid;
>-	char nd[IB_SMP_DATA_SIZE];
>-	uint8_t data[IB_SMP_DATA_SIZE];
>+	char nd[IB_SMP_DATA_SIZE] = { 0 };
>+	uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
> 	char dots[128];
> 	char *nodename = NULL;
>
>@@ -117,7 +119,7 @@ static char *node_desc(ib_portid_t * dest, char **argv, int argc)
> static char *node_info(ib_portid_t * dest, char **argv, int argc)
> {
> 	char buf[2048];
>-	char data[IB_SMP_DATA_SIZE];
>+	char data[IB_SMP_DATA_SIZE] = { 0 };
>
> 	if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
> 		return "node info query failed";
>@@ -130,8 +132,8 @@ static char *node_info(ib_portid_t * dest, char **argv, int argc)
>
> static char *port_info(ib_portid_t * dest, char **argv, int argc)
> {
>-	char buf[2048];
>-	char data[IB_SMP_DATA_SIZE];
>+	char buf[2300];
>+	char data[IB_SMP_DATA_SIZE] = { 0 };
> 	int portnum = 0;
>
> 	if (argc > 0)
>@@ -146,10 +148,28 @@ static char *port_info(ib_portid_t * dest, char **argv, int argc)
> 	return 0;
> }
>
>+static char *mlnx_ext_port_info(ib_portid_t * dest, char **argv, int argc)
>+{
>+	char buf[2300];
>+	char data[IB_SMP_DATA_SIZE];
>+	int portnum = 0;
>+
>+	if (argc > 0)
>+		portnum = strtol(argv[0], 0, 0);
>+
>+	if (!smp_query_via(data, dest, IB_ATTR_MLNX_EXT_PORT_INFO, portnum, 0, srcport))
>+		return "Mellanox ext port info query failed";
>+
>+	mad_dump_mlnx_ext_port_info(buf, sizeof buf, data, sizeof data);
>+
>+	printf("# MLNX ext Port info: %s port %d\n%s", portid2str(dest), portnum, buf);
>+	return 0;
>+}
>+
> static char *switch_info(ib_portid_t * dest, char **argv, int argc)
> {
> 	char buf[2048];
>-	char data[IB_SMP_DATA_SIZE];
>+	char data[IB_SMP_DATA_SIZE] = { 0 };
>
> 	if (!smp_query_via(data, dest, IB_ATTR_SWITCH_INFO, 0, 0, srcport))
> 		return "switch info query failed";
>@@ -162,7 +182,7 @@ static char *switch_info(ib_portid_t * dest, char **argv, int argc)
>
> static char *pkey_table(ib_portid_t * dest, char **argv, int argc)
> {
>-	uint8_t data[IB_SMP_DATA_SIZE];
>+	uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
> 	int i, j, k;
> 	uint16_t *p;
> 	unsigned mod;
>@@ -215,7 +235,7 @@ static char *pkey_table(ib_portid_t * dest, char **argv, int argc)
> static char *sl2vl_dump_table_entry(ib_portid_t * dest, int in, int out)
> {
> 	char buf[2048];
>-	char data[IB_SMP_DATA_SIZE];
>+	char data[IB_SMP_DATA_SIZE] = { 0 };
> 	int portnum = (in << 8) | out;
>
> 	if (!smp_query_via(data, dest, IB_ATTR_SLVL_TABLE, portnum, 0, srcport))
>@@ -229,7 +249,7 @@ static char *sl2vl_dump_table_entry(ib_portid_t * dest, int in, int out)
>
> static char *sl2vl_table(ib_portid_t * dest, char **argv, int argc)
> {
>-	uint8_t data[IB_SMP_DATA_SIZE];
>+	uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
> 	int type, num_ports, portnum = 0;
> 	int i;
> 	char *ret;
>@@ -266,7 +286,7 @@ static char *vlarb_dump_table_entry(ib_portid_t * dest, int portnum, int offset,
> 				    unsigned cap)
> {
> 	char buf[2048];
>-	char data[IB_SMP_DATA_SIZE];
>+	char data[IB_SMP_DATA_SIZE] = { 0 };
>
> 	if (!smp_query_via(data, dest, IB_ATTR_VL_ARBITRATION,
> 			   (offset << 16) | portnum, 0, srcport))
>@@ -292,7 +312,7 @@ static char *vlarb_dump_table(ib_portid_t * dest, int portnum,
>
> static char *vlarb_table(ib_portid_t * dest, char **argv, int argc)
> {
>-	uint8_t data[IB_SMP_DATA_SIZE];
>+	uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
> 	int portnum = 0;
> 	int type, enhsp0, lowcap, highcap;
> 	char *ret = 0;
>@@ -308,6 +328,7 @@ static char *vlarb_table(ib_portid_t * dest, char **argv, int argc)
>
> 		mad_decode_field(data, IB_NODE_TYPE_F, &type);
> 		if (type == IB_NODE_SWITCH) {
>+			memset(data, 0, sizeof(data));
> 			if (!smp_query_via(data, dest, IB_ATTR_SWITCH_INFO, 0,
> 					   0, srcport))
> 				return "switch info query failed";
>@@ -318,6 +339,7 @@ static char *vlarb_table(ib_portid_t * dest, char **argv, int argc)
> 				     portid2str(dest), 0);
> 				return 0;
> 			}
>+			memset(data, 0, sizeof(data));
> 		}
> 	}
>
>@@ -341,7 +363,7 @@ static char *vlarb_table(ib_portid_t * dest, char **argv, int argc)
>
> static char *guid_info(ib_portid_t * dest, char **argv, int argc)
> {
>-	uint8_t data[IB_SMP_DATA_SIZE];
>+	uint8_t data[IB_SMP_DATA_SIZE] = { 0 };
> 	int i, j, k;
> 	uint64_t *p;
> 	unsigned mod;
>diff --git a/trunk/tools/infiniband-diags/src/smpquery/SOURCES b/trunk/tools/infiniband-diags/src/smpquery/SOURCES
>index a6ecae4..b276a21 100644
>--- a/trunk/tools/infiniband-diags/src/smpquery/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/smpquery/SOURCES
>@@ -21,6 +21,7 @@ TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
> 	$(SDK_LIB_PATH)\ws2_32.lib		\
> 	$(TARGETPATH)\*\complib.lib		\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib
>
>diff --git a/trunk/tools/infiniband-diags/src/vendstat.c b/trunk/tools/infiniband-diags/src/vendstat.c
>index 92a90c8..8dbd1ee 100644
>--- a/trunk/tools/infiniband-diags/src/vendstat.c
>+++ b/trunk/tools/infiniband-diags/src/vendstat.c
>@@ -375,6 +375,7 @@ int main(int argc, char **argv)
> 	gi = (is3_general_info_t *) & buf;
> 	if (do_vendor(&portid, srcport, IB_MLX_VENDOR_CLASS, IB_MAD_METHOD_GET,
> 		      IB_MLX_IS3_GENERAL_INFO, 0, gi))
>+		IBERROR("generalinfo query");
>
> 	if (general_info) {
> 		/* dump IS3 or IS4 general info here */
>diff --git a/trunk/tools/infiniband-diags/src/vendstat/SOURCES b/trunk/tools/infiniband-diags/src/vendstat/SOURCES
>index 06fd5f4..450502b 100644
>--- a/trunk/tools/infiniband-diags/src/vendstat/SOURCES
>+++ b/trunk/tools/infiniband-diags/src/vendstat/SOURCES
>@@ -20,6 +20,7 @@ C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H
> TARGETLIBS = \
> 	$(SDK_LIB_PATH)\kernel32.lib	\
> 	$(SDK_LIB_PATH)\ws2_32.lib		\
>+	$(TARGETPATH)\*\ibal.lib		\
> 	$(TARGETPATH)\*\libibmad.lib	\
> 	$(TARGETPATH)\*\libibumad.lib
>
>diff --git a/trunk/ulp/libibmad/include/infiniband/mad.h b/trunk/ulp/libibmad/include/infiniband/mad.h
>index 7571a61..6d65a29 100644
>--- a/trunk/ulp/libibmad/include/infiniband/mad.h
>+++ b/trunk/ulp/libibmad/include/infiniband/mad.h
>@@ -1,7 +1,7 @@
> /*
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>  * Copyright (c) 2009 HNR Consulting.  All rights reserved.
>- * Copyright (c) 2009 Mellanox Technologies LTD.  All rights reserved.
>+ * Copyright (c) 2009-2011 Mellanox Technologies LTD.  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
>@@ -46,6 +46,9 @@
> #endif				/* __cplusplus */
>
> BEGIN_C_DECLS
>+#define IB_MAD_RPC_VERSION_MASK	0x0f00
>+#define IB_MAD_RPC_VERSION1	(1<<8)
>+
> #define IB_SUBNET_PATH_HOPS_MAX	64
> #define IB_DEFAULT_SUBN_PREFIX	0xfe80000000000000ULL
> #define IB_DEFAULT_QP1_QKEY	0x80010000
>@@ -62,6 +65,7 @@ BEGIN_C_DECLS
> #define IB_PC_DATA_SZ		(IB_MAD_SIZE - IB_PC_DATA_OFFS)
> #define IB_SA_MCM_RECSZ		53
> #define IB_SA_PR_RECSZ		64
>+#define IB_SA_GIR_RECSZ		72
> #define IB_BM_DATA_OFFS		64
> #define IB_BM_DATA_SZ		(IB_MAD_SIZE - IB_BM_DATA_OFFS)
> #define IB_BM_BKEY_OFFS		24
>@@ -137,7 +141,9 @@ enum SMI_ATTR_ID {
> 	IB_ATTR_VENDORMADSTBL = 0x1d,
> 	IB_ATTR_SMINFO = 0x20,
>
>-	IB_ATTR_LAST
>+	IB_ATTR_LAST,
>+
>+	IB_ATTR_MLNX_EXT_PORT_INFO = 0xff90,
> };
>
> enum SA_ATTR_ID {
>@@ -170,7 +176,20 @@ enum GSI_ATTR_ID {
> 	IB_GSI_PORT_COUNTERS = 0x12,
> 	IB_GSI_PORT_RCV_ERROR_DETAILS = 0x15,
> 	IB_GSI_PORT_XMIT_DISCARD_DETAILS = 0x16,
>+	IB_GSI_PORT_PORT_OP_RCV_COUNTERS = 0x17,
>+	IB_GSI_PORT_PORT_FLOW_CTL_COUNTERS = 0x18,
>+	IB_GSI_PORT_PORT_VL_OP_PACKETS = 0x19,
>+	IB_GSI_PORT_PORT_VL_OP_DATA = 0x1A,
>+	IB_GSI_PORT_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS = 0x1B,
>+	IB_GSI_PORT_PORT_VL_XMIT_WAIT_COUNTERS = 0x1C,
> 	IB_GSI_PORT_COUNTERS_EXT = 0x1D,
>+	IB_GSI_PORT_EXT_SPEEDS_COUNTERS = 0x1F,
>+	IB_GSI_SW_PORT_VL_CONGESTION = 0x30,
>+	IB_GSI_PORT_RCV_CON_CTRL = 0x31,
>+	IB_GSI_PORT_SL_RCV_FECN = 0x32,
>+	IB_GSI_PORT_SL_RCV_BECN = 0x33,
>+	IB_GSI_PORT_XMIT_CON_CTRL = 0x34,
>+	IB_GSI_PORT_VL_XMIT_TIME_CONG = 0x35,
> 	IB_GSI_PORT_XMIT_DATA_SL = 0x36,
> 	IB_GSI_PORT_RCV_DATA_SL = 0x37,
> 	IB_GSI_ATTR_LAST
>@@ -234,6 +253,22 @@ typedef struct {
> 	uint32_t oui;		/* for vendor range 2 mads */
> } ib_rpc_t;
>
>+typedef struct {
>+	int mgtclass;
>+	int method;
>+	ib_attr_t attr;
>+	uint32_t rstatus;	/* return status */
>+	int dataoffs;
>+	int datasz;
>+	uint64_t mkey;
>+	uint64_t trid;		/* used for out mad if nonzero, return real val */
>+	uint64_t mask;		/* for sa mads */
>+	unsigned recsz;		/* for sa mads (attribute offset) */
>+	int timeout;
>+	uint32_t oui;		/* for vendor range 2 mads */
>+	int error;		/* errno */
>+} ib_rpc_v1_t;
>+
> typedef struct portid {
> 	int lid;		/* lid or 0 if directed route */
> 	ib_dr_path_t drpath;
>@@ -579,7 +614,8 @@ enum MAD_FIELDS {
> 	/*
> 	 * GUIDInfo fields
> 	 */
>-	IB_GUID_GUID0_F,
>+	IB_GUID_GUID0_F, /* Obsolete, kept for compatibility
>+			    Use IB_GI_GUID0_F going forward */
>
> 	/*
> 	 * ClassPortInfo fields
>@@ -706,6 +742,301 @@ enum MAD_FIELDS {
> 	IB_PSC_SAMPLES_ONLY_OPT_MASK_F,
> 	IB_PSC_LAST_F,
>
>+	/*
>+	 * GUIDInfo fields
>+	 */
>+	IB_GI_GUID0_F, /* a duplicate of IB_GUID_GUID0_F for backwards
>+			  compatibility */
>+	IB_GI_GUID1_F,
>+	IB_GI_GUID2_F,
>+	IB_GI_GUID3_F,
>+	IB_GI_GUID4_F,
>+	IB_GI_GUID5_F,
>+	IB_GI_GUID6_F,
>+	IB_GI_GUID7_F,
>+
>+	/*
>+	 * GUID Info Record
>+	 */
>+	IB_SA_GIR_LID_F,
>+	IB_SA_GIR_BLOCKNUM_F,
>+	IB_SA_GIR_GUID0_F,
>+	IB_SA_GIR_GUID1_F,
>+	IB_SA_GIR_GUID2_F,
>+	IB_SA_GIR_GUID3_F,
>+	IB_SA_GIR_GUID4_F,
>+	IB_SA_GIR_GUID5_F,
>+	IB_SA_GIR_GUID6_F,
>+	IB_SA_GIR_GUID7_F,
>+
>+	/*
>+	 * More PortInfo fields
>+	 */
>+	IB_PORT_LINK_SPEED_EXT_ACTIVE_F,
>+	IB_PORT_LINK_SPEED_EXT_SUPPORTED_F,
>+	IB_PORT_LINK_SPEED_EXT_ENABLED_F,
>+	IB_PORT_LINK_SPEED_EXT_LAST_F,
>+
>+	/*
>+	 * PortExtendedSpeedsCounters fields
>+	 */
>+	IB_PESC_PORT_SELECT_F,
>+	IB_PESC_COUNTER_SELECT_F,
>+	IB_PESC_SYNC_HDR_ERR_CTR_F,
>+	IB_PESC_UNK_BLOCK_CTR_F,
>+	IB_PESC_ERR_DET_CTR_LANE0_F,
>+	IB_PESC_ERR_DET_CTR_LANE1_F,
>+	IB_PESC_ERR_DET_CTR_LANE2_F,
>+	IB_PESC_ERR_DET_CTR_LANE3_F,
>+	IB_PESC_ERR_DET_CTR_LANE4_F,
>+	IB_PESC_ERR_DET_CTR_LANE5_F,
>+	IB_PESC_ERR_DET_CTR_LANE6_F,
>+	IB_PESC_ERR_DET_CTR_LANE7_F,
>+	IB_PESC_ERR_DET_CTR_LANE8_F,
>+	IB_PESC_ERR_DET_CTR_LANE9_F,
>+	IB_PESC_ERR_DET_CTR_LANE10_F,
>+	IB_PESC_ERR_DET_CTR_LANE11_F,
>+	IB_PESC_FEC_CORR_BLOCK_CTR_LANE0_F,
>+	IB_PESC_FEC_CORR_BLOCK_CTR_LANE1_F,
>+	IB_PESC_FEC_CORR_BLOCK_CTR_LANE2_F,
>+	IB_PESC_FEC_CORR_BLOCK_CTR_LANE3_F,
>+	IB_PESC_FEC_CORR_BLOCK_CTR_LANE4_F,
>+	IB_PESC_FEC_CORR_BLOCK_CTR_LANE5_F,
>+	IB_PESC_FEC_CORR_BLOCK_CTR_LANE6_F,
>+	IB_PESC_FEC_CORR_BLOCK_CTR_LANE7_F,
>+	IB_PESC_FEC_CORR_BLOCK_CTR_LANE8_F,
>+	IB_PESC_FEC_CORR_BLOCK_CTR_LANE9_F,
>+	IB_PESC_FEC_CORR_BLOCK_CTR_LANE10_F,
>+	IB_PESC_FEC_CORR_BLOCK_CTR_LANE11_F,
>+	IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE0_F,
>+	IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE1_F,
>+	IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE2_F,
>+	IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE3_F,
>+	IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE4_F,
>+	IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE5_F,
>+	IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE6_F,
>+	IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE7_F,
>+	IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE8_F,
>+	IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE9_F,
>+	IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE10_F,
>+	IB_PESC_FEC_UNCORR_BLOCK_CTR_LANE11_F,
>+	IB_PESC_LAST_F,
>+
>+	/*
>+	 * PortOpRcvCounters fields
>+	 */
>+	IB_PC_PORT_OP_RCV_COUNTERS_FIRST_F,
>+	IB_PC_PORT_OP_RCV_PKTS_F = IB_PC_PORT_OP_RCV_COUNTERS_FIRST_F,
>+	IB_PC_PORT_OP_RCV_DATA_F,
>+	IB_PC_PORT_OP_RCV_COUNTERS_LAST_F,
>+
>+	/*
>+	 * PortFlowCtlCounters fields
>+	 */
>+	IB_PC_PORT_FLOW_CTL_COUNTERS_FIRST_F,
>+	IB_PC_PORT_XMIT_FLOW_PKTS_F = IB_PC_PORT_FLOW_CTL_COUNTERS_FIRST_F,
>+	IB_PC_PORT_RCV_FLOW_PKTS_F,
>+	IB_PC_PORT_FLOW_CTL_COUNTERS_LAST_F,
>+
>+	/*
>+	 * PortVLOpPackets fields
>+	 */
>+	IB_PC_PORT_VL_OP_PACKETS_FIRST_F,
>+	IB_PC_PORT_VL_OP_PACKETS0_F = IB_PC_PORT_VL_OP_PACKETS_FIRST_F,
>+	IB_PC_PORT_VL_OP_PACKETS1_F,
>+	IB_PC_PORT_VL_OP_PACKETS2_F,
>+	IB_PC_PORT_VL_OP_PACKETS3_F,
>+	IB_PC_PORT_VL_OP_PACKETS4_F,
>+	IB_PC_PORT_VL_OP_PACKETS5_F,
>+	IB_PC_PORT_VL_OP_PACKETS6_F,
>+	IB_PC_PORT_VL_OP_PACKETS7_F,
>+	IB_PC_PORT_VL_OP_PACKETS8_F,
>+	IB_PC_PORT_VL_OP_PACKETS9_F,
>+	IB_PC_PORT_VL_OP_PACKETS10_F,
>+	IB_PC_PORT_VL_OP_PACKETS11_F,
>+	IB_PC_PORT_VL_OP_PACKETS12_F,
>+	IB_PC_PORT_VL_OP_PACKETS13_F,
>+	IB_PC_PORT_VL_OP_PACKETS14_F,
>+	IB_PC_PORT_VL_OP_PACKETS15_F,
>+	IB_PC_PORT_VL_OP_PACKETS_LAST_F,
>+
>+	/*
>+	 * PortVLOpData fields
>+	 */
>+	IB_PC_PORT_VL_OP_DATA_FIRST_F,
>+	IB_PC_PORT_VL_OP_DATA0_F = IB_PC_PORT_VL_OP_DATA_FIRST_F,
>+	IB_PC_PORT_VL_OP_DATA1_F,
>+	IB_PC_PORT_VL_OP_DATA2_F,
>+	IB_PC_PORT_VL_OP_DATA3_F,
>+	IB_PC_PORT_VL_OP_DATA4_F,
>+	IB_PC_PORT_VL_OP_DATA5_F,
>+	IB_PC_PORT_VL_OP_DATA6_F,
>+	IB_PC_PORT_VL_OP_DATA7_F,
>+	IB_PC_PORT_VL_OP_DATA8_F,
>+	IB_PC_PORT_VL_OP_DATA9_F,
>+	IB_PC_PORT_VL_OP_DATA10_F,
>+	IB_PC_PORT_VL_OP_DATA11_F,
>+	IB_PC_PORT_VL_OP_DATA12_F,
>+	IB_PC_PORT_VL_OP_DATA13_F,
>+	IB_PC_PORT_VL_OP_DATA14_F,
>+	IB_PC_PORT_VL_OP_DATA15_F,
>+	IB_PC_PORT_VL_OP_DATA_LAST_F,
>+
>+	/*
>+	 * PortVLXmitFlowCtlUpdateErrors fields
>+	 */
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_FIRST_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS0_F = IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_FIRST_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS1_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS2_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS3_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS4_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS5_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS6_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS7_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS8_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS9_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS10_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS11_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS12_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS13_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS14_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS15_F,
>+	IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_LAST_F,
>+
>+	/*
>+	 * PortVLXmitWaitCounters fields
>+	 */
>+	IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_FIRST_F,
>+	IB_PC_PORT_VL_XMIT_WAIT0_F = IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_FIRST_F,
>+	IB_PC_PORT_VL_XMIT_WAIT1_F,
>+	IB_PC_PORT_VL_XMIT_WAIT2_F,
>+	IB_PC_PORT_VL_XMIT_WAIT3_F,
>+	IB_PC_PORT_VL_XMIT_WAIT4_F,
>+	IB_PC_PORT_VL_XMIT_WAIT5_F,
>+	IB_PC_PORT_VL_XMIT_WAIT6_F,
>+	IB_PC_PORT_VL_XMIT_WAIT7_F,
>+	IB_PC_PORT_VL_XMIT_WAIT8_F,
>+	IB_PC_PORT_VL_XMIT_WAIT9_F,
>+	IB_PC_PORT_VL_XMIT_WAIT10_F,
>+	IB_PC_PORT_VL_XMIT_WAIT11_F,
>+	IB_PC_PORT_VL_XMIT_WAIT12_F,
>+	IB_PC_PORT_VL_XMIT_WAIT13_F,
>+	IB_PC_PORT_VL_XMIT_WAIT14_F,
>+	IB_PC_PORT_VL_XMIT_WAIT15_F,
>+	IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_LAST_F,
>+
>+	/*
>+	 * SwPortVLCongestion fields
>+	 */
>+	IB_PC_SW_PORT_VL_CONGESTION_FIRST_F,
>+	IB_PC_SW_PORT_VL_CONGESTION0_F = IB_PC_SW_PORT_VL_CONGESTION_FIRST_F,
>+	IB_PC_SW_PORT_VL_CONGESTION1_F,
>+	IB_PC_SW_PORT_VL_CONGESTION2_F,
>+	IB_PC_SW_PORT_VL_CONGESTION3_F,
>+	IB_PC_SW_PORT_VL_CONGESTION4_F,
>+	IB_PC_SW_PORT_VL_CONGESTION5_F,
>+	IB_PC_SW_PORT_VL_CONGESTION6_F,
>+	IB_PC_SW_PORT_VL_CONGESTION7_F,
>+	IB_PC_SW_PORT_VL_CONGESTION8_F,
>+	IB_PC_SW_PORT_VL_CONGESTION9_F,
>+	IB_PC_SW_PORT_VL_CONGESTION10_F,
>+	IB_PC_SW_PORT_VL_CONGESTION11_F,
>+	IB_PC_SW_PORT_VL_CONGESTION12_F,
>+	IB_PC_SW_PORT_VL_CONGESTION13_F,
>+	IB_PC_SW_PORT_VL_CONGESTION14_F,
>+	IB_PC_SW_PORT_VL_CONGESTION15_F,
>+	IB_PC_SW_PORT_VL_CONGESTION_LAST_F,
>+
>+	/*
>+	 * PortRcvConCtrl fields
>+	 */
>+	IB_PC_RCV_CON_CTRL_FIRST_F,
>+	IB_PC_RCV_CON_CTRL_PKT_RCV_FECN_F = IB_PC_RCV_CON_CTRL_FIRST_F,
>+	IB_PC_RCV_CON_CTRL_PKT_RCV_BECN_F,
>+	IB_PC_RCV_CON_CTRL_LAST_F,
>+
>+	/*
>+	 * PortSLRcvFECN fields
>+	 */
>+	IB_PC_SL_RCV_FECN_FIRST_F,
>+	IB_PC_SL_RCV_FECN0_F = IB_PC_SL_RCV_FECN_FIRST_F,
>+	IB_PC_SL_RCV_FECN1_F,
>+	IB_PC_SL_RCV_FECN2_F,
>+	IB_PC_SL_RCV_FECN3_F,
>+	IB_PC_SL_RCV_FECN4_F,
>+	IB_PC_SL_RCV_FECN5_F,
>+	IB_PC_SL_RCV_FECN6_F,
>+	IB_PC_SL_RCV_FECN7_F,
>+	IB_PC_SL_RCV_FECN8_F,
>+	IB_PC_SL_RCV_FECN9_F,
>+	IB_PC_SL_RCV_FECN10_F,
>+	IB_PC_SL_RCV_FECN11_F,
>+	IB_PC_SL_RCV_FECN12_F,
>+	IB_PC_SL_RCV_FECN13_F,
>+	IB_PC_SL_RCV_FECN14_F,
>+	IB_PC_SL_RCV_FECN15_F,
>+	IB_PC_SL_RCV_FECN_LAST_F,
>+
>+	/*
>+	 * PortSLRcvBECN fields
>+	 */
>+	IB_PC_SL_RCV_BECN_FIRST_F,
>+	IB_PC_SL_RCV_BECN0_F = IB_PC_SL_RCV_BECN_FIRST_F,
>+	IB_PC_SL_RCV_BECN1_F,
>+	IB_PC_SL_RCV_BECN2_F,
>+	IB_PC_SL_RCV_BECN3_F,
>+	IB_PC_SL_RCV_BECN4_F,
>+	IB_PC_SL_RCV_BECN5_F,
>+	IB_PC_SL_RCV_BECN6_F,
>+	IB_PC_SL_RCV_BECN7_F,
>+	IB_PC_SL_RCV_BECN8_F,
>+	IB_PC_SL_RCV_BECN9_F,
>+	IB_PC_SL_RCV_BECN10_F,
>+	IB_PC_SL_RCV_BECN11_F,
>+	IB_PC_SL_RCV_BECN12_F,
>+	IB_PC_SL_RCV_BECN13_F,
>+	IB_PC_SL_RCV_BECN14_F,
>+	IB_PC_SL_RCV_BECN15_F,
>+	IB_PC_SL_RCV_BECN_LAST_F,
>+
>+	/*
>+	 * PortXmitConCtrl fields
>+	 */
>+	IB_PC_XMIT_CON_CTRL_FIRST_F,
>+	IB_PC_XMIT_CON_CTRL_TIME_CONG_F = IB_PC_XMIT_CON_CTRL_FIRST_F,
>+	IB_PC_XMIT_CON_CTRL_LAST_F,
>+
>+	/*
>+	 * PortVLXmitTimeCong fields
>+	 */
>+	IB_PC_VL_XMIT_TIME_CONG_FIRST_F,
>+	IB_PC_VL_XMIT_TIME_CONG0_F = IB_PC_VL_XMIT_TIME_CONG_FIRST_F,
>+	IB_PC_VL_XMIT_TIME_CONG1_F,
>+	IB_PC_VL_XMIT_TIME_CONG2_F,
>+	IB_PC_VL_XMIT_TIME_CONG3_F,
>+	IB_PC_VL_XMIT_TIME_CONG4_F,
>+	IB_PC_VL_XMIT_TIME_CONG5_F,
>+	IB_PC_VL_XMIT_TIME_CONG6_F,
>+	IB_PC_VL_XMIT_TIME_CONG7_F,
>+	IB_PC_VL_XMIT_TIME_CONG8_F,
>+	IB_PC_VL_XMIT_TIME_CONG9_F,
>+	IB_PC_VL_XMIT_TIME_CONG10_F,
>+	IB_PC_VL_XMIT_TIME_CONG11_F,
>+	IB_PC_VL_XMIT_TIME_CONG12_F,
>+	IB_PC_VL_XMIT_TIME_CONG13_F,
>+	IB_PC_VL_XMIT_TIME_CONG14_F,
>+	IB_PC_VL_XMIT_TIME_CONG_LAST_F,
>+
>+	/*
>+	 * Mellanox ExtendedPortInfo fields
>+	 */
>+	IB_MLNX_EXT_PORT_STATE_CHG_ENABLE_F,
>+	IB_MLNX_EXT_PORT_LINK_SPEED_SUPPORTED_F,
>+	IB_MLNX_EXT_PORT_LINK_SPEED_ENABLED_F,
>+	IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F,
>+	IB_MLNX_EXT_PORT_LAST_F,
>+
> 	IB_FIELD_LAST_		/* must be last */
> };
>
>@@ -959,6 +1290,14 @@ MAD_EXPORT uint8_t *smp_query_via(void *buf, ib_portid_t * id, unsigned attrid,
> MAD_EXPORT uint8_t *smp_set_via(void *buf, ib_portid_t * id, unsigned attrid,
> 				unsigned mod, unsigned timeout,
> 				const struct ibmad_port *srcport);
>+MAD_EXPORT uint8_t *smp_query_status_via(void *rcvbuf, ib_portid_t * portid,
>+					 unsigned attrid, unsigned mod,
>+					 unsigned timeout, int *rstatus,
>+					 const struct ibmad_port *srcport);
>+MAD_EXPORT uint8_t *smp_set_status_via(void *data, ib_portid_t * portid,
>+				       unsigned attrid, unsigned mod,
>+				       unsigned timeout, int *rstatus,
>+				       const struct ibmad_port *srcport);
>
> /* sa.c */
> uint8_t *sa_call(void *rcvbuf, ib_portid_t * portid, ib_sa_call_t * sa,
>@@ -1021,6 +1360,7 @@ MAD_EXPORT ib_mad_dump_fn
>     mad_dump_linkwidth, mad_dump_linkwidthsup, mad_dump_linkwidthen,
>     mad_dump_linkdowndefstate,
>     mad_dump_linkspeed, mad_dump_linkspeedsup, mad_dump_linkspeeden,
>+    mad_dump_linkspeedext, mad_dump_linkspeedextsup, mad_dump_linkspeedexten,
>     mad_dump_portstate, mad_dump_portstates,
>     mad_dump_physportstate, mad_dump_portcapmask,
>     mad_dump_mtu, mad_dump_vlcap, mad_dump_opervls,
>@@ -1029,7 +1369,14 @@ MAD_EXPORT ib_mad_dump_fn
>     mad_dump_switchinfo, mad_dump_perfcounters, mad_dump_perfcounters_ext,
>     mad_dump_perfcounters_xmt_sl, mad_dump_perfcounters_rcv_sl,
>     mad_dump_perfcounters_xmt_disc, mad_dump_perfcounters_rcv_err,
>-    mad_dump_portsamples_control;
>+    mad_dump_portsamples_control, mad_dump_port_ext_speeds_counters,
>+    mad_dump_perfcounters_port_op_rcv_counters, mad_dump_perfcounters_port_flow_ctl_counters,
>+    mad_dump_perfcounters_port_vl_op_packet, mad_dump_perfcounters_port_vl_op_data,
>+    mad_dump_perfcounters_port_vl_xmit_flow_ctl_update_errors, mad_dump_perfcounters_port_vl_xmit_wait_counters,
>+    mad_dump_perfcounters_sw_port_vl_congestion, mad_dump_perfcounters_rcv_con_ctrl,
>+    mad_dump_perfcounters_sl_rcv_fecn, mad_dump_perfcounters_sl_rcv_becn,
>+    mad_dump_perfcounters_xmit_con_ctrl, mad_dump_perfcounters_vl_xmit_time_cong,
>+    mad_dump_mlnx_ext_port_info;
>
> MAD_EXPORT void mad_dump_fields(char *buf, int bufsz, void *val, int valsz,
> 				int start, int end);
>diff --git a/trunk/ulp/libibmad/include/infiniband/mad_osd.h b/trunk/ulp/libibmad/include/infiniband/mad_osd.h
>index faabaec..c32e666 100644
>--- a/trunk/ulp/libibmad/include/infiniband/mad_osd.h
>+++ b/trunk/ulp/libibmad/include/infiniband/mad_osd.h
>@@ -35,6 +35,7 @@
> #include <windows.h>
> #include <winsock2.h>
> #include <ws2tcpip.h>
>+#include <_errno.h>
>
> typedef unsigned __int8		uint8_t;
> typedef unsigned __int16	uint16_t;
>diff --git a/trunk/ulp/libibmad/src/dump.c b/trunk/ulp/libibmad/src/dump.c
>index c29f625..29fb742 100644
>--- a/trunk/ulp/libibmad/src/dump.c
>+++ b/trunk/ulp/libibmad/src/dump.c
>@@ -1,7 +1,7 @@
> /*
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>  * Copyright (c) 2007 Xsigo Systems Inc.  All rights reserved.
>- * Copyright (c) 2009 Mellanox Technologies LTD.  All rights reserved.
>+ * Copyright (c) 2009-2011 Mellanox Technologies LTD.  All rights reserved.
>  * Copyright (c) 2009 HNR Consulting.  All rights reserved.
>  *
>  * This software is available to you under a choice of one of two
>@@ -308,6 +308,70 @@ void mad_dump_linkspeeden(char *buf, int bufsz, void *val, int valsz)
> 	dump_linkspeed(buf, bufsz, speed);
> }
>
>+void mad_dump_linkspeedext(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int speed = *(int *)val;
>+
>+	switch (speed) {
>+	case 0:
>+		snprintf(buf, bufsz, "No Extended Speed");
>+		break;
>+	case 1:
>+		snprintf(buf, bufsz, "14.0625 Gbps");
>+		break;
>+	case 2:
>+		snprintf(buf, bufsz, "25.78125 Gbps");
>+		break;
>+	default:
>+		snprintf(buf, bufsz, "undefined (%d)", speed);
>+		break;
>+	}
>+}
>+
>+static void dump_linkspeedext(char *buf, int bufsz, int speed)
>+{
>+	int n = 0;
>+
>+	if (speed == 0) {
>+		sprintf(buf, "%d", speed);
>+		return;
>+	}
>+
>+	if (speed & 0x1)
>+		n += snprintf(buf + n, bufsz - n, "14.0625 Gbps or ");
>+	if (n < bufsz && speed & 0x2)
>+		n += snprintf(buf + n, bufsz - n, "25.78125 Gbps or ");
>+	if (n >= bufsz) {
>+		if (bufsz > 3)
>+			buf[n - 4] = '\0';
>+		return;
>+	}
>+
>+	if (speed >> 2) {
>+		n += snprintf(buf + n, bufsz - n, "undefined (%d)", speed);
>+		return;
>+	} else if (bufsz > 3)
>+		buf[n - 4] = '\0';
>+}
>+
>+void mad_dump_linkspeedextsup(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int speed = *(int *)val;
>+
>+	dump_linkspeedext(buf, bufsz, speed);
>+}
>+
>+void mad_dump_linkspeedexten(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int speed = *(int *)val;
>+
>+	if (speed == 30) {
>+		sprintf(buf, "%s", "Extended link speeds disabled");
>+		return;
>+	}
>+	dump_linkspeedext(buf, bufsz, speed);
>+}
>+
> void mad_dump_portstate(char *buf, int bufsz, void *val, int valsz)
> {
> 	int state = *(int *)val;
>@@ -495,6 +559,8 @@ void mad_dump_portcapmask(char *buf, int bufsz, void *val, int valsz)
> 	if (mask & (1 << 12))
> 		s += sprintf(s,
> 			     "\t\t\t\tIsPkeySwitchExternalPortTrapSupported\n");
>+	if (mask & (1 << 14))
>+		s += sprintf(s, "\t\t\t\tIsExtendedSpeedsSupported\n");
> 	if (mask & (1 << 16))
> 		s += sprintf(s, "\t\t\t\tIsCommunicatonManagementSupported\n");
> 	if (mask & (1 << 17))
>@@ -692,7 +758,12 @@ void mad_dump_nodeinfo(char *buf, int bufsz, void *val, int valsz)
>
> void mad_dump_portinfo(char *buf, int bufsz, void *val, int valsz)
> {
>-	_dump_fields(buf, bufsz, val, IB_PORT_FIRST_F, IB_PORT_LAST_F);
>+	int cnt;
>+
>+	cnt = _dump_fields(buf, bufsz, val, IB_PORT_FIRST_F, IB_PORT_LAST_F);
>+	_dump_fields(buf + cnt, bufsz - cnt, val,
>+		     IB_PORT_LINK_SPEED_EXT_ACTIVE_F,
>+		     IB_PORT_LINK_SPEED_EXT_LAST_F);
> }
>
> void mad_dump_portstates(char *buf, int bufsz, void *val, int valsz)
>@@ -760,6 +831,138 @@ void mad_dump_portsamples_control(char *buf, int bufsz, void *val, int valsz)
> 	_dump_fields(buf, bufsz, val, IB_PSC_OPCODE_F, IB_PSC_LAST_F);
> }
>
>+void mad_dump_port_ext_speeds_counters(char *buf, int bufsz, void *val, int valsz)
>+{
>+	_dump_fields(buf, bufsz, val, IB_PESC_PORT_SELECT_F, IB_PESC_LAST_F);
>+}
>+
>+void mad_dump_perfcounters_port_op_rcv_counters(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int cnt;
>+
>+	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
>+			   IB_PC_EXT_XMT_BYTES_F);
>+	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_OP_RCV_COUNTERS_FIRST_F,
>+		     IB_PC_PORT_OP_RCV_COUNTERS_LAST_F);
>+}
>+
>+void mad_dump_perfcounters_port_flow_ctl_counters(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int cnt;
>+
>+	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
>+			   IB_PC_EXT_XMT_BYTES_F);
>+	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_FLOW_CTL_COUNTERS_FIRST_F,
>+		     IB_PC_PORT_FLOW_CTL_COUNTERS_LAST_F);
>+}
>+
>+void mad_dump_perfcounters_port_vl_op_packet(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int cnt;
>+
>+	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
>+			   IB_PC_EXT_XMT_BYTES_F);
>+	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_VL_OP_PACKETS_FIRST_F,
>+		     IB_PC_PORT_VL_OP_PACKETS_LAST_F);
>+}
>+
>+void mad_dump_perfcounters_port_vl_op_data(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int cnt;
>+
>+	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
>+			   IB_PC_EXT_XMT_BYTES_F);
>+	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_VL_OP_DATA_FIRST_F,
>+		     IB_PC_PORT_VL_OP_DATA_LAST_F);
>+}
>+
>+void mad_dump_perfcounters_port_vl_xmit_flow_ctl_update_errors(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int cnt;
>+
>+	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
>+			   IB_PC_EXT_XMT_BYTES_F);
>+	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_FIRST_F,
>+		     IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_LAST_F);
>+}
>+
>+void mad_dump_perfcounters_port_vl_xmit_wait_counters(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int cnt;
>+
>+	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
>+			   IB_PC_EXT_XMT_BYTES_F);
>+	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_FIRST_F,
>+		     IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_LAST_F);
>+}
>+
>+void mad_dump_perfcounters_sw_port_vl_congestion(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int cnt;
>+
>+	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
>+			   IB_PC_EXT_XMT_BYTES_F);
>+	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_SW_PORT_VL_CONGESTION_FIRST_F,
>+		     IB_PC_SW_PORT_VL_CONGESTION_LAST_F);
>+}
>+
>+void mad_dump_perfcounters_rcv_con_ctrl(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int cnt;
>+
>+	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
>+			   IB_PC_EXT_XMT_BYTES_F);
>+	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_RCV_CON_CTRL_FIRST_F,
>+		     IB_PC_RCV_CON_CTRL_LAST_F);
>+}
>+
>+
>+void mad_dump_perfcounters_sl_rcv_fecn(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int cnt;
>+
>+	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
>+			   IB_PC_EXT_XMT_BYTES_F);
>+	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_SL_RCV_FECN_FIRST_F,
>+		     IB_PC_SL_RCV_FECN_LAST_F);
>+}
>+
>+void mad_dump_perfcounters_sl_rcv_becn(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int cnt;
>+
>+	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
>+			   IB_PC_EXT_XMT_BYTES_F);
>+	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_SL_RCV_BECN_FIRST_F,
>+		     IB_PC_SL_RCV_BECN_LAST_F);
>+}
>+
>+void mad_dump_perfcounters_xmit_con_ctrl(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int cnt;
>+
>+	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
>+			   IB_PC_EXT_XMT_BYTES_F);
>+	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_XMIT_CON_CTRL_FIRST_F,
>+		     IB_PC_XMIT_CON_CTRL_LAST_F);
>+}
>+
>+void mad_dump_perfcounters_vl_xmit_time_cong(char *buf, int bufsz, void *val, int valsz)
>+{
>+	int cnt;
>+
>+	cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F,
>+			   IB_PC_EXT_XMT_BYTES_F);
>+	_dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_VL_XMIT_TIME_CONG_FIRST_F,
>+		     IB_PC_VL_XMIT_TIME_CONG_LAST_F);
>+}
>+
>+void mad_dump_mlnx_ext_port_info(char *buf, int bufsz, void *val, int valsz)
>+{
>+	_dump_fields(buf, bufsz, val, IB_MLNX_EXT_PORT_STATE_CHG_ENABLE_F,
>+		     IB_MLNX_EXT_PORT_LAST_F);
>+}
>+
> void xdump(FILE * file, char *msg, void *p, int size)
> {
> #define HEX(x)  ((x) < 10 ? '0' + (x) : 'a' + ((x) -10))
>diff --git a/trunk/ulp/libibmad/src/fields.c b/trunk/ulp/libibmad/src/fields.c
>index a5a510a..7e5ac7d 100644
>--- a/trunk/ulp/libibmad/src/fields.c
>+++ b/trunk/ulp/libibmad/src/fields.c
>@@ -1,7 +1,7 @@
> /*
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>  * Copyright (c) 2009 HNR Consulting.  All rights reserved.
>- * Copyright (c) 2009 Mellanox Technologies LTD.  All rights reserved.
>+ * Copyright (c) 2009-2010 Mellanox Technologies LTD.  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
>@@ -246,24 +246,24 @@ static const ib_field_t ib_mad_f[] = {
> 	 */
> 	{BITSOFFS(8, 8), "PortSelect", mad_dump_uint},
> 	{BITSOFFS(16, 16), "CounterSelect", mad_dump_hex},
>-	{BITSOFFS(32, 16), "SymbolErrors", mad_dump_uint},
>-	{BITSOFFS(48, 8), "LinkRecovers", mad_dump_uint},
>-	{BITSOFFS(56, 8), "LinkDowned", mad_dump_uint},
>-	{BITSOFFS(64, 16), "RcvErrors", mad_dump_uint},
>-	{BITSOFFS(80, 16), "RcvRemotePhysErrors", mad_dump_uint},
>-	{BITSOFFS(96, 16), "RcvSwRelayErrors", mad_dump_uint},
>-	{BITSOFFS(112, 16), "XmtDiscards", mad_dump_uint},
>-	{BITSOFFS(128, 8), "XmtConstraintErrors", mad_dump_uint},
>-	{BITSOFFS(136, 8), "RcvConstraintErrors", mad_dump_uint},
>+	{BITSOFFS(32, 16), "SymbolErrorCounter", mad_dump_uint},
>+	{BITSOFFS(48, 8), "LinkErrorRecoveryCounter", mad_dump_uint},
>+	{BITSOFFS(56, 8), "LinkDownedCounter", mad_dump_uint},
>+	{BITSOFFS(64, 16), "PortRcvErrors", mad_dump_uint},
>+	{BITSOFFS(80, 16), "PortRcvRemotePhysicalErrors", mad_dump_uint},
>+	{BITSOFFS(96, 16), "PortRcvSwitchRelayErrors", mad_dump_uint},
>+	{BITSOFFS(112, 16), "PortXmitDiscards", mad_dump_uint},
>+	{BITSOFFS(128, 8), "PortXmitConstraintErrors", mad_dump_uint},
>+	{BITSOFFS(136, 8), "PortRcvConstraintErrors", mad_dump_uint},
> 	{BITSOFFS(144, 8), "CounterSelect2", mad_dump_hex},
>-	{BITSOFFS(152, 4), "LinkIntegrityErrors", mad_dump_uint},
>-	{BITSOFFS(156, 4), "ExcBufOverrunErrors", mad_dump_uint},
>+	{BITSOFFS(152, 4), "LocalLinkIntegrityErrors", mad_dump_uint},
>+	{BITSOFFS(156, 4), "ExcessiveBufferOverrunErrors", mad_dump_uint},
> 	{BITSOFFS(176, 16), "VL15Dropped", mad_dump_uint},
>-	{192, 32, "XmtData", mad_dump_uint},
>-	{224, 32, "RcvData", mad_dump_uint},
>-	{256, 32, "XmtPkts", mad_dump_uint},
>-	{288, 32, "RcvPkts", mad_dump_uint},
>-	{320, 32, "XmtWait", mad_dump_uint},
>+	{192, 32, "PortXmitData", mad_dump_uint},
>+	{224, 32, "PortRcvData", mad_dump_uint},
>+	{256, 32, "PortXmitPkts", mad_dump_uint},
>+	{288, 32, "PortRcvPkts", mad_dump_uint},
>+	{320, 32, "PortXmitWait", mad_dump_uint},
> 	{0, 0},			/* IB_PC_LAST_F */
>
> 	/*
>@@ -452,21 +452,21 @@ static const ib_field_t ib_mad_f[] = {
> 	/*
> 	 * PortXmitDiscardDetails fields
> 	 */
>-	{32, 16, "PortInactiveDiscards", mad_dump_uint},
>-	{48, 16, "PortNeighborMTUDiscards", mad_dump_uint},
>-	{64, 16, "PortSwLifetimeLimitDiscards", mad_dump_uint},
>-	{80, 16, "PortSwHOQLifetimeLimitDiscards", mad_dump_uint},
>+	{BITSOFFS(32, 16), "PortInactiveDiscards", mad_dump_uint},
>+	{BITSOFFS(48, 16), "PortNeighborMTUDiscards", mad_dump_uint},
>+	{BITSOFFS(64, 16), "PortSwLifetimeLimitDiscards", mad_dump_uint},
>+	{BITSOFFS(80, 16), "PortSwHOQLifetimeLimitDiscards", mad_dump_uint},
> 	{0, 0},			/* IB_PC_XMT_DISC_LAST_F */
>
> 	/*
> 	 * PortRcvErrorDetails fields
> 	 */
>-	{32, 16, "PortLocalPhysicalErrors", mad_dump_uint},
>-	{48, 16, "PortMalformedPktErrors", mad_dump_uint},
>-	{64, 16, "PortBufferOverrunErrors", mad_dump_uint},
>-	{80, 16, "PortDLIDMappingErrors", mad_dump_uint},
>-	{96, 16, "PortVLMappingErrors", mad_dump_uint},
>-	{112, 16, "PortLoopingErrors", mad_dump_uint},
>+	{BITSOFFS(32, 16), "PortLocalPhysicalErrors", mad_dump_uint},
>+	{BITSOFFS(48, 16), "PortMalformedPktErrors", mad_dump_uint},
>+	{BITSOFFS(64, 16), "PortBufferOverrunErrors", mad_dump_uint},
>+	{BITSOFFS(80, 16), "PortDLIDMappingErrors", mad_dump_uint},
>+	{BITSOFFS(96, 16), "PortVLMappingErrors", mad_dump_uint},
>+	{BITSOFFS(112, 16), "PortLoopingErrors", mad_dump_uint},
> 	{0, 0},                 /* IB_PC_RCV_ERR_LAST_F */
>
> 	/*
>@@ -485,25 +485,303 @@ static const ib_field_t ib_mad_f[] = {
> 	{160, 64, "VendorMask", mad_dump_hex},
> 	{224, 32, "SampleStart", mad_dump_uint},
> 	{256, 32, "SampleInterval", mad_dump_uint},
>-	{288, 16, "Tag", mad_dump_hex},
>-	{304, 16, "CounterSelect0", mad_dump_hex},
>-	{320, 16, "CounterSelect1", mad_dump_hex},
>-	{336, 16, "CounterSelect2", mad_dump_hex},
>-	{352, 16, "CounterSelect3", mad_dump_hex},
>-	{368, 16, "CounterSelect4", mad_dump_hex},
>-	{384, 16, "CounterSelect5", mad_dump_hex},
>-	{400, 16, "CounterSelect6", mad_dump_hex},
>-	{416, 16, "CounterSelect7", mad_dump_hex},
>-	{432, 16, "CounterSelect8", mad_dump_hex},
>-	{448, 16, "CounterSelect9", mad_dump_hex},
>-	{464, 16, "CounterSelect10", mad_dump_hex},
>-	{480, 16, "CounterSelect11", mad_dump_hex},
>-	{496, 16, "CounterSelect12", mad_dump_hex},
>-	{512, 16, "CounterSelect13", mad_dump_hex},
>-	{528, 16, "CounterSelect14", mad_dump_hex},
>+	{BITSOFFS(288, 16), "Tag", mad_dump_hex},
>+	{BITSOFFS(304, 16), "CounterSelect0", mad_dump_hex},
>+	{BITSOFFS(320, 16), "CounterSelect1", mad_dump_hex},
>+	{BITSOFFS(336, 16), "CounterSelect2", mad_dump_hex},
>+	{BITSOFFS(352, 16), "CounterSelect3", mad_dump_hex},
>+	{BITSOFFS(368, 16), "CounterSelect4", mad_dump_hex},
>+	{BITSOFFS(384, 16), "CounterSelect5", mad_dump_hex},
>+	{BITSOFFS(400, 16), "CounterSelect6", mad_dump_hex},
>+	{BITSOFFS(416, 16), "CounterSelect7", mad_dump_hex},
>+	{BITSOFFS(432, 16), "CounterSelect8", mad_dump_hex},
>+	{BITSOFFS(448, 16), "CounterSelect9", mad_dump_hex},
>+	{BITSOFFS(464, 16), "CounterSelect10", mad_dump_hex},
>+	{BITSOFFS(480, 16), "CounterSelect11", mad_dump_hex},
>+	{BITSOFFS(496, 16), "CounterSelect12", mad_dump_hex},
>+	{BITSOFFS(512, 16), "CounterSelect13", mad_dump_hex},
>+	{BITSOFFS(528, 16), "CounterSelect14", mad_dump_hex},
> 	{576, 64, "SamplesOnlyOptionMask", mad_dump_hex},
> 	{0, 0},			/* IB_PSC_LAST_F */
>
>+	/* GUIDInfo fields */
>+	{0, 64, "GUID0", mad_dump_hex},
>+	{64, 64, "GUID1", mad_dump_hex},
>+	{128, 64, "GUID2", mad_dump_hex},
>+	{192, 64, "GUID3", mad_dump_hex},
>+	{256, 64, "GUID4", mad_dump_hex},
>+	{320, 64, "GUID5", mad_dump_hex},
>+	{384, 64, "GUID6", mad_dump_hex},
>+	{448, 64, "GUID7", mad_dump_hex},
>+
>+	/* GUID Info Record */
>+	{BITSOFFS(0, 16), "Lid", mad_dump_uint},
>+	{BITSOFFS(16, 8), "BlockNum", mad_dump_uint},
>+	{64, 64, "Guid0", mad_dump_hex},
>+	{128, 64, "Guid1", mad_dump_hex},
>+	{192, 64, "Guid2", mad_dump_hex},
>+	{256, 64, "Guid3", mad_dump_hex},
>+	{320, 64, "Guid4", mad_dump_hex},
>+	{384, 64, "Guid5", mad_dump_hex},
>+	{448, 64, "Guid6", mad_dump_hex},
>+	{512, 64, "Guid7", mad_dump_hex},
>+
>+	/*
>+	 * More PortInfo fields
>+	 */
>+	{BITSOFFS(496, 4), "LinkSpeedExtActive", mad_dump_linkspeedext},
>+	{BITSOFFS(500, 4), "LinkSpeedExtSupported", mad_dump_linkspeedextsup},
>+	{BITSOFFS(507, 5), "LinkSpeedExtEnabled", mad_dump_linkspeedexten},
>+	{0, 0},			/* IB_PORT_LINK_SPEED_EXT_LAST_F */
>+
>+	/*
>+	 * PortExtendedSpeedsCounters fields
>+	 */
>+	{BITSOFFS(8, 8), "PortSelect", mad_dump_uint},
>+	{64, 64, "CounterSelect", mad_dump_hex},
>+	{BITSOFFS(128, 8), "SyncHeaderErrorCounter", mad_dump_uint},
>+	{BITSOFFS(136, 8), "UnknownBlockCounter", mad_dump_uint},
>+	{BITSOFFS(144, 8), "ErrorDetectionCounterLane0", mad_dump_uint},
>+	{BITSOFFS(152, 8), "ErrorDetectionCounterLane1", mad_dump_uint},
>+	{BITSOFFS(160, 8), "ErrorDetectionCounterLane2", mad_dump_uint},
>+	{BITSOFFS(168, 8), "ErrorDetectionCounterLane3", mad_dump_uint},
>+	{BITSOFFS(176, 8), "ErrorDetectionCounterLane4", mad_dump_uint},
>+	{BITSOFFS(184, 8), "ErrorDetectionCounterLane5", mad_dump_uint},
>+	{BITSOFFS(192, 8), "ErrorDetectionCounterLane6", mad_dump_uint},
>+	{BITSOFFS(200, 8), "ErrorDetectionCounterLane7", mad_dump_uint},
>+	{BITSOFFS(208, 8), "ErrorDetectionCounterLane8", mad_dump_uint},
>+	{BITSOFFS(216, 8), "ErrorDetectionCounterLane9", mad_dump_uint},
>+	{BITSOFFS(224, 8), "ErrorDetectionCounterLane10", mad_dump_uint},
>+	{BITSOFFS(232, 8), "ErrorDetectionCounterLane11", mad_dump_uint},
>+	{256, 32, "FECCorrectableBlockCtrLane0", mad_dump_uint},
>+	{288, 32, "FECCorrectableBlockCtrLane1", mad_dump_uint},
>+	{320, 32, "FECCorrectableBlockCtrLane2", mad_dump_uint},
>+	{352, 32, "FECCorrectableBlockCtrLane3", mad_dump_uint},
>+	{384, 32, "FECCorrectableBlockCtrLane4", mad_dump_uint},
>+	{416, 32, "FECCorrectableBlockCtrLane5", mad_dump_uint},
>+	{448, 32, "FECCorrectableBlockCtrLane6", mad_dump_uint},
>+	{480, 32, "FECCorrectableBlockCtrLane7", mad_dump_uint},
>+	{512, 32, "FECCorrectableBlockCtrLane8", mad_dump_uint},
>+	{544, 32, "FECCorrectableBlockCtrLane9", mad_dump_uint},
>+	{580, 32, "FECCorrectableBlockCtrLane10", mad_dump_uint},
>+	{608, 32, "FECCorrectableBlockCtrLane11", mad_dump_uint},
>+	{640, 32, "FECUncorrectableBlockCtrLane0", mad_dump_uint},
>+	{672, 32, "FECUncorrectableBlockCtrLane1", mad_dump_uint},
>+	{704, 32, "FECUncorrectableBlockCtrLane2", mad_dump_uint},
>+	{736, 32, "FECUncorrectableBlockCtrLane3", mad_dump_uint},
>+	{768, 32, "FECUncorrectableBlockCtrLane4", mad_dump_uint},
>+	{800, 32, "FECUncorrectableBlockCtrLane5", mad_dump_uint},
>+	{832, 32, "FECUncorrectableBlockCtrLane6", mad_dump_uint},
>+	{864, 32, "FECUncorrectableBlockCtrLane7", mad_dump_uint},
>+	{896, 32, "FECUncorrectableBlockCtrLane8", mad_dump_uint},
>+	{928, 32, "FECUncorrectableBlockCtrLane9", mad_dump_uint},
>+	{960, 32, "FECUncorrectableBlockCtrLane10", mad_dump_uint},
>+	{992, 32, "FECUncorrectableBlockCtrLane11", mad_dump_uint},
>+	{0, 0},			/* IB_PESC_LAST_F */
>+
>+	/*
>+	 * PortOpRcvCounters fields
>+	 */
>+	{32, 32, "PortOpRcvPkts", mad_dump_uint},
>+	{64, 32, "PortOpRcvData", mad_dump_uint},
>+	{0, 0},			/* IB_PC_PORT_OP_RCV_COUNTERS_LAST_F */
>+
>+	/*
>+	 * PortFlowCtlCounters fields
>+	 */
>+	{32, 32, "PortXmitFlowPkts", mad_dump_uint},
>+	{64, 32, "PortRcvFlowPkts", mad_dump_uint},
>+	{0, 0},			/* IB_PC_PORT_FLOW_CTL_COUNTERS_LAST_F */
>+
>+	/*
>+	 * PortVLOpPackets fields
>+	 */
>+	{BITSOFFS(32, 16), "PortVLOpPackets0", mad_dump_uint},
>+	{BITSOFFS(48, 16), "PortVLOpPackets1", mad_dump_uint},
>+	{BITSOFFS(64, 16), "PortVLOpPackets2", mad_dump_uint},
>+	{BITSOFFS(80, 16), "PortVLOpPackets3", mad_dump_uint},
>+	{BITSOFFS(96, 16), "PortVLOpPackets4", mad_dump_uint},
>+	{BITSOFFS(112, 16), "PortVLOpPackets5", mad_dump_uint},
>+	{BITSOFFS(128, 16), "PortVLOpPackets6", mad_dump_uint},
>+	{BITSOFFS(144, 16), "PortVLOpPackets7", mad_dump_uint},
>+	{BITSOFFS(160, 16), "PortVLOpPackets8", mad_dump_uint},
>+	{BITSOFFS(176, 16), "PortVLOpPackets9", mad_dump_uint},
>+	{BITSOFFS(192, 16), "PortVLOpPackets10", mad_dump_uint},
>+	{BITSOFFS(208, 16), "PortVLOpPackets11", mad_dump_uint},
>+	{BITSOFFS(224, 16), "PortVLOpPackets12", mad_dump_uint},
>+	{BITSOFFS(240, 16), "PortVLOpPackets13", mad_dump_uint},
>+	{BITSOFFS(256, 16), "PortVLOpPackets14", mad_dump_uint},
>+	{BITSOFFS(272, 16), "PortVLOpPackets15", mad_dump_uint},
>+	{0, 0},			/* IB_PC_PORT_VL_OP_PACKETS_LAST_F */
>+
>+	/*
>+	 * PortVLOpData fields
>+	 */
>+	{32, 32, "PortVLOpData0", mad_dump_uint},
>+	{64, 32, "PortVLOpData1", mad_dump_uint},
>+	{96, 32, "PortVLOpData2", mad_dump_uint},
>+	{128, 32, "PortVLOpData3", mad_dump_uint},
>+	{160, 32, "PortVLOpData4", mad_dump_uint},
>+	{192, 32, "PortVLOpData5", mad_dump_uint},
>+	{224, 32, "PortVLOpData6", mad_dump_uint},
>+	{256, 32, "PortVLOpData7", mad_dump_uint},
>+	{288, 32, "PortVLOpData8", mad_dump_uint},
>+	{320, 32, "PortVLOpData9", mad_dump_uint},
>+	{352, 32, "PortVLOpData10", mad_dump_uint},
>+	{384, 32, "PortVLOpData11", mad_dump_uint},
>+	{416, 32, "PortVLOpData12", mad_dump_uint},
>+	{448, 32, "PortVLOpData13", mad_dump_uint},
>+	{480, 32, "PortVLOpData14", mad_dump_uint},
>+	{512, 32, "PortVLOpData15", mad_dump_uint},
>+	{0, 0},			/* IB_PC_PORT_VL_OP_DATA_LAST_F */
>+
>+	/*
>+	 * PortVLXmitFlowCtlUpdateErrors fields
>+	 */
>+	{BITSOFFS(32, 2), "PortVLXmitFlowCtlUpdateErrors0", mad_dump_uint},
>+	{BITSOFFS(34, 2), "PortVLXmitFlowCtlUpdateErrors1", mad_dump_uint},
>+	{BITSOFFS(36, 2), "PortVLXmitFlowCtlUpdateErrors2", mad_dump_uint},
>+	{BITSOFFS(38, 2), "PortVLXmitFlowCtlUpdateErrors3", mad_dump_uint},
>+	{BITSOFFS(40, 2), "PortVLXmitFlowCtlUpdateErrors4", mad_dump_uint},
>+	{BITSOFFS(42, 2), "PortVLXmitFlowCtlUpdateErrors5", mad_dump_uint},
>+	{BITSOFFS(44, 2), "PortVLXmitFlowCtlUpdateErrors6", mad_dump_uint},
>+	{BITSOFFS(46, 2), "PortVLXmitFlowCtlUpdateErrors7", mad_dump_uint},
>+	{BITSOFFS(48, 2), "PortVLXmitFlowCtlUpdateErrors8", mad_dump_uint},
>+	{BITSOFFS(50, 2), "PortVLXmitFlowCtlUpdateErrors9", mad_dump_uint},
>+	{BITSOFFS(52, 2), "PortVLXmitFlowCtlUpdateErrors10", mad_dump_uint},
>+	{BITSOFFS(54, 2), "PortVLXmitFlowCtlUpdateErrors11", mad_dump_uint},
>+	{BITSOFFS(56, 2), "PortVLXmitFlowCtlUpdateErrors12", mad_dump_uint},
>+	{BITSOFFS(58, 2), "PortVLXmitFlowCtlUpdateErrors13", mad_dump_uint},
>+	{BITSOFFS(60, 2), "PortVLXmitFlowCtlUpdateErrors14", mad_dump_uint},
>+	{BITSOFFS(62, 2), "PortVLXmitFlowCtlUpdateErrors15", mad_dump_uint},
>+	{0, 0},			/* IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_LAST_F */
>+
>+	/*
>+	 * PortVLXmitWaitCounters fields
>+	 */
>+	{BITSOFFS(32, 16), "PortVLXmitWait0", mad_dump_uint},
>+	{BITSOFFS(48, 16), "PortVLXmitWait1", mad_dump_uint},
>+	{BITSOFFS(64, 16), "PortVLXmitWait2", mad_dump_uint},
>+	{BITSOFFS(80, 16), "PortVLXmitWait3", mad_dump_uint},
>+	{BITSOFFS(96, 16), "PortVLXmitWait4", mad_dump_uint},
>+	{BITSOFFS(112, 16), "PortVLXmitWait5", mad_dump_uint},
>+	{BITSOFFS(128, 16), "PortVLXmitWait6", mad_dump_uint},
>+	{BITSOFFS(144, 16), "PortVLXmitWait7", mad_dump_uint},
>+	{BITSOFFS(160, 16), "PortVLXmitWait8", mad_dump_uint},
>+	{BITSOFFS(176, 16), "PortVLXmitWait9", mad_dump_uint},
>+	{BITSOFFS(192, 16), "PortVLXmitWait10", mad_dump_uint},
>+	{BITSOFFS(208, 16), "PortVLXmitWait11", mad_dump_uint},
>+	{BITSOFFS(224, 16), "PortVLXmitWait12", mad_dump_uint},
>+	{BITSOFFS(240, 16), "PortVLXmitWait13", mad_dump_uint},
>+	{BITSOFFS(256, 16), "PortVLXmitWait14", mad_dump_uint},
>+	{BITSOFFS(272, 16), "PortVLXmitWait15", mad_dump_uint},
>+	{0, 0},			/* IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_LAST_F */
>+
>+	/*
>+	 * SwPortVLCongestion fields
>+	 */
>+	{BITSOFFS(32, 16), "SWPortVLCongestion0", mad_dump_uint},
>+	{BITSOFFS(48, 16), "SWPortVLCongestion1", mad_dump_uint},
>+	{BITSOFFS(64, 16), "SWPortVLCongestion2", mad_dump_uint},
>+	{BITSOFFS(80, 16), "SWPortVLCongestion3", mad_dump_uint},
>+	{BITSOFFS(96, 16), "SWPortVLCongestion4", mad_dump_uint},
>+	{BITSOFFS(112, 16), "SWPortVLCongestion5", mad_dump_uint},
>+	{BITSOFFS(128, 16), "SWPortVLCongestion6", mad_dump_uint},
>+	{BITSOFFS(144, 16), "SWPortVLCongestion7", mad_dump_uint},
>+	{BITSOFFS(160, 16), "SWPortVLCongestion8", mad_dump_uint},
>+	{BITSOFFS(176, 16), "SWPortVLCongestion9", mad_dump_uint},
>+	{BITSOFFS(192, 16), "SWPortVLCongestion10", mad_dump_uint},
>+	{BITSOFFS(208, 16), "SWPortVLCongestion11", mad_dump_uint},
>+	{BITSOFFS(224, 16), "SWPortVLCongestion12", mad_dump_uint},
>+	{BITSOFFS(240, 16), "SWPortVLCongestion13", mad_dump_uint},
>+	{BITSOFFS(256, 16), "SWPortVLCongestion14", mad_dump_uint},
>+	{BITSOFFS(272, 16), "SWPortVLCongestion15", mad_dump_uint},
>+	{0, 0},			/* IB_PC_SW_PORT_VL_CONGESTION_LAST_F */
>+
>+	/*
>+	 * PortRcvConCtrl fields
>+	 */
>+	{32, 32, "PortPktRcvFECN", mad_dump_uint},
>+	{64, 32, "PortPktRcvBECN", mad_dump_uint},
>+	{0, 0},			/* IB_PC_RCV_CON_CTRL_LAST_F */
>+
>+	/*
>+	 * PortSLRcvFECN fields
>+	 */
>+	{32, 32, "PortSLRcvFECN0", mad_dump_uint},
>+	{64, 32, "PortSLRcvFECN1", mad_dump_uint},
>+	{96, 32, "PortSLRcvFECN2", mad_dump_uint},
>+	{128, 32, "PortSLRcvFECN3", mad_dump_uint},
>+	{160, 32, "PortSLRcvFECN4", mad_dump_uint},
>+	{192, 32, "PortSLRcvFECN5", mad_dump_uint},
>+	{224, 32, "PortSLRcvFECN6", mad_dump_uint},
>+	{256, 32, "PortSLRcvFECN7", mad_dump_uint},
>+	{288, 32, "PortSLRcvFECN8", mad_dump_uint},
>+	{320, 32, "PortSLRcvFECN9", mad_dump_uint},
>+	{352, 32, "PortSLRcvFECN10", mad_dump_uint},
>+	{384, 32, "PortSLRcvFECN11", mad_dump_uint},
>+	{416, 32, "PortSLRcvFECN12", mad_dump_uint},
>+	{448, 32, "PortSLRcvFECN13", mad_dump_uint},
>+	{480, 32, "PortSLRcvFECN14", mad_dump_uint},
>+	{512, 32, "PortSLRcvFECN15", mad_dump_uint},
>+	{0, 0},			/* IB_PC_SL_RCV_FECN_LAST_F */
>+
>+	/*
>+	 * PortSLRcvBECN fields
>+	 */
>+	{32, 32, "PortSLRcvBECN0", mad_dump_uint},
>+	{64, 32, "PortSLRcvBECN1", mad_dump_uint},
>+	{96, 32, "PortSLRcvBECN2", mad_dump_uint},
>+	{128, 32, "PortSLRcvBECN3", mad_dump_uint},
>+	{160, 32, "PortSLRcvBECN4", mad_dump_uint},
>+	{192, 32, "PortSLRcvBECN5", mad_dump_uint},
>+	{224, 32, "PortSLRcvBECN6", mad_dump_uint},
>+	{256, 32, "PortSLRcvBECN7", mad_dump_uint},
>+	{288, 32, "PortSLRcvBECN8", mad_dump_uint},
>+	{320, 32, "PortSLRcvBECN9", mad_dump_uint},
>+	{352, 32, "PortSLRcvBECN10", mad_dump_uint},
>+	{384, 32, "PortSLRcvBECN11", mad_dump_uint},
>+	{416, 32, "PortSLRcvBECN12", mad_dump_uint},
>+	{448, 32, "PortSLRcvBECN13", mad_dump_uint},
>+	{480, 32, "PortSLRcvBECN14", mad_dump_uint},
>+	{512, 32, "PortSLRcvBECN15", mad_dump_uint},
>+	{0, 0},			/* IB_PC_SL_RCV_BECN_LAST_F */
>+
>+	/*
>+	 * PortXmitConCtrl fields
>+	 */
>+	{32, 32, "PortXmitTimeCong", mad_dump_uint},
>+	{0, 0},			/* IB_PC_XMIT_CON_CTRL_LAST_F */
>+
>+	/*
>+	 * PortVLXmitTimeCong fields
>+	 */
>+	{32, 32, "PortVLXmitTimeCong0", mad_dump_uint},
>+	{64, 32, "PortVLXmitTimeCong1", mad_dump_uint},
>+	{96, 32, "PortVLXmitTimeCong2", mad_dump_uint},
>+	{128, 32, "PortVLXmitTimeCong3", mad_dump_uint},
>+	{160, 32, "PortVLXmitTimeCong4", mad_dump_uint},
>+	{192, 32, "PortVLXmitTimeCong5", mad_dump_uint},
>+	{224, 32, "PortVLXmitTimeCong6", mad_dump_uint},
>+	{256, 32, "PortVLXmitTimeCong7", mad_dump_uint},
>+	{288, 32, "PortVLXmitTimeCong8", mad_dump_uint},
>+	{320, 32, "PortVLXmitTimeCong9", mad_dump_uint},
>+	{352, 32, "PortVLXmitTimeCong10", mad_dump_uint},
>+	{384, 32, "PortVLXmitTimeCong11", mad_dump_uint},
>+	{416, 32, "PortVLXmitTimeCong12", mad_dump_uint},
>+	{448, 32, "PortVLXmitTimeCong13", mad_dump_uint},
>+	{480, 32, "PortVLXmitTimeCong14", mad_dump_uint},
>+	{0, 0},			/* IB_PC_VL_XMIT_TIME_CONG_LAST_F */
>+
>+	/*
>+	 * Mellanox ExtendedPortInfo fields
>+	 */
>+	{BITSOFFS(24, 8), "StateChangeEnable", mad_dump_hex},
>+	{BITSOFFS(56, 8), "LinkSpeedSupported", mad_dump_hex},
>+	{BITSOFFS(88, 8), "LinkSpeedEnabled", mad_dump_hex},
>+	{BITSOFFS(120, 8), "LinkSpeedActive", mad_dump_hex},
>+	{0, 0},			/* IB_MLNX_EXT_PORT_LAST_F */
>+
> 	{0, 0}			/* IB_FIELD_LAST_ */
>
> };
>diff --git a/trunk/ulp/libibmad/src/gs.c b/trunk/ulp/libibmad/src/gs.c
>index 3cb2b25..5541b6b 100644
>--- a/trunk/ulp/libibmad/src/gs.c
>+++ b/trunk/ulp/libibmad/src/gs.c
>@@ -1,5 +1,6 @@
> /*
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>+ * Copyright (c) 2011 Mellanox Technologies LTD.  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
>@@ -38,6 +39,7 @@
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>+#include <errno.h>
>
> #include <infiniband/umad.h>
> #include <infiniband/mad.h>
>@@ -49,8 +51,10 @@ uint8_t *pma_query_via(void *rcvbuf, ib_portid_t * dest, int port,
> 		       unsigned timeout, unsigned id,
> 		       const struct ibmad_port * srcport)
> {
>-	ib_rpc_t rpc = { 0 };
>+	ib_rpc_v1_t rpc = { 0 };
>+	ib_rpc_t *rpcold = (ib_rpc_t *)(void *)&rpc;
> 	int lid = dest->lid;
>+	void *p_ret;
>
> 	DEBUG("lid %u port %d", lid, port);
>
>@@ -59,7 +63,7 @@ uint8_t *pma_query_via(void *rcvbuf, ib_portid_t * dest, int port,
> 		return NULL;
> 	}
>
>-	rpc.mgtclass = IB_PERFORMANCE_CLASS;
>+	rpc.mgtclass = IB_PERFORMANCE_CLASS | IB_MAD_RPC_VERSION1;
> 	rpc.method = IB_MAD_METHOD_GET;
> 	rpc.attr.id = id;
>
>@@ -75,15 +79,20 @@ uint8_t *pma_query_via(void *rcvbuf, ib_portid_t * dest, int port,
> 	if (!dest->qkey)
> 		dest->qkey = IB_DEFAULT_QP1_QKEY;
>
>-	return mad_rpc(srcport, &rpc, dest, rcvbuf, rcvbuf);
>+	p_ret = mad_rpc(srcport, rpcold, dest, rcvbuf, rcvbuf);
>+	errno = rpc.error;
>+	return p_ret;
> }
>
> uint8_t *performance_reset_via(void *rcvbuf, ib_portid_t * dest,
> 			       int port, unsigned mask, unsigned timeout,
> 			       unsigned id, const struct ibmad_port * srcport)
> {
>-	ib_rpc_t rpc = { 0 };
>+	ib_rpc_v1_t rpc = { 0 };
>+	ib_rpc_t *rpcold = (ib_rpc_t *)(void *)&rpc;
>+
> 	int lid = dest->lid;
>+	void *p_ret;
>
> 	DEBUG("lid %u port %d mask 0x%x", lid, port, mask);
>
>@@ -95,7 +104,7 @@ uint8_t *performance_reset_via(void *rcvbuf, ib_portid_t * dest,
> 	if (!mask)
> 		mask = ~0;
>
>-	rpc.mgtclass = IB_PERFORMANCE_CLASS;
>+	rpc.mgtclass = IB_PERFORMANCE_CLASS | IB_MAD_RPC_VERSION1;
> 	rpc.method = IB_MAD_METHOD_SET;
> 	rpc.attr.id = id;
>
>@@ -115,5 +124,7 @@ uint8_t *performance_reset_via(void *rcvbuf, ib_portid_t * dest,
> 	if (!dest->qkey)
> 		dest->qkey = IB_DEFAULT_QP1_QKEY;
>
>-	return mad_rpc(srcport, &rpc, dest, rcvbuf, rcvbuf);
>+	p_ret = mad_rpc(srcport, rpcold, dest, rcvbuf, rcvbuf);
>+	errno = rpc.error;
>+	return p_ret;
> }
>diff --git a/trunk/ulp/libibmad/src/ibmad_exports.src b/trunk/ulp/libibmad/src/ibmad_exports.src
>index d0f9480..c0d3489 100644
>--- a/trunk/ulp/libibmad/src/ibmad_exports.src
>+++ b/trunk/ulp/libibmad/src/ibmad_exports.src
>@@ -2,42 +2,133 @@ LIBRARY libibmad.dll
>
> #ifndef _WIN64
> EXPORTS
>-	mad_set_field;
>-	mad_get_field;
>-	mad_set_array;
>-	mad_get_array;
>-	mad_set_field64;
>-	mad_get_field64;
>-	mad_decode_field;
>-	mad_encode_field;
>-	mad_encode;
>-	mad_trid;
>-	mad_build_pkt;
>-	mad_register_port_client;
>-	mad_register_client;
>-	mad_register_server;
>-	mad_class_agent;
>-	mad_send;
>-	mad_receive;
>-	mad_respond;
>-	mad_alloc;
>-	mad_free;
>-	madrpc_portid;
>-	madrpc_init;
>-	madrpc_set_retries;
>-	madrpc_set_timeout;
>-	madrpc_show_errors;
>-	smp_query;
>-	smp_set;
>-	smp_query_via;
>-	ib_vendor_call;
>-	ib_path_query;
>-	ib_resolve_smlid;
>-	ib_resolve_portid_str;
>-	ib_resolve_self;
>-	portid2str;
>-	portid2portnum;
>-	str2drpath;
>-	drpath2str;
>-	xdump
>+		xdump;
>+		mad_dump_field;
>+		mad_dump_val;
>+		mad_print_field;
>+		mad_dump_array;
>+		mad_dump_bitfield;
>+		mad_dump_hex;
>+		mad_dump_int;
>+		mad_dump_linkdowndefstate;
>+		mad_dump_linkspeed;
>+		mad_dump_linkspeeden;
>+		mad_dump_linkspeedsup;
>+		mad_dump_linkspeedext;
>+		mad_dump_linkspeedexten;
>+		mad_dump_linkspeedextsup;
>+		mad_dump_linkwidth;
>+		mad_dump_linkwidthen;
>+		mad_dump_linkwidthsup;
>+		mad_dump_mlnx_ext_port_info;
>+		mad_dump_mtu;
>+		mad_dump_node_type;
>+		mad_dump_nodedesc;
>+		mad_dump_nodeinfo;
>+		mad_dump_opervls;
>+		mad_dump_fields;
>+		mad_dump_perfcounters;
>+		mad_dump_perfcounters_ext;
>+		mad_dump_perfcounters_xmt_sl;
>+		mad_dump_perfcounters_rcv_sl;
>+		mad_dump_perfcounters_xmt_disc;
>+		mad_dump_perfcounters_rcv_err;
>+		mad_dump_physportstate;
>+		mad_dump_portcapmask;
>+		mad_dump_portinfo;
>+		mad_dump_portsamples_control;
>+		mad_dump_perfcounters_port_op_rcv_counters;
>+		mad_dump_perfcounters_port_flow_ctl_counters;
>+		mad_dump_perfcounters_port_vl_op_packet;
>+		mad_dump_perfcounters_port_vl_op_data;
>+		mad_dump_perfcounters_port_vl_xmit_flow_ctl_update_errors;
>+		mad_dump_perfcounters_port_vl_xmit_wait_counters;
>+		mad_dump_perfcounters_sw_port_vl_congestion;
>+		mad_dump_perfcounters_rcv_con_ctrl;
>+		mad_dump_perfcounters_sl_rcv_fecn;
>+		mad_dump_perfcounters_sl_rcv_becn;
>+		mad_dump_perfcounters_xmit_con_ctrl;
>+		mad_dump_perfcounters_vl_xmit_time_cong;
>+		mad_dump_portstates;
>+		mad_dump_portstate;
>+		mad_dump_rhex;
>+		mad_dump_sltovl;
>+		mad_dump_string;
>+		mad_dump_switchinfo;
>+		mad_dump_uint;
>+		mad_dump_vlarbitration;
>+		mad_dump_vlcap;
>+		mad_get_field;
>+		mad_set_field;
>+		mad_get_field64;
>+		mad_set_field64;
>+		mad_get_array;
>+		mad_set_array;
>+		pma_query_via;
>+		performance_reset_via;
>+		mad_build_pkt;
>+		mad_decode_field;
>+		mad_encode;
>+		mad_encode_field;
>+		mad_trid;
>+		portid2portnum;
>+		portid2str;
>+		str2drpath;
>+		drpath2str;
>+		mad_class_agent;
>+		mad_register_client;
>+		mad_register_server;
>+		mad_register_client_via;
>+		mad_register_server_via;
>+		ib_resolve_portid_str;
>+		ib_resolve_self;
>+		ib_resolve_smlid;
>+		ibdebug;
>+		mad_rpc_open_port;
>+		mad_rpc_close_port;
>+		mad_rpc;
>+		mad_rpc_rmpp;
>+		mad_rpc_portid;
>+		mad_rpc_class_agent;
>+		mad_rpc_set_retries;
>+		mad_rpc_set_timeout;
>+		mad_get_timeout;
>+		mad_get_retries;
>+		madrpc;
>+		madrpc_def_timeout;
>+		madrpc_init;
>+		madrpc_portid;
>+		madrpc_rmpp;
>+		madrpc_save_mad;
>+		madrpc_set_retries;
>+		madrpc_set_timeout;
>+		madrpc_show_errors;
>+		ib_path_query;
>+		sa_call;
>+		sa_rpc_call;
>+		mad_alloc;
>+		mad_free;
>+		mad_receive;
>+		mad_respond;
>+		mad_receive_via;
>+		mad_respond_via;
>+		mad_send;
>+		mad_send_via;
>+		smp_query;
>+		smp_set;
>+		ib_vendor_call;
>+		ib_vendor_call_via;
>+		smp_query_via;
>+		smp_query_status_via;
>+		smp_set_via;
>+		smp_set_status_via;
>+		ib_path_query_via;
>+		ib_resolve_smlid_via;
>+		ib_resolve_guid_via;
>+		ib_resolve_gid_via;
>+		ib_resolve_portid_str_via;
>+		ib_resolve_self_via;
>+		mad_field_name;
>+		bm_call_via;
>+		mad_dump_port_ext_speeds_counters;
> #endif
>diff --git a/trunk/ulp/libibmad/src/libibmad.map b/trunk/ulp/libibmad/src/libibmad.map
>index 5778e3e..508c18b 100644
>--- a/trunk/ulp/libibmad/src/libibmad.map
>+++ b/trunk/ulp/libibmad/src/libibmad.map
>@@ -12,9 +12,13 @@ IBMAD_1.3 {
> 		mad_dump_linkspeed;
> 		mad_dump_linkspeeden;
> 		mad_dump_linkspeedsup;
>+		mad_dump_linkspeedext;
>+		mad_dump_linkspeedexten;
>+		mad_dump_linkspeedextsup;
> 		mad_dump_linkwidth;
> 		mad_dump_linkwidthen;
> 		mad_dump_linkwidthsup;
>+		mad_dump_mlnx_ext_port_info;
> 		mad_dump_mtu;
> 		mad_dump_node_type;
> 		mad_dump_nodedesc;
>@@ -31,6 +35,18 @@ IBMAD_1.3 {
> 		mad_dump_portcapmask;
> 		mad_dump_portinfo;
> 		mad_dump_portsamples_control;
>+		mad_dump_perfcounters_port_op_rcv_counters;
>+		mad_dump_perfcounters_port_flow_ctl_counters;
>+		mad_dump_perfcounters_port_vl_op_packet;
>+		mad_dump_perfcounters_port_vl_op_data;
>+		mad_dump_perfcounters_port_vl_xmit_flow_ctl_update_errors;
>+		mad_dump_perfcounters_port_vl_xmit_wait_counters;
>+		mad_dump_perfcounters_sw_port_vl_congestion;
>+		mad_dump_perfcounters_rcv_con_ctrl;
>+		mad_dump_perfcounters_sl_rcv_fecn;
>+		mad_dump_perfcounters_sl_rcv_becn;
>+		mad_dump_perfcounters_xmit_con_ctrl;
>+		mad_dump_perfcounters_vl_xmit_time_cong;
> 		mad_dump_portstates;
> 		mad_dump_portstate;
> 		mad_dump_rhex;
>@@ -101,7 +117,9 @@ IBMAD_1.3 {
> 		ib_vendor_call;
> 		ib_vendor_call_via;
> 		smp_query_via;
>+		smp_query_status_via;
> 		smp_set_via;
>+		smp_set_status_via;
> 		ib_path_query_via;
> 		ib_resolve_smlid_via;
> 		ib_resolve_guid_via;
>@@ -110,5 +128,6 @@ IBMAD_1.3 {
> 		ib_resolve_self_via;
> 		mad_field_name;
> 		bm_call_via;
>+		mad_dump_port_ext_speeds_counters;
> 	local: *;
> };
>diff --git a/trunk/ulp/libibmad/src/mad.c b/trunk/ulp/libibmad/src/mad.c
>index acd0e85..463c61d 100644
>--- a/trunk/ulp/libibmad/src/mad.c
>+++ b/trunk/ulp/libibmad/src/mad.c
>@@ -1,6 +1,7 @@
> /*
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>  * Copyright (c) 2009 HNR Consulting.  All rights reserved.
>+ * Copyright (c) 2011 Mellanox Technologies LTD.  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
>@@ -83,12 +84,12 @@ void *mad_encode(void *buf, ib_rpc_t * rpc, ib_dr_path_t * drpath, void *data)
> 	mad_set_field(buf, 0, IB_MAD_METHOD_F, rpc->method);
> 	mad_set_field(buf, 0, IB_MAD_RESPONSE_F, is_resp ? 1 : 0);
> 	mad_set_field(buf, 0, IB_MAD_CLASSVER_F,
>-		      rpc->mgtclass == IB_SA_CLASS ? 2 : 1);
>-	mad_set_field(buf, 0, IB_MAD_MGMTCLASS_F, rpc->mgtclass);
>+		      (rpc->mgtclass & 0xff) == IB_SA_CLASS ? 2 : 1);
>+	mad_set_field(buf, 0, IB_MAD_MGMTCLASS_F, rpc->mgtclass & 0xff);
> 	mad_set_field(buf, 0, IB_MAD_BASEVER_F, 1);
>
> 	/* second word */
>-	if (rpc->mgtclass == IB_SMI_DIRECT_CLASS) {
>+	if ((rpc->mgtclass & 0xff) == IB_SMI_DIRECT_CLASS) {
> 		if (!drpath) {
> 			IBWARN("encoding dr mad without drpath (null)");
> 			return NULL;
>@@ -116,7 +117,7 @@ void *mad_encode(void *buf, ib_rpc_t * rpc, ib_dr_path_t * drpath, void *data)
> 	/* words 7,8 */
> 	mad_set_field64(buf, 0, IB_MAD_MKEY_F, rpc->mkey);
>
>-	if (rpc->mgtclass == IB_SMI_DIRECT_CLASS) {
>+	if ((rpc->mgtclass & 0xff) == IB_SMI_DIRECT_CLASS) {
> 		/* word 9 */
> 		mad_set_field(buf, 0, IB_DRSMP_DRDLID_F,
> 			      drpath->drdlid ? drpath->drdlid : 0xffff);
>@@ -130,14 +131,14 @@ void *mad_encode(void *buf, ib_rpc_t * rpc, ib_dr_path_t * drpath, void *data)
> 			mad_set_array(buf, 0, IB_DRSMP_PATH_F, drpath->p);
> 	}
>
>-	if (rpc->mgtclass == IB_SA_CLASS)
>+	if ((rpc->mgtclass & 0xff) == IB_SA_CLASS)
> 		mad_set_field64(buf, 0, IB_SA_COMPMASK_F, rpc->mask);
>
> 	if (data)
> 		memcpy((char *)buf + rpc->dataoffs, data, rpc->datasz);
>
> 	/* vendor mads range 2 */
>-	if (mad_is_vendor_range2(rpc->mgtclass))
>+	if (mad_is_vendor_range2(rpc->mgtclass & 0xff))
> 		mad_set_field(buf, 0, IB_VEND2_OUI_F, rpc->oui);
>
> 	return (uint8_t *) buf + IB_MAD_SIZE;
>@@ -147,9 +148,9 @@ int mad_build_pkt(void *umad, ib_rpc_t * rpc, ib_portid_t * dport,
> 		  ib_rmpp_hdr_t * rmpp, void *data)
> {
> 	uint8_t *p, *mad;
>-	int lid_routed = rpc->mgtclass != IB_SMI_DIRECT_CLASS;
>-	int is_smi = (rpc->mgtclass == IB_SMI_CLASS ||
>-		      rpc->mgtclass == IB_SMI_DIRECT_CLASS);
>+	int lid_routed = (rpc->mgtclass & 0xff) != IB_SMI_DIRECT_CLASS;
>+	int is_smi = ((rpc->mgtclass & 0xff) == IB_SMI_CLASS ||
>+		      (rpc->mgtclass & 0xff) == IB_SMI_DIRECT_CLASS);
> 	struct ib_mad_addr addr;
>
> 	if (!is_smi)
>diff --git a/trunk/ulp/libibmad/src/register.c b/trunk/ulp/libibmad/src/register.c
>index 0ff8006..1fdb64a 100644
>--- a/trunk/ulp/libibmad/src/register.c
>+++ b/trunk/ulp/libibmad/src/register.c
>@@ -77,7 +77,7 @@ static int mgmt_class_vers(int mgmt_class)
>
> int mad_class_agent(int mgmt)
> {
>-	if (mgmt < 1 || mgmt > MAX_CLASS)
>+	if (mgmt < 1 || mgmt >= MAX_CLASS)
> 		return -1;
> 	return ibmp->class_agents[mgmt];
> }
>diff --git a/trunk/ulp/libibmad/src/rpc.c b/trunk/ulp/libibmad/src/rpc.c
>index c5246fe..d20c321 100644
>--- a/trunk/ulp/libibmad/src/rpc.c
>+++ b/trunk/ulp/libibmad/src/rpc.c
>@@ -1,6 +1,7 @@
> /*
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>  * Copyright (c) 2009 HNR Consulting.  All rights reserved.
>+ * Copyright (c) 2011 Mellanox Technologies LTD.  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
>@@ -119,14 +120,14 @@ int mad_rpc_portid(struct ibmad_port *srcport)
>
> int mad_rpc_class_agent(struct ibmad_port *port, int class)
> {
>-	if (class < 1 || class > MAX_CLASS)
>+	if (class < 1 || class >= MAX_CLASS)
> 		return -1;
> 	return port->class_agents[class];
> }
>
> static int
> _do_madrpc(int port_id, void *sndbuf, void *rcvbuf, int agentid, int len,
>-	   int timeout, int max_retries)
>+	   int timeout, int max_retries, int *p_error)
> {
> 	uint32_t trid;		/* only low 32 bits */
> 	int retries;
>@@ -181,6 +182,7 @@ _do_madrpc(int port_id, void *sndbuf, void *rcvbuf, int agentid, int len,
> 			return length;
> 	}
>
>+	*p_error = ETIMEDOUT;
> 	ERRS("timeout after %d retries, %d ms", retries, timeout * retries);
> 	return -1;
> }
>@@ -212,7 +214,11 @@ void *mad_rpc(const struct ibmad_port *port, ib_rpc_t * rpc,
> 	int status, len;
> 	uint8_t sndbuf[1024], rcvbuf[1024], *mad;
> 	int redirect = 1;
>+	ib_rpc_v1_t *rpcv1 = (ib_rpc_v1_t *)rpc;
>+	int error = 0;
>
>+	if ((rpc->mgtclass & IB_MAD_RPC_VERSION_MASK) == IB_MAD_RPC_VERSION1)
>+		rpcv1->error = 0;
> 	while (redirect) {
> 		len = 0;
> 		memset(sndbuf, 0, umad_size() + IB_MAD_SIZE);
>@@ -221,9 +227,12 @@ void *mad_rpc(const struct ibmad_port *port, ib_rpc_t * rpc,
> 			return NULL;
>
> 		if ((len = _do_madrpc(port->port_id, sndbuf, rcvbuf,
>-				      port->class_agents[rpc->mgtclass],
>+				      port->class_agents[rpc->mgtclass & 0xff],
> 				      len, mad_get_timeout(port, rpc->timeout),
>-				      mad_get_retries(port))) < 0) {
>+				      mad_get_retries(port), &error)) < 0) {
>+			if ((rpc->mgtclass & IB_MAD_RPC_VERSION_MASK) ==
>+			    IB_MAD_RPC_VERSION1)
>+				rpcv1->error = error;
> 			IBWARN("_do_madrpc failed; dport (%s)",
> 			       portid2str(dport));
> 			return NULL;
>@@ -243,6 +252,10 @@ void *mad_rpc(const struct ibmad_port *port, ib_rpc_t * rpc,
> 			redirect = 0;
> 	}
>
>+	if ((rpc->mgtclass & IB_MAD_RPC_VERSION_MASK) == IB_MAD_RPC_VERSION1)
>+		rpcv1->error = error;
>+	rpc->rstatus = status;
>+
> 	if (status != 0) {
> 		ERRS("MAD completed with error status 0x%x; dport (%s)",
> 		     status, portid2str(dport));
>@@ -265,22 +278,31 @@ void *mad_rpc_rmpp(const struct ibmad_port *port, ib_rpc_t * rpc,
> {
> 	int status, len;
> 	uint8_t sndbuf[1024], rcvbuf[1024], *mad;
>+	ib_rpc_v1_t *rpcv1 = (ib_rpc_v1_t *)rpc;
>+	int error = 0;
>
> 	memset(sndbuf, 0, umad_size() + IB_MAD_SIZE);
>
> 	DEBUG("rmpp %p data %p", rmpp, data);
>
>+	if ((rpc->mgtclass & IB_MAD_RPC_VERSION_MASK) == IB_MAD_RPC_VERSION1)
>+		rpcv1->error = 0;
> 	if ((len = mad_build_pkt(sndbuf, rpc, dport, rmpp, data)) < 0)
> 		return NULL;
>
> 	if ((len = _do_madrpc(port->port_id, sndbuf, rcvbuf,
>-			      port->class_agents[rpc->mgtclass],
>+			      port->class_agents[rpc->mgtclass & 0xff],
> 			      len, mad_get_timeout(port, rpc->timeout),
>-			      mad_get_retries(port))) < 0) {
>+			      mad_get_retries(port), &error)) < 0) {
>+		if ((rpc->mgtclass & IB_MAD_RPC_VERSION_MASK) == IB_MAD_RPC_VERSION1)
>+			rpcv1->error = error;
> 		IBWARN("_do_madrpc failed; dport (%s)", portid2str(dport));
> 		return NULL;
> 	}
>
>+	if ((rpc->mgtclass & IB_MAD_RPC_VERSION_MASK) == IB_MAD_RPC_VERSION1)
>+		rpcv1->error = error;
>+
> 	mad = umad_get_mad(rcvbuf);
>
> 	if ((status = mad_get_field(mad, 0, IB_MAD_STATUS_F)) != 0) {
>diff --git a/trunk/ulp/libibmad/src/serv.c b/trunk/ulp/libibmad/src/serv.c
>index df61f25..2e3b7ef 100644
>--- a/trunk/ulp/libibmad/src/serv.c
>+++ b/trunk/ulp/libibmad/src/serv.c
>@@ -72,7 +72,7 @@ int mad_send_via(ib_rpc_t * rpc, ib_portid_t * dport, ib_rmpp_hdr_t * rmpp,
> 		      (char *)umad_get_mad(umad) + rpc->dataoffs, rpc->datasz);
> 	}
>
>-	if (umad_send(srcport->port_id, srcport->class_agents[rpc->mgtclass],
>+	if (umad_send(srcport->port_id, srcport->class_agents[rpc->mgtclass & 0xff],
> 		      umad, IB_MAD_SIZE, mad_get_timeout(srcport, rpc->timeout),
> 		      0) < 0) {
> 		IBWARN("send failed; %m");
>diff --git a/trunk/ulp/libibmad/src/smp.c b/trunk/ulp/libibmad/src/smp.c
>index 3ff58ce..a337663 100644
>--- a/trunk/ulp/libibmad/src/smp.c
>+++ b/trunk/ulp/libibmad/src/smp.c
>@@ -1,5 +1,6 @@
> /*
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>+ * Copyright (c) 2011 Mellanox Technologies LTD.  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
>@@ -45,11 +46,12 @@
> #undef DEBUG
> #define DEBUG 	if (ibdebug)	IBWARN
>
>-uint8_t *smp_set_via(void *data, ib_portid_t * portid, unsigned attrid,
>-		     unsigned mod, unsigned timeout,
>-		     const struct ibmad_port *srcport)
>+uint8_t *smp_set_status_via(void *data, ib_portid_t * portid, unsigned attrid,
>+			    unsigned mod, unsigned timeout, int *rstatus,
>+			    const struct ibmad_port *srcport)
> {
> 	ib_rpc_t rpc = { 0 };
>+	uint8_t *res;
>
> 	DEBUG("attr 0x%x mod 0x%x route %s", attrid, mod, portid2str(portid));
> 	if ((portid->lid <= 0) ||
>@@ -69,7 +71,18 @@ uint8_t *smp_set_via(void *data, ib_portid_t * portid, unsigned attrid,
> 	portid->sl = 0;
> 	portid->qp = 0;
>
>-	return mad_rpc(srcport, &rpc, portid, data, data);
>+	res = mad_rpc(srcport, &rpc, portid, data, data);
>+	if (rstatus)
>+		*rstatus = rpc.rstatus;
>+	return res;
>+}
>+
>+uint8_t *smp_set_via(void *data, ib_portid_t * portid, unsigned attrid,
>+		     unsigned mod, unsigned timeout,
>+		     const struct ibmad_port *srcport)
>+{
>+	return smp_set_status_via(data, portid, attrid, mod, timeout, NULL,
>+				  srcport);
> }
>
> uint8_t *smp_set(void *data, ib_portid_t * portid, unsigned attrid,
>@@ -78,11 +91,12 @@ uint8_t *smp_set(void *data, ib_portid_t * portid, unsigned attrid,
> 	return smp_set_via(data, portid, attrid, mod, timeout, ibmp);
> }
>
>-uint8_t *smp_query_via(void *rcvbuf, ib_portid_t * portid, unsigned attrid,
>-		       unsigned mod, unsigned timeout,
>-		       const struct ibmad_port * srcport)
>+uint8_t *smp_query_status_via(void *rcvbuf, ib_portid_t * portid,
>+			      unsigned attrid, unsigned mod, unsigned timeout,
>+			      int *rstatus, const struct ibmad_port * srcport)
> {
> 	ib_rpc_t rpc = { 0 };
>+	uint8_t *res;
>
> 	DEBUG("attr 0x%x mod 0x%x route %s", attrid, mod, portid2str(portid));
> 	rpc.method = IB_MAD_METHOD_GET;
>@@ -102,7 +116,18 @@ uint8_t *smp_query_via(void *rcvbuf, ib_portid_t * portid, unsigned attrid,
> 	portid->sl = 0;
> 	portid->qp = 0;
>
>-	return mad_rpc(srcport, &rpc, portid, 0, rcvbuf);
>+	res = mad_rpc(srcport, &rpc, portid, rcvbuf, rcvbuf);
>+	if (rstatus)
>+		*rstatus = rpc.rstatus;
>+	return res;
>+}
>+
>+uint8_t *smp_query_via(void *rcvbuf, ib_portid_t * portid, unsigned attrid,
>+		       unsigned mod, unsigned timeout,
>+		       const struct ibmad_port * srcport)
>+{
>+	return smp_query_status_via(rcvbuf, portid, attrid, mod, timeout, NULL,
>+				    srcport);
> }
>
> uint8_t *smp_query(void *rcvbuf, ib_portid_t * portid, unsigned attrid,
>diff --git a/trunk/ulp/libibmad/src/vendor.c b/trunk/ulp/libibmad/src/vendor.c
>index 11efd76..22d6843 100644
>--- a/trunk/ulp/libibmad/src/vendor.c
>+++ b/trunk/ulp/libibmad/src/vendor.c
>@@ -1,5 +1,6 @@
> /*
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>+ * Copyright (c) 2011 Mellanox Technologies LTD.  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
>@@ -38,6 +39,7 @@
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>+#include <errno.h>
>
> #include <infiniband/mad.h>
> #include "mad_internal.h"
>@@ -61,8 +63,10 @@ uint8_t *ib_vendor_call_via(void *data, ib_portid_t * portid,
> 			    ib_vendor_call_t * call,
> 			    struct ibmad_port * srcport)
> {
>-	ib_rpc_t rpc = { 0 };
>+	ib_rpc_v1_t rpc = { 0 };
>+	ib_rpc_t *rpcold = (ib_rpc_t *)(void *)&rpc;
> 	int range1 = 0, resp_expected;
>+	void *p_ret;
>
> 	DEBUG("route %s data %p", portid2str(portid), data);
> 	if (portid->lid <= 0)
>@@ -74,7 +78,7 @@ uint8_t *ib_vendor_call_via(void *data, ib_portid_t * portid,
>
> 	resp_expected = response_expected(call->method);
>
>-	rpc.mgtclass = call->mgmt_class;
>+	rpc.mgtclass = call->mgmt_class | IB_MAD_RPC_VERSION1;
>
> 	rpc.method = call->method;
> 	rpc.attr.id = call->attrid;
>@@ -97,8 +101,11 @@ uint8_t *ib_vendor_call_via(void *data, ib_portid_t * portid,
> 	if (!portid->qkey)
> 		portid->qkey = IB_DEFAULT_QP1_QKEY;
>
>-	if (resp_expected)
>-		return mad_rpc_rmpp(srcport, &rpc, portid, 0, data);	/* FIXME: no RMPP for now */
>+	if (resp_expected) {
>+		p_ret = mad_rpc_rmpp(srcport, rpcold, portid, 0, data);	/* FIXME: no RMPP for now */
>+		errno = rpc.error;
>+		return p_ret;
>+	}
>
>-	return mad_send_via(&rpc, portid, 0, data, srcport) < 0 ? 0 : data;	/* FIXME: no RMPP for now */
>+	return mad_send_via(rpcold, portid, 0, data, srcport) < 0 ? 0 : data;	/* FIXME: no RMPP for now */
> }
>diff --git a/trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc.h b/trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc.h
>index 49ff743..300094e 100644
>--- a/trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc.h
>+++ b/trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc.h
>@@ -1,6 +1,7 @@
> /*
>  * Copyright (c) 2009 Voltaire, Inc. All rights reserved.
>  * Copyright (c) 2008 Lawrence Livermore National Lab.  All rights reserved.
>+ * Copyright (c) 2010 Mellanox Technologies LTD.  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
>@@ -39,9 +40,13 @@
> #include <infiniband/mad.h>
> #include <iba/ib_types.h>
>
>+#include <infiniband/ibnetdisc_osd.h>
>+
> struct ibnd_chassis;		/* forward declare */
> struct ibnd_port;		/* forward declare */
>
>+#define CHASSIS_TYPE_SIZE 20
>+
> /** =========================================================================
>  * Node
>  */
>@@ -79,6 +84,7 @@ typedef struct ibnd_node {
> 	struct ibnd_node *next_chassis_node;	/* next node in ibnd_chassis_t->nodes */
> 	struct ibnd_chassis *chassis;	/* if != NULL the chassis this node belongs to */
> 	unsigned char ch_type;
>+	char ch_type_str[CHASSIS_TYPE_SIZE];
> 	unsigned char ch_anafanum;
> 	unsigned char ch_slotnum;
> 	unsigned char ch_slot;
>@@ -149,6 +155,8 @@ typedef struct ibnd_fabric {
> 	 * or by default the node you ar running on
> 	 */
> 	ibnd_node_t *from_node;
>+	int from_portnum;
>+
> 	/* NULL term list of all nodes in the fabric */
> 	ibnd_node_t *nodes;
> 	/* NULL terminated list of all chassis found in the fabric */
>@@ -187,6 +195,9 @@ IBND_EXPORT ibnd_fabric_t *ibnd_load_fabric(const char *file,
> IBND_EXPORT int ibnd_cache_fabric(ibnd_fabric_t * fabric, const char *file,
> 				 unsigned int flags);
>
>+#define IBND_CACHE_FABRIC_FLAG_DEFAULT      0x0000
>+#define IBND_CACHE_FABRIC_FLAG_NO_OVERWRITE 0x0001
>+
> /** =========================================================================
>  * Node operations
>  */
>@@ -202,6 +213,17 @@ IBND_EXPORT void ibnd_iter_nodes_type(ibnd_fabric_t * fabric,
> 				     int node_type, void *user_data);
>
> /** =========================================================================
>+ * Port operations
>+ */
>+IBND_EXPORT ibnd_port_t *ibnd_find_port_guid(ibnd_fabric_t * fabric,
>+					uint64_t guid);
>+IBND_EXPORT ibnd_port_t *ibnd_find_port_dr(ibnd_fabric_t * fabric,
>+					char *dr_str);
>+typedef void (*ibnd_iter_port_func_t) (ibnd_port_t * port, void *user_data);
>+IBND_EXPORT void ibnd_iter_ports(ibnd_fabric_t * fabric,
>+				ibnd_iter_port_func_t func, void *user_data);
>+
>+/** =========================================================================
>  * Chassis queries
>  */
> IBND_EXPORT uint64_t ibnd_get_chassis_guid(ibnd_fabric_t * fabric,
>diff --git a/trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc_osd.h b/trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc_osd.h
>new file mode 100644
>index 0000000..b25104a
>--- /dev/null
>+++ b/trunk/ulp/libibnetdisc/include/infiniband/ibnetdisc_osd.h
>@@ -0,0 +1,41 @@
>+/*
>+ * Copyright (c) 2011 Lawrence Livermore National Security.  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 _IBNETDISC_OSD_H_
>+#define _IBNETDISC_OSD_H_
>+
>+/* Define OS specific bits */
>+
>+/* Windows */
>+
>+#endif				/* _IBNETDISC_OSD_H_ */
>diff --git a/trunk/ulp/libibnetdisc/src/chassis.c b/trunk/ulp/libibnetdisc/src/chassis.c
>index 25d7473..5726f8e 100644
>--- a/trunk/ulp/libibnetdisc/src/chassis.c
>+++ b/trunk/ulp/libibnetdisc/src/chassis.c
>@@ -50,9 +50,9 @@
> #include "internal.h"
> #include "chassis.h"
>
>-static char *ChassisTypeStr[6] =
>-{ "", "ISR9288", "ISR9096", "ISR2012", "ISR2004", "ISR4700" };
>-static char *ChassisSlotTypeStr[4] = { "", "Line", "Spine", "SRBD" };
>+static char *ChassisTypeStr[] =
>+{ "", "ISR9288", "ISR9096", "ISR2012", "ISR2004", "ISR4700", "ISR4200" };
>+static char *ChassisSlotTypeStr[] = { "", "Line", "Spine", "SRBD" };
>
> typedef struct chassis_scan {
> 	ibnd_chassis_t *first_chassis;
>@@ -62,30 +62,53 @@ typedef struct chassis_scan {
>
> char *ibnd_get_chassis_type(ibnd_node_t * node)
> {
>+	int chassis_type;
>+
> 	if (!node) {
> 		IBND_DEBUG("node parameter NULL\n");
> 		return NULL;
> 	}
>
>-	/* Currently, only if Voltaire chassis */
>-	if (mad_get_field(node->info, 0, IB_NODE_VENDORID_F) != VTR_VENDOR_ID)
>-		return NULL;
> 	if (!node->chassis)
> 		return NULL;
>-	if (node->ch_type == UNRESOLVED_CT || node->ch_type > ISR4700_CT)
>-		return NULL;
>-	return ChassisTypeStr[node->ch_type];
>+
>+	chassis_type = mad_get_field(node->info, 0, IB_NODE_VENDORID_F);
>+
>+	switch (chassis_type)
>+	{
>+		case VTR_VENDOR_ID: /* Voltaire chassis */
>+		{
>+			if (node->ch_type == UNRESOLVED_CT || node->ch_type > ISR4200_CT)
>+				return NULL;
>+			return ChassisTypeStr[node->ch_type];
>+		}
>+		case MLX_VENDOR_ID:
>+		{
>+			if (node->ch_type_str[0] == '\0')
>+				return NULL;
>+			return node->ch_type_str;
>+		}
>+		default:
>+		{
>+			break;
>+		}
>+	}
>+	return NULL;
> }
>
> char *ibnd_get_chassis_slot_str(ibnd_node_t * node, char *str, size_t size)
> {
>+	int vendor_id;
>+
> 	if (!node) {
> 		IBND_DEBUG("node parameter NULL\n");
> 		return NULL;
> 	}
>
>-	/* Currently, only if Voltaire chassis */
>-	if (mad_get_field(node->info, 0, IB_NODE_VENDORID_F) != VTR_VENDOR_ID)
>+	/* Currently, only if Voltaire or Mellanox chassis */
>+	vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
>+
>+	if ((vendor_id != VTR_VENDOR_ID) && (vendor_id != MLX_VENDOR_ID))
> 		return NULL;
> 	if (!node->chassis)
> 		return NULL;
>@@ -286,11 +309,18 @@ static int is_spine_4700x2(ibnd_node_t * n)
> 	return (devid == VTR_DEVID_SFB4700X2);
> }
>
>+static int is_spine_4200(ibnd_node_t * n)
>+{
>+	uint32_t devid = mad_get_field(n->info, 0, IB_NODE_DEVID_F);
>+	return (devid == VTR_DEVID_SFB4200);
>+}
>+
> static int is_spine(ibnd_node_t * n)
> {
> 	return (is_spine_9096(n) || is_spine_9288(n) ||
> 		is_spine_2004(n) || is_spine_2012(n) ||
>-		is_spine_4700(n) || is_spine_4700x2(n));
>+		is_spine_4700(n) || is_spine_4700x2(n) ||
>+		is_spine_4200(n));
> }
>
> static int is_line_24(ibnd_node_t * n)
>@@ -376,6 +406,18 @@ char anafa_line_slot_2_sfb18x2[37] = {
> 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
> };
>
>+/* LB slot = table[spine port] */
>+char line_slot_2_sfb4200[37] = {
>+	0,
>+	1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5,
>+	5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9};
>+/* LB asic num = table[spine port] */
>+char anafa_line_slot_2_sfb4200[37] = {
>+	0,
>+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
>+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
>+};
>+
> /* IPR FCR modules connectivity while using sFB4 port as reference */
> char ipr_slot_2_sfb4_port[37] = {
> 	0,
>@@ -424,6 +466,18 @@ char anafa_spine18x2_slot_2_slb[37] = {
> 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
> };
>
>+/* FB slot = table[line port] */
>+char sfb4200_slot_2_slb[37] = {
>+	0,
>+	1, 1, 1, 1, 0, 0, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
>+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
>+};
>+/* FB asic = table[line port] */
>+char anafa_sfb4200_slot_2_slb[37] = {
>+	0,
>+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
>+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
>+};
>
> /*	reference                     { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 }; */
>
>@@ -454,10 +508,13 @@ static int get_sfb_slot(ibnd_node_t * n, ibnd_port_t * lineport)
> 		n->ch_type = ISR4700_CT;
> 		n->ch_slotnum = spine18_slot_2_slb[lineport->portnum];
> 		n->ch_anafanum = anafa_spine18x2_slot_2_slb[lineport->portnum];
>+	} else if (is_spine_4200(n)) {
>+		n->ch_type = ISR4200_CT;
>+		n->ch_slotnum = sfb4200_slot_2_slb[lineport->portnum];
>+		n->ch_anafanum = anafa_sfb4200_slot_2_slb[lineport->portnum];
> 	} else {
> 		IBND_ERROR("Unexpected node found: guid 0x%016" PRIx64 "\n",
> 			   n->guid);
>-		return -1;
> 	}
> 	return 0;
> }
>@@ -498,7 +555,6 @@ static int get_router_slot(ibnd_node_t * n, ibnd_port_t * spineport)
> 	} else {
> 		IBND_ERROR("Unexpected node found: guid 0x%016" PRIx64 "\n",
> 			   spineport->node->guid);
>-		return -1;
> 	}
> 	return 0;
> }
>@@ -530,14 +586,177 @@ static int get_slb_slot(ibnd_node_t * n, ibnd_port_t * spineport)
> 		n->ch_type = ISR4700_CT;
> 		n->ch_slotnum = line_slot_2_sfb18x2[spineport->portnum];
> 		n->ch_anafanum = anafa_line_slot_2_sfb18x2[spineport->portnum];
>+	} else if (is_spine_4200(spineport->node)) {
>+		n->ch_type = ISR4200_CT;
>+		n->ch_slotnum = line_slot_2_sfb4200[spineport->portnum];
>+		n->ch_anafanum = anafa_line_slot_2_sfb4200[spineport->portnum];
> 	} else {
> 		IBND_ERROR("Unexpected node found: guid 0x%016" PRIx64 "\n",
> 			   spineport->node->guid);
>-		return -1;
> 	}
> 	return 0;
> }
>
>+
>+/*
>+	This function called for every Mellanox node in fabric
>+*/
>+static int fill_mellanox_chassis_record(ibnd_node_t * node)
>+{
>+	int p = 0;
>+	ibnd_port_t *port;
>+
>+	char node_desc[IB_SMP_DATA_SIZE];
>+	char *system_name;
>+	char *system_type;
>+	char *system_slot_name;
>+	char *node_index;
>+	char *iter;
>+	int dev_id;
>+
>+	/*
>+	The node description has the following format:
>+
>+	'MF0;<system name>:<system type>/<system slot name>[:board type]/U<node index>'
>+
>+     - System slot name in our systems can be L[01-36] , S[01-18]
>+     - Node index is always 1 (we don.t have boards with multiple IS4 chips).
>+     - System name is taken from the currently configured host name.
>+     -The board type is optional and we don.t set it currently  - A leaf or spine slot can currently hold a single type of board.
>+	 */
>+
>+	memcpy(node_desc, node->nodedesc, IB_SMP_DATA_SIZE);
>+
>+	IBND_DEBUG("fill_mellanox_chassis_record: node_desc:%s \n",node_desc);
>+
>+	if (node->ch_found)	/* somehow this node has already been passed */
>+		return 0;
>+
>+	/* All mellanox IS4 switches have the same vendor id*/
>+	dev_id = mad_get_field(node->info, 0,IB_NODE_DEVID_F);
>+	if (dev_id != MLX_DEVID_IS4)
>+		return 0;
>+
>+	if((node_desc[0] != 'M') ||
>+	   (node_desc[1] != 'F') ||
>+	   (node_desc[2] != '0') ||
>+	   (node_desc[3] != ';')) {
>+		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s \n",node_desc);
>+		return 0;
>+	}
>+
>+	/* parse system name*/
>+	system_name = &node_desc[4];
>+	for (iter = system_name ; (*iter != ':') && (*iter != '\0') ; iter++);
>+	if(*iter == '\0'){
>+		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_name failed)
>\n",node_desc);
>+		return 0;
>+	}
>+	*iter = '\0';
>+	iter++;
>+	/* parse system type*/
>+	system_type = iter;
>+	for ( ; (*iter != '/') && (*iter != '\0') ; iter++);
>+	if(*iter == '\0'){
>+		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_type failed)
>\n",node_desc);
>+		return 0;
>+	}
>+	*iter = '\0';
>+	iter++;
>+	/* parse system slot name*/
>+	system_slot_name = iter;
>+	for ( ; (*iter != '/') && (*iter != ':') && (*iter != '\0') ; iter++);
>+	if(*iter == '\0'){
>+		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get system_slot_name failed)
>\n",node_desc);
>+		return 0;
>+	}
>+	if(*iter == ':'){
>+		*iter = '\0';
>+		iter++;
>+		for ( ; (*iter != '/') && (*iter != '\0') ; iter++);
>+		if(*iter == '\0'){
>+			IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get board type failed)
>\n",node_desc);
>+			return 0;
>+		}
>+	}
>+	*iter = '\0';
>+	iter++;
>+	node_index = iter;
>+	if(node_index[0] != 'U'){
>+		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported node description format:%s - (get node index) \n",node_desc);
>+		return 0;
>+	}
>+
>+	/* set Chip number (node index) */
>+	node->ch_anafanum = (unsigned char) atoi(&node_index[1]);
>+	if(node->ch_anafanum != 1){
>+		IBND_DEBUG("Unexpected Chip number:%d \n",node->ch_anafanum);
>+	}
>+
>+
>+	/* set Line Spine numbers */
>+	if(system_slot_name[0] == 'L')
>+		node->ch_slot = LINE_CS;
>+	else if(system_slot_name[0] == 'S')
>+		node->ch_slot = SPINE_CS;
>+	else{
>+		IBND_DEBUG("fill_mellanox_chassis_record: Unsupported system_slot_name:%s \n",system_slot_name);
>+		return 0;
>+	}
>+
>+	/* The switch will be displayed under Line or Spine and not under Chassis switches */
>+	node->ch_found = 1;
>+
>+	node->ch_slotnum = (unsigned char) atoi(&system_slot_name[1]);
>+	if((node->ch_slot == LINE_CS && (node->ch_slotnum >  (LINES_MAX_NUM + 1))) ||
>+	   (node->ch_slot == SPINE_CS && (node->ch_slotnum > (SPINES_MAX_NUM + 1)))){
>+		IBND_ERROR("fill_mellanox_chassis_record: invalid slot number:%d \n",node->ch_slotnum);
>+		node->ch_slotnum = 0;
>+		return 0;
>+	}
>+
>+	/*set ch_type_str*/
>+	strncpy(node->ch_type_str , system_type, sizeof(node->ch_type_str)-1);
>+
>+	/* Line ports 1-18 are mapped to external ports 1-18*/
>+	if(node->ch_slot == LINE_CS)
>+	{
>+		for (p = 1; p <= node->numports && p <= 18 ; p++) {
>+			port = node->ports[p];
>+			if (!port)
>+				continue;
>+			port->ext_portnum = p;
>+		}
>+	}
>+
>+	return 0;
>+}
>+
>+static int insert_mellanox_line_and_spine(ibnd_node_t * node, ibnd_chassis_t * chassis)
>+{
>+	if (node->ch_slot == LINE_CS){
>+
>+		if (chassis->linenode[node->ch_slotnum])
>+			return 0;	/* already filled slot */
>+
>+		chassis->linenode[node->ch_slotnum] = node;
>+	}
>+	else if (node->ch_slot == SPINE_CS){
>+
>+		if (chassis->spinenode[node->ch_slotnum])
>+			return 0;	/* already filled slot */
>+
>+		chassis->spinenode[node->ch_slotnum] = node;
>+	}
>+	else
>+		return 0;
>+
>+	node->chassis = chassis;
>+
>+	return 0;
>+}
>+
>+
> /* forward declare this */
> static void voltaire_portmap(ibnd_port_t * port);
> /*
>@@ -588,8 +807,7 @@ static int fill_voltaire_chassis_record(ibnd_node_t * node)
> 			}
> 			if (!node->ch_type)
> 				/* we assume here that remoteport belongs to line */
>-				if (get_sfb_slot(node, port->remoteport))
>-					return -1;
>+				get_sfb_slot(node, port->remoteport);
>
> 			/* we could break here, but need to find if more routers connected */
> 		}
>@@ -607,8 +825,7 @@ static int fill_voltaire_chassis_record(ibnd_node_t * node)
> 				continue;
>
> 			/* we assume here that remoteport belongs to spine */
>-			if (get_slb_slot(node, port->remoteport))
>-				return -1;
>+			get_slb_slot(node, port->remoteport);
> 			break;
> 		}
> 	}
>@@ -1025,6 +1242,7 @@ int group_nodes(ibnd_fabric_t * fabric)
> 	ibnd_chassis_t *chassis;
> 	ibnd_chassis_t *ch, *ch_next;
> 	chassis_scan_t chassis_scan;
>+	int vendor_id;
>
> 	chassis_scan.first_chassis = NULL;
> 	chassis_scan.current_chassis = NULL;
>@@ -1035,10 +1253,16 @@ int group_nodes(ibnd_fabric_t * fabric)
> 	/* according to internal connectivity */
> 	/* not very efficient but clear code so... */
> 	for (node = fabric->switches; node; node = node->type_next) {
>-		if (mad_get_field(node->info, 0,
>-				  IB_NODE_VENDORID_F) == VTR_VENDOR_ID
>+
>+		vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
>+
>+		if (vendor_id == VTR_VENDOR_ID
> 		    && fill_voltaire_chassis_record(node))
> 			goto cleanup;
>+		else if (vendor_id == MLX_VENDOR_ID
>+			&& fill_mellanox_chassis_record(node))
>+			goto cleanup;
>+
> 	}
>
> 	/* separate every Voltaire chassis from each other and build linked list of them */
>@@ -1084,8 +1308,10 @@ int group_nodes(ibnd_fabric_t * fabric)
> 	/* now, make another pass to see which nodes are part of chassis */
> 	/* (defined as chassis->nodecount > 1) */
> 	for (node = fabric->nodes; node; node = node->next) {
>-		if (mad_get_field(node->info, 0,
>-				  IB_NODE_VENDORID_F) == VTR_VENDOR_ID)
>+
>+		vendor_id = mad_get_field(node->info, 0,IB_NODE_VENDORID_F);
>+
>+		if (vendor_id == VTR_VENDOR_ID)
> 			continue;
> 		if (mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F)) {
> 			chassis = find_chassisguid(fabric, node);
>@@ -1096,6 +1322,9 @@ int group_nodes(ibnd_fabric_t * fabric)
> 					node->ch_found = 1;
> 					add_node_to_chassis(chassis, node);
> 				}
>+				else if (vendor_id == MLX_VENDOR_ID){
>+					insert_mellanox_line_and_spine(node, chassis);
>+				}
> 			}
> 		}
> 	}
>diff --git a/trunk/ulp/libibnetdisc/src/chassis.h b/trunk/ulp/libibnetdisc/src/chassis.h
>index f8e0ee2..7a91be3 100644
>--- a/trunk/ulp/libibnetdisc/src/chassis.h
>+++ b/trunk/ulp/libibnetdisc/src/chassis.h
>@@ -73,16 +73,20 @@
> #define VTR_DEVID_SLB4018		0x5a5b
> #define VTR_DEVID_SFB4700		0x5a5c
> #define VTR_DEVID_SFB4700X2		0x5a5d
>+#define VTR_DEVID_SFB4200		0x5a60
>+
>+#define MLX_DEVID_IS4			0xbd36
>
> /* Vendor IDs (for chassis based systems) */
> #define VTR_VENDOR_ID			0x8f1	/* Voltaire */
>+#define MLX_VENDOR_ID			0x2c9	/* Mellanox */
> #define TS_VENDOR_ID			0x5ad	/* Cisco */
> #define SS_VENDOR_ID			0x66a	/* InfiniCon */
> #define XS_VENDOR_ID			0x1397	/* Xsigo */
>
> enum ibnd_chassis_type {
> 	UNRESOLVED_CT, ISR9288_CT, ISR9096_CT, ISR2012_CT, ISR2004_CT,
>-	ISR4700_CT
>+	ISR4700_CT, ISR4200_CT
> };
> enum ibnd_chassis_slot_type { UNRESOLVED_CS, LINE_CS, SPINE_CS, SRBD_CS };
>
>diff --git a/trunk/ulp/libibnetdisc/src/ibnetdisc.c b/trunk/ulp/libibnetdisc/src/ibnetdisc.c
>index f525d71..9800c9d 100644
>--- a/trunk/ulp/libibnetdisc/src/ibnetdisc.c
>+++ b/trunk/ulp/libibnetdisc/src/ibnetdisc.c
>@@ -2,6 +2,7 @@
>  * Copyright (c) 2004-2009 Voltaire Inc.  All rights reserved.
>  * Copyright (c) 2007 Xsigo Systems Inc.  All rights reserved.
>  * Copyright (c) 2008 Lawrence Livermore National Laboratory
>+ * Copyright (c) 2010 Mellanox Technologies LTD.  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
>@@ -55,8 +56,13 @@
> #include "chassis.h"
>
> /* forward declare */
>+struct ni_cbdata
>+{
>+	ibnd_node_t *node;
>+	int port_num;
>+};
> static int query_node_info(smp_engine_t * engine, ib_portid_t * portid,
>-			   ibnd_node_t * node);
>+			   struct ni_cbdata * cbdata);
>
> static int recv_switch_info(smp_engine_t * engine, ibnd_smp_t * smp,
> 			    uint8_t * mad, void *cb_data)
>@@ -79,13 +85,33 @@ static int query_switch_info(smp_engine_t * engine, ib_portid_t * portid,
>
> static int add_port_to_dpath(ib_dr_path_t * path, int nextport)
> {
>-	if (path->cnt > sizeof(path->p) - 1)
>+	if (path->cnt > sizeof(path->p) - 2)
> 		return -1;
> 	++path->cnt;
> 	path->p[path->cnt] = (uint8_t) nextport;
> 	return path->cnt;
> }
>
>+static int retract_dpath(smp_engine_t * engine, ib_portid_t * portid)
>+{
>+	ibnd_scan_t *scan = engine->user_data;
>+	ibnd_fabric_t *fabric = scan->fabric;
>+
>+	if (scan->cfg->max_hops &&
>+	    fabric->maxhops_discovered > scan->cfg->max_hops)
>+		return 0;
>+
>+	/* this may seem wrong but the only time we would retract the path is
>+	 * if the user specified a CA for the DR path and we are retracting
>+	 * from that to find the node it is connected to.  This counts as a
>+	 * positive hop discovered
>+	 */
>+	fabric->maxhops_discovered++;
>+	portid->drpath.p[portid->drpath.cnt] = 0;
>+	portid->drpath.cnt--;
>+	return 1;
>+}
>+
> static int extend_dpath(smp_engine_t * engine, ib_portid_t * portid,
> 			int nextport)
> {
>@@ -93,7 +119,7 @@ static int extend_dpath(smp_engine_t * engine, ib_portid_t * portid,
> 	ibnd_fabric_t *fabric = scan->fabric;
>
> 	if (scan->cfg->max_hops &&
>-	    fabric->maxhops_discovered >= scan->cfg->max_hops)
>+	    fabric->maxhops_discovered > scan->cfg->max_hops)
> 		return 0;
>
> 	if (portid->lid) {
>@@ -114,8 +140,9 @@ static int extend_dpath(smp_engine_t * engine, ib_portid_t * portid,
> 		return -1;
> 	}
>
>-	if ((unsigned) portid->drpath.cnt > fabric->maxhops_discovered)
>-		fabric->maxhops_discovered = portid->drpath.cnt;
>+	if (((unsigned) portid->drpath.cnt - scan->initial_hops) >
>+	    fabric->maxhops_discovered)
>+		fabric->maxhops_discovered++;
>
> 	return 1;
> }
>@@ -170,7 +197,8 @@ static int recv_port_info(smp_engine_t * engine, ibnd_smp_t * smp,
> 	if (!port) {
> 		port = node->ports[port_num] = calloc(1, sizeof(*port));
> 		if (!port) {
>-			IBND_ERROR("Failed to allocate port\n");
>+			IBND_ERROR("Failed to allocate 0x%" PRIx64 " port %u\n",
>+				    node->guid, port_num);
> 			return -1;
> 		}
> 		port->guid =
>@@ -199,10 +227,27 @@ static int recv_port_info(smp_engine_t * engine, ibnd_smp_t * smp,
> 	if (port_num && mad_get_field(port->info, 0, IB_PORT_PHYS_STATE_F)
> 	    == IB_PORT_PHYS_STATE_LINKUP
> 	    && ((node->type == IB_NODE_SWITCH && port_num != local_port) ||
>-		(node == fabric->from_node && port_num == local_port))) {
>+		(node == fabric->from_node && port_num == fabric->from_portnum))) {
>+
>+		int rc = 0;
> 		ib_portid_t path = smp->path;
>-		if (extend_dpath(engine, &path, port_num) > 0)
>-			query_node_info(engine, &path, node);
>+
>+		if (node->type != IB_NODE_SWITCH &&
>+		    node == fabric->from_node &&
>+		    path.drpath.cnt > 1)
>+			rc = retract_dpath(engine, &path);
>+		else {
>+			/* we can't proceed through an HCA with DR */
>+			if (path.lid == 0 || node->type == IB_NODE_SWITCH)
>+				rc = extend_dpath(engine, &path, port_num);
>+		}
>+
>+		if (rc > 0) {
>+			struct ni_cbdata * cbdata = malloc(sizeof(*cbdata));
>+			cbdata->node = node;
>+			cbdata->port_num = port_num;
>+			query_node_info(engine, &path, cbdata);
>+		}
> 	}
>
> 	return 0;
>@@ -253,11 +298,6 @@ static ibnd_node_t *create_node(smp_engine_t * engine, ib_portid_t * path,
> 	return rc;
> }
>
>-static int get_last_port(ib_portid_t * path)
>-{
>-	return path->drpath.p[path->drpath.cnt];
>-}
>-
> static void link_ports(ibnd_node_t * node, ibnd_port_t * port,
> 		       ibnd_node_t * remotenode, ibnd_port_t * remoteport)
> {
>@@ -292,7 +332,9 @@ static int recv_node_info(smp_engine_t * engine, ibnd_smp_t * smp,
> 	ibnd_fabric_t *fabric = scan->fabric;
> 	int i = 0;
> 	uint8_t *node_info = mad + IB_SMP_DATA_OFFS;
>-	ibnd_node_t *rem_node = cb_data;
>+	struct ni_cbdata *ni_cbdata = (struct ni_cbdata *)cb_data;
>+	ibnd_node_t *rem_node = NULL;
>+	int rem_port_num = 0;
> 	ibnd_node_t *node;
> 	int node_is_new = 0;
> 	uint64_t node_guid = mad_get_field64(node_info, 0, IB_NODE_GUID_F);
>@@ -300,6 +342,12 @@ static int recv_node_info(smp_engine_t * engine, ibnd_smp_t * smp,
> 	int port_num = mad_get_field(node_info, 0, IB_NODE_LOCAL_PORT_F);
> 	ibnd_port_t *port = NULL;
>
>+	if (ni_cbdata) {
>+		rem_node = ni_cbdata->node;
>+		rem_port_num = ni_cbdata->port_num;
>+		free(ni_cbdata);
>+	}
>+
> 	node = ibnd_find_node_guid(fabric, node_guid);
> 	if (!node) {
> 		node = create_node(engine, &smp->path, node_info);
>@@ -315,6 +363,8 @@ static int recv_node_info(smp_engine_t * engine, ibnd_smp_t * smp,
> 	if (!port) {
> 		/* If we have not see this port before create a shell for it */
> 		port = node->ports[port_num] = calloc(1, sizeof(*port));
>+		if (!port)
>+			return -1;
> 		port->node = node;
> 		port->portnum = port_num;
> 	}
>@@ -324,12 +374,11 @@ static int recv_node_info(smp_engine_t * engine, ibnd_smp_t * smp,
> 		dump_endnode(&smp->path, node_is_new ? "new" : "known",
> 			     node, port);
>
>-	if (rem_node == NULL)	/* this is the start node */
>+	if (rem_node == NULL) {	/* this is the start node */
> 		fabric->from_node = node;
>-	else {
>+		fabric->from_portnum = port_num;
>+	} else {
> 		/* link ports... */
>-		int rem_port_num = get_last_port(&smp->path);
>-
> 		if (!rem_node->ports[rem_port_num]) {
> 			IBND_ERROR("Internal Error; "
> 				   "Node(%p) 0x%" PRIx64
>@@ -358,11 +407,11 @@ static int recv_node_info(smp_engine_t * engine, ibnd_smp_t * smp,
> }
>
> static int query_node_info(smp_engine_t * engine, ib_portid_t * portid,
>-			   ibnd_node_t * node)
>+			   struct ni_cbdata * cbdata)
> {
> 	IBND_DEBUG("Query Node Info; %s\n", portid2str(portid));
> 	return issue_smp(engine, portid, IB_ATTR_NODE_INFO, 0,
>-			 recv_node_info, node);
>+			 recv_node_info, (void *)cbdata);
> }
>
> ibnd_node_t *ibnd_find_node_guid(ibnd_fabric_t * fabric, uint64_t guid)
>@@ -382,37 +431,13 @@ ibnd_node_t *ibnd_find_node_guid(ibnd_fabric_t * fabric, uint64_t guid)
> 	return NULL;
> }
>
>+/* forward declare */
>+ibnd_port_t *ibnd_find_port_dr(ibnd_fabric_t * fabric, char *dr_str);
>+
> ibnd_node_t *ibnd_find_node_dr(ibnd_fabric_t * fabric, char *dr_str)
> {
>-	int i = 0;
>-	ibnd_node_t *rc;
>-	ib_dr_path_t path;
>-
>-	if (!fabric) {
>-		IBND_DEBUG("fabric parameter NULL\n");
>-		return NULL;
>-	}
>-
>-	rc = fabric->from_node;
>-
>-	if (str2drpath(&path, dr_str, 0, 0) == -1)
>-		return NULL;
>-
>-	for (i = 0; i <= path.cnt; i++) {
>-		ibnd_port_t *remote_port = NULL;
>-		if (path.p[i] == 0)
>-			continue;
>-		if (!rc->ports)
>-			return NULL;
>-
>-		remote_port = rc->ports[path.p[i]]->remoteport;
>-		if (!remote_port)
>-			return NULL;
>-
>-		rc = remote_port->node;
>-	}
>-
>-	return rc;
>+	ibnd_port_t *rc = ibnd_find_port_dr(fabric, dr_str);
>+	return rc->node;
> }
>
> void add_to_nodeguid_hash(ibnd_node_t * node, ibnd_node_t * hash[])
>@@ -479,15 +504,15 @@ ibnd_fabric_t *ibnd_discover_fabric(char * ca_name, int ca_port,
> 	int nc = 2;
> 	int mc[2] = { IB_SMI_CLASS, IB_SMI_DIRECT_CLASS };
>
>+	/* If not specified start from "my" port */
>+	if (!from)
>+		from = &my_portid;
>+
> 	if (set_config(&config, cfg)) {
> 		IBND_ERROR("Invalid ibnd_config\n");
> 		return NULL;
> 	}
>
>-	/* If not specified start from "my" port */
>-	if (!from)
>-		from = &my_portid;
>-
> 	fabric = calloc(1, sizeof(*fabric));
> 	if (!fabric) {
> 		IBND_ERROR("OOM: failed to calloc ibnd_fabric_t\n");
>@@ -499,6 +524,7 @@ ibnd_fabric_t *ibnd_discover_fabric(char * ca_name, int ca_port,
> 	memset(&scan.selfportid, 0, sizeof(scan.selfportid));
> 	scan.fabric = fabric;
> 	scan.cfg = &config;
>+	scan.initial_hops = from->drpath.cnt;
>
> 	if (smp_engine_init(&engine, ca_name, ca_port, &scan, &config)) {
> 		free(fabric);
>@@ -521,6 +547,7 @@ ibnd_fabric_t *ibnd_discover_fabric(char * ca_name, int ca_port,
> 			goto error;
>
> 	fabric->total_mads_used = engine.total_smps;
>+	fabric->maxhops_discovered += scan.initial_hops;
>
> 	if (group_nodes(fabric))
> 		goto error;
>@@ -624,3 +651,81 @@ void ibnd_iter_nodes_type(ibnd_fabric_t * fabric, ibnd_iter_node_func_t func,
> 	for (cur = list; cur; cur = cur->type_next)
> 		func(cur, user_data);
> }
>+
>+ibnd_port_t *ibnd_find_port_guid(ibnd_fabric_t * fabric, uint64_t guid)
>+{
>+	int hash = HASHGUID(guid) % HTSZ;
>+	ibnd_port_t *port;
>+
>+	if (!fabric) {
>+		IBND_DEBUG("fabric parameter NULL\n");
>+		return NULL;
>+	}
>+
>+	for (port = fabric->portstbl[hash]; port; port = port->htnext)
>+		if (port->guid == guid)
>+			return port;
>+
>+	return NULL;
>+}
>+
>+ibnd_port_t *ibnd_find_port_dr(ibnd_fabric_t * fabric, char *dr_str)
>+{
>+	int i = 0;
>+	ibnd_node_t *cur_node;
>+	ibnd_port_t *rc = NULL;
>+	ib_dr_path_t path;
>+
>+	if (!fabric) {
>+		IBND_DEBUG("fabric parameter NULL\n");
>+		return NULL;
>+	}
>+
>+	if (!dr_str) {
>+		IBND_DEBUG("dr_str parameter NULL\n");
>+		return NULL;
>+	}
>+
>+	cur_node = fabric->from_node;
>+
>+	if (str2drpath(&path, dr_str, 0, 0) == -1)
>+		return NULL;
>+
>+	for (i = 0; i <= path.cnt; i++) {
>+		ibnd_port_t *remote_port = NULL;
>+		if (path.p[i] == 0)
>+			continue;
>+		if (!cur_node->ports)
>+			return NULL;
>+
>+		remote_port = cur_node->ports[path.p[i]]->remoteport;
>+		if (!remote_port)
>+			return NULL;
>+
>+		rc = remote_port;
>+		cur_node = remote_port->node;
>+	}
>+
>+	return rc;
>+}
>+
>+void ibnd_iter_ports(ibnd_fabric_t * fabric, ibnd_iter_port_func_t func,
>+			void *user_data)
>+{
>+	int i = 0;
>+	ibnd_port_t *cur = NULL;
>+
>+	if (!fabric) {
>+		IBND_DEBUG("fabric parameter NULL\n");
>+		return;
>+	}
>+
>+	if (!func) {
>+		IBND_DEBUG("func parameter NULL\n");
>+		return;
>+	}
>+
>+	for (i = 0; i<HTSZ; i++)
>+		for (cur = fabric->portstbl[i]; cur; cur = cur->htnext)
>+			func(cur, user_data);
>+}
>diff --git a/trunk/ulp/libibnetdisc/src/ibnetdisc_cache.c b/trunk/ulp/libibnetdisc/src/ibnetdisc_cache.c
>index 5151f63..2690373 100644
>--- a/trunk/ulp/libibnetdisc/src/ibnetdisc_cache.c
>+++ b/trunk/ulp/libibnetdisc/src/ibnetdisc_cache.c
>@@ -326,6 +326,7 @@ static int _load_node(int fd, ibnd_fabric_cache_t * fabric_cache)
> 	node = (ibnd_node_t *) malloc(sizeof(ibnd_node_t));
> 	if (!node) {
> 		IBND_DEBUG("OOM: node\n");
>+		free(node_cache);
> 		return -1;
> 	}
> 	memset(node, '\0', sizeof(ibnd_node_t));
>@@ -426,6 +427,7 @@ static int _load_port(int fd, ibnd_fabric_cache_t * fabric_cache)
> 	port = (ibnd_port_t *) malloc(sizeof(ibnd_port_t));
> 	if (!port) {
> 		IBND_DEBUG("OOM: port\n");
>+		free(port_cache);
> 		return -1;
> 	}
> 	memset(port, '\0', sizeof(ibnd_port_t));
>@@ -887,9 +889,20 @@ int ibnd_cache_fabric(ibnd_fabric_t * fabric, const char *file,
> 		return -1;
> 	}
>
>-	if (!stat(file, &statbuf)) {
>-		IBND_DEBUG("file '%s' already exists\n", file);
>-		return -1;
>+	if (!(flags & IBND_CACHE_FABRIC_FLAG_NO_OVERWRITE)) {
>+		if (!stat(file, &statbuf)) {
>+			if (unlink(file) < 0) {
>+				IBND_DEBUG("error removing '%s': %s\n",
>+					   file, strerror(errno));
>+				return -1;
>+			}
>+		}
>+	}
>+	else {
>+		if (!stat(file, &statbuf)) {
>+			IBND_DEBUG("file '%s' already exists\n", file);
>+			return -1;
>+		}
> 	}
>
> 	if ((fd = open(file, O_CREAT | O_EXCL | O_WRONLY, 0644)) < 0) {
>diff --git a/trunk/ulp/libibnetdisc/src/ibnetdisc_exports.src b/trunk/ulp/libibnetdisc/src/ibnetdisc_exports.src
>index 018bd17..776e154 100644
>--- a/trunk/ulp/libibnetdisc/src/ibnetdisc_exports.src
>+++ b/trunk/ulp/libibnetdisc/src/ibnetdisc_exports.src
>@@ -4,6 +4,8 @@ LIBRARY libibnetdisc.dll
> EXPORTS
> 		ibnd_discover_fabric;
> 		ibnd_destroy_fabric;
>+		ibnd_load_fabric;
>+		ibnd_cache_fabric;
> 		ibnd_find_node_guid;
> 		ibnd_find_node_dr;
> 		ibnd_is_xsigo_guid;
>@@ -14,4 +16,7 @@ EXPORTS
> 		ibnd_get_chassis_slot_str;
> 		ibnd_iter_nodes;
> 		ibnd_iter_nodes_type;
>+		ibnd_find_port_guid;
>+		ibnd_find_port_dr;
>+		ibnd_iter_ports;
> #endif
>diff --git a/trunk/ulp/libibnetdisc/src/internal.h b/trunk/ulp/libibnetdisc/src/internal.h
>index 3c599ec..80918c4 100644
>--- a/trunk/ulp/libibnetdisc/src/internal.h
>+++ b/trunk/ulp/libibnetdisc/src/internal.h
>@@ -62,6 +62,7 @@ typedef struct ibnd_scan {
> 	ibnd_fabric_t *fabric;
> 	struct ibnd_config *cfg;
> 	struct ibmad_port *ibmad_port;
>+	unsigned initial_hops;
> } ibnd_scan_t;
>
> typedef struct ibnd_smp ibnd_smp_t;
>diff --git a/trunk/ulp/opensm/user/opensm/osm_helper.c b/trunk/ulp/opensm/user/opensm/osm_helper.c
>index 54680da..fcb2597 100644
>--- a/trunk/ulp/opensm/user/opensm/osm_helper.c
>+++ b/trunk/ulp/opensm/user/opensm/osm_helper.c
>@@ -860,7 +860,7 @@ void osm_dump_portinfo_record(IN osm_log_t * p_log,
> 			"\t\t\t\tRID\n"
> 			"\t\t\t\tEndPortLid..............%u\n"
> 			"\t\t\t\tPortNum.................%u\n"
>-			"\t\t\t\tReserved................0x%X\n"
>+			"\t\t\t\tOptions.................0x%X\n"
> 			"\t\t\t\tPortInfo dump:\n"
> 			"\t\t\t\tm_key...................0x%016" PRIx64 "\n"
> 			"\t\t\t\tsubnet_prefix...........0x%016" PRIx64 "\n"
>@@ -894,7 +894,7 @@ void osm_dump_portinfo_record(IN osm_log_t * p_log,
> 			"\t\t\t\tsubnet_timeout..........0x%X\n"
> 			"\t\t\t\tresp_time_value.........0x%X\n"
> 			"\t\t\t\terror_threshold.........0x%X\n",
>-			cl_ntoh16(p_pir->lid), p_pir->port_num, p_pir->resv,
>+			cl_ntoh16(p_pir->lid), p_pir->port_num, p_pir->options,
> 			cl_ntoh64(p_pi->m_key), cl_ntoh64(p_pi->subnet_prefix),
> 			cl_ntoh16(p_pi->base_lid),
> 			cl_ntoh16(p_pi->master_sm_base_lid),
>
>_______________________________________________
>ofw mailing list
>ofw at lists.openfabrics.org
>http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ofw



More information about the ofw mailing list