infiniband-diags: replace ib-diags with latest
authorshefty <shefty@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 3 Mar 2009 00:18:25 +0000 (00:18 +0000)
committershefty <shefty@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 3 Mar 2009 00:18:25 +0000 (00:18 +0000)
Replace the infiniband_diags port of ib-diags with a version that is in sync with the main management.git tree.  The infiniband-diags tree is current with
git commit 1f5fdf3dfc69733a427520198bcbdd03645bb326.  All executable ib-diags are supported.  (Perl scripts that parse the output are not ported.)

The infiniband-diags directory is a mirror of the infiniband-diags directory of my ib-mgmt.git tree.  This is a clone of the management.git tree, with a 1 line patch added to complete the port from Linux to Windows.

Signed-off-by: Sean Hefty <sean.hefty@intel.com>
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@1998 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

95 files changed:
tools/dirs
tools/infiniband-diags/dirs [new file with mode: 0644]
tools/infiniband-diags/include/grouping.h [moved from tools/infiniband_diags/include/grouping.h with 94% similarity]
tools/infiniband-diags/include/ibdiag_common.h [moved from tools/infiniband_diags/include/ibdiag_common.h with 65% similarity]
tools/infiniband-diags/include/ibnetdiscover.h [moved from tools/infiniband_diags/include/ibnetdiscover.h with 96% similarity]
tools/infiniband-diags/include/windows/config.h [new file with mode: 0644]
tools/infiniband-diags/include/windows/ibdiag_version.h [moved from tools/infiniband_diags/include/ibdiag_version.h with 92% similarity]
tools/infiniband-diags/src/dirs [new file with mode: 0644]
tools/infiniband-diags/src/grouping.c [moved from tools/infiniband_diags/src/grouping.c with 90% similarity]
tools/infiniband-diags/src/ibaddr.c [moved from tools/infiniband_diags/src/ibaddr.c with 54% similarity]
tools/infiniband-diags/src/ibaddr/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/ibaddr/ibaddr.rc [new file with mode: 0644]
tools/infiniband-diags/src/ibaddr/makefile [moved from tools/infiniband_diags/src/ibnetdiscover/makefile with 100% similarity]
tools/infiniband-diags/src/ibdiag_common.c [new file with mode: 0644]
tools/infiniband-diags/src/ibdiag_windows.c [moved from tools/infiniband_diags/src/ibdiag_osd.c with 66% similarity]
tools/infiniband-diags/src/ibnetdiscover.c [moved from tools/infiniband_diags/src/ibnetdiscover.c with 86% similarity]
tools/infiniband-diags/src/ibnetdiscover/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/ibnetdiscover/ibnetdiscover.rc [moved from tools/infiniband_diags/src/ibnetdiscover/ibnetdiscover.rc with 88% similarity]
tools/infiniband-diags/src/ibnetdiscover/makefile [moved from tools/infiniband_diags/src/ibportstate/makefile with 100% similarity]
tools/infiniband-diags/src/ibping.c [moved from tools/infiniband_diags/src/ibping.c with 63% similarity]
tools/infiniband-diags/src/ibping/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/ibping/ibping.rc [new file with mode: 0644]
tools/infiniband-diags/src/ibping/makefile [moved from tools/infiniband_diags/src/ibroute/makefile with 100% similarity]
tools/infiniband-diags/src/ibportstate.c [moved from tools/infiniband_diags/src/ibportstate.c with 78% similarity]
tools/infiniband-diags/src/ibportstate/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/ibportstate/ibportstate.rc [moved from tools/infiniband_diags/src/ibportstate/ibportstate.rc with 100% similarity]
tools/infiniband-diags/src/ibportstate/makefile [moved from tools/infiniband_diags/src/ibstat/makefile with 100% similarity]
tools/infiniband-diags/src/ibroute.c [moved from tools/infiniband_diags/src/ibroute.c with 68% similarity]
tools/infiniband-diags/src/ibroute/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/ibroute/ibroute.rc [moved from tools/infiniband_diags/src/ibroute/ibroute.rc with 87% similarity]
tools/infiniband-diags/src/ibroute/makefile [moved from tools/infiniband_diags/src/ibsysstat/makefile with 100% similarity]
tools/infiniband-diags/src/ibsendtrap.c [moved from tools/infiniband_diags/src/ibsendtrap.c with 72% similarity]
tools/infiniband-diags/src/ibsendtrap/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/ibsendtrap/ibsendtrap.rc [new file with mode: 0644]
tools/infiniband-diags/src/ibsendtrap/makefile [moved from tools/infiniband_diags/src/ibtracert/makefile with 100% similarity]
tools/infiniband-diags/src/ibstat.c [moved from tools/infiniband_diags/src/ibstat.c with 63% similarity]
tools/infiniband-diags/src/ibstat/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/ibstat/ibstat.rc [moved from tools/infiniband_diags/src/ibstat/ibstat.rc with 100% similarity]
tools/infiniband-diags/src/ibstat/makefile [moved from tools/infiniband_diags/src/saquery/makefile with 100% similarity]
tools/infiniband-diags/src/ibsysstat.c [moved from tools/infiniband_diags/src/ibsysstat.c with 54% similarity]
tools/infiniband-diags/src/ibsysstat/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/ibsysstat/ibsysstat.rc [moved from tools/infiniband_diags/src/ibsysstat/ibsysstat.rc with 83% similarity]
tools/infiniband-diags/src/ibsysstat/makefile [new file with mode: 0644]
tools/infiniband-diags/src/ibtracert.c [moved from tools/infiniband_diags/src/ibtracert.c with 81% similarity]
tools/infiniband-diags/src/ibtracert/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/ibtracert/ibtracert.rc [moved from tools/infiniband_diags/src/ibtracert/ibtracert.rc with 89% similarity]
tools/infiniband-diags/src/ibtracert/makefile [new file with mode: 0644]
tools/infiniband-diags/src/mcm_rereg_test.c [moved from tools/infiniband_diags/src/mcm_rereg_test.c with 93% similarity]
tools/infiniband-diags/src/mcm_rereg_test/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/mcm_rereg_test/makefile [new file with mode: 0644]
tools/infiniband-diags/src/mcm_rereg_test/mcm_rereg_test.rc [new file with mode: 0644]
tools/infiniband-diags/src/perfquery.c [moved from tools/infiniband_diags/src/perfquery.c with 74% similarity]
tools/infiniband-diags/src/perfquery/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/perfquery/makefile [new file with mode: 0644]
tools/infiniband-diags/src/perfquery/perfquery.rc [new file with mode: 0644]
tools/infiniband-diags/src/saquery.c [moved from tools/infiniband_diags/src/saquery.c with 50% similarity]
tools/infiniband-diags/src/saquery/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/saquery/makefile [new file with mode: 0644]
tools/infiniband-diags/src/saquery/saquery.rc [new file with mode: 0644]
tools/infiniband-diags/src/sminfo.c [moved from tools/infiniband_diags/src/sminfo.c with 55% similarity]
tools/infiniband-diags/src/sminfo/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/sminfo/makefile [new file with mode: 0644]
tools/infiniband-diags/src/sminfo/sminfo.rc [new file with mode: 0644]
tools/infiniband-diags/src/smpdump.c [moved from tools/infiniband_diags/src/smpdump.c with 65% similarity]
tools/infiniband-diags/src/smpdump/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/smpdump/makefile [new file with mode: 0644]
tools/infiniband-diags/src/smpdump/smpdump.rc [new file with mode: 0644]
tools/infiniband-diags/src/smpquery.c [moved from tools/infiniband_diags/src/smpquery.c with 72% similarity]
tools/infiniband-diags/src/smpquery/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/smpquery/makefile [new file with mode: 0644]
tools/infiniband-diags/src/smpquery/smpquery.rc [new file with mode: 0644]
tools/infiniband-diags/src/vendstat.c [moved from tools/infiniband_diags/src/vendstat.c with 72% similarity]
tools/infiniband-diags/src/vendstat/SOURCES [new file with mode: 0644]
tools/infiniband-diags/src/vendstat/makefile [new file with mode: 0644]
tools/infiniband-diags/src/vendstat/vendstat.rc [new file with mode: 0644]
tools/infiniband_diags/dirs [deleted file]
tools/infiniband_diags/include/InfiniBand/complib/cl_debug.h [deleted file]
tools/infiniband_diags/include/InfiniBand/complib/cl_nodenamemap.h [deleted file]
tools/infiniband_diags/include/ibdiag_common_osd.h [deleted file]
tools/infiniband_diags/src/cl_nodenamemap.c [deleted file]
tools/infiniband_diags/src/dirs [deleted file]
tools/infiniband_diags/src/ibaddr/SOURCES [deleted file]
tools/infiniband_diags/src/ibdiag_common.c [deleted file]
tools/infiniband_diags/src/ibnetdiscover/SOURCES [deleted file]
tools/infiniband_diags/src/ibping/SOURCES [deleted file]
tools/infiniband_diags/src/ibportstate/SOURCES [deleted file]
tools/infiniband_diags/src/ibroute/SOURCES [deleted file]
tools/infiniband_diags/src/ibstat/SOURCES [deleted file]
tools/infiniband_diags/src/ibsysstat/SOURCES [deleted file]
tools/infiniband_diags/src/ibtracert/SOURCES [deleted file]
tools/infiniband_diags/src/perfquery/SOURCES [deleted file]
tools/infiniband_diags/src/saquery/SOURCES [deleted file]
tools/infiniband_diags/src/saquery/saquery.rc [deleted file]
tools/infiniband_diags/src/sminfo/SOURCES [deleted file]
tools/infiniband_diags/src/vendstat/SOURCES [deleted file]

index 64d2582..2cd347e 100644 (file)
@@ -4,4 +4,4 @@ DIRS = \
        nsc                     \\r
        perftests       \\r
        part_man        \\r
-       infiniband_diags
\ No newline at end of file
+       infiniband-diags
\ No newline at end of file
diff --git a/tools/infiniband-diags/dirs b/tools/infiniband-diags/dirs
new file mode 100644 (file)
index 0000000..60fcb0f
--- /dev/null
@@ -0,0 +1 @@
+DIRS = src\r
similarity index 94%
rename from tools/infiniband_diags/include/grouping.h
rename to tools/infiniband-diags/include/grouping.h
index 22b2e5f..811e372 100644 (file)
-/*\r
- * Copyright (c) 2004-2007 Voltaire Inc.  All rights reserved.\r
- * Copyright (c) 2007 Xsigo Systems Inc.  All rights reserved.\r
- *\r
- * This software is available to you under a choice of one of two\r
- * licenses.  You may choose to be licensed under the terms of the GNU\r
- * General Public License (GPL) Version 2, available from the file\r
- * COPYING in the main directory of this source tree, or the\r
- * OpenIB.org BSD license below:\r
- *\r
- *     Redistribution and use in source and binary forms, with or\r
- *     without modification, are permitted provided that the following\r
- *     conditions are met:\r
- *\r
- *      - Redistributions of source code must retain the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer.\r
- *\r
- *      - Redistributions in binary form must reproduce the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer in the documentation and/or other materials\r
- *        provided with the distribution.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- * SOFTWARE.\r
- *\r
- */\r
-\r
-#ifndef _GROUPING_H_\r
-#define _GROUPING_H_\r
-\r
-/*========================================================*/\r
-/*               FABRIC SCANNER SPECIFIC DATA             */\r
-/*========================================================*/\r
-\r
-#define SPINES_MAX_NUM 12\r
-#define LINES_MAX_NUM 36\r
-\r
-typedef struct ChassisList ChassisList;\r
-typedef struct AllChassisList AllChassisList;\r
-\r
-struct ChassisList {\r
-       ChassisList *next;\r
-       uint64_t chassisguid;\r
-       int chassisnum;\r
-       int chassistype;\r
-       int nodecount;          /* used for grouping by SystemImageGUID */\r
-       Node *spinenode[SPINES_MAX_NUM + 1];\r
-       Node *linenode[LINES_MAX_NUM + 1];\r
-};\r
-\r
-struct AllChassisList {\r
-       ChassisList *first;\r
-       ChassisList *current;\r
-       ChassisList *last;\r
-};\r
-\r
-/*========================================================*/\r
-/*                CHASSIS RECOGNITION SPECIFIC DATA       */\r
-/*========================================================*/\r
-\r
-/* Device IDs */\r
-#define VTR_DEVID_IB_FC_ROUTER         0x5a00\r
-#define VTR_DEVID_IB_IP_ROUTER         0x5a01\r
-#define VTR_DEVID_ISR9600_SPINE                0x5a02\r
-#define VTR_DEVID_ISR9600_LEAF         0x5a03\r
-#define VTR_DEVID_HCA1                 0x5a04\r
-#define VTR_DEVID_HCA2                 0x5a44\r
-#define VTR_DEVID_HCA3                 0x6278\r
-#define VTR_DEVID_SW_6IB4              0x5a05\r
-#define VTR_DEVID_ISR9024              0x5a06\r
-#define VTR_DEVID_ISR9288              0x5a07\r
-#define VTR_DEVID_SLB24                        0x5a09\r
-#define VTR_DEVID_SFB12                        0x5a08\r
-#define VTR_DEVID_SFB4                 0x5a0b\r
-#define VTR_DEVID_ISR9024_12           0x5a0c\r
-#define VTR_DEVID_SLB8                 0x5a0d\r
-#define VTR_DEVID_RLX_SWITCH_BLADE     0x5a20\r
-#define VTR_DEVID_ISR9024_DDR          0x5a31\r
-#define VTR_DEVID_SFB12_DDR            0x5a32\r
-#define VTR_DEVID_SFB4_DDR             0x5a33\r
-#define VTR_DEVID_SLB24_DDR            0x5a34\r
-#define VTR_DEVID_SFB2012              0x5a37\r
-#define VTR_DEVID_SLB2024              0x5a38\r
-#define VTR_DEVID_ISR2012              0x5a39\r
-#define VTR_DEVID_SFB2004              0x5a40\r
-#define VTR_DEVID_ISR2004              0x5a41\r
-#define VTR_DEVID_SRB2004              0x5a42\r
-\r
-enum ChassisType { UNRESOLVED_CT, ISR9288_CT, ISR9096_CT, ISR2012_CT, ISR2004_CT };\r
-enum ChassisSlot { UNRESOLVED_CS, LINE_CS, SPINE_CS, SRBD_CS };\r
-\r
-/*========================================================*/\r
-/*                External interface                      */\r
-/*========================================================*/\r
-\r
-ChassisList *group_nodes();\r
-char *portmapstring(Port *port);\r
-char *get_chassis_type(unsigned char chassistype);\r
-char *get_chassis_slot(unsigned char chassisslot);\r
-uint64_t get_chassis_guid(unsigned char chassisnum);\r
-\r
-int is_xsigo_guid(uint64_t guid);\r
-int is_xsigo_tca(uint64_t guid);\r
-int is_xsigo_hca(uint64_t guid);\r
-\r
-#endif /* _GROUPING_H_ */\r
+/*
+ * Copyright (c) 2004-2007 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2007 Xsigo Systems Inc.  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 _GROUPING_H_
+#define _GROUPING_H_
+
+/*========================================================*/
+/*               FABRIC SCANNER SPECIFIC DATA             */
+/*========================================================*/
+
+#define SPINES_MAX_NUM 12
+#define LINES_MAX_NUM 36
+
+typedef struct ChassisList ChassisList;
+typedef struct AllChassisList AllChassisList;
+
+struct ChassisList {
+       ChassisList *next;
+       uint64_t chassisguid;
+       unsigned char chassisnum;
+       unsigned char chassistype;
+       unsigned int nodecount;   /* used for grouping by SystemImageGUID */
+       Node *spinenode[SPINES_MAX_NUM + 1];
+       Node *linenode[LINES_MAX_NUM + 1];
+};
+
+struct AllChassisList {
+       ChassisList *first;
+       ChassisList *current;
+       ChassisList *last;
+};
+
+/*========================================================*/
+/*                CHASSIS RECOGNITION SPECIFIC DATA       */
+/*========================================================*/
+
+/* Device IDs */
+#define VTR_DEVID_IB_FC_ROUTER         0x5a00
+#define VTR_DEVID_IB_IP_ROUTER         0x5a01
+#define VTR_DEVID_ISR9600_SPINE                0x5a02
+#define VTR_DEVID_ISR9600_LEAF         0x5a03
+#define VTR_DEVID_HCA1                 0x5a04
+#define VTR_DEVID_HCA2                 0x5a44
+#define VTR_DEVID_HCA3                 0x6278
+#define VTR_DEVID_SW_6IB4              0x5a05
+#define VTR_DEVID_ISR9024              0x5a06
+#define VTR_DEVID_ISR9288              0x5a07
+#define VTR_DEVID_SLB24                        0x5a09
+#define VTR_DEVID_SFB12                        0x5a08
+#define VTR_DEVID_SFB4                 0x5a0b
+#define VTR_DEVID_ISR9024_12           0x5a0c
+#define VTR_DEVID_SLB8                 0x5a0d
+#define VTR_DEVID_RLX_SWITCH_BLADE     0x5a20
+#define VTR_DEVID_ISR9024_DDR          0x5a31
+#define VTR_DEVID_SFB12_DDR            0x5a32
+#define VTR_DEVID_SFB4_DDR             0x5a33
+#define VTR_DEVID_SLB24_DDR            0x5a34
+#define VTR_DEVID_SFB2012              0x5a37
+#define VTR_DEVID_SLB2024              0x5a38
+#define VTR_DEVID_ISR2012              0x5a39
+#define VTR_DEVID_SFB2004              0x5a40
+#define VTR_DEVID_ISR2004              0x5a41
+#define VTR_DEVID_SRB2004              0x5a42
+
+enum ChassisType { UNRESOLVED_CT, ISR9288_CT, ISR9096_CT, ISR2012_CT, ISR2004_CT };
+enum ChassisSlot { UNRESOLVED_CS, LINE_CS, SPINE_CS, SRBD_CS };
+
+/*========================================================*/
+/*                External interface                      */
+/*========================================================*/
+
+ChassisList *group_nodes();
+char *portmapstring(Port *port);
+char *get_chassis_type(unsigned char chassistype);
+char *get_chassis_slot(unsigned char chassisslot);
+uint64_t get_chassis_guid(unsigned char chassisnum);
+
+int is_xsigo_guid(uint64_t guid);
+int is_xsigo_tca(uint64_t guid);
+int is_xsigo_hca(uint64_t guid);
+
+#endif /* _GROUPING_H_ */
@@ -1,61 +1,78 @@
-/*\r
- * Copyright (c) 2006-2007 The Regents of the University of California.\r
- * Copyright (c) 2004-2008 Voltaire Inc.  All rights reserved.\r
- *\r
- * This software is available to you under a choice of one of two\r
- * licenses.  You may choose to be licensed under the terms of the GNU\r
- * General Public License (GPL) Version 2, available from the file\r
- * COPYING in the main directory of this source tree, or the\r
- * OpenIB.org BSD license below:\r
- *\r
- *     Redistribution and use in source and binary forms, with or\r
- *     without modification, are permitted provided that the following\r
- *     conditions are met:\r
- *\r
- *      - Redistributions of source code must retain the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer.\r
- *\r
- *      - Redistributions in binary form must reproduce the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer in the documentation and/or other materials\r
- *        provided with the distribution.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- * SOFTWARE.\r
- *\r
- */\r
-\r
-#ifndef _IBDIAG_COMMON_H_\r
-#define _IBDIAG_COMMON_H_\r
-\r
-#include <stdio.h>\r
-#include <ibdiag_common_osd.h>\r
-\r
-extern char *argv0;\r
-extern int   ibdebug;\r
-\r
-/*========================================================*/\r
-/*                External interface                      */\r
-/*========================================================*/\r
-\r
-#undef DEBUG\r
-#define        DEBUG   if (ibdebug || verbose) IBWARN\r
-#define        VERBOSE if (ibdebug || verbose > 1) IBWARN\r
-#define IBERROR(fmt, ...) iberror(__FUNCTION__, fmt, ## __VA_ARGS__)\r
-void  iberror(const char *fn, char *msg, ...);\r
-\r
-#include <ibdiag_version.h>\r
-\r
-static inline const char* get_build_version(void)\r
-{\r
-       return "BUILD VERSION: " IBDIAG_VERSION " Build date: " __DATE__ " " __TIME__ ;\r
-}\r
-\r
-#endif /* _IBDIAG_COMMON_H_ */\r
+/*
+ * Copyright (c) 2006-2007 The Regents of the University of California.
+ * Copyright (c) 2004-2008 Voltaire Inc.  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 _IBDIAG_COMMON_H_
+#define _IBDIAG_COMMON_H_
+
+#include <infiniband/mad.h>
+
+extern int ibdebug;
+extern int ibverbose;
+extern char *ibd_ca;
+extern int ibd_ca_port;
+extern enum MAD_DEST ibd_dest_type;
+extern ib_portid_t *ibd_sm_id;
+extern int ibd_timeout;
+
+/*========================================================*/
+/*                External interface                      */
+/*========================================================*/
+
+#undef DEBUG
+#define DEBUG(fmt, ...) do { \
+       if (ibdebug || ibverbose) IBWARN(fmt, ## __VA_ARGS__); \
+} while (0)
+#define VERBOSE(fmt, ...) do { \
+       if (ibdebug || ibverbose > 1) IBWARN(fmt, ## __VA_ARGS__); \
+} while (0)
+#define IBERROR(fmt, ...) iberror(__FUNCTION__, fmt, ## __VA_ARGS__)
+
+struct ibdiag_opt {
+       const char *name;
+       char letter;
+       unsigned has_arg;
+       const char *arg_tmpl;
+       const char *description;
+};
+
+extern int ibdiag_process_opts(int argc, char * const argv[], void *context,
+                              const char *exclude_common_str,
+                              const struct ibdiag_opt custom_opts[],
+                              int (*custom_handler)(void *cxt, int val, char *optarg),
+                              const char *usage_args,
+                              const char *usage_examples[]);
+extern void ibdiag_show_usage();
+extern void iberror(const char *fn, char *msg, ...);
+
+#endif                         /* _IBDIAG_COMMON_H_ */
-/*\r
- * Copyright (c) 2004-2007 Voltaire Inc.  All rights reserved.\r
- * Copyright (c) 2007 Xsigo Systems Inc.  All rights reserved.\r
- *\r
- * This software is available to you under a choice of one of two\r
- * licenses.  You may choose to be licensed under the terms of the GNU\r
- * General Public License (GPL) Version 2, available from the file\r
- * COPYING in the main directory of this source tree, or the\r
- * OpenIB.org BSD license below:\r
- *\r
- *     Redistribution and use in source and binary forms, with or\r
- *     without modification, are permitted provided that the following\r
- *     conditions are met:\r
- *\r
- *      - Redistributions of source code must retain the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer.\r
- *\r
- *      - Redistributions in binary form must reproduce the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer in the documentation and/or other materials\r
- *        provided with the distribution.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- * SOFTWARE.\r
- *\r
- */\r
-\r
-#ifndef _IBNETDISCOVER_H_\r
-#define _IBNETDISCOVER_H_\r
-\r
-#define MAXHOPS                63\r
-\r
-#define CA_NODE                1\r
-#define SWITCH_NODE    2\r
-#define ROUTER_NODE    3\r
-\r
-#define LIST_CA_NODE    (1 << CA_NODE)\r
-#define LIST_SWITCH_NODE (1 << SWITCH_NODE)\r
-#define LIST_ROUTER_NODE (1 << ROUTER_NODE)\r
-\r
-/* Vendor IDs (for chassis based systems) */\r
-#define VTR_VENDOR_ID                  0x8f1   /* Voltaire */\r
-#define TS_VENDOR_ID                   0x5ad   /* Cisco */\r
-#define SS_VENDOR_ID                   0x66a   /* InfiniCon */\r
-#define XS_VENDOR_ID                   0x1397  /* Xsigo */\r
-\r
-\r
-typedef struct Port Port;\r
-typedef struct Node Node;\r
-typedef struct ChassisRecord ChassisRecord;\r
-\r
-struct ChassisRecord {\r
-       ChassisRecord *next;\r
-\r
-       unsigned char chassisnum;\r
-       unsigned char anafanum;\r
-       unsigned char slotnum;\r
-       unsigned char chassistype;\r
-       unsigned char chassisslot;\r
-};\r
-\r
-struct Port {\r
-       Port *next;\r
-       uint64_t portguid;\r
-       int portnum;\r
-       int lid;\r
-       int lmc;\r
-       int state;\r
-       int physstate;\r
-       int linkwidth;\r
-       int linkspeed;\r
-\r
-       Node *node;\r
-       Port *remoteport;               /* null if SMA */\r
-};\r
-\r
-struct Node {\r
-       Node *htnext;\r
-       Node *dnext;\r
-       Port *ports;\r
-       ib_portid_t path;\r
-       int type;\r
-       int dist;\r
-       int numports;\r
-       int localport;\r
-       int smalid;\r
-       int smalmc;\r
-       int smaenhsp0;\r
-       uint32_t devid;\r
-       uint32_t vendid;\r
-       uint64_t sysimgguid;\r
-       uint64_t nodeguid;\r
-       uint64_t portguid;\r
-       char nodedesc[64];\r
-       uint8_t nodeinfo[64];\r
-\r
-       ChassisRecord *chrecord;\r
-};\r
-\r
-#endif /* _IBNETDISCOVER_H_ */\r
+/*
+ * Copyright (c) 2004-2007 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2007 Xsigo Systems Inc.  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 _IBNETDISCOVER_H_
+#define _IBNETDISCOVER_H_
+
+#define MAXHOPS                63
+
+#define CA_NODE                1
+#define SWITCH_NODE    2
+#define ROUTER_NODE    3
+
+#define LIST_CA_NODE    (1 << CA_NODE)
+#define LIST_SWITCH_NODE (1 << SWITCH_NODE)
+#define LIST_ROUTER_NODE (1 << ROUTER_NODE)
+
+/* Vendor IDs (for chassis based systems) */
+#define VTR_VENDOR_ID                  0x8f1   /* Voltaire */
+#define TS_VENDOR_ID                   0x5ad   /* Cisco */
+#define SS_VENDOR_ID                   0x66a   /* InfiniCon */
+#define XS_VENDOR_ID                   0x1397  /* Xsigo */
+
+
+typedef struct Port Port;
+typedef struct Node Node;
+typedef struct ChassisRecord ChassisRecord;
+
+struct ChassisRecord {
+       ChassisRecord *next;
+
+       unsigned char chassisnum;
+       unsigned char anafanum;
+       unsigned char slotnum;
+       unsigned char chassistype;
+       unsigned char chassisslot;
+};
+
+struct Port {
+       Port *next;
+       uint64_t portguid;
+       int portnum;
+       int lid;
+       int lmc;
+       int state;
+       int physstate;
+       int linkwidth;
+       int linkspeed;
+
+       Node *node;
+       Port *remoteport;               /* null if SMA */
+};
+
+struct Node {
+       Node *htnext;
+       Node *dnext;
+       Port *ports;
+       ib_portid_t path;
+       int type;
+       int dist;
+       int numports;
+       int localport;
+       int smalid;
+       int smalmc;
+       int smaenhsp0;
+       uint32_t devid;
+       uint32_t vendid;
+       uint64_t sysimgguid;
+       uint64_t nodeguid;
+       uint64_t portguid;
+       char nodedesc[64];
+       uint8_t nodeinfo[64];
+
+       ChassisRecord *chrecord;
+};
+
+#endif /* _IBNETDISCOVER_H_ */
diff --git a/tools/infiniband-diags/include/windows/config.h b/tools/infiniband-diags/include/windows/config.h
new file mode 100644 (file)
index 0000000..e5d7c13
--- /dev/null
@@ -0,0 +1,41 @@
+/*\r
+ * Copyright (c) 2009 Intel Corp, Inc.  All rights reserved.\r
+ *\r
+ * This software is available to you under a choice of one of two\r
+ * licenses.  You may choose to be licensed under the terms of the GNU\r
+ * General Public License (GPL) Version 2, available from the file\r
+ * COPYING in the main directory of this source tree, or the\r
+ * OpenIB.org BSD license below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ */\r
+\r
+#ifndef _CONFIG_H_\r
+#define _CONFIG_H_\r
+\r
+#include <../../../../ulp/libibverbs/include/infiniband/verbs.h>\r
+\r
+#include <_string.h>\r
+\r
+#endif /* _CONFIG_H_ */\r
@@ -1,39 +1,41 @@
-/*\r
- * Copyright (c) 2008 Voltaire Inc.  All rights reserved.\r
- *\r
- * This software is available to you under a choice of one of two\r
- * licenses.  You may choose to be licensed under the terms of the GNU\r
- * General Public License (GPL) Version 2, available from the file\r
- * COPYING in the main directory of this source tree, or the\r
- * OpenIB.org BSD license below:\r
- *\r
- *     Redistribution and use in source and binary forms, with or\r
- *     without modification, are permitted provided that the following\r
- *     conditions are met:\r
- *\r
- *      - Redistributions of source code must retain the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer.\r
- *\r
- *      - Redistributions in binary form must reproduce the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer in the documentation and/or other materials\r
- *        provided with the distribution.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- * SOFTWARE.\r
- *\r
- */\r
-\r
-#ifndef _IBDIAG_VERSION_H_\r
-#define _IBDIAG_VERSION_H_\r
-\r
-#define IBDIAG_VERSION "1.4.2"\r
-\r
-#endif /* _IBDIAG_VERSION_H_ */\r
+/*
+ * Copyright (c) 2008 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2009 Intel Corp, Inc.  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 _IBDIAG_VERSION_H_
+#define _IBDIAG_VERSION_H_
+
+// TODO: figure this out
+#define IBDIAG_VERSION "@OPENIB_REV@"
+
+#endif /* _IBDIAG_VERSION_H_ */
diff --git a/tools/infiniband-diags/src/dirs b/tools/infiniband-diags/src/dirs
new file mode 100644 (file)
index 0000000..b361fe5
--- /dev/null
@@ -0,0 +1,17 @@
+DIRS = \\r
+       ibaddr          \\r
+       ibnetdiscover   \\r
+       ibping          \\r
+       ibportstate     \\r
+       ibroute         \\r
+       ibsendtrap      \\r
+       ibstat          \\r
+       ibsysstat       \\r
+       ibtracert       \\r
+       mcm_rereg_test  \\r
+       perfquery       \\r
+       saquery         \\r
+       sminfo          \\r
+       smpdump         \\r
+       smpquery        \\r
+       vendstat
\ No newline at end of file
similarity index 90%
rename from tools/infiniband_diags/src/grouping.c
rename to tools/infiniband-diags/src/grouping.c
index 667c5c2..048efc7 100644 (file)
-/*\r
- * Copyright (c) 2004-2007 Voltaire Inc.  All rights reserved.\r
- * Copyright (c) 2007 Xsigo Systems Inc.  All rights reserved.\r
- *\r
- * This software is available to you under a choice of one of two\r
- * licenses.  You may choose to be licensed under the terms of the GNU\r
- * General Public License (GPL) Version 2, available from the file\r
- * COPYING in the main directory of this source tree, or the\r
- * OpenIB.org BSD license below:\r
- *\r
- *     Redistribution and use in source and binary forms, with or\r
- *     without modification, are permitted provided that the following\r
- *     conditions are met:\r
- *\r
- *      - Redistributions of source code must retain the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer.\r
- *\r
- *      - Redistributions in binary form must reproduce the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer in the documentation and/or other materials\r
- *        provided with the distribution.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- * SOFTWARE.\r
- *\r
- */\r
-\r
-/*========================================================*/\r
-/*               FABRIC SCANNER SPECIFIC DATA             */\r
-/*========================================================*/\r
-\r
-#if HAVE_CONFIG_H\r
-#  include <config.h>\r
-#endif /* HAVE_CONFIG_H */\r
-\r
-#include <stdlib.h>\r
-\r
-#if !defined(_WIN32)\r
-#include <stdint.h>\r
-#include <inttypes.h>\r
-#endif\r
-\r
-#include <infiniband/mad.h>\r
-\r
-#include "ibnetdiscover.h"\r
-#include "grouping.h"\r
-\r
-#define OUT_BUFFER_SIZE 16\r
-\r
-\r
-extern Node *nodesdist[MAXHOPS+1];     /* last is CA list */\r
-extern Node *mynode;\r
-extern Port *myport;\r
-extern int maxhops_discovered;\r
-\r
-AllChassisList mylist;\r
-\r
-char *ChassisTypeStr[5] = { "", "ISR9288", "ISR9096", "ISR2012", "ISR2004" };\r
-char *ChassisSlotStr[4] = { "", "Line", "Spine", "SRBD" };\r
-\r
-\r
-char *get_chassis_type(unsigned char chassistype)\r
-{\r
-       if (chassistype == UNRESOLVED_CT || chassistype > ISR2004_CT)\r
-               return NULL;\r
-       return ChassisTypeStr[chassistype];\r
-}\r
-\r
-char *get_chassis_slot(unsigned char chassisslot)\r
-{\r
-       if (chassisslot == UNRESOLVED_CS || chassisslot > SRBD_CS)\r
-               return NULL;\r
-       return ChassisSlotStr[chassisslot];\r
-}\r
-\r
-static struct ChassisList *find_chassisnum(unsigned char chassisnum)\r
-{\r
-       ChassisList *current;\r
-\r
-       for (current = mylist.first; current; current = current->next) {\r
-               if (current->chassisnum == chassisnum)\r
-                       return current;\r
-       }\r
-\r
-       return NULL;\r
-}\r
-\r
-static uint64_t topspin_chassisguid(uint64_t guid)\r
-{\r
-       /* Byte 3 in system image GUID is chassis type, and */\r
-       /* Byte 4 is location ID (slot) so just mask off byte 4 */\r
-       return guid & 0xffffffff00ffffffULL;\r
-}\r
-\r
-int is_xsigo_guid(uint64_t guid)\r
-{\r
-       if ((guid & 0xffffff0000000000ULL) == 0x0013970000000000ULL)\r
-               return 1;\r
-       else\r
-               return 0;\r
-}\r
-\r
-static int is_xsigo_leafone(uint64_t guid)\r
-{\r
-       if ((guid & 0xffffffffff000000ULL) == 0x0013970102000000ULL)\r
-               return 1;\r
-       else\r
-               return 0;\r
-}\r
-\r
-int is_xsigo_hca(uint64_t guid)\r
-{\r
-       /* NodeType 2 is HCA */\r
-       if ((guid & 0xffffffff00000000ULL) == 0x0013970200000000ULL)\r
-               return 1;\r
-       else\r
-               return 0;\r
-}\r
-\r
-int is_xsigo_tca(uint64_t guid)\r
-{\r
-       /* NodeType 3 is TCA */\r
-       if ((guid & 0xffffffff00000000ULL) == 0x0013970300000000ULL)\r
-               return 1;\r
-       else\r
-               return 0;\r
-}\r
-\r
-static int is_xsigo_ca(uint64_t guid)\r
-{\r
-       if (is_xsigo_hca(guid) || is_xsigo_tca(guid))\r
-               return 1;\r
-       else\r
-               return 0;\r
-}\r
-\r
-static int is_xsigo_switch(uint64_t guid)\r
-{\r
-       if ((guid & 0xffffffff00000000ULL) == 0x0013970100000000ULL)\r
-               return 1;\r
-       else\r
-               return 0;\r
-}\r
-\r
-static uint64_t xsigo_chassisguid(Node *node)\r
-{\r
-       if (!is_xsigo_ca(node->sysimgguid)) {\r
-               /* Byte 3 is NodeType and byte 4 is PortType */\r
-               /* If NodeType is 1 (switch), PortType is masked */\r
-               if (is_xsigo_switch(node->sysimgguid))\r
-                       return node->sysimgguid & 0xffffffff00ffffffULL;\r
-               else\r
-                       return node->sysimgguid;\r
-       } else {\r
-               /* Is there a peer port ? */\r
-               if (!node->ports->remoteport)\r
-                       return node->sysimgguid;\r
-\r
-               /* If peer port is Leaf 1, use its chassis GUID */\r
-               if (is_xsigo_leafone(node->ports->remoteport->node->sysimgguid))\r
-                       return node->ports->remoteport->node->sysimgguid &\r
-                              0xffffffff00ffffffULL;\r
-               else\r
-                       return node->sysimgguid;\r
-       }\r
-}\r
-\r
-static uint64_t get_chassisguid(Node *node)\r
-{\r
-       if (node->vendid == TS_VENDOR_ID || node->vendid == SS_VENDOR_ID)\r
-               return topspin_chassisguid(node->sysimgguid);\r
-       else if (node->vendid == XS_VENDOR_ID || is_xsigo_guid(node->sysimgguid))\r
-               return xsigo_chassisguid(node);\r
-       else\r
-               return node->sysimgguid;\r
-}\r
-\r
-static struct ChassisList *find_chassisguid(Node *node)\r
-{\r
-       ChassisList *current;\r
-       uint64_t chguid;\r
-\r
-       chguid = get_chassisguid(node);\r
-       for (current = mylist.first; current; current = current->next) {\r
-               if (current->chassisguid == chguid)\r
-                       return current;\r
-       }\r
-\r
-       return NULL;\r
-}\r
-\r
-uint64_t get_chassis_guid(unsigned char chassisnum)\r
-{\r
-       ChassisList *chassis;\r
-\r
-       chassis = find_chassisnum(chassisnum);\r
-       if (chassis)\r
-               return chassis->chassisguid;\r
-       else\r
-               return 0;\r
-}\r
-\r
-static int is_router(Node *node)\r
-{\r
-       return (node->devid == VTR_DEVID_IB_FC_ROUTER ||\r
-               node->devid == VTR_DEVID_IB_IP_ROUTER);\r
-}\r
-\r
-static int is_spine_9096(Node *node)\r
-{\r
-       return (node->devid == VTR_DEVID_SFB4 ||\r
-               node->devid == VTR_DEVID_SFB4_DDR);\r
-}\r
-\r
-static int is_spine_9288(Node *node)\r
-{\r
-       return (node->devid == VTR_DEVID_SFB12 ||\r
-               node->devid == VTR_DEVID_SFB12_DDR);\r
-}\r
-\r
-static int is_spine_2004(Node *node)\r
-{\r
-       return (node->devid == VTR_DEVID_SFB2004);\r
-}\r
-\r
-static int is_spine_2012(Node *node)\r
-{\r
-       return (node->devid == VTR_DEVID_SFB2012);\r
-}\r
-\r
-static int is_spine(Node *node)\r
-{\r
-       return (is_spine_9096(node) || is_spine_9288(node) ||\r
-               is_spine_2004(node) || is_spine_2012(node));\r
-}\r
-\r
-static int is_line_24(Node *node)\r
-{\r
-       return (node->devid == VTR_DEVID_SLB24 ||\r
-               node->devid == VTR_DEVID_SLB24_DDR ||\r
-               node->devid == VTR_DEVID_SRB2004);\r
-}\r
-\r
-static int is_line_8(Node *node)\r
-{\r
-       return (node->devid == VTR_DEVID_SLB8);\r
-}\r
-\r
-static int is_line_2024(Node *node)\r
-{\r
-       return (node->devid == VTR_DEVID_SLB2024);\r
-}\r
-\r
-static int is_line(Node *node)\r
-{\r
-       return (is_line_24(node) || is_line_8(node) || is_line_2024(node));\r
-}\r
-\r
-int is_chassis_switch(Node *node)\r
-{\r
-    return (is_spine(node) || is_line(node));\r
-}\r
-\r
-/* these structs help find Line (Anafa) slot number while using spine portnum */\r
-uint8_t line_slot_2_sfb4[25]        = { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4 };\r
-uint8_t anafa_line_slot_2_sfb4[25]  = { 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2 };\r
-uint8_t line_slot_2_sfb12[25]       = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10, 10, 11, 11, 12, 12 };\r
-uint8_t anafa_line_slot_2_sfb12[25] = { 0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 };\r
-\r
-/* IPR FCR modules connectivity while using sFB4 port as reference */\r
-uint8_t ipr_slot_2_sfb4_port[25]    = { 0, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1 };\r
-\r
-/* these structs help find Spine (Anafa) slot number while using spine portnum */\r
-uint8_t spine12_slot_2_slb[25]      = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
-uint8_t anafa_spine12_slot_2_slb[25]= { 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
-uint8_t spine4_slot_2_slb[25]       = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
-uint8_t anafa_spine4_slot_2_slb[25] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
-/*     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 }; */\r
-\r
-static void get_sfb_slot(Node *node, Port *lineport)\r
-{\r
-       ChassisRecord *ch = node->chrecord;\r
-\r
-       ch->chassisslot = SPINE_CS;\r
-       if (is_spine_9096(node)) {\r
-               ch->chassistype = ISR9096_CT;\r
-               ch->slotnum = spine4_slot_2_slb[lineport->portnum];\r
-               ch->anafanum = anafa_spine4_slot_2_slb[lineport->portnum];\r
-       } else if (is_spine_9288(node)) {\r
-               ch->chassistype = ISR9288_CT;\r
-               ch->slotnum = spine12_slot_2_slb[lineport->portnum];\r
-               ch->anafanum = anafa_spine12_slot_2_slb[lineport->portnum];\r
-       } else if (is_spine_2012(node)) {\r
-               ch->chassistype = ISR2012_CT;\r
-               ch->slotnum = spine12_slot_2_slb[lineport->portnum];\r
-               ch->anafanum = anafa_spine12_slot_2_slb[lineport->portnum];\r
-       } else if (is_spine_2004(node)) {\r
-               ch->chassistype = ISR2004_CT;\r
-               ch->slotnum = spine4_slot_2_slb[lineport->portnum];\r
-               ch->anafanum = anafa_spine4_slot_2_slb[lineport->portnum];\r
-       } else {\r
-               IBPANIC("Unexpected node found: guid 0x%016" PRIx64, node->nodeguid);\r
-       }\r
-}\r
-\r
-static void get_router_slot(Node *node, Port *spineport)\r
-{\r
-       ChassisRecord *ch = node->chrecord;\r
-       uint64_t guessnum = 0;\r
-\r
-       if (!ch) {\r
-               if (!(node->chrecord = calloc(1, sizeof(ChassisRecord))))\r
-                       IBPANIC("out of mem");\r
-               ch = node->chrecord;\r
-       }\r
-\r
-       ch->chassisslot = SRBD_CS;\r
-       if (is_spine_9096(spineport->node)) {\r
-               ch->chassistype = ISR9096_CT;\r
-               ch->slotnum = line_slot_2_sfb4[spineport->portnum];\r
-               ch->anafanum = ipr_slot_2_sfb4_port[spineport->portnum];\r
-       } else if (is_spine_9288(spineport->node)) {\r
-               ch->chassistype = ISR9288_CT;\r
-               ch->slotnum = line_slot_2_sfb12[spineport->portnum];\r
-               /* this is a smart guess based on nodeguids order on sFB-12 module */\r
-               guessnum = spineport->node->nodeguid % 4;\r
-               /* module 1 <--> remote anafa 3 */\r
-               /* module 2 <--> remote anafa 2 */\r
-               /* module 3 <--> remote anafa 1 */\r
-               ch->anafanum = (guessnum == 3 ? 1 : (guessnum == 1 ? 3 : 2));\r
-       } else if (is_spine_2012(spineport->node)) {\r
-               ch->chassistype = ISR2012_CT;\r
-               ch->slotnum = line_slot_2_sfb12[spineport->portnum];\r
-               /* this is a smart guess based on nodeguids order on sFB-12 module */\r
-               guessnum = spineport->node->nodeguid % 4;\r
-               // module 1 <--> remote anafa 3\r
-               // module 2 <--> remote anafa 2\r
-               // module 3 <--> remote anafa 1\r
-               ch->anafanum = (guessnum == 3? 1 : (guessnum == 1 ? 3 : 2));\r
-       } else if (is_spine_2004(spineport->node)) {\r
-               ch->chassistype = ISR2004_CT;\r
-               ch->slotnum = line_slot_2_sfb4[spineport->portnum];\r
-               ch->anafanum = ipr_slot_2_sfb4_port[spineport->portnum];\r
-       } else {\r
-               IBPANIC("Unexpected node found: guid 0x%016" PRIx64, spineport->node->nodeguid);\r
-       }\r
-}\r
-\r
-static void get_slb_slot(ChassisRecord *ch, Port *spineport)\r
-{\r
-       ch->chassisslot = LINE_CS;\r
-       if (is_spine_9096(spineport->node)) {\r
-               ch->chassistype = ISR9096_CT;\r
-               ch->slotnum = line_slot_2_sfb4[spineport->portnum];\r
-               ch->anafanum = anafa_line_slot_2_sfb4[spineport->portnum];\r
-       } else if (is_spine_9288(spineport->node)) {\r
-               ch->chassistype = ISR9288_CT;\r
-               ch->slotnum = line_slot_2_sfb12[spineport->portnum];\r
-               ch->anafanum = anafa_line_slot_2_sfb12[spineport->portnum];\r
-       } else if (is_spine_2012(spineport->node)) {\r
-               ch->chassistype = ISR2012_CT;\r
-               ch->slotnum = line_slot_2_sfb12[spineport->portnum];\r
-               ch->anafanum = anafa_line_slot_2_sfb12[spineport->portnum];\r
-       } else if (is_spine_2004(spineport->node)) {\r
-               ch->chassistype = ISR2004_CT;\r
-               ch->slotnum = line_slot_2_sfb4[spineport->portnum];\r
-               ch->anafanum = anafa_line_slot_2_sfb4[spineport->portnum];\r
-       } else {\r
-               IBPANIC("Unexpected node found: guid 0x%016" PRIx64, spineport->node->nodeguid);\r
-       }\r
-}\r
-\r
-/*\r
-       This function called for every Voltaire node in fabric\r
-       It could be optimized so, but time overhead is very small\r
-       and its only diag.util\r
-*/\r
-static void fill_chassis_record(Node *node)\r
-{\r
-       Port *port;\r
-       Node *remnode = 0;\r
-       ChassisRecord *ch = 0;\r
-\r
-       if (node->chrecord) /* somehow this node has already been passed */\r
-               return;\r
-\r
-       if (!(node->chrecord = calloc(1, sizeof(ChassisRecord))))\r
-               IBPANIC("out of mem");\r
-\r
-       ch = node->chrecord;\r
-\r
-       /* node is router only in case of using unique lid */\r
-       /* (which is lid of chassis router port) */\r
-       /* in such case node->ports is actually a requested port... */\r
-       if (is_router(node) && is_spine(node->ports->remoteport->node))\r
-               get_router_slot(node, node->ports->remoteport);\r
-       else if (is_spine(node)) {\r
-               for (port = node->ports; port; port = port->next) {\r
-                       if (!port->remoteport)\r
-                               continue;\r
-                       remnode = port->remoteport->node;\r
-                       if (remnode->type != SWITCH_NODE) {\r
-                               if (!remnode->chrecord)\r
-                                       get_router_slot(remnode, port);\r
-                               continue;\r
-                       }\r
-                       if (!ch->chassistype)\r
-                               /* we assume here that remoteport belongs to line */\r
-                               get_sfb_slot(node, port->remoteport);\r
-\r
-                               /* we could break here, but need to find if more routers connected */\r
-               }\r
-\r
-       } else if (is_line(node)) {\r
-               for (port = node->ports; port; port = port->next) {\r
-                       if (port->portnum > 12)\r
-                               continue;\r
-                       if (!port->remoteport)\r
-                               continue;\r
-                       /* we assume here that remoteport belongs to spine */\r
-                       get_slb_slot(ch, port->remoteport);\r
-                       break;\r
-               }\r
-       }\r
-\r
-       return;\r
-}\r
-\r
-static int get_line_index(Node *node)\r
-{\r
-       int retval = 3 * (node->chrecord->slotnum - 1) + node->chrecord->anafanum;\r
-\r
-       if (retval > LINES_MAX_NUM || retval < 1)\r
-               IBPANIC("Internal error");\r
-       return retval;\r
-}\r
-\r
-static int get_spine_index(Node *node)\r
-{\r
-       int retval;\r
-\r
-       if (is_spine_9288(node) || is_spine_2012(node))\r
-               retval = 3 * (node->chrecord->slotnum - 1) + node->chrecord->anafanum;\r
-       else\r
-               retval = node->chrecord->slotnum;\r
-\r
-       if (retval > SPINES_MAX_NUM || retval < 1)\r
-               IBPANIC("Internal error");\r
-       return retval;\r
-}\r
-\r
-static void insert_line_router(Node *node, ChassisList *chassislist)\r
-{\r
-       int i = get_line_index(node);\r
-\r
-       if (chassislist->linenode[i])\r
-               return;         /* already filled slot */\r
-\r
-       chassislist->linenode[i] = node;\r
-       node->chrecord->chassisnum = (uint8_t)chassislist->chassisnum;\r
-}\r
-\r
-static void insert_spine(Node *node, ChassisList *chassislist)\r
-{\r
-       int i = get_spine_index(node);\r
-\r
-       if (chassislist->spinenode[i])\r
-               return;         /* already filled slot */\r
-\r
-       chassislist->spinenode[i] = node;\r
-       node->chrecord->chassisnum = (uint8_t)chassislist->chassisnum;\r
-}\r
-\r
-static void pass_on_lines_catch_spines(ChassisList *chassislist)\r
-{\r
-       Node *node, *remnode;\r
-       Port *port;\r
-       int i;\r
-\r
-       for (i = 1; i <= LINES_MAX_NUM; i++) {\r
-               node = chassislist->linenode[i];\r
-\r
-               if (!(node && is_line(node)))\r
-                       continue;       /* empty slot or router */\r
-\r
-               for (port = node->ports; port; port = port->next) {\r
-                       if (port->portnum > 12)\r
-                               continue;\r
-\r
-                       if (!port->remoteport)\r
-                               continue;\r
-                       remnode = port->remoteport->node;\r
-\r
-                       if (!remnode->chrecord)\r
-                               continue;       /* some error - spine not initialized ? FIXME */\r
-                       insert_spine(remnode, chassislist);\r
-               }\r
-       }\r
-}\r
-\r
-static void pass_on_spines_catch_lines(ChassisList *chassislist)\r
-{\r
-       Node *node, *remnode;\r
-       Port *port;\r
-       int i;\r
-\r
-       for (i = 1; i <= SPINES_MAX_NUM; i++) {\r
-               node = chassislist->spinenode[i];\r
-               if (!node)\r
-                       continue;       /* empty slot */\r
-               for (port = node->ports; port; port = port->next) {\r
-                       if (!port->remoteport)\r
-                               continue;\r
-                       remnode = port->remoteport->node;\r
-\r
-                       if (!remnode->chrecord)\r
-                               continue;       /* some error - line/router not initialized ? FIXME */\r
-                       insert_line_router(remnode, chassislist);\r
-               }\r
-       }\r
-}\r
-\r
-/*\r
-       Stupid interpolation algorithm...\r
-       But nothing to do - have to be compliant with VoltaireSM/NMS\r
-*/\r
-static void pass_on_spines_interpolate_chguid(ChassisList *chassislist)\r
-{\r
-       Node *node;\r
-       int i;\r
-\r
-       for (i = 1; i <= SPINES_MAX_NUM; i++) {\r
-               node = chassislist->spinenode[i];\r
-               if (!node)\r
-                       continue;       /* skip the empty slots */\r
-\r
-               /* take first guid minus one to be consistent with SM */\r
-               chassislist->chassisguid = node->nodeguid - 1;\r
-               break;\r
-       }\r
-}\r
-\r
-/*\r
-       This function fills chassislist structure with all nodes\r
-       in that chassis\r
-       chassislist structure = structure of one standalone chassis\r
-*/\r
-static void build_chassis(Node *node, ChassisList *chassislist)\r
-{\r
-       Node *remnode = 0;\r
-       Port *port = 0;\r
-\r
-       /* we get here with node = chassis_spine */\r
-       chassislist->chassistype = node->chrecord->chassistype;\r
-       insert_spine(node, chassislist);\r
-\r
-       /* loop: pass on all ports of node */\r
-       for (port = node->ports; port; port = port->next) {\r
-               if (!port->remoteport)\r
-                       continue;\r
-               remnode = port->remoteport->node;\r
-\r
-               if (!remnode->chrecord)\r
-                       continue; /* some error - line or router not initialized ? FIXME */\r
-\r
-               insert_line_router(remnode, chassislist);\r
-       }\r
-\r
-       pass_on_lines_catch_spines(chassislist);\r
-       /* this pass needed for to catch routers, since routers connected only */\r
-       /* to spines in slot 1 or 4 and we could miss them first time */\r
-       pass_on_spines_catch_lines(chassislist);\r
-\r
-       /* additional 2 passes needed for to overcome a problem of pure "in-chassis" */\r
-       /* connectivity - extra pass to ensure that all related chips/modules */\r
-       /* inserted into the chassislist */\r
-       pass_on_lines_catch_spines(chassislist);\r
-       pass_on_spines_catch_lines(chassislist);\r
-       pass_on_spines_interpolate_chguid(chassislist);\r
-}\r
-\r
-/*========================================================*/\r
-/*                INTERNAL TO EXTERNAL PORT MAPPING       */\r
-/*========================================================*/\r
-\r
-/*\r
-Description : On ISR9288/9096 external ports indexing\r
-              is not matching the internal ( anafa ) port\r
-              indexes. Use this MAP to translate the data you get from\r
-              the OpenIB diagnostics (smpquery, ibroute, ibtracert, etc.)\r
-\r
-\r
-Module : sLB-24\r
-                anafa 1             anafa 2\r
-ext port | 13 14 15 16 17 18 | 19 20 21 22 23 24\r
-int port | 22 23 24 18 17 16 | 22 23 24 18 17 16\r
-ext port | 1  2  3  4  5  6  | 7  8  9  10 11 12\r
-int port | 19 20 21 15 14 13 | 19 20 21 15 14 13\r
-------------------------------------------------\r
-\r
-Module : sLB-8\r
-                anafa 1             anafa 2\r
-ext port | 13 14 15 16 17 18 | 19 20 21 22 23 24\r
-int port | 24 23 22 18 17 16 | 24 23 22 18 17 16\r
-ext port | 1  2  3  4  5  6  | 7  8  9  10 11 12\r
-int port | 21 20 19 15 14 13 | 21 20 19 15 14 13\r
-\r
------------>\r
-                anafa 1             anafa 2\r
-ext port | -  -  5  -  -  6  | -  -  7  -  -  8\r
-int port | 24 23 22 18 17 16 | 24 23 22 18 17 16\r
-ext port | -  -  1  -  -  2  | -  -  3  -  -  4\r
-int port | 21 20 19 15 14 13 | 21 20 19 15 14 13\r
-------------------------------------------------\r
-\r
-Module : sLB-2024\r
-\r
-ext port | 13 14 15 16 17 18 19 20 21 22 23 24\r
-A1 int port| 13 14 15 16 17 18 19 20 21 22 23 24\r
-ext port | 1 2 3 4 5 6 7 8 9 10 11 12\r
-A2 int port| 13 14 15 16 17 18 19 20 21 22 23 24\r
----------------------------------------------------\r
-\r
-*/\r
-\r
-int int2ext_map_slb24[2][25] = {\r
-                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 5, 4, 18, 17, 16, 1, 2, 3, 13, 14, 15 },\r
-                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 11, 10, 24, 23, 22, 7, 8, 9, 19, 20, 21 }\r
-                               };\r
-int int2ext_map_slb8[2][25] = {\r
-                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 6, 6, 6, 1, 1, 1, 5, 5, 5 },\r
-                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 8, 8, 8, 3, 3, 3, 7, 7, 7 }\r
-                               };\r
-int int2ext_map_slb2024[2][25] = {\r
-                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 },\r
-                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }\r
-                               };\r
-/*     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 }; */\r
-\r
-/*\r
-       This function relevant only for line modules/chips\r
-       Returns string with external port index\r
-*/\r
-char *portmapstring(Port *port)\r
-{\r
-       static char mapping[OUT_BUFFER_SIZE];\r
-       ChassisRecord *ch = port->node->chrecord;\r
-       int portnum = port->portnum;\r
-       int chipnum = 0;\r
-       int pindex = 0;\r
-       Node *node = port->node;\r
-\r
-       if (!ch || !is_line(node) || (portnum < 13 || portnum > 24))\r
-               return NULL;\r
-\r
-       if (ch->anafanum < 1 || ch->anafanum > 2)\r
-               return NULL;\r
-\r
-       memset(mapping, 0, sizeof(mapping));\r
-\r
-       chipnum = ch->anafanum - 1;\r
-\r
-       if (is_line_24(node))\r
-               pindex = int2ext_map_slb24[chipnum][portnum];\r
-       else if (is_line_2024(node))\r
-               pindex = int2ext_map_slb2024[chipnum][portnum];\r
-       else\r
-               pindex = int2ext_map_slb8[chipnum][portnum];\r
-\r
-       sprintf(mapping, "[ext %d]", pindex);\r
-\r
-       return mapping;\r
-}\r
-\r
-static void add_chassislist()\r
-{\r
-       if (!(mylist.current = calloc(1, sizeof(ChassisList))))\r
-               IBPANIC("out of mem");\r
-\r
-       if (mylist.first == NULL) {\r
-               mylist.first = mylist.current;\r
-               mylist.last = mylist.current;\r
-       } else {\r
-               mylist.last->next = mylist.current;\r
-               mylist.current->next = NULL;\r
-               mylist.last = mylist.current;\r
-       }\r
-}\r
-\r
-/*\r
-       Main grouping function\r
-       Algorithm:\r
-       1. pass on every Voltaire node\r
-       2. catch spine chip for every Voltaire node\r
-               2.1 build/interpolate chassis around this chip\r
-               2.2 go to 1.\r
-       3. pass on non Voltaire nodes (SystemImageGUID based grouping)\r
-       4. now group non Voltaire nodes by SystemImageGUID\r
-*/\r
-ChassisList *group_nodes()\r
-{\r
-       Node *node;\r
-       int dist;\r
-       int chassisnum = 0;\r
-       struct ChassisList *chassis;\r
-\r
-       mylist.first = NULL;\r
-       mylist.current = NULL;\r
-       mylist.last = NULL;\r
-\r
-       /* first pass on switches and build for every Voltaire node */\r
-       /* an appropriate chassis record (slotnum and position) */\r
-       /* according to internal connectivity */\r
-       /* not very efficient but clear code so... */\r
-       for (dist = 0; dist <= maxhops_discovered; dist++) {\r
-               for (node = nodesdist[dist]; node; node = node->dnext) {\r
-                       if (node->vendid == VTR_VENDOR_ID)\r
-                               fill_chassis_record(node);\r
-               }\r
-       }\r
-\r
-       /* separate every Voltaire chassis from each other and build linked list of them */\r
-       /* algorithm: catch spine and find all surrounding nodes */\r
-       for (dist = 0; dist <= maxhops_discovered; dist++) {\r
-               for (node = nodesdist[dist]; node; node = node->dnext) {\r
-                       if (node->vendid != VTR_VENDOR_ID)\r
-                               continue;\r
-                       if (!node->chrecord || node->chrecord->chassisnum || !is_spine(node))\r
-                               continue;\r
-                       add_chassislist();\r
-                       mylist.current->chassisnum = ++chassisnum;\r
-                       build_chassis(node, mylist.current);\r
-               }\r
-       }\r
-\r
-       /* now make pass on nodes for chassis which are not Voltaire */\r
-       /* grouped by common SystemImageGUID */\r
-       for (dist = 0; dist <= maxhops_discovered; dist++) {\r
-               for (node = nodesdist[dist]; node; node = node->dnext) {\r
-                       if (node->vendid == VTR_VENDOR_ID)\r
-                               continue;\r
-                       if (node->sysimgguid) {\r
-                               chassis = find_chassisguid(node);\r
-                               if (chassis)\r
-                                       chassis->nodecount++;\r
-                               else {\r
-                                       /* Possible new chassis */\r
-                                       add_chassislist();\r
-                                       mylist.current->chassisguid = get_chassisguid(node);\r
-                                       mylist.current->nodecount = 1;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-       /* now, make another pass to see which nodes are part of chassis */\r
-       /* (defined as chassis->nodecount > 1) */\r
-       for (dist = 0; dist <= MAXHOPS; ) {\r
-               for (node = nodesdist[dist]; node; node = node->dnext) {\r
-                       if (node->vendid == VTR_VENDOR_ID)\r
-                               continue;\r
-                       if (node->sysimgguid) {\r
-                               chassis = find_chassisguid(node);\r
-                               if (chassis && chassis->nodecount > 1) {\r
-                                       if (!chassis->chassisnum)\r
-                                               chassis->chassisnum = ++chassisnum;\r
-                                       if (!node->chrecord) {\r
-                                               if (!(node->chrecord = calloc(1, sizeof(ChassisRecord))))\r
-                                                       IBPANIC("out of mem");\r
-                                               node->chrecord->chassisnum = (uint8_t)chassis->chassisnum;\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-               if (dist == maxhops_discovered)\r
-                       dist = MAXHOPS; /* skip to CAs */\r
-               else\r
-                       dist++;\r
-       }\r
-\r
-       return (mylist.first);\r
-}\r
+/*
+ * Copyright (c) 2004-2007 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2007 Xsigo Systems Inc.  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.
+ *
+ */
+
+/*========================================================*/
+/*               FABRIC SCANNER SPECIFIC DATA             */
+/*========================================================*/
+
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include <infiniband/mad.h>
+
+#include "ibnetdiscover.h"
+#include "grouping.h"
+
+#define OUT_BUFFER_SIZE 16
+
+
+extern Node *nodesdist[MAXHOPS+1];     /* last is CA list */
+extern Node *mynode;
+extern Port *myport;
+extern int maxhops_discovered;
+
+AllChassisList mylist;
+
+char *ChassisTypeStr[5] = { "", "ISR9288", "ISR9096", "ISR2012", "ISR2004" };
+char *ChassisSlotStr[4] = { "", "Line", "Spine", "SRBD" };
+
+
+char *get_chassis_type(unsigned char chassistype)
+{
+       if (chassistype == UNRESOLVED_CT || chassistype > ISR2004_CT)
+               return NULL;
+       return ChassisTypeStr[chassistype];
+}
+
+char *get_chassis_slot(unsigned char chassisslot)
+{
+       if (chassisslot == UNRESOLVED_CS || chassisslot > SRBD_CS)
+               return NULL;
+       return ChassisSlotStr[chassisslot];
+}
+
+static struct ChassisList *find_chassisnum(unsigned char chassisnum)
+{
+       ChassisList *current;
+
+       for (current = mylist.first; current; current = current->next) {
+               if (current->chassisnum == chassisnum)
+                       return current;
+       }
+
+       return NULL;
+}
+
+static uint64_t topspin_chassisguid(uint64_t guid)
+{
+       /* Byte 3 in system image GUID is chassis type, and */
+       /* Byte 4 is location ID (slot) so just mask off byte 4 */
+       return guid & 0xffffffff00ffffffULL;
+}
+
+int is_xsigo_guid(uint64_t guid)
+{
+       if ((guid & 0xffffff0000000000ULL) == 0x0013970000000000ULL)
+               return 1;
+       else
+               return 0;
+}
+
+static int is_xsigo_leafone(uint64_t guid)
+{
+       if ((guid & 0xffffffffff000000ULL) == 0x0013970102000000ULL)
+               return 1;
+       else
+               return 0;
+}
+
+int is_xsigo_hca(uint64_t guid)
+{
+       /* NodeType 2 is HCA */
+       if ((guid & 0xffffffff00000000ULL) == 0x0013970200000000ULL)
+               return 1;
+       else
+               return 0;
+}
+
+int is_xsigo_tca(uint64_t guid)
+{
+       /* NodeType 3 is TCA */
+       if ((guid & 0xffffffff00000000ULL) == 0x0013970300000000ULL)
+               return 1;
+       else
+               return 0;
+}
+
+static int is_xsigo_ca(uint64_t guid)
+{
+       if (is_xsigo_hca(guid) || is_xsigo_tca(guid))
+               return 1;
+       else
+               return 0;
+}
+
+static int is_xsigo_switch(uint64_t guid)
+{
+       if ((guid & 0xffffffff00000000ULL) == 0x0013970100000000ULL)
+               return 1;
+       else
+               return 0;
+}
+
+static uint64_t xsigo_chassisguid(Node *node)
+{
+       if (!is_xsigo_ca(node->sysimgguid)) {
+               /* Byte 3 is NodeType and byte 4 is PortType */
+               /* If NodeType is 1 (switch), PortType is masked */
+               if (is_xsigo_switch(node->sysimgguid))
+                       return node->sysimgguid & 0xffffffff00ffffffULL;
+               else
+                       return node->sysimgguid;
+       } else {
+               /* Is there a peer port ? */
+               if (!node->ports->remoteport)
+                       return node->sysimgguid;
+
+               /* If peer port is Leaf 1, use its chassis GUID */
+               if (is_xsigo_leafone(node->ports->remoteport->node->sysimgguid))
+                       return node->ports->remoteport->node->sysimgguid &
+                              0xffffffff00ffffffULL;
+               else
+                       return node->sysimgguid;
+       }
+}
+
+static uint64_t get_chassisguid(Node *node)
+{
+       if (node->vendid == TS_VENDOR_ID || node->vendid == SS_VENDOR_ID)
+               return topspin_chassisguid(node->sysimgguid);
+       else if (node->vendid == XS_VENDOR_ID || is_xsigo_guid(node->sysimgguid))
+               return xsigo_chassisguid(node);
+       else
+               return node->sysimgguid;
+}
+
+static struct ChassisList *find_chassisguid(Node *node)
+{
+       ChassisList *current;
+       uint64_t chguid;
+
+       chguid = get_chassisguid(node);
+       for (current = mylist.first; current; current = current->next) {
+               if (current->chassisguid == chguid)
+                       return current;
+       }
+
+       return NULL;
+}
+
+uint64_t get_chassis_guid(unsigned char chassisnum)
+{
+       ChassisList *chassis;
+
+       chassis = find_chassisnum(chassisnum);
+       if (chassis)
+               return chassis->chassisguid;
+       else
+               return 0;
+}
+
+static int is_router(Node *node)
+{
+       return (node->devid == VTR_DEVID_IB_FC_ROUTER ||
+               node->devid == VTR_DEVID_IB_IP_ROUTER);
+}
+
+static int is_spine_9096(Node *node)
+{
+       return (node->devid == VTR_DEVID_SFB4 ||
+               node->devid == VTR_DEVID_SFB4_DDR);
+}
+
+static int is_spine_9288(Node *node)
+{
+       return (node->devid == VTR_DEVID_SFB12 ||
+               node->devid == VTR_DEVID_SFB12_DDR);
+}
+
+static int is_spine_2004(Node *node)
+{
+       return (node->devid == VTR_DEVID_SFB2004);
+}
+
+static int is_spine_2012(Node *node)
+{
+       return (node->devid == VTR_DEVID_SFB2012);
+}
+
+static int is_spine(Node *node)
+{
+       return (is_spine_9096(node) || is_spine_9288(node) ||
+               is_spine_2004(node) || is_spine_2012(node));
+}
+
+static int is_line_24(Node *node)
+{
+       return (node->devid == VTR_DEVID_SLB24 ||
+               node->devid == VTR_DEVID_SLB24_DDR ||
+               node->devid == VTR_DEVID_SRB2004);
+}
+
+static int is_line_8(Node *node)
+{
+       return (node->devid == VTR_DEVID_SLB8);
+}
+
+static int is_line_2024(Node *node)
+{
+       return (node->devid == VTR_DEVID_SLB2024);
+}
+
+static int is_line(Node *node)
+{
+       return (is_line_24(node) || is_line_8(node) || is_line_2024(node));
+}
+
+int is_chassis_switch(Node *node)
+{
+    return (is_spine(node) || is_line(node));
+}
+
+/* these structs help find Line (Anafa) slot number while using spine portnum */
+char line_slot_2_sfb4[25]        = { 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4 };
+char anafa_line_slot_2_sfb4[25]  = { 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2 };
+char line_slot_2_sfb12[25]       = { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10, 10, 11, 11, 12, 12 };
+char anafa_line_slot_2_sfb12[25] = { 0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 };
+
+/* IPR FCR modules connectivity while using sFB4 port as reference */
+char ipr_slot_2_sfb4_port[25]    = { 0, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1, 3, 2, 1 };
+
+/* these structs help find Spine (Anafa) slot number while using spine portnum */
+char spine12_slot_2_slb[25]      = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+char anafa_spine12_slot_2_slb[25]= { 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+char spine4_slot_2_slb[25]       = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+char anafa_spine4_slot_2_slb[25] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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 }; */
+
+static void get_sfb_slot(Node *node, Port *lineport)
+{
+       ChassisRecord *ch = node->chrecord;
+
+       ch->chassisslot = SPINE_CS;
+       if (is_spine_9096(node)) {
+               ch->chassistype = ISR9096_CT;
+               ch->slotnum = spine4_slot_2_slb[lineport->portnum];
+               ch->anafanum = anafa_spine4_slot_2_slb[lineport->portnum];
+       } else if (is_spine_9288(node)) {
+               ch->chassistype = ISR9288_CT;
+               ch->slotnum = spine12_slot_2_slb[lineport->portnum];
+               ch->anafanum = anafa_spine12_slot_2_slb[lineport->portnum];
+       } else if (is_spine_2012(node)) {
+               ch->chassistype = ISR2012_CT;
+               ch->slotnum = spine12_slot_2_slb[lineport->portnum];
+               ch->anafanum = anafa_spine12_slot_2_slb[lineport->portnum];
+       } else if (is_spine_2004(node)) {
+               ch->chassistype = ISR2004_CT;
+               ch->slotnum = spine4_slot_2_slb[lineport->portnum];
+               ch->anafanum = anafa_spine4_slot_2_slb[lineport->portnum];
+       } else {
+               IBPANIC("Unexpected node found: guid 0x%016" PRIx64, node->nodeguid);
+       }
+}
+
+static void get_router_slot(Node *node, Port *spineport)
+{
+       ChassisRecord *ch = node->chrecord;
+       uint64_t guessnum = 0;
+
+       if (!ch) {
+               if (!(node->chrecord = calloc(1, sizeof(ChassisRecord))))
+                       IBPANIC("out of mem");
+               ch = node->chrecord;
+       }
+
+       ch->chassisslot = SRBD_CS;
+       if (is_spine_9096(spineport->node)) {
+               ch->chassistype = ISR9096_CT;
+               ch->slotnum = line_slot_2_sfb4[spineport->portnum];
+               ch->anafanum = ipr_slot_2_sfb4_port[spineport->portnum];
+       } else if (is_spine_9288(spineport->node)) {
+               ch->chassistype = ISR9288_CT;
+               ch->slotnum = line_slot_2_sfb12[spineport->portnum];
+               /* this is a smart guess based on nodeguids order on sFB-12 module */
+               guessnum = spineport->node->nodeguid % 4;
+               /* module 1 <--> remote anafa 3 */
+               /* module 2 <--> remote anafa 2 */
+               /* module 3 <--> remote anafa 1 */
+               ch->anafanum = (guessnum == 3 ? 1 : (guessnum == 1 ? 3 : 2));
+       } else if (is_spine_2012(spineport->node)) {
+               ch->chassistype = ISR2012_CT;
+               ch->slotnum = line_slot_2_sfb12[spineport->portnum];
+               /* this is a smart guess based on nodeguids order on sFB-12 module */
+               guessnum = spineport->node->nodeguid % 4;
+               // module 1 <--> remote anafa 3
+               // module 2 <--> remote anafa 2
+               // module 3 <--> remote anafa 1
+               ch->anafanum = (guessnum == 3? 1 : (guessnum == 1 ? 3 : 2));
+       } else if (is_spine_2004(spineport->node)) {
+               ch->chassistype = ISR2004_CT;
+               ch->slotnum = line_slot_2_sfb4[spineport->portnum];
+               ch->anafanum = ipr_slot_2_sfb4_port[spineport->portnum];
+       } else {
+               IBPANIC("Unexpected node found: guid 0x%016" PRIx64, spineport->node->nodeguid);
+       }
+}
+
+static void get_slb_slot(ChassisRecord *ch, Port *spineport)
+{
+       ch->chassisslot = LINE_CS;
+       if (is_spine_9096(spineport->node)) {
+               ch->chassistype = ISR9096_CT;
+               ch->slotnum = line_slot_2_sfb4[spineport->portnum];
+               ch->anafanum = anafa_line_slot_2_sfb4[spineport->portnum];
+       } else if (is_spine_9288(spineport->node)) {
+               ch->chassistype = ISR9288_CT;
+               ch->slotnum = line_slot_2_sfb12[spineport->portnum];
+               ch->anafanum = anafa_line_slot_2_sfb12[spineport->portnum];
+       } else if (is_spine_2012(spineport->node)) {
+               ch->chassistype = ISR2012_CT;
+               ch->slotnum = line_slot_2_sfb12[spineport->portnum];
+               ch->anafanum = anafa_line_slot_2_sfb12[spineport->portnum];
+       } else if (is_spine_2004(spineport->node)) {
+               ch->chassistype = ISR2004_CT;
+               ch->slotnum = line_slot_2_sfb4[spineport->portnum];
+               ch->anafanum = anafa_line_slot_2_sfb4[spineport->portnum];
+       } else {
+               IBPANIC("Unexpected node found: guid 0x%016" PRIx64, spineport->node->nodeguid);
+       }
+}
+
+/*
+       This function called for every Voltaire node in fabric
+       It could be optimized so, but time overhead is very small
+       and its only diag.util
+*/
+static void fill_chassis_record(Node *node)
+{
+       Port *port;
+       Node *remnode = 0;
+       ChassisRecord *ch = 0;
+
+       if (node->chrecord) /* somehow this node has already been passed */
+               return;
+
+       if (!(node->chrecord = calloc(1, sizeof(ChassisRecord))))
+               IBPANIC("out of mem");
+
+       ch = node->chrecord;
+
+       /* node is router only in case of using unique lid */
+       /* (which is lid of chassis router port) */
+       /* in such case node->ports is actually a requested port... */
+       if (is_router(node) && is_spine(node->ports->remoteport->node))
+               get_router_slot(node, node->ports->remoteport);
+       else if (is_spine(node)) {
+               for (port = node->ports; port; port = port->next) {
+                       if (!port->remoteport)
+                               continue;
+                       remnode = port->remoteport->node;
+                       if (remnode->type != SWITCH_NODE) {
+                               if (!remnode->chrecord)
+                                       get_router_slot(remnode, port);
+                               continue;
+                       }
+                       if (!ch->chassistype)
+                               /* we assume here that remoteport belongs to line */
+                               get_sfb_slot(node, port->remoteport);
+
+                               /* we could break here, but need to find if more routers connected */
+               }
+
+       } else if (is_line(node)) {
+               for (port = node->ports; port; port = port->next) {
+                       if (port->portnum > 12)
+                               continue;
+                       if (!port->remoteport)
+                               continue;
+                       /* we assume here that remoteport belongs to spine */
+                       get_slb_slot(ch, port->remoteport);
+                       break;
+               }
+       }
+
+       return;
+}
+
+static int get_line_index(Node *node)
+{
+       int retval = 3 * (node->chrecord->slotnum - 1) + node->chrecord->anafanum;
+
+       if (retval > LINES_MAX_NUM || retval < 1)
+               IBPANIC("Internal error");
+       return retval;
+}
+
+static int get_spine_index(Node *node)
+{
+       int retval;
+
+       if (is_spine_9288(node) || is_spine_2012(node))
+               retval = 3 * (node->chrecord->slotnum - 1) + node->chrecord->anafanum;
+       else
+               retval = node->chrecord->slotnum;
+
+       if (retval > SPINES_MAX_NUM || retval < 1)
+               IBPANIC("Internal error");
+       return retval;
+}
+
+static void insert_line_router(Node *node, ChassisList *chassislist)
+{
+       int i = get_line_index(node);
+
+       if (chassislist->linenode[i])
+               return;         /* already filled slot */
+
+       chassislist->linenode[i] = node;
+       node->chrecord->chassisnum = chassislist->chassisnum;
+}
+
+static void insert_spine(Node *node, ChassisList *chassislist)
+{
+       int i = get_spine_index(node);
+
+       if (chassislist->spinenode[i])
+               return;         /* already filled slot */
+
+       chassislist->spinenode[i] = node;
+       node->chrecord->chassisnum = chassislist->chassisnum;
+}
+
+static void pass_on_lines_catch_spines(ChassisList *chassislist)
+{
+       Node *node, *remnode;
+       Port *port;
+       int i;
+
+       for (i = 1; i <= LINES_MAX_NUM; i++) {
+               node = chassislist->linenode[i];
+
+               if (!(node && is_line(node)))
+                       continue;       /* empty slot or router */
+
+               for (port = node->ports; port; port = port->next) {
+                       if (port->portnum > 12)
+                               continue;
+
+                       if (!port->remoteport)
+                               continue;
+                       remnode = port->remoteport->node;
+
+                       if (!remnode->chrecord)
+                               continue;       /* some error - spine not initialized ? FIXME */
+                       insert_spine(remnode, chassislist);
+               }
+       }
+}
+
+static void pass_on_spines_catch_lines(ChassisList *chassislist)
+{
+       Node *node, *remnode;
+       Port *port;
+       int i;
+
+       for (i = 1; i <= SPINES_MAX_NUM; i++) {
+               node = chassislist->spinenode[i];
+               if (!node)
+                       continue;       /* empty slot */
+               for (port = node->ports; port; port = port->next) {
+                       if (!port->remoteport)
+                               continue;
+                       remnode = port->remoteport->node;
+
+                       if (!remnode->chrecord)
+                               continue;       /* some error - line/router not initialized ? FIXME */
+                       insert_line_router(remnode, chassislist);
+               }
+       }
+}
+
+/*
+       Stupid interpolation algorithm...
+       But nothing to do - have to be compliant with VoltaireSM/NMS
+*/
+static void pass_on_spines_interpolate_chguid(ChassisList *chassislist)
+{
+       Node *node;
+       int i;
+
+       for (i = 1; i <= SPINES_MAX_NUM; i++) {
+               node = chassislist->spinenode[i];
+               if (!node)
+                       continue;       /* skip the empty slots */
+
+               /* take first guid minus one to be consistent with SM */
+               chassislist->chassisguid = node->nodeguid - 1;
+               break;
+       }
+}
+
+/*
+       This function fills chassislist structure with all nodes
+       in that chassis
+       chassislist structure = structure of one standalone chassis
+*/
+static void build_chassis(Node *node, ChassisList *chassislist)
+{
+       Node *remnode = 0;
+       Port *port = 0;
+
+       /* we get here with node = chassis_spine */
+       chassislist->chassistype = node->chrecord->chassistype;
+       insert_spine(node, chassislist);
+
+       /* loop: pass on all ports of node */
+       for (port = node->ports; port; port = port->next) {
+               if (!port->remoteport)
+                       continue;
+               remnode = port->remoteport->node;
+
+               if (!remnode->chrecord)
+                       continue; /* some error - line or router not initialized ? FIXME */
+
+               insert_line_router(remnode, chassislist);
+       }
+
+       pass_on_lines_catch_spines(chassislist);
+       /* this pass needed for to catch routers, since routers connected only */
+       /* to spines in slot 1 or 4 and we could miss them first time */
+       pass_on_spines_catch_lines(chassislist);
+
+       /* additional 2 passes needed for to overcome a problem of pure "in-chassis" */
+       /* connectivity - extra pass to ensure that all related chips/modules */
+       /* inserted into the chassislist */
+       pass_on_lines_catch_spines(chassislist);
+       pass_on_spines_catch_lines(chassislist);
+       pass_on_spines_interpolate_chguid(chassislist);
+}
+
+/*========================================================*/
+/*                INTERNAL TO EXTERNAL PORT MAPPING       */
+/*========================================================*/
+
+/*
+Description : On ISR9288/9096 external ports indexing
+              is not matching the internal ( anafa ) port
+              indexes. Use this MAP to translate the data you get from
+              the OpenIB diagnostics (smpquery, ibroute, ibtracert, etc.)
+
+
+Module : sLB-24
+                anafa 1             anafa 2
+ext port | 13 14 15 16 17 18 | 19 20 21 22 23 24
+int port | 22 23 24 18 17 16 | 22 23 24 18 17 16
+ext port | 1  2  3  4  5  6  | 7  8  9  10 11 12
+int port | 19 20 21 15 14 13 | 19 20 21 15 14 13
+------------------------------------------------
+
+Module : sLB-8
+                anafa 1             anafa 2
+ext port | 13 14 15 16 17 18 | 19 20 21 22 23 24
+int port | 24 23 22 18 17 16 | 24 23 22 18 17 16
+ext port | 1  2  3  4  5  6  | 7  8  9  10 11 12
+int port | 21 20 19 15 14 13 | 21 20 19 15 14 13
+
+----------->
+                anafa 1             anafa 2
+ext port | -  -  5  -  -  6  | -  -  7  -  -  8
+int port | 24 23 22 18 17 16 | 24 23 22 18 17 16
+ext port | -  -  1  -  -  2  | -  -  3  -  -  4
+int port | 21 20 19 15 14 13 | 21 20 19 15 14 13
+------------------------------------------------
+
+Module : sLB-2024
+
+ext port | 13 14 15 16 17 18 19 20 21 22 23 24
+A1 int port| 13 14 15 16 17 18 19 20 21 22 23 24
+ext port | 1 2 3 4 5 6 7 8 9 10 11 12
+A2 int port| 13 14 15 16 17 18 19 20 21 22 23 24
+---------------------------------------------------
+
+*/
+
+int int2ext_map_slb24[2][25] = {
+                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 5, 4, 18, 17, 16, 1, 2, 3, 13, 14, 15 },
+                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 11, 10, 24, 23, 22, 7, 8, 9, 19, 20, 21 }
+                               };
+int int2ext_map_slb8[2][25] = {
+                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 6, 6, 6, 1, 1, 1, 5, 5, 5 },
+                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 8, 8, 8, 3, 3, 3, 7, 7, 7 }
+                               };
+int int2ext_map_slb2024[2][25] = {
+                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 },
+                                       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
+                               };
+/*     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 }; */
+
+/*
+       This function relevant only for line modules/chips
+       Returns string with external port index
+*/
+char *portmapstring(Port *port)
+{
+       static char mapping[OUT_BUFFER_SIZE];
+       ChassisRecord *ch = port->node->chrecord;
+       int portnum = port->portnum;
+       int chipnum = 0;
+       int pindex = 0;
+       Node *node = port->node;
+
+       if (!ch || !is_line(node) || (portnum < 13 || portnum > 24))
+               return NULL;
+
+       if (ch->anafanum < 1 || ch->anafanum > 2)
+               return NULL;
+
+       memset(mapping, 0, sizeof(mapping));
+
+       chipnum = ch->anafanum - 1;
+
+       if (is_line_24(node))
+               pindex = int2ext_map_slb24[chipnum][portnum];
+       else if (is_line_2024(node))
+               pindex = int2ext_map_slb2024[chipnum][portnum];
+       else
+               pindex = int2ext_map_slb8[chipnum][portnum];
+
+       sprintf(mapping, "[ext %d]", pindex);
+
+       return mapping;
+}
+
+static void add_chassislist()
+{
+       if (!(mylist.current = calloc(1, sizeof(ChassisList))))
+               IBPANIC("out of mem");
+
+       if (mylist.first == NULL) {
+               mylist.first = mylist.current;
+               mylist.last = mylist.current;
+       } else {
+               mylist.last->next = mylist.current;
+               mylist.current->next = NULL;
+               mylist.last = mylist.current;
+       }
+}
+
+/*
+       Main grouping function
+       Algorithm:
+       1. pass on every Voltaire node
+       2. catch spine chip for every Voltaire node
+               2.1 build/interpolate chassis around this chip
+               2.2 go to 1.
+       3. pass on non Voltaire nodes (SystemImageGUID based grouping)
+       4. now group non Voltaire nodes by SystemImageGUID
+*/
+ChassisList *group_nodes()
+{
+       Node *node;
+       int dist;
+       int chassisnum = 0;
+       struct ChassisList *chassis;
+
+       mylist.first = NULL;
+       mylist.current = NULL;
+       mylist.last = NULL;
+
+       /* first pass on switches and build for every Voltaire node */
+       /* an appropriate chassis record (slotnum and position) */
+       /* according to internal connectivity */
+       /* not very efficient but clear code so... */
+       for (dist = 0; dist <= maxhops_discovered; dist++) {
+               for (node = nodesdist[dist]; node; node = node->dnext) {
+                       if (node->vendid == VTR_VENDOR_ID)
+                               fill_chassis_record(node);
+               }
+       }
+
+       /* separate every Voltaire chassis from each other and build linked list of them */
+       /* algorithm: catch spine and find all surrounding nodes */
+       for (dist = 0; dist <= maxhops_discovered; dist++) {
+               for (node = nodesdist[dist]; node; node = node->dnext) {
+                       if (node->vendid != VTR_VENDOR_ID)
+                               continue;
+                       if (!node->chrecord || node->chrecord->chassisnum || !is_spine(node))
+                               continue;
+                       add_chassislist();
+                       mylist.current->chassisnum = ++chassisnum;
+                       build_chassis(node, mylist.current);
+               }
+       }
+
+       /* now make pass on nodes for chassis which are not Voltaire */
+       /* grouped by common SystemImageGUID */
+       for (dist = 0; dist <= maxhops_discovered; dist++) {
+               for (node = nodesdist[dist]; node; node = node->dnext) {
+                       if (node->vendid == VTR_VENDOR_ID)
+                               continue;
+                       if (node->sysimgguid) {
+                               chassis = find_chassisguid(node);
+                               if (chassis)
+                                       chassis->nodecount++;
+                               else {
+                                       /* Possible new chassis */
+                                       add_chassislist();
+                                       mylist.current->chassisguid = get_chassisguid(node);
+                                       mylist.current->nodecount = 1;
+                               }
+                       }
+               }
+       }
+
+       /* now, make another pass to see which nodes are part of chassis */
+       /* (defined as chassis->nodecount > 1) */
+       for (dist = 0; dist <= MAXHOPS; ) {
+               for (node = nodesdist[dist]; node; node = node->dnext) {
+                       if (node->vendid == VTR_VENDOR_ID)
+                               continue;
+                       if (node->sysimgguid) {
+                               chassis = find_chassisguid(node);
+                               if (chassis && chassis->nodecount > 1) {
+                                       if (!chassis->chassisnum)
+                                               chassis->chassisnum = ++chassisnum;
+                                       if (!node->chrecord) {
+                                               if (!(node->chrecord = calloc(1, sizeof(ChassisRecord))))
+                                                       IBPANIC("out of mem");
+                                               node->chrecord->chassisnum = chassis->chassisnum;
+                                       }
+                               }
+                       }
+               }
+               if (dist == maxhops_discovered)
+                       dist = MAXHOPS; /* skip to CAs */
+               else
+                       dist++;
+       }
+
+       return (mylist.first);
+}
similarity index 54%
rename from tools/infiniband_diags/src/ibaddr.c
rename to tools/infiniband-diags/src/ibaddr.c
index 3b72ae4..9098699 100644 (file)
-/*\r
- * Copyright (c) 2004-2008 Voltaire Inc.  All rights reserved.\r
- *\r
- * This software is available to you under a choice of one of two\r
- * licenses.  You may choose to be licensed under the terms of the GNU\r
- * General Public License (GPL) Version 2, available from the file\r
- * COPYING in the main directory of this source tree, or the\r
- * OpenIB.org BSD license below:\r
- *\r
- *     Redistribution and use in source and binary forms, with or\r
- *     without modification, are permitted provided that the following\r
- *     conditions are met:\r
- *\r
- *      - Redistributions of source code must retain the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer.\r
- *\r
- *      - Redistributions in binary form must reproduce the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer in the documentation and/or other materials\r
- *        provided with the distribution.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- * SOFTWARE.\r
- *\r
- */\r
-\r
-#if HAVE_CONFIG_H\r
-#  include <config.h>\r
-#endif /* HAVE_CONFIG_H */\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-\r
-#include <infiniband/umad.h>\r
-#include <infiniband/mad.h>\r
-\r
-#include "ibdiag_common.h"\r
-\r
-char *argv0 = "ibaddr";\r
-\r
-static int\r
-ib_resolve_addr(ib_portid_t *portid, int portnum, int show_lid, int show_gid)\r
-{\r
-       char   gid_str[INET6_ADDRSTRLEN];\r
-       uint8_t portinfo[64];\r
-       uint8_t nodeinfo[64];\r
-       uint64_t guid, prefix;\r
-       ibmad_gid_t gid;\r
-       int lmc;\r
-\r
-       if (!smp_query(nodeinfo, portid, IB_ATTR_NODE_INFO, 0, 0))\r
-               return -1;\r
-\r
-       if (!smp_query(portinfo, portid, IB_ATTR_PORT_INFO, portnum, 0))\r
-               return -1;\r
-\r
-       mad_decode_field(portinfo, IB_PORT_LID_F, &portid->lid);\r
-       mad_decode_field(portinfo, IB_PORT_GID_PREFIX_F, &prefix);\r
-       mad_decode_field(portinfo, IB_PORT_LMC_F, &lmc);\r
-       mad_decode_field(nodeinfo, IB_NODE_PORT_GUID_F, &guid);\r
-\r
-       mad_encode_field(gid, IB_GID_PREFIX_F, &prefix);\r
-       mad_encode_field(gid, IB_GID_GUID_F, &guid);\r
-\r
-       if (show_gid) {\r
-               printf("GID %s ", inet_ntop(AF_INET6, gid, gid_str,\r
-                       sizeof gid_str));\r
-       }\r
-\r
-       if (show_lid > 0)\r
-               printf("LID start 0x%x end 0x%x", portid->lid, portid->lid + (1 << lmc) - 1);\r
-       else if (show_lid < 0)\r
-               printf("LID start %d end %d", portid->lid, portid->lid + (1 << lmc) - 1);\r
-       printf("\n");\r
-       return 0;\r
-}\r
-\r
-static void\r
-usage(void)\r
-{\r
-       char *basename;\r
-\r
-       if (!(basename = strrchr(argv0, '/')))\r
-               basename = argv0;\r
-       else\r
-               basename++;\r
-\r
-       fprintf(stderr, "Usage: %s [-d(ebug) -D(irect) -G(uid) -l(id_show) -g(id_show) -s(m_port) sm_lid -C ca_name -P ca_port "\r
-                       "-t(imeout) timeout_ms -V(ersion) -h(elp)] [<lid|dr_path|guid>]\n",\r
-                       basename);\r
-       fprintf(stderr, "\tExamples:\n");\r
-       fprintf(stderr, "\t\t%s\t\t\t# local port's address\n", basename);\r
-       fprintf(stderr, "\t\t%s 32\t\t# show lid range and gid of lid 32\n", basename);\r
-       fprintf(stderr, "\t\t%s -G 0x8f1040023\t# same but using guid address\n", basename);\r
-       fprintf(stderr, "\t\t%s -l 32\t\t# show lid range only\n", basename);\r
-       fprintf(stderr, "\t\t%s -L 32\t\t# show decimal lid range only\n", basename);\r
-       fprintf(stderr, "\t\t%s -g 32\t\t# show gid address only\n", basename);\r
-       exit(-1);\r
-}\r
-\r
-int _CDECL\r
-main(int argc, char **argv)\r
-{\r
-       int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS};\r
-       ib_portid_t *sm_id = 0, sm_portid = {0};\r
-       ib_portid_t portid = {0};\r
-       extern int ibdebug;\r
-       int dest_type = IB_DEST_LID;\r
-       int timeout = 0;        /* use default */\r
-       int show_lid = 0, show_gid = 0;\r
-       int port = 0;\r
-       char *ca = 0;\r
-       int ca_port = 0;\r
-\r
-       static char const str_opts[] = "C:P:t:s:dDGglLVhu";\r
-       static const struct option long_opts[] = {\r
-               { "C", 1, 0, 'C'},\r
-               { "P", 1, 0, 'P'},\r
-               { "debug", 0, 0, 'd'},\r
-               { "Direct", 0, 0, 'D'},\r
-               { "Guid", 0, 0, 'G'},\r
-               { "gid_show", 0, 0, 'g'},\r
-               { "lid_show", 0, 0, 'l'},\r
-               { "Lid_show", 0, 0, 'L'},\r
-               { "timeout", 1, 0, 't'},\r
-               { "sm_port", 1, 0, 's'},\r
-               { "Version", 0, 0, 'V'},\r
-               { "help", 0, 0, 'h'},\r
-               { "usage", 0, 0, 'u'},\r
-               { 0 }\r
-       };\r
-\r
-       argv0 = argv[0];\r
-\r
-       while (1) {\r
-               int ch = getopt_long(argc, argv, str_opts, long_opts, NULL);\r
-               if ( ch == -1 )\r
-                       break;\r
-               switch(ch) {\r
-               case 'C':\r
-                       ca = optarg;\r
-                       break;\r
-               case 'P':\r
-                       ca_port = strtoul(optarg, 0, 0);\r
-                       break;\r
-               case 'd':\r
-                       ibdebug++;\r
-                       break;\r
-               case 'D':\r
-                       dest_type = IB_DEST_DRPATH;\r
-                       break;\r
-               case 'g':\r
-                       show_gid++;\r
-                       break;\r
-               case 'G':\r
-                       dest_type = IB_DEST_GUID;\r
-                       break;\r
-               case 'l':\r
-                       show_lid++;\r
-                       break;\r
-               case 'L':\r
-                       show_lid = -100;\r
-                       break;\r
-               case 's':\r
-                       if (ib_resolve_portid_str(&sm_portid, optarg, IB_DEST_LID, 0) < 0)\r
-                               IBERROR("can't resolve SM destination port %s", optarg);\r
-                       sm_id = &sm_portid;\r
-                       break;\r
-               case 't':\r
-                       timeout = strtoul(optarg, 0, 0);\r
-                       madrpc_set_timeout(timeout);\r
-                       break;\r
-               case 'V':\r
-                       fprintf(stderr, "%s %s\n", argv0, get_build_version() );\r
-                       exit(-1);\r
-               default:\r
-                       usage();\r
-                       break;\r
-               }\r
-       }\r
-       argc -= optind;\r
-       argv += optind;\r
-\r
-       if (argc > 1)\r
-               port = strtoul(argv[1], 0, 0);\r
-\r
-       if (!show_lid && !show_gid)\r
-               show_lid = show_gid = 1;\r
-\r
-       madrpc_init(ca, ca_port, mgmt_classes, 3);\r
-\r
-       if (argc) {\r
-               if (ib_resolve_portid_str(&portid, argv[0], dest_type, sm_id) < 0)\r
-                       IBERROR("can't resolve destination port %s", argv[0]);\r
-       } else {\r
-               if (ib_resolve_self(&portid, &port, 0) < 0)\r
-                       IBERROR("can't resolve self port %s", argv[0]);\r
-       }\r
-\r
-       if (ib_resolve_addr(&portid, port, show_lid, show_gid) < 0)\r
-               IBERROR("can't resolve requested address");\r
-       exit(0);\r
-}\r
+/*
+ * Copyright (c) 2004-2008 Voltaire Inc.  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.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include <infiniband/umad.h>
+#include <infiniband/mad.h>
+
+#include "ibdiag_common.h"
+
+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];
+       uint64_t guid, prefix;
+       ibmad_gid_t gid;
+       int lmc;
+
+       if (!smp_query(nodeinfo, portid, IB_ATTR_NODE_INFO, 0, 0))
+               return -1;
+
+       if (!smp_query(portinfo, portid, IB_ATTR_PORT_INFO, portnum, 0))
+               return -1;
+
+       mad_decode_field(portinfo, IB_PORT_LID_F, &portid->lid);
+       mad_decode_field(portinfo, IB_PORT_GID_PREFIX_F, &prefix);
+       mad_decode_field(portinfo, IB_PORT_LMC_F, &lmc);
+       mad_decode_field(nodeinfo, IB_NODE_PORT_GUID_F, &guid);
+
+       mad_encode_field(gid, IB_GID_PREFIX_F, &prefix);
+       mad_encode_field(gid, IB_GID_GUID_F, &guid);
+
+       if (show_gid) {
+               printf("GID %s ", inet_ntop(AF_INET6, gid, gid_str,
+                       sizeof gid_str));
+       }
+
+       if (show_lid > 0)
+               printf("LID start 0x%x end 0x%x", portid->lid, portid->lid + (1 << lmc) - 1);
+       else if (show_lid < 0)
+               printf("LID start %d end %d", portid->lid, portid->lid + (1 << lmc) - 1);
+       printf("\n");
+       return 0;
+}
+
+static int show_lid, show_gid;
+
+static int process_opt(void *context, int ch, char *optarg)
+{
+       switch (ch) {
+       case 'g':
+               show_gid = 1;
+               break;
+       case 'l':
+               show_lid++;
+               break;
+       case 'L':
+               show_lid = -100;
+               break;
+       default:
+               return -1;
+       }
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS};
+       ib_portid_t portid = {0};
+       int port = 0;
+
+       const struct ibdiag_opt opts[] = {
+               { "gid_show", 'g', 0, NULL, "show gid address only"},
+               { "lid_show", 'l', 0, NULL, "show lid range only"},
+               { "Lid_show", 'L', 0, NULL, "show lid range (in decimal) only"},
+               { 0 }
+       };
+       char usage_args[] = "[<lid|dr_path|guid>]";
+       const char *usage_examples[] = {
+               "\t\t# local port's address",
+               "32\t\t# show lid range and gid of lid 32",
+               "-G 0x8f1040023\t# same but using guid address",
+               "-l 32\t\t# show lid range only",
+               "-L 32\t\t# show decimal lid range only",
+               "-g 32\t\t# show gid address only",
+               NULL
+       };
+
+       ibdiag_process_opts(argc, argv, NULL, "L", opts, process_opt,
+                           usage_args, usage_examples);
+
+       argc -= optind;
+       argv += optind;
+
+       if (argc > 1)
+               port = strtoul(argv[1], 0, 0);
+
+       if (!show_lid && !show_gid)
+               show_lid = show_gid = 1;
+
+       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+
+       if (argc) {
+               if (ib_resolve_portid_str(&portid, argv[0], ibd_dest_type, ibd_sm_id) < 0)
+                       IBERROR("can't resolve destination port %s", argv[0]);
+       } else {
+               if (ib_resolve_self(&portid, &port, 0) < 0)
+                       IBERROR("can't resolve self port %s", argv[0]);
+       }
+
+       if (ib_resolve_addr(&portid, port, show_lid, show_gid) < 0)
+               IBERROR("can't resolve requested address");
+       exit(0);
+}
diff --git a/tools/infiniband-diags/src/ibaddr/SOURCES b/tools/infiniband-diags/src/ibaddr/SOURCES
new file mode 100644 (file)
index 0000000..1d72abc
--- /dev/null
@@ -0,0 +1,31 @@
+TARGETNAME = ibaddr\r
+TARGETPATH = ..\..\..\..\bin\user\obj$(BUILD_ALT_DIR)\r
+TARGETTYPE = PROGRAM\r
+\r
+UMTYPE = console\r
+UMENTRY = main\r
+\r
+USE_MSVCRT = 1\r
+\r
+SOURCES = ..\ibaddr.c ..\ibdiag_common.c ..\ibdiag_windows.c ibaddr.rc\r
+       \r
+INCLUDES = ..\..\include;..\..\include\windows;\\r
+                  ..\..\..\..\ulp\libibmad\include;\\r
+                  ..\..\..\..\ulp\libibumad\include;\\r
+                  ..\..\..\..\inc;..\..\..\..\inc\user;\\r
+                  ..\..\..\..\inc\user\linux;\r
+\r
+C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H\r
+\r
+TARGETLIBS = \\r
+       $(SDK_LIB_PATH)\kernel32.lib    \\r
+       $(SDK_LIB_PATH)\ws2_32.lib              \\r
+!if $(FREEBUILD)\r
+       $(TARGETPATH)\*\libibmad.lib    \\r
+       $(TARGETPATH)\*\libibumad.lib   \r
+!else\r
+       $(TARGETPATH)\*\libibmadd.lib   \\r
+       $(TARGETPATH)\*\libibumadd.lib  \r
+!endif\r
+\r
+MSC_WARNING_LEVEL = /W3 /WX /wd4007\r
diff --git a/tools/infiniband-diags/src/ibaddr/ibaddr.rc b/tools/infiniband-diags/src/ibaddr/ibaddr.rc
new file mode 100644 (file)
index 0000000..c7341a8
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+ * Copyright (c) 2009 Intel Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id$\r
+ */\r
+\r
+\r
+#include <oib_ver.h>\r
+\r
+#define VER_FILETYPE                   VFT_APP\r
+#define VER_FILESUBTYPE                        VFT2_UNKNOWN\r
+\r
+#ifdef DBG\r
+#define VER_FILEDESCRIPTION_STR        "InfiniBand Address Information (Debug)"\r
+#else\r
+#define VER_FILEDESCRIPTION_STR        "InfiniBand Address Information"\r
+#endif\r
+\r
+#define VER_INTERNALNAME_STR           "ibaddr.exe"\r
+#define VER_ORIGINALFILENAME_STR       "ibaddr.exe"\r
+\r
+#include <common.ver>\r
diff --git a/tools/infiniband-diags/src/ibdiag_common.c b/tools/infiniband-diags/src/ibdiag_common.c
new file mode 100644 (file)
index 0000000..5f2472d
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2006-2007 The Regents of the University of California.
+ * Copyright (c) 2004-2006 Voltaire, Inc. 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.
+ *
+ */
+
+/**
+ * Define common functions which can be included in the various C based diags.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <config.h>
+#include <getopt.h>
+
+#include <infiniband/umad.h>
+#include <infiniband/mad.h>
+#include <ibdiag_common.h>
+#include <ibdiag_version.h>
+
+int ibdebug;
+int ibverbose;
+char *ibd_ca;
+int ibd_ca_port;
+enum MAD_DEST ibd_dest_type = IB_DEST_LID;
+ib_portid_t *ibd_sm_id;
+int ibd_timeout;
+
+static ib_portid_t sm_portid = {0};
+
+static const char *prog_name;
+static const char *prog_args;
+static const char **prog_examples;
+static struct option *long_opts;
+static const struct ibdiag_opt *opts_map[256];
+
+const static char *get_build_version(void)
+{
+       return "BUILD VERSION: " IBDIAG_VERSION " Build date: " __DATE__ " " __TIME__;
+}
+
+static void pretty_print(int start, int width, const char *str)
+{
+       int len = width - start;
+       const char *p, *e;
+
+       while (1) {
+               while(isspace(*str))
+                       str++;
+               p = str;
+               do {
+                       e = p + 1;
+                       p = strchr(e, ' ');
+               } while (p && p - str < len);
+               if (!p) {
+                       fprintf(stderr, "%s", str);
+                       break;
+               }
+               if (e - str == 1)
+                       e = p;
+               fprintf(stderr, "%.*s\n%*s", e - str, str, start, "");
+               str = e;
+       }
+}
+
+void ibdiag_show_usage()
+{
+       struct option *o = long_opts;
+       int n;
+
+       fprintf(stderr, "\nUsage: %s [options] %s\n\n", prog_name,
+               prog_args ? prog_args : "");
+
+       if (long_opts[0].name)
+               fprintf(stderr, "Options:\n");
+       for (o = long_opts; o->name; o++) {
+               const struct ibdiag_opt *io = opts_map[o->val];
+               n = fprintf(stderr, "  --%s", io->name);
+               if (isprint(io->letter))
+                       n += fprintf(stderr, ", -%c", io->letter);
+               if (io->has_arg)
+                       n += fprintf(stderr, " %s",
+                                    io->arg_tmpl ? io->arg_tmpl : "<val>");
+               if (io->description && *io->description) {
+                       n += fprintf(stderr, "%*s  ", 24 - n > 0 ? 24 - n : 0, "");
+                       pretty_print(n, 74, io->description);
+               }
+               fprintf(stderr, "\n");
+       }
+
+       if (prog_examples) {
+               const char **p;
+               fprintf(stderr, "\nExamples:\n");
+               for (p = prog_examples; *p && **p; p++)
+                       fprintf(stderr, "  %s %s\n", prog_name, *p);
+       }
+
+       fprintf(stderr, "\n");
+
+       exit(2);
+}
+
+static int process_opt(int ch, char *optarg)
+{
+       int val;
+
+       switch (ch) {
+       case 'h':
+       case 'u':
+               ibdiag_show_usage();
+               break;
+       case 'V':
+               fprintf(stderr, "%s %s\n", prog_name, get_build_version());
+               exit(2);
+       case 'e':
+               madrpc_show_errors(1);
+               break;
+       case 'v':
+               ibverbose++;
+               break;
+       case 'd':
+               ibdebug++;
+               madrpc_show_errors(1);
+               umad_debug(ibdebug - 1);
+               break;
+       case 'C':
+               ibd_ca = optarg;
+               break;
+       case 'P':
+               ibd_ca_port = strtoul(optarg, 0, 0);
+               break;
+       case 'D':
+               ibd_dest_type = IB_DEST_DRPATH;
+               break;
+       case 'L':
+               ibd_dest_type = IB_DEST_LID;
+               break;
+       case 'G':
+               ibd_dest_type = IB_DEST_GUID;
+               break;
+       case 't':
+               val = strtoul(optarg, 0, 0);
+               madrpc_set_timeout(val);
+               ibd_timeout = val;
+               break;
+       case 's':
+               if (ib_resolve_portid_str(&sm_portid, optarg, IB_DEST_LID, 0) < 0)
+                       IBERROR("cannot resolve SM destination port %s", optarg);
+               ibd_sm_id = &sm_portid;
+               break;
+       default:
+               return -1;
+       }
+
+       return 0;
+}
+
+static const struct ibdiag_opt common_opts[] = {
+       { "Ca", 'C', 1, "<ca>", "Ca name to use"},
+       { "Port", 'P', 1, "<port>", "Ca port number to use"},
+       { "Direct", 'D', 0, NULL, "use Direct address argument"},
+       { "Lid", 'L', 0, NULL, "use LID address argument"},
+       { "Guid", 'G', 0, NULL, "use GUID address argument"},
+       { "timeout", 't', 1, "<ms>", "timeout in ms"},
+       { "sm_port", 's', 1, "<lid>", "SM port lid" },
+       { "errors", 'e', 0, NULL, "show send and receive errors" },
+       { "verbose", 'v', 0, NULL, "increase verbosity level" },
+       { "debug", 'd', 0, NULL, "raise debug level" },
+       { "usage", 'u', 0, NULL, "usage message" },
+       { "help", 'h', 0, NULL, "help message" },
+       { "version", 'V', 0, NULL, "show version" },
+       { 0 }
+};
+
+static void make_opt(struct option *l, const struct ibdiag_opt *o,
+                    const struct ibdiag_opt *map[])
+{
+       l->name = o->name;
+       l->has_arg = o->has_arg;
+       l->flag = NULL;
+       l->val = o->letter;
+       if (!map[l->val])
+               map[l->val] = o;
+}
+
+static struct option *make_long_opts(const char *exclude_str,
+                                    const struct ibdiag_opt *custom_opts,
+                                    const struct ibdiag_opt *map[])
+{
+       struct option *long_opts, *l;
+       const struct ibdiag_opt *o;
+       unsigned n = 0;
+
+       if (custom_opts)
+               for (o = custom_opts; o->name; o++)
+                       n++;
+
+       long_opts = malloc((sizeof(common_opts)/sizeof(common_opts[0]) + n) *
+                          sizeof(*long_opts));
+       if (!long_opts)
+               return NULL;
+
+       l = long_opts;
+
+       if (custom_opts)
+               for (o = custom_opts; o->name; o++)
+                       make_opt(l++, o, map);
+
+       for (o = common_opts; o->name; o++) {
+               if (exclude_str && strchr(exclude_str, o->letter))
+                       continue;
+               make_opt(l++, o, map);
+       }
+
+       memset(l, 0, sizeof(*l));
+
+       return long_opts;
+}
+
+static void make_str_opts(const struct option *o, char *p, unsigned size)
+{
+       unsigned i, n = 0;
+
+       for (n = 0; o->name  && n + 2 + o->has_arg < size; o++) {
+               p[n++] = (char) o->val;
+               for (i = 0; i < (unsigned) o->has_arg; i++)
+                       p[n++] = ':';
+       }
+       p[n] = '\0';
+}
+
+int ibdiag_process_opts(int argc, char * const argv[], void *cxt,
+                       const char *exclude_common_str,
+                       const struct ibdiag_opt custom_opts[],
+                       int (*custom_handler)(void *cxt, int val, char *optarg),
+                       const char *usage_args, const char *usage_examples[])
+{
+       char str_opts[1024];
+       const struct ibdiag_opt *o;
+
+       prog_name = argv[0];
+       prog_args = usage_args;
+       prog_examples = usage_examples;
+
+       long_opts = make_long_opts(exclude_common_str, custom_opts, opts_map);
+       if (!long_opts)
+               return -1;
+
+       make_str_opts(long_opts, str_opts, sizeof(str_opts));
+
+       while (1) {
+               int ch = getopt_long(argc, argv, str_opts, long_opts, NULL);
+               if ( ch == -1 )
+                       break;
+               o = opts_map[ch];
+               if (!o)
+                       ibdiag_show_usage();
+               if (custom_handler) {
+                       if (custom_handler(cxt, ch, optarg) &&
+                           process_opt(ch, optarg))
+                               ibdiag_show_usage();
+               } else if (process_opt(ch, optarg))
+                       ibdiag_show_usage();
+       }
+
+       free(long_opts);
+
+       return 0;
+}
+
+void iberror(const char *fn, char *msg, ...)
+{
+       char buf[512];
+       va_list va;
+       int n;
+
+       va_start(va, msg);
+       n = vsprintf(buf, msg, va);
+       va_end(va);
+       buf[n] = 0;
+
+       if (ibdebug)
+               printf("%s: iberror: [pid %d] %s: failed: %s\n",
+                      prog_name ? prog_name : "", getpid(), fn, buf);
+       else
+               printf("%s: iberror: failed: %s\n",
+                      prog_name ? prog_name : "", buf);
+
+       exit(-1);
+}
similarity index 66%
rename from tools/infiniband_diags/src/ibdiag_osd.c
rename to tools/infiniband-diags/src/ibdiag_windows.c
index e0438ee..419dde9 100644 (file)
@@ -1,8 +1,11 @@
 /*\r
- * Copyright (c) 2009 Intel Corporation. All rights reserved.\r
+ * Copyright (c) 2009 Intel Corp., Inc.\r
  *\r
- * This software is available to you under the OpenIB.org BSD license\r
- * below:\r
+ * This software is available to you under a choice of one of two\r
+ * licenses.  You may choose to be licensed under the terms of the GNU\r
+ * General Public License (GPL) Version 2, available from the file\r
+ * COPYING in the main directory of this source tree, or the\r
+ * OpenIB.org BSD license below:\r
  *\r
  *     Redistribution and use in source and binary forms, with or\r
  *     without modification, are permitted provided that the following\r
  *\r
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
  * SOFTWARE.\r
+ *\r
  */\r
 \r
 #include "..\..\..\..\etc\user\getopt.c"\r
+\r
+#if USE_INET\r
+#if WINVER < 0x600\r
+#include "..\..\..\..\etc\user\inet.c"\r
+#endif\r
+#endif
\ No newline at end of file
similarity index 86%
rename from tools/infiniband_diags/src/ibnetdiscover.c
rename to tools/infiniband-diags/src/ibnetdiscover.c
index 158e2f8..6946fd7 100644 (file)
-/*\r
- * Copyright (c) 2004-2008 Voltaire Inc.  All rights reserved.\r
- * Copyright (c) 2007 Xsigo Systems Inc.  All rights reserved.\r
- *\r
- * This software is available to you under a choice of one of two\r
- * licenses.  You may choose to be licensed under the terms of the GNU\r
- * General Public License (GPL) Version 2, available from the file\r
- * COPYING in the main directory of this source tree, or the\r
- * OpenIB.org BSD license below:\r
- *\r
- *     Redistribution and use in source and binary forms, with or\r
- *     without modification, are permitted provided that the following\r
- *     conditions are met:\r
- *\r
- *      - Redistributions of source code must retain the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer.\r
- *\r
- *      - Redistributions in binary form must reproduce the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer in the documentation and/or other materials\r
- *        provided with the distribution.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- * SOFTWARE.\r
- *\r
- */\r
-\r
-#if HAVE_CONFIG_H\r
-#  include <config.h>\r
-#endif /* HAVE_CONFIG_H */\r
-\r
-#define _GNU_SOURCE\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#if defined(_WIN32)\r
-#include <time.h>\r
-#include <string.h>\r
-#include <getopt.h>\r
-#else\r
-#include <unistd.h>\r
-#include <stdarg.h>\r
-#include <time.h>\r
-#include <string.h>\r
-#include <getopt.h>\r
-#include <errno.h>\r
-#include <inttypes.h>\r
-#endif\r
-\r
-#include <infiniband/umad.h>\r
-#include <infiniband/mad.h>\r
-#include <infiniband/complib/cl_nodenamemap.h>\r
-\r
-#include "ibnetdiscover.h"\r
-#include "grouping.h"\r
-#include "ibdiag_common.h"\r
-\r
-static char *node_type_str[] = {\r
-       "???",\r
-       "ca",\r
-       "switch",\r
-       "router",\r
-       "iwarp rnic"\r
-};\r
-\r
-static char *linkwidth_str[] = {\r
-       "??",\r
-       "1x",\r
-       "4x",\r
-       "??",\r
-       "8x",\r
-       "??",\r
-       "??",\r
-       "??",\r
-       "12x"\r
-};\r
-\r
-static char *linkspeed_str[] = {\r
-       "???",\r
-       "SDR",\r
-       "DDR",\r
-       "???",\r
-       "QDR"\r
-};\r
-\r
-static int timeout = 2000;             /* ms */\r
-static int dumplevel = 0;\r
-static int verbose;\r
-static FILE *f;\r
-\r
-char *argv0 = "ibnetdiscover";\r
-\r
-static char *node_name_map_file = NULL;\r
-static nn_map_t *node_name_map = NULL;\r
-\r
-Node *nodesdist[MAXHOPS+1];     /* last is Ca list */\r
-Node *mynode;\r
-int maxhops_discovered = 0;\r
-\r
-struct ChassisList *chassis = NULL;\r
-\r
-static char *\r
-get_linkwidth_str(int linkwidth)\r
-{\r
-       if (linkwidth > 8)\r
-               return linkwidth_str[0];\r
-       else\r
-               return linkwidth_str[linkwidth];\r
-}\r
-\r
-static char *\r
-get_linkspeed_str(int linkspeed)\r
-{\r
-       if (linkspeed > 4)\r
-               return linkspeed_str[0];\r
-       else\r
-               return linkspeed_str[linkspeed];\r
-}\r
-\r
-static inline const char*\r
-node_type_str2(Node *node)\r
-{\r
-       switch(node->type) {\r
-       case SWITCH_NODE: return "SW";\r
-       case CA_NODE:     return "CA";\r
-       case ROUTER_NODE: return "RT";\r
-       }\r
-       return "??";\r
-}\r
-\r
-void\r
-decode_port_info(void *pi, Port *port)\r
-{\r
-       mad_decode_field(pi, IB_PORT_LID_F, &port->lid);\r
-       mad_decode_field(pi, IB_PORT_LMC_F, &port->lmc);\r
-       mad_decode_field(pi, IB_PORT_STATE_F, &port->state);\r
-       mad_decode_field(pi, IB_PORT_PHYS_STATE_F, &port->physstate);\r
-       mad_decode_field(pi, IB_PORT_LINK_WIDTH_ACTIVE_F, &port->linkwidth);\r
-       mad_decode_field(pi, IB_PORT_LINK_SPEED_ACTIVE_F, &port->linkspeed);\r
-}\r
-\r
-\r
-int\r
-get_port(Port *port, int portnum, ib_portid_t *portid)\r
-{\r
-       char portinfo[64];\r
-       void *pi = portinfo;\r
-\r
-       port->portnum = portnum;\r
-\r
-       if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, portnum, timeout))\r
-               return -1;\r
-       decode_port_info(pi, port);\r
-\r
-       DEBUG("portid %s portnum %d: lid %d state %d physstate %d %s %s",\r
-               portid2str(portid), portnum, port->lid, port->state, port->physstate, get_linkwidth_str(port->linkwidth), get_linkspeed_str(port->linkspeed));\r
-       return 1;\r
-}\r
-/*\r
- * Returns 0 if non switch node is found, 1 if switch is found, -1 if error.\r
- */\r
-int\r
-get_node(Node *node, Port *port, ib_portid_t *portid)\r
-{\r
-       char portinfo[64];\r
-       char switchinfo[64];\r
-       void *pi = portinfo, *ni = node->nodeinfo, *nd = node->nodedesc;\r
-       void *si = switchinfo;\r
-\r
-       if (!smp_query(ni, portid, IB_ATTR_NODE_INFO, 0, timeout))\r
-               return -1;\r
-\r
-       mad_decode_field(ni, IB_NODE_GUID_F, &node->nodeguid);\r
-       mad_decode_field(ni, IB_NODE_TYPE_F, &node->type);\r
-       mad_decode_field(ni, IB_NODE_NPORTS_F, &node->numports);\r
-       mad_decode_field(ni, IB_NODE_DEVID_F, &node->devid);\r
-       mad_decode_field(ni, IB_NODE_VENDORID_F, &node->vendid);\r
-       mad_decode_field(ni, IB_NODE_SYSTEM_GUID_F, &node->sysimgguid);\r
-       mad_decode_field(ni, IB_NODE_PORT_GUID_F, &node->portguid);\r
-       mad_decode_field(ni, IB_NODE_LOCAL_PORT_F, &node->localport);\r
-       port->portnum = node->localport;\r
-       port->portguid = node->portguid;\r
-\r
-       if (!smp_query(nd, portid, IB_ATTR_NODE_DESC, 0, timeout))\r
-               return -1;\r
-\r
-       if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, 0, timeout))\r
-               return -1;\r
-       decode_port_info(pi, port);\r
-\r
-       if (node->type != SWITCH_NODE)\r
-               return 0;\r
-\r
-       node->smalid = port->lid;\r
-       node->smalmc = port->lmc;\r
-\r
-       /* after we have the sma information find out the real PortInfo for this port */\r
-       if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, node->localport, timeout))\r
-               return -1;\r
-       decode_port_info(pi, port);\r
-\r
-        if (!smp_query(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout))\r
-                node->smaenhsp0 = 0;   /* assume base SP0 */\r
-       else\r
-               mad_decode_field(si, IB_SW_ENHANCED_PORT0_F, &node->smaenhsp0);\r
-\r
-       DEBUG("portid %s: got switch node %" PRIx64 " '%s'",\r
-             portid2str(portid), node->nodeguid, node->nodedesc);\r
-       return 1;\r
-}\r
-\r
-static int\r
-extend_dpath(ib_dr_path_t *path, int nextport)\r
-{\r
-       if (path->cnt+2 >= sizeof(path->p))\r
-               return -1;\r
-       ++path->cnt;\r
-       if (path->cnt > maxhops_discovered)\r
-               maxhops_discovered = path->cnt;\r
-       path->p[path->cnt] = (uint8_t)nextport;\r
-       return path->cnt;\r
-}\r
-\r
-static void\r
-dump_endnode(ib_portid_t *path, char *prompt, Node *node, Port *port)\r
-{\r
-       if (!dumplevel)\r
-               return;\r
-\r
-       fprintf(f, "%s -> %s %s {%016" PRIx64 "} portnum %d lid %d-%d\"%s\"\n",\r
-               portid2str(path), prompt,\r
-               (node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"),\r
-               node->nodeguid, node->type == SWITCH_NODE ? 0 : port->portnum,\r
-               port->lid, port->lid + (1 << port->lmc) - 1,\r
-               clean_nodedesc(node->nodedesc));\r
-}\r
-\r
-#define HASHGUID(guid)         ((uint32_t)(((uint32_t)(guid) * 101) ^ ((uint32_t)((guid) >> 32) * 103)))\r
-#define HTSZ 137\r
-\r
-static Node *nodestbl[HTSZ];\r
-\r
-static Node *\r
-find_node(Node *new)\r
-{\r
-       int hash = HASHGUID(new->nodeguid) % HTSZ;\r
-       Node *node;\r
-\r
-       for (node = nodestbl[hash]; node; node = node->htnext)\r
-               if (node->nodeguid == new->nodeguid)\r
-                       return node;\r
-\r
-       return NULL;\r
-}\r
-\r
-static Node *\r
-create_node(Node *temp, ib_portid_t *path, int dist)\r
-{\r
-       Node *node;\r
-       int hash = HASHGUID(temp->nodeguid) % HTSZ;\r
-\r
-       node = malloc(sizeof(*node));\r
-       if (!node)\r
-               return NULL;\r
-\r
-       memcpy(node, temp, sizeof(*node));\r
-       node->dist = dist;\r
-       node->path = *path;\r
-\r
-       node->htnext = nodestbl[hash];\r
-       nodestbl[hash] = node;\r
-\r
-       if (node->type != SWITCH_NODE)\r
-               dist = MAXHOPS;         /* special Ca list */\r
-\r
-       node->dnext = nodesdist[dist];\r
-       nodesdist[dist] = node;\r
-\r
-       return node;\r
-}\r
-\r
-static Port *\r
-find_port(Node *node, Port *port)\r
-{\r
-       Port *old;\r
-\r
-       for (old = node->ports; old; old = old->next)\r
-               if (old->portnum == port->portnum)\r
-                       return old;\r
-\r
-       return NULL;\r
-}\r
-\r
-static Port *\r
-create_port(Node *node, Port *temp)\r
-{\r
-       Port *port;\r
-\r
-       port = malloc(sizeof(*port));\r
-       if (!port)\r
-               return NULL;\r
-\r
-       memcpy(port, temp, sizeof(*port));\r
-       port->node = node;\r
-       port->next = node->ports;\r
-       node->ports = port;\r
-\r
-       return port;\r
-}\r
-\r
-static void\r
-link_ports(Node *node, Port *port, Node *remotenode, Port *remoteport)\r
-{\r
-       DEBUG("linking: 0x%" PRIx64 " %p->%p:%u and 0x%" PRIx64 " %p->%p:%u",\r
-               node->nodeguid, node, port, port->portnum,\r
-               remotenode->nodeguid, remotenode, remoteport, remoteport->portnum);\r
-       if (port->remoteport)\r
-               port->remoteport->remoteport = NULL;\r
-       if (remoteport->remoteport)\r
-               remoteport->remoteport->remoteport = NULL;\r
-       port->remoteport = remoteport;\r
-       remoteport->remoteport = port;\r
-}\r
-\r
-static int\r
-handle_port(Node *node, Port *port, ib_portid_t *path, int portnum, int dist)\r
-{\r
-       Node node_buf;\r
-       Port port_buf;\r
-       Node *remotenode, *oldnode;\r
-       Port *remoteport, *oldport;\r
-\r
-       memset(&node_buf, 0, sizeof(node_buf));\r
-       memset(&port_buf, 0, sizeof(port_buf));\r
-\r
-       DEBUG("handle node %p port %p:%d dist %d", node, port, portnum, dist);\r
-       if (port->physstate != 5)       /* LinkUp */\r
-               return -1;\r
-\r
-       if (extend_dpath(&path->drpath, portnum) < 0)\r
-               return -1;\r
-\r
-       if (get_node(&node_buf, &port_buf, path) < 0) {\r
-               IBWARN("NodeInfo on %s failed, skipping port",\r
-                       portid2str(path));\r
-               path->drpath.cnt--;     /* restore path */\r
-               return -1;\r
-       }\r
-\r
-       oldnode = find_node(&node_buf);\r
-       if (oldnode)\r
-               remotenode = oldnode;\r
-       else if (!(remotenode = create_node(&node_buf, path, dist + 1)))\r
-               IBERROR("no memory");\r
-\r
-       oldport = find_port(remotenode, &port_buf);\r
-       if (oldport) {\r
-               remoteport = oldport;\r
-               if (node != remotenode || port != remoteport)\r
-                       IBWARN("port moving...");\r
-       } else if (!(remoteport = create_port(remotenode, &port_buf)))\r
-               IBERROR("no memory");\r
-\r
-       dump_endnode(path, oldnode ? "known remote" : "new remote",\r
-                    remotenode, remoteport);\r
-\r
-       link_ports(node, port, remotenode, remoteport);\r
-\r
-       path->drpath.cnt--;     /* restore path */\r
-       return 0;\r
-}\r
-\r
-/*\r
- * Return 1 if found, 0 if not, -1 on errors.\r
- */\r
-static int\r
-discover(ib_portid_t *from)\r
-{\r
-       Node node_buf;\r
-       Port port_buf;\r
-       Node *node;\r
-       Port *port;\r
-       int i;\r
-       int dist = 0;\r
-       ib_portid_t *path;\r
-\r
-       DEBUG("from %s", portid2str(from));\r
-\r
-       memset(&node_buf, 0, sizeof(node_buf));\r
-       memset(&port_buf, 0, sizeof(port_buf));\r
-\r
-       if (get_node(&node_buf, &port_buf, from) < 0) {\r
-               IBWARN("can't reach node %s", portid2str(from));\r
-               return -1;\r
-       }\r
-\r
-       node = create_node(&node_buf, from, 0);\r
-       if (!node)\r
-               IBERROR("out of memory");\r
-\r
-       mynode = node;\r
-\r
-       port = create_port(node, &port_buf);\r
-       if (!port)\r
-               IBERROR("out of memory");\r
-\r
-       if (node->type != SWITCH_NODE &&\r
-           handle_port(node, port, from, node->localport, 0) < 0)\r
-               return 0;\r
-\r
-       for (dist = 0; dist < MAXHOPS; dist++) {\r
-\r
-               for (node = nodesdist[dist]; node; node = node->dnext) {\r
-\r
-                       path = &node->path;\r
-\r
-                       DEBUG("dist %d node %p", dist, node);\r
-                       dump_endnode(path, "processing", node, port);\r
-\r
-                       for (i = 1; i <= node->numports; i++) {\r
-                               if (i == node->localport)\r
-                                       continue;\r
-\r
-                               if (get_port(&port_buf, i, path) < 0) {\r
-                                       IBWARN("can't reach node %s port %d", portid2str(path), i);\r
-                                       continue;\r
-                               }\r
-\r
-                               port = find_port(node, &port_buf);\r
-                               if (port)\r
-                                       continue;\r
-\r
-                               port = create_port(node, &port_buf);\r
-                               if (!port)\r
-                                       IBERROR("out of memory");\r
-\r
-                               /* If switch, set port GUID to node GUID */\r
-                               if (node->type == SWITCH_NODE)\r
-                                       port->portguid = node->portguid;\r
-\r
-                               handle_port(node, port, path, i, dist);\r
-                       }\r
-               }\r
-       }\r
-\r
-       return 0;\r
-}\r
-\r
-char *\r
-node_name(Node *node)\r
-{\r
-       static char buf[256];\r
-\r
-       switch(node->type) {\r
-       case SWITCH_NODE:\r
-               sprintf(buf, "\"%s", "S");\r
-               break;\r
-       case CA_NODE:\r
-               sprintf(buf, "\"%s", "H");\r
-               break;\r
-       case ROUTER_NODE:\r
-               sprintf(buf, "\"%s", "R");\r
-               break;\r
-       default:\r
-               sprintf(buf, "\"%s", "?");\r
-               break;\r
-       }\r
-       sprintf(buf+2, "-%016" PRIx64 "\"", node->nodeguid);\r
-\r
-       return buf;\r
-}\r
-\r
-void\r
-list_node(Node *node)\r
-{\r
-       char *node_type;\r
-       char *nodename = remap_node_name(node_name_map, node->nodeguid,\r
-                                             node->nodedesc);\r
-\r
-       switch(node->type) {\r
-       case SWITCH_NODE:\r
-               node_type = "Switch";\r
-               break;\r
-       case CA_NODE:\r
-               node_type = "Ca";\r
-               break;\r
-       case ROUTER_NODE:\r
-               node_type = "Router";\r
-               break;\r
-       default:\r
-               node_type = "???";\r
-               break;\r
-       }\r
-       fprintf(f, "%s\t : 0x%016" PRIx64 " ports %d devid 0x%x vendid 0x%x \"%s\"\n",\r
-               node_type,\r
-               node->nodeguid, node->numports, node->devid, node->vendid,\r
-               nodename);\r
-\r
-       free(nodename);\r
-}\r
-\r
-void\r
-out_ids(Node *node, int group, char *chname)\r
-{\r
-       fprintf(f, "\nvendid=0x%x\ndevid=0x%x\n", node->vendid, node->devid);\r
-       if (node->sysimgguid)\r
-               fprintf(f, "sysimgguid=0x%" PRIx64, node->sysimgguid);\r
-       if (group\r
-           && node->chrecord && node->chrecord->chassisnum) {\r
-               fprintf(f, "\t\t# Chassis %d", node->chrecord->chassisnum);\r
-               if (chname)\r
-                       fprintf(f, " (%s)", chname);\r
-               if (is_xsigo_tca(node->nodeguid) && node->ports->remoteport)\r
-                       fprintf(f, " slot %d", node->ports->remoteport->portnum);\r
-       }\r
-       fprintf(f, "\n");\r
-}\r
-\r
-uint64_t\r
-out_chassis(int chassisnum)\r
-{\r
-       uint64_t guid;\r
-\r
-       fprintf(f, "\nChassis %d", chassisnum);\r
-       guid = get_chassis_guid((uint8_t)chassisnum);\r
-       if (guid)\r
-               fprintf(f, " (guid 0x%" PRIx64 ")", guid);\r
-       fprintf(f, "\n");\r
-       return guid;\r
-}\r
-\r
-void\r
-out_switch(Node *node, int group, char *chname)\r
-{\r
-       char *str;\r
-       char *nodename = NULL;\r
-\r
-       out_ids(node, group, chname);\r
-       fprintf(f, "switchguid=0x%" PRIx64, node->nodeguid);\r
-       fprintf(f, "(%" PRIx64 ")", node->portguid);\r
-       /* Currently, only if Voltaire chassis */\r
-       if (group\r
-           && node->chrecord && node->chrecord->chassisnum\r
-           && node->vendid == VTR_VENDOR_ID) {\r
-               str = get_chassis_type(node->chrecord->chassistype);\r
-               if (str)\r
-                       fprintf(f, "%s ", str);\r
-               str = get_chassis_slot(node->chrecord->chassisslot);\r
-               if (str)\r
-                       fprintf(f, "%s ", str);\r
-               fprintf(f, "%d Chip %d", node->chrecord->slotnum, node->chrecord->anafanum);\r
-       }\r
-\r
-       nodename = remap_node_name(node_name_map, node->nodeguid,\r
-                               node->nodedesc);\r
-\r
-       fprintf(f, "\nSwitch\t%d %s\t\t# \"%s\" %s port 0 lid %d lmc %d\n",\r
-               node->numports, node_name(node),\r
-               nodename,\r
-               node->smaenhsp0 ? "enhanced" : "base",\r
-               node->smalid, node->smalmc);\r
-\r
-       free(nodename);\r
-}\r
-\r
-void\r
-out_ca(Node *node, int group, char *chname)\r
-{\r
-       char *node_type;\r
-       char *node_type2;\r
-       char *nodename = remap_node_name(node_name_map, node->nodeguid,\r
-                                             node->nodedesc);\r
-\r
-       out_ids(node, group, chname);\r
-       switch(node->type) {\r
-       case CA_NODE:\r
-               node_type = "ca";\r
-               node_type2 = "Ca";\r
-               break;\r
-       case ROUTER_NODE:\r
-               node_type = "rt";\r
-               node_type2 = "Rt";\r
-               break;\r
-       default:\r
-               node_type = "???";\r
-               node_type2 = "???";\r
-               break;\r
-       }\r
-\r
-       fprintf(f, "%sguid=0x%" PRIx64 "\n", node_type, node->nodeguid);\r
-       fprintf(f, "%s\t%d %s\t\t# \"%s\"",\r
-               node_type2, node->numports, node_name(node),\r
-               nodename);\r
-       if (group && is_xsigo_hca(node->nodeguid))\r
-               fprintf(f, " (scp)");\r
-       fprintf(f, "\n");\r
-\r
-       free(nodename);\r
-}\r
-\r
-static char *\r
-out_ext_port(Port *port, int group)\r
-{\r
-       char *str = NULL;\r
-\r
-       /* Currently, only if Voltaire chassis */\r
-       if (group\r
-           && port->node->chrecord && port->node->vendid == VTR_VENDOR_ID)\r
-               str = portmapstring(port);\r
-\r
-       return (str);\r
-}\r
-\r
-void\r
-out_switch_port(Port *port, int group)\r
-{\r
-       char *ext_port_str = NULL;\r
-       char *rem_nodename = NULL;\r
-\r
-       DEBUG("port %p:%d remoteport %p", port, port->portnum, port->remoteport);\r
-       fprintf(f, "[%d]", port->portnum);\r
-\r
-       ext_port_str = out_ext_port(port, group);\r
-       if (ext_port_str)\r
-               fprintf(f, "%s", ext_port_str);\r
-\r
-       rem_nodename = remap_node_name(node_name_map,\r
-                               port->remoteport->node->nodeguid,\r
-                               port->remoteport->node->nodedesc);\r
-\r
-       ext_port_str = out_ext_port(port->remoteport, group);\r
-       fprintf(f, "\t%s[%d]%s",\r
-               node_name(port->remoteport->node),\r
-               port->remoteport->portnum,\r
-               ext_port_str ? ext_port_str : "");\r
-       if (port->remoteport->node->type != SWITCH_NODE)\r
-               fprintf(f, "(%" PRIx64 ") ", port->remoteport->portguid);\r
-       fprintf(f, "\t\t# \"%s\" lid %d %s%s",\r
-               rem_nodename,\r
-               port->remoteport->node->type == SWITCH_NODE ? port->remoteport->node->smalid : port->remoteport->lid,\r
-               get_linkwidth_str(port->linkwidth),\r
-               get_linkspeed_str(port->linkspeed));\r
-\r
-       if (is_xsigo_tca(port->remoteport->portguid))\r
-               fprintf(f, " slot %d", port->portnum);\r
-       else if (is_xsigo_hca(port->remoteport->portguid))\r
-               fprintf(f, " (scp)");\r
-       fprintf(f, "\n");\r
-\r
-       free(rem_nodename);\r
-}\r
-\r
-void\r
-out_ca_port(Port *port, int group)\r
-{\r
-       char *str = NULL;\r
-       char *rem_nodename = NULL;\r
-\r
-       fprintf(f, "[%d]", port->portnum);\r
-       if (port->node->type != SWITCH_NODE)\r
-               fprintf(f, "(%" PRIx64 ") ", port->portguid);\r
-       fprintf(f, "\t%s[%d]",\r
-               node_name(port->remoteport->node),\r
-               port->remoteport->portnum);\r
-       str = out_ext_port(port->remoteport, group);\r
-       if (str)\r
-               fprintf(f, "%s", str);\r
-       if (port->remoteport->node->type != SWITCH_NODE)\r
-               fprintf(f, " (%" PRIx64 ") ", port->remoteport->portguid);\r
-\r
-       rem_nodename = remap_node_name(node_name_map,\r
-                               port->remoteport->node->nodeguid,\r
-                               port->remoteport->node->nodedesc);\r
-\r
-       fprintf(f, "\t\t# lid %d lmc %d \"%s\" lid %d %s%s\n",\r
-               port->lid, port->lmc, rem_nodename,\r
-               port->remoteport->node->type == SWITCH_NODE ? port->remoteport->node->smalid : port->remoteport->lid,\r
-               get_linkwidth_str(port->linkwidth),\r
-               get_linkspeed_str(port->linkspeed));\r
-\r
-       free(rem_nodename);\r
-}\r
-\r
-int\r
-dump_topology(int listtype, int group)\r
-{\r
-       Node *node;\r
-       Port *port;\r
-       int i = 0, dist = 0;\r
-       time_t t = time(0);\r
-       uint64_t chguid;\r
-       char *chname = NULL;\r
-\r
-       if (!listtype) {\r
-               fprintf(f, "#\n# Topology file: generated on %s#\n", ctime(&t));\r
-               fprintf(f, "# Max of %d hops discovered\n", maxhops_discovered);\r
-               fprintf(f, "# Initiated from node %016" PRIx64 " port %016" PRIx64 "\n", mynode->nodeguid, mynode->portguid);\r
-       }\r
-\r
-       /* Make pass on switches */\r
-       if (group && !listtype) {\r
-               ChassisList *ch = NULL;\r
-\r
-               /* Chassis based switches first */\r
-               for (ch = chassis; ch; ch = ch->next) {\r
-                       int n = 0;\r
-\r
-                       if (!ch->chassisnum)\r
-                               continue;\r
-                       chguid = out_chassis(ch->chassisnum);\r
-                       if (chname)\r
-                               free(chname);\r
-                       chname = NULL;\r
-                       if (is_xsigo_guid(chguid)) {\r
-                               for (node = nodesdist[MAXHOPS]; node; node = node->dnext) {\r
-                                       if (!node->chrecord ||\r
-                                           !node->chrecord->chassisnum)\r
-                                               continue;\r
-\r
-                                       if (node->chrecord->chassisnum != ch->chassisnum)\r
-                                               continue;\r
-\r
-                                       if (is_xsigo_hca(node->nodeguid)) {\r
-                                               chname = remap_node_name(node_name_map,\r
-                                                               node->nodeguid,\r
-                                                               node->nodedesc);\r
-                                               fprintf(f, "Hostname: %s\n", chname);\r
-                                       }\r
-                               }\r
-                       }\r
-\r
-                       fprintf(f, "\n# Spine Nodes");\r
-                       for (n = 1; n <= (SPINES_MAX_NUM+1); n++) {\r
-                               if (ch->spinenode[n]) {\r
-                                       out_switch(ch->spinenode[n], group, chname);\r
-                                       for (port = ch->spinenode[n]->ports; port; port = port->next, i++)\r
-                                               if (port->remoteport)\r
-                                                       out_switch_port(port, group);\r
-                               }\r
-                       }\r
-                       fprintf(f, "\n# Line Nodes");\r
-                       for (n = 1; n <= (LINES_MAX_NUM+1); n++) {\r
-                               if (ch->linenode[n]) {\r
-                                       out_switch(ch->linenode[n], group, chname);\r
-                                       for (port = ch->linenode[n]->ports; port; port = port->next, i++)\r
-                                               if (port->remoteport)\r
-                                                       out_switch_port(port, group);\r
-                               }\r
-                       }\r
-\r
-                       fprintf(f, "\n# Chassis Switches");\r
-                       for (dist = 0; dist <= maxhops_discovered; dist++) {\r
-\r
-                               for (node = nodesdist[dist]; node; node = node->dnext) {\r
-\r
-                                       /* Non Voltaire chassis */\r
-                                       if (node->vendid == VTR_VENDOR_ID)\r
-                                               continue;\r
-                                       if (!node->chrecord ||\r
-                                           !node->chrecord->chassisnum)\r
-                                               continue;\r
-\r
-                                       if (node->chrecord->chassisnum != ch->chassisnum)\r
-                                               continue;\r
-\r
-                                       out_switch(node, group, chname);\r
-                                       for (port = node->ports; port; port = port->next, i++)\r
-                                               if (port->remoteport)\r
-                                                       out_switch_port(port, group);\r
-\r
-                               }\r
-\r
-                       }\r
-\r
-                       fprintf(f, "\n# Chassis CAs");\r
-                       for (node = nodesdist[MAXHOPS]; node; node = node->dnext) {\r
-                               if (!node->chrecord ||\r
-                                   !node->chrecord->chassisnum)\r
-                                       continue;\r
-\r
-                               if (node->chrecord->chassisnum != ch->chassisnum)\r
-                                       continue;\r
-\r
-                               out_ca(node, group, chname);\r
-                               for (port = node->ports; port; port = port->next, i++)\r
-                                       if (port->remoteport)\r
-                                               out_ca_port(port, group);\r
-\r
-                       }\r
-\r
-               }\r
-\r
-       } else {\r
-               for (dist = 0; dist <= maxhops_discovered; dist++) {\r
-\r
-                       for (node = nodesdist[dist]; node; node = node->dnext) {\r
-\r
-                               DEBUG("SWITCH: dist %d node %p", dist, node);\r
-                               if (!listtype)\r
-                                       out_switch(node, group, chname);\r
-                               else {\r
-                                       if (listtype & LIST_SWITCH_NODE)\r
-                                               list_node(node);\r
-                                       continue;\r
-                               }\r
-\r
-                               for (port = node->ports; port; port = port->next, i++)\r
-                                       if (port->remoteport)\r
-                                               out_switch_port(port, group);\r
-                       }\r
-               }\r
-       }\r
-\r
-       if (chname)\r
-               free(chname);\r
-       chname = NULL;\r
-       if (group && !listtype) {\r
-\r
-               fprintf(f, "\nNon-Chassis Nodes\n");\r
-\r
-               for (dist = 0; dist <= maxhops_discovered; dist++) {\r
-\r
-                       for (node = nodesdist[dist]; node; node = node->dnext) {\r
-\r
-                               DEBUG("SWITCH: dist %d node %p", dist, node);\r
-                               /* Now, skip chassis based switches */\r
-                               if (node->chrecord &&\r
-                                   node->chrecord->chassisnum)\r
-                                       continue;\r
-                               out_switch(node, group, chname);\r
-\r
-                               for (port = node->ports; port; port = port->next, i++)\r
-                                       if (port->remoteport)\r
-                                               out_switch_port(port, group);\r
-                       }\r
-\r
-               }\r
-\r
-       }\r
-\r
-       /* Make pass on CAs */\r
-       for (node = nodesdist[MAXHOPS]; node; node = node->dnext) {\r
-\r
-               DEBUG("CA: dist %d node %p", dist, node);\r
-               if (!listtype) {\r
-                       /* Now, skip chassis based CAs */\r
-                       if (group && node->chrecord &&\r
-                           node->chrecord->chassisnum)\r
-                               continue;\r
-                       out_ca(node, group, chname);\r
-               } else {\r
-                       if (((listtype & LIST_CA_NODE) && (node->type == CA_NODE)) ||\r
-                           ((listtype & LIST_ROUTER_NODE) && (node->type == ROUTER_NODE)))\r
-                               list_node(node);\r
-                       continue;\r
-               }\r
-\r
-               for (port = node->ports; port; port = port->next, i++)\r
-                       if (port->remoteport)\r
-                               out_ca_port(port, group);\r
-       }\r
-\r
-       if (chname)\r
-               free(chname);\r
-\r
-       return i;\r
-}\r
-\r
-void dump_ports_report ()\r
-{\r
-       int b, n = 0, p;\r
-       Node *node;\r
-       Port *port;\r
-\r
-       // If switch and LID == 0, search of other switch ports with\r
-       // valid LID and assign it to all ports of that switch\r
-       for (b = 0; b <= MAXHOPS; b++)\r
-               for (node = nodesdist[b]; node; node = node->dnext)\r
-                       if (node->type == SWITCH_NODE) {\r
-                               int swlid = 0;\r
-                               for (p = 0, port = node->ports;\r
-                                    p < node->numports && port && !swlid;\r
-                                    port = port->next)\r
-                                       if (port->lid != 0)\r
-                                               swlid = port->lid;\r
-                               for (p = 0, port = node->ports;\r
-                                    p < node->numports && port;\r
-                                    port = port->next)\r
-                                       port->lid = swlid;\r
-                       }\r
-\r
-       for (b = 0; b <= MAXHOPS; b++)\r
-               for (node = nodesdist[b]; node; node = node->dnext) {\r
-                       for (p = 0, port = node->ports;\r
-                            p < node->numports && port;\r
-                            p++, port = port->next) {\r
-                               fprintf(stdout,\r
-                                       "%2s %5d %2d 0x%016" PRIx64 " %s %s",\r
-                                       node_type_str2(port->node), port->lid,\r
-                                       port->portnum,\r
-                                       port->portguid,\r
-                                       get_linkwidth_str(port->linkwidth),\r
-                                       get_linkspeed_str(port->linkspeed));\r
-                               if (port->remoteport)\r
-                                       fprintf(stdout,\r
-                                               " - %2s %5d %2d 0x%016" PRIx64\r
-                                               " ( '%s' - '%s' )\n",\r
-                                               node_type_str2(port->remoteport->node),\r
-                                               port->remoteport->lid,\r
-                                               port->remoteport->portnum,\r
-                                               port->remoteport->portguid,\r
-                                               port->node->nodedesc,\r
-                                               port->remoteport->node->nodedesc);\r
-                               else\r
-                                       fprintf(stdout, "%36s'%s'\n", "",\r
-                                               port->node->nodedesc);\r
-                       }\r
-                       n++;\r
-               }\r
-}\r
-\r
-void\r
-usage(void)\r
-{\r
-       fprintf(stderr, "Usage: %s [-d(ebug)] -e(rr_show) -v(erbose) -s(how) -l(ist) -g(rouping) -H(ca_list) -S(witch_list) -R(outer_list) -V(ersion) -C ca_name -P ca_port "\r
-                       "-t(imeout) timeout_ms --node-name-map node-name-map] -p(orts) [<topology-file>]\n",\r
-                       argv0);\r
-       fprintf(stderr, "       --node-name-map <node-name-map> specify a node name map file\n");\r
-       exit(-1);\r
-}\r
-\r
-int _CDECL\r
-main(int argc, char **argv)\r
-{\r
-       int mgmt_classes[2] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS};\r
-       ib_portid_t my_portid = {0};\r
-       int udebug = 0, list = 0;\r
-       char *ca = 0;\r
-       int ca_port = 0;\r
-       int group = 0;\r
-       int ports_report = 0;\r
-\r
-       static char const str_opts[] = "C:P:t:devslgHSRpVhu";\r
-       static const struct option long_opts[] = {\r
-               { "C", 1, 0, 'C'},\r
-               { "P", 1, 0, 'P'},\r
-               { "debug", 0, 0, 'd'},\r
-               { "err_show", 0, 0, 'e'},\r
-               { "verbose", 0, 0, 'v'},\r
-               { "show", 0, 0, 's'},\r
-               { "list", 0, 0, 'l'},\r
-               { "grouping", 0, 0, 'g'},\r
-               { "Hca_list", 0, 0, 'H'},\r
-               { "Switch_list", 0, 0, 'S'},\r
-               { "Router_list", 0, 0, 'R'},\r
-               { "timeout", 1, 0, 't'},\r
-               { "node-name-map", 1, 0, 1},\r
-               { "ports", 0, 0, 'p'},\r
-               { "Version", 0, 0, 'V'},\r
-               { "help", 0, 0, 'h'},\r
-               { "usage", 0, 0, 'u'},\r
-               { NULL }\r
-       };\r
-\r
-       f = stdout;\r
-\r
-       argv0 = argv[0];\r
-\r
-       while (1) {\r
-               int ch = getopt_long(argc, argv, str_opts, long_opts, NULL);\r
-               if ( ch == -1 )\r
-                       break;\r
-               switch(ch) {\r
-               case 1:\r
-                       node_name_map_file = strdup(optarg);\r
-                       break;\r
-               case 'C':\r
-                       ca = optarg;\r
-                       break;\r
-               case 'P':\r
-                       ca_port = strtoul(optarg, 0, 0);\r
-                       break;\r
-               case 'd':\r
-                       ibdebug++;\r
-                       madrpc_show_errors(1);\r
-                       umad_debug(udebug);\r
-                       udebug++;\r
-                       break;\r
-               case 't':\r
-                       timeout = strtoul(optarg, 0, 0);\r
-                       break;\r
-               case 'v':\r
-                       verbose++;\r
-                       dumplevel++;\r
-                       break;\r
-               case 's':\r
-                       dumplevel = 1;\r
-                       break;\r
-               case 'e':\r
-                       madrpc_show_errors(1);\r
-                       break;\r
-               case 'l':\r
-                       list = LIST_CA_NODE | LIST_SWITCH_NODE | LIST_ROUTER_NODE;\r
-                       break;\r
-               case 'g':\r
-                       group = 1;\r
-                       break;\r
-               case 'S':\r
-                       list = LIST_SWITCH_NODE;\r
-                       break;\r
-               case 'H':\r
-                       list = LIST_CA_NODE;\r
-                       break;\r
-               case 'R':\r
-                       list = LIST_ROUTER_NODE;\r
-                       break;\r
-               case 'V':\r
-                       fprintf(stderr, "%s %s\n", argv0, get_build_version() );\r
-                       exit(-1);\r
-               case 'p':\r
-                       ports_report = 1;\r
-                       break;\r
-               default:\r
-                       usage();\r
-                       break;\r
-               }\r
-       }\r
-       argc -= optind;\r
-       argv += optind;\r
-\r
-       if (argc && !(f = fopen(argv[0], "w")))\r
-               IBERROR("can't open file %s for writing", argv[0]);\r
-\r
-       madrpc_init(ca, ca_port, mgmt_classes, 2);\r
-       node_name_map = open_node_name_map(node_name_map_file);\r
-\r
-       if (discover(&my_portid) < 0)\r
-               IBERROR("discover");\r
-\r
-       if (group)\r
-               chassis = group_nodes();\r
-\r
-       if (ports_report)\r
-               dump_ports_report();\r
-       else\r
-               dump_topology(list, group);\r
-\r
-       close_node_name_map(node_name_map);\r
-       exit(0);\r
-}\r
+/*
+ * Copyright (c) 2004-2008 Voltaire Inc.  All rights reserved.
+ * Copyright (c) 2007 Xsigo Systems Inc.  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.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <string.h>
+#include <getopt.h>
+#include <inttypes.h>
+
+#include <infiniband/umad.h>
+#include <infiniband/mad.h>
+#include <complib/cl_nodenamemap.h>
+
+#include "ibnetdiscover.h"
+#include "grouping.h"
+#include "ibdiag_common.h"
+
+static char *node_type_str[] = {
+       "???",
+       "ca",
+       "switch",
+       "router",
+       "iwarp rnic"
+};
+
+static char *linkwidth_str[] = {
+       "??",
+       "1x",
+       "4x",
+       "??",
+       "8x",
+       "??",
+       "??",
+       "??",
+       "12x"
+};
+
+static char *linkspeed_str[] = {
+       "???",
+       "SDR",
+       "DDR",
+       "???",
+       "QDR"
+};
+
+static int timeout = 2000;             /* ms */
+static int dumplevel = 0;
+static FILE *f;
+
+static char *node_name_map_file = NULL;
+static nn_map_t *node_name_map = NULL;
+
+Node *nodesdist[MAXHOPS+1];     /* last is Ca list */
+Node *mynode;
+int maxhops_discovered = 0;
+
+struct ChassisList *chassis = NULL;
+
+static char *
+get_linkwidth_str(int linkwidth)
+{
+       if (linkwidth > 8)
+               return linkwidth_str[0];
+       else
+               return linkwidth_str[linkwidth];
+}
+
+static char *
+get_linkspeed_str(int linkspeed)
+{
+       if (linkspeed > 4)
+               return linkspeed_str[0];
+       else
+               return linkspeed_str[linkspeed];
+}
+
+static inline const char*
+node_type_str2(Node *node)
+{
+       switch(node->type) {
+       case SWITCH_NODE: return "SW";
+       case CA_NODE:     return "CA";
+       case ROUTER_NODE: return "RT";
+       }
+       return "??";
+}
+
+void
+decode_port_info(void *pi, Port *port)
+{
+       mad_decode_field(pi, IB_PORT_LID_F, &port->lid);
+       mad_decode_field(pi, IB_PORT_LMC_F, &port->lmc);
+       mad_decode_field(pi, IB_PORT_STATE_F, &port->state);
+       mad_decode_field(pi, IB_PORT_PHYS_STATE_F, &port->physstate);
+       mad_decode_field(pi, IB_PORT_LINK_WIDTH_ACTIVE_F, &port->linkwidth);
+       mad_decode_field(pi, IB_PORT_LINK_SPEED_ACTIVE_F, &port->linkspeed);
+}
+
+
+int
+get_port(Port *port, int portnum, ib_portid_t *portid)
+{
+       char portinfo[64];
+       void *pi = portinfo;
+
+       port->portnum = portnum;
+
+       if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, portnum, timeout))
+               return -1;
+       decode_port_info(pi, port);
+
+       DEBUG("portid %s portnum %d: lid %d state %d physstate %d %s %s",
+               portid2str(portid), portnum, port->lid, port->state, port->physstate, get_linkwidth_str(port->linkwidth), get_linkspeed_str(port->linkspeed));
+       return 1;
+}
+/*
+ * Returns 0 if non switch node is found, 1 if switch is found, -1 if error.
+ */
+int
+get_node(Node *node, Port *port, ib_portid_t *portid)
+{
+       char portinfo[64];
+       char switchinfo[64];
+       void *pi = portinfo, *ni = node->nodeinfo, *nd = node->nodedesc;
+       void *si = switchinfo;
+
+       if (!smp_query(ni, portid, IB_ATTR_NODE_INFO, 0, timeout))
+               return -1;
+
+       mad_decode_field(ni, IB_NODE_GUID_F, &node->nodeguid);
+       mad_decode_field(ni, IB_NODE_TYPE_F, &node->type);
+       mad_decode_field(ni, IB_NODE_NPORTS_F, &node->numports);
+       mad_decode_field(ni, IB_NODE_DEVID_F, &node->devid);
+       mad_decode_field(ni, IB_NODE_VENDORID_F, &node->vendid);
+       mad_decode_field(ni, IB_NODE_SYSTEM_GUID_F, &node->sysimgguid);
+       mad_decode_field(ni, IB_NODE_PORT_GUID_F, &node->portguid);
+       mad_decode_field(ni, IB_NODE_LOCAL_PORT_F, &node->localport);
+       port->portnum = node->localport;
+       port->portguid = node->portguid;
+
+       if (!smp_query(nd, portid, IB_ATTR_NODE_DESC, 0, timeout))
+               return -1;
+
+       if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, 0, timeout))
+               return -1;
+       decode_port_info(pi, port);
+
+       if (node->type != SWITCH_NODE)
+               return 0;
+
+       node->smalid = port->lid;
+       node->smalmc = port->lmc;
+
+       /* after we have the sma information find out the real PortInfo for this port */
+       if (!smp_query(pi, portid, IB_ATTR_PORT_INFO, node->localport, timeout))
+               return -1;
+       decode_port_info(pi, port);
+
+       port->lid = node->smalid;  /* LID is still defined by port 0 */
+       port->lmc = node->smalmc;
+
+        if (!smp_query(si, portid, IB_ATTR_SWITCH_INFO, 0, timeout))
+                node->smaenhsp0 = 0;   /* assume base SP0 */
+       else
+               mad_decode_field(si, IB_SW_ENHANCED_PORT0_F, &node->smaenhsp0);
+
+       DEBUG("portid %s: got switch node %" PRIx64 " '%s'",
+             portid2str(portid), node->nodeguid, node->nodedesc);
+       return 1;
+}
+
+static int
+extend_dpath(ib_dr_path_t *path, int nextport)
+{
+       if (path->cnt+2 >= sizeof(path->p))
+               return -1;
+       ++path->cnt;
+       if (path->cnt > maxhops_discovered)
+               maxhops_discovered = path->cnt;
+       path->p[path->cnt] = (uint8_t) nextport;
+       return path->cnt;
+}
+
+static void
+dump_endnode(ib_portid_t *path, char *prompt, Node *node, Port *port)
+{
+       if (!dumplevel)
+               return;
+
+       fprintf(f, "%s -> %s %s {%016" PRIx64 "} portnum %d lid %d-%d\"%s\"\n",
+               portid2str(path), prompt,
+               (node->type <= IB_NODE_MAX ? node_type_str[node->type] : "???"),
+               node->nodeguid, node->type == SWITCH_NODE ? 0 : port->portnum,
+               port->lid, port->lid + (1 << port->lmc) - 1,
+               clean_nodedesc(node->nodedesc));
+}
+
+#define HASHGUID(guid)         ((uint32_t)(((uint32_t)(guid) * 101) ^ ((uint32_t)((guid) >> 32) * 103)))
+#define HTSZ 137
+
+static Node *nodestbl[HTSZ];
+
+static Node *
+find_node(Node *new)
+{
+       int hash = HASHGUID(new->nodeguid) % HTSZ;
+       Node *node;
+
+       for (node = nodestbl[hash]; node; node = node->htnext)
+               if (node->nodeguid == new->nodeguid)
+                       return node;
+
+       return NULL;
+}
+
+static Node *
+create_node(Node *temp, ib_portid_t *path, int dist)
+{
+       Node *node;
+       int hash = HASHGUID(temp->nodeguid) % HTSZ;
+
+       node = malloc(sizeof(*node));
+       if (!node)
+               return NULL;
+
+       memcpy(node, temp, sizeof(*node));
+       node->dist = dist;
+       node->path = *path;
+
+       node->htnext = nodestbl[hash];
+       nodestbl[hash] = node;
+
+       if (node->type != SWITCH_NODE)
+               dist = MAXHOPS;         /* special Ca list */
+
+       node->dnext = nodesdist[dist];
+       nodesdist[dist] = node;
+
+       return node;
+}
+
+static Port *
+find_port(Node *node, Port *port)
+{
+       Port *old;
+
+       for (old = node->ports; old; old = old->next)
+               if (old->portnum == port->portnum)
+                       return old;
+
+       return NULL;
+}
+
+static Port *
+create_port(Node *node, Port *temp)
+{
+       Port *port;
+
+       port = malloc(sizeof(*port));
+       if (!port)
+               return NULL;
+
+       memcpy(port, temp, sizeof(*port));
+       port->node = node;
+       port->next = node->ports;
+       node->ports = port;
+
+       return port;
+}
+
+static void
+link_ports(Node *node, Port *port, Node *remotenode, Port *remoteport)
+{
+       DEBUG("linking: 0x%" PRIx64 " %p->%p:%u and 0x%" PRIx64 " %p->%p:%u",
+               node->nodeguid, node, port, port->portnum,
+               remotenode->nodeguid, remotenode, remoteport, remoteport->portnum);
+       if (port->remoteport)
+               port->remoteport->remoteport = NULL;
+       if (remoteport->remoteport)
+               remoteport->remoteport->remoteport = NULL;
+       port->remoteport = remoteport;
+       remoteport->remoteport = port;
+}
+
+static int
+handle_port(Node *node, Port *port, ib_portid_t *path, int portnum, int dist)
+{
+       Node node_buf;
+       Port port_buf;
+       Node *remotenode, *oldnode;
+       Port *remoteport, *oldport;
+
+       memset(&node_buf, 0, sizeof(node_buf));
+       memset(&port_buf, 0, sizeof(port_buf));
+
+       DEBUG("handle node %p port %p:%d dist %d", node, port, portnum, dist);
+       if (port->physstate != 5)       /* LinkUp */
+               return -1;
+
+       if (extend_dpath(&path->drpath, portnum) < 0)
+               return -1;
+
+       if (get_node(&node_buf, &port_buf, path) < 0) {
+               IBWARN("NodeInfo on %s failed, skipping port",
+                       portid2str(path));
+               path->drpath.cnt--;     /* restore path */
+               return -1;
+       }
+
+       oldnode = find_node(&node_buf);
+       if (oldnode)
+               remotenode = oldnode;
+       else if (!(remotenode = create_node(&node_buf, path, dist + 1)))
+               IBERROR("no memory");
+
+       oldport = find_port(remotenode, &port_buf);
+       if (oldport) {
+               remoteport = oldport;
+               if (node != remotenode || port != remoteport)
+                       IBWARN("port moving...");
+       } else if (!(remoteport = create_port(remotenode, &port_buf)))
+               IBERROR("no memory");
+
+       dump_endnode(path, oldnode ? "known remote" : "new remote",
+                    remotenode, remoteport);
+
+       link_ports(node, port, remotenode, remoteport);
+
+       path->drpath.cnt--;     /* restore path */
+       return 0;
+}
+
+/*
+ * Return 1 if found, 0 if not, -1 on errors.
+ */
+static int
+discover(ib_portid_t *from)
+{
+       Node node_buf;
+       Port port_buf;
+       Node *node;
+       Port *port;
+       int i;
+       int dist = 0;
+       ib_portid_t *path;
+
+       DEBUG("from %s", portid2str(from));
+
+       memset(&node_buf, 0, sizeof(node_buf));
+       memset(&port_buf, 0, sizeof(port_buf));
+
+       if (get_node(&node_buf, &port_buf, from) < 0) {
+               IBWARN("can't reach node %s", portid2str(from));
+               return -1;
+       }
+
+       node = create_node(&node_buf, from, 0);
+       if (!node)
+               IBERROR("out of memory");
+
+       mynode = node;
+
+       port = create_port(node, &port_buf);
+       if (!port)
+               IBERROR("out of memory");
+
+       if (node->type != SWITCH_NODE &&
+           handle_port(node, port, from, node->localport, 0) < 0)
+               return 0;
+
+       for (dist = 0; dist < MAXHOPS; dist++) {
+
+               for (node = nodesdist[dist]; node; node = node->dnext) {
+
+                       path = &node->path;
+
+                       DEBUG("dist %d node %p", dist, node);
+                       dump_endnode(path, "processing", node, port);
+
+                       for (i = 1; i <= node->numports; i++) {
+                               if (i == node->localport)
+                                       continue;
+
+                               if (get_port(&port_buf, i, path) < 0) {
+                                       IBWARN("can't reach node %s port %d", portid2str(path), i);
+                                       continue;
+                               }
+
+                               port = find_port(node, &port_buf);
+                               if (port)
+                                       continue;
+
+                               port = create_port(node, &port_buf);
+                               if (!port)
+                                       IBERROR("out of memory");
+
+                               /* If switch, set port GUID to node GUID */
+                               if (node->type == SWITCH_NODE)
+                                       port->portguid = node->portguid;
+
+                               handle_port(node, port, path, i, dist);
+                       }
+               }
+       }
+
+       return 0;
+}
+
+char *
+node_name(Node *node)
+{
+       static char buf[256];
+
+       switch(node->type) {
+       case SWITCH_NODE:
+               sprintf(buf, "\"%s", "S");
+               break;
+       case CA_NODE:
+               sprintf(buf, "\"%s", "H");
+               break;
+       case ROUTER_NODE:
+               sprintf(buf, "\"%s", "R");
+               break;
+       default:
+               sprintf(buf, "\"%s", "?");
+               break;
+       }
+       sprintf(buf+2, "-%016" PRIx64 "\"", node->nodeguid);
+
+       return buf;
+}
+
+void
+list_node(Node *node)
+{
+       char *node_type;
+       char *nodename = remap_node_name(node_name_map, node->nodeguid,
+                                             node->nodedesc);
+
+       switch(node->type) {
+       case SWITCH_NODE:
+               node_type = "Switch";
+               break;
+       case CA_NODE:
+               node_type = "Ca";
+               break;
+       case ROUTER_NODE:
+               node_type = "Router";
+               break;
+       default:
+               node_type = "???";
+               break;
+       }
+       fprintf(f, "%s\t : 0x%016" PRIx64 " ports %d devid 0x%x vendid 0x%x \"%s\"\n",
+               node_type,
+               node->nodeguid, node->numports, node->devid, node->vendid,
+               nodename);
+
+       free(nodename);
+}
+
+void
+out_ids(Node *node, int group, char *chname)
+{
+       fprintf(f, "\nvendid=0x%x\ndevid=0x%x\n", node->vendid, node->devid);
+       if (node->sysimgguid)
+               fprintf(f, "sysimgguid=0x%" PRIx64, node->sysimgguid);
+       if (group
+           && node->chrecord && node->chrecord->chassisnum) {
+               fprintf(f, "\t\t# Chassis %d", node->chrecord->chassisnum);
+               if (chname)
+                       fprintf(f, " (%s)", chname);
+               if (is_xsigo_tca(node->nodeguid) && node->ports->remoteport)
+                       fprintf(f, " slot %d", node->ports->remoteport->portnum);
+       }
+       fprintf(f, "\n");
+}
+
+uint64_t
+out_chassis(unsigned char chassisnum)
+{
+       uint64_t guid;
+
+       fprintf(f, "\nChassis %d", chassisnum);
+       guid = get_chassis_guid(chassisnum);
+       if (guid)
+               fprintf(f, " (guid 0x%" PRIx64 ")", guid);
+       fprintf(f, "\n");
+       return guid;
+}
+
+void
+out_switch(Node *node, int group, char *chname)
+{
+       char *str;
+       char *nodename = NULL;
+
+       out_ids(node, group, chname);
+       fprintf(f, "switchguid=0x%" PRIx64, node->nodeguid);
+       fprintf(f, "(%" PRIx64 ")", node->portguid);
+       /* Currently, only if Voltaire chassis */
+       if (group
+           && node->chrecord && node->chrecord->chassisnum
+           && node->vendid == VTR_VENDOR_ID) {
+               str = get_chassis_type(node->chrecord->chassistype);
+               if (str)
+                       fprintf(f, "%s ", str);
+               str = get_chassis_slot(node->chrecord->chassisslot);
+               if (str)
+                       fprintf(f, "%s ", str);
+               fprintf(f, "%d Chip %d", node->chrecord->slotnum, node->chrecord->anafanum);
+       }
+
+       nodename = remap_node_name(node_name_map, node->nodeguid,
+                               node->nodedesc);
+
+       fprintf(f, "\nSwitch\t%d %s\t\t# \"%s\" %s port 0 lid %d lmc %d\n",
+               node->numports, node_name(node),
+               nodename,
+               node->smaenhsp0 ? "enhanced" : "base",
+               node->smalid, node->smalmc);
+
+       free(nodename);
+}
+
+void
+out_ca(Node *node, int group, char *chname)
+{
+       char *node_type;
+       char *node_type2;
+       char *nodename = remap_node_name(node_name_map, node->nodeguid,
+                                             node->nodedesc);
+
+       out_ids(node, group, chname);
+       switch(node->type) {
+       case CA_NODE:
+               node_type = "ca";
+               node_type2 = "Ca";
+               break;
+       case ROUTER_NODE:
+               node_type = "rt";
+               node_type2 = "Rt";
+               break;
+       default:
+               node_type = "???";
+               node_type2 = "???";
+               break;
+       }
+
+       fprintf(f, "%sguid=0x%" PRIx64 "\n", node_type, node->nodeguid);
+       fprintf(f, "%s\t%d %s\t\t# \"%s\"",
+               node_type2, node->numports, node_name(node),
+               nodename);
+       if (group && is_xsigo_hca(node->nodeguid))
+               fprintf(f, " (scp)");
+       fprintf(f, "\n");
+
+       free(nodename);
+}
+
+static char *
+out_ext_port(Port *port, int group)
+{
+       char *str = NULL;
+
+       /* Currently, only if Voltaire chassis */
+       if (group
+           && port->node->chrecord && port->node->vendid == VTR_VENDOR_ID)
+               str = portmapstring(port);
+
+       return (str);
+}
+
+void
+out_switch_port(Port *port, int group)
+{
+       char *ext_port_str = NULL;
+       char *rem_nodename = NULL;
+
+       DEBUG("port %p:%d remoteport %p", port, port->portnum, port->remoteport);
+       fprintf(f, "[%d]", port->portnum);
+
+       ext_port_str = out_ext_port(port, group);
+       if (ext_port_str)
+               fprintf(f, "%s", ext_port_str);
+
+       rem_nodename = remap_node_name(node_name_map,
+                               port->remoteport->node->nodeguid,
+                               port->remoteport->node->nodedesc);
+
+       ext_port_str = out_ext_port(port->remoteport, group);
+       fprintf(f, "\t%s[%d]%s",
+               node_name(port->remoteport->node),
+               port->remoteport->portnum,
+               ext_port_str ? ext_port_str : "");
+       if (port->remoteport->node->type != SWITCH_NODE)
+               fprintf(f, "(%" PRIx64 ") ", port->remoteport->portguid);
+       fprintf(f, "\t\t# \"%s\" lid %d %s%s",
+               rem_nodename,
+               port->remoteport->node->type == SWITCH_NODE ? port->remoteport->node->smalid : port->remoteport->lid,
+               get_linkwidth_str(port->linkwidth),
+               get_linkspeed_str(port->linkspeed));
+
+       if (is_xsigo_tca(port->remoteport->portguid))
+               fprintf(f, " slot %d", port->portnum);
+       else if (is_xsigo_hca(port->remoteport->portguid))
+               fprintf(f, " (scp)");
+       fprintf(f, "\n");
+
+       free(rem_nodename);
+}
+
+void
+out_ca_port(Port *port, int group)
+{
+       char *str = NULL;
+       char *rem_nodename = NULL;
+
+       fprintf(f, "[%d]", port->portnum);
+       if (port->node->type != SWITCH_NODE)
+               fprintf(f, "(%" PRIx64 ") ", port->portguid);
+       fprintf(f, "\t%s[%d]",
+               node_name(port->remoteport->node),
+               port->remoteport->portnum);
+       str = out_ext_port(port->remoteport, group);
+       if (str)
+               fprintf(f, "%s", str);
+       if (port->remoteport->node->type != SWITCH_NODE)
+               fprintf(f, " (%" PRIx64 ") ", port->remoteport->portguid);
+
+       rem_nodename = remap_node_name(node_name_map,
+                               port->remoteport->node->nodeguid,
+                               port->remoteport->node->nodedesc);
+
+       fprintf(f, "\t\t# lid %d lmc %d \"%s\" lid %d %s%s\n",
+               port->lid, port->lmc, rem_nodename,
+               port->remoteport->node->type == SWITCH_NODE ? port->remoteport->node->smalid : port->remoteport->lid,
+               get_linkwidth_str(port->linkwidth),
+               get_linkspeed_str(port->linkspeed));
+
+       free(rem_nodename);
+}
+
+int
+dump_topology(int listtype, int group)
+{
+       Node *node;
+       Port *port;
+       int i = 0, dist = 0;
+       time_t t = time(0);
+       uint64_t chguid;
+       char *chname = NULL;
+
+       if (!listtype) {
+               fprintf(f, "#\n# Topology file: generated on %s#\n", ctime(&t));
+               fprintf(f, "# Max of %d hops discovered\n", maxhops_discovered);
+               fprintf(f, "# Initiated from node %016" PRIx64 " port %016" PRIx64 "\n", mynode->nodeguid, mynode->portguid);
+       }
+
+       /* Make pass on switches */
+       if (group && !listtype) {
+               ChassisList *ch = NULL;
+
+               /* Chassis based switches first */
+               for (ch = chassis; ch; ch = ch->next) {
+                       int n = 0;
+
+                       if (!ch->chassisnum)
+                               continue;
+                       chguid = out_chassis(ch->chassisnum);
+                       if (chname)
+                               free(chname);
+                       chname = NULL;
+                       if (is_xsigo_guid(chguid)) {
+                               for (node = nodesdist[MAXHOPS]; node; node = node->dnext) {
+                                       if (!node->chrecord ||
+                                           !node->chrecord->chassisnum)
+                                               continue;
+
+                                       if (node->chrecord->chassisnum != ch->chassisnum)
+                                               continue;
+
+                                       if (is_xsigo_hca(node->nodeguid)) {
+                                               chname = remap_node_name(node_name_map,
+                                                               node->nodeguid,
+                                                               node->nodedesc);
+                                               fprintf(f, "Hostname: %s\n", chname);
+                                       }
+                               }
+                       }
+
+                       fprintf(f, "\n# Spine Nodes");
+                       for (n = 1; n <= (SPINES_MAX_NUM+1); n++) {
+                               if (ch->spinenode[n]) {
+                                       out_switch(ch->spinenode[n], group, chname);
+                                       for (port = ch->spinenode[n]->ports; port; port = port->next, i++)
+                                               if (port->remoteport)
+                                                       out_switch_port(port, group);
+                               }
+                       }
+                       fprintf(f, "\n# Line Nodes");
+                       for (n = 1; n <= (LINES_MAX_NUM+1); n++) {
+                               if (ch->linenode[n]) {
+                                       out_switch(ch->linenode[n], group, chname);
+                                       for (port = ch->linenode[n]->ports; port; port = port->next, i++)
+                                               if (port->remoteport)
+                                                       out_switch_port(port, group);
+                               }
+                       }
+
+                       fprintf(f, "\n# Chassis Switches");
+                       for (dist = 0; dist <= maxhops_discovered; dist++) {
+
+                               for (node = nodesdist[dist]; node; node = node->dnext) {
+
+                                       /* Non Voltaire chassis */
+                                       if (node->vendid == VTR_VENDOR_ID)
+                                               continue;
+                                       if (!node->chrecord ||
+                                           !node->chrecord->chassisnum)
+                                               continue;
+
+                                       if (node->chrecord->chassisnum != ch->chassisnum)
+                                               continue;
+
+                                       out_switch(node, group, chname);
+                                       for (port = node->ports; port; port = port->next, i++)
+                                               if (port->remoteport)
+                                                       out_switch_port(port, group);
+
+                               }
+
+                       }
+
+                       fprintf(f, "\n# Chassis CAs");
+                       for (node = nodesdist[MAXHOPS]; node; node = node->dnext) {
+                               if (!node->chrecord ||
+                                   !node->chrecord->chassisnum)
+                                       continue;
+
+                               if (node->chrecord->chassisnum != ch->chassisnum)
+                                       continue;
+
+                               out_ca(node, group, chname);
+                               for (port = node->ports; port; port = port->next, i++)
+                                       if (port->remoteport)
+                                               out_ca_port(port, group);
+
+                       }
+
+               }
+
+       } else {
+               for (dist = 0; dist <= maxhops_discovered; dist++) {
+
+                       for (node = nodesdist[dist]; node; node = node->dnext) {
+
+                               DEBUG("SWITCH: dist %d node %p", dist, node);
+                               if (!listtype)
+                                       out_switch(node, group, chname);
+                               else {
+                                       if (listtype & LIST_SWITCH_NODE)
+                                               list_node(node);
+                                       continue;
+                               }
+
+                               for (port = node->ports; port; port = port->next, i++)
+                                       if (port->remoteport)
+                                               out_switch_port(port, group);
+                       }
+               }
+       }
+
+       if (chname)
+               free(chname);
+       chname = NULL;
+       if (group && !listtype) {
+
+               fprintf(f, "\nNon-Chassis Nodes\n");
+
+               for (dist = 0; dist <= maxhops_discovered; dist++) {
+
+                       for (node = nodesdist[dist]; node; node = node->dnext) {
+
+                               DEBUG("SWITCH: dist %d node %p", dist, node);
+                               /* Now, skip chassis based switches */
+                               if (node->chrecord &&
+                                   node->chrecord->chassisnum)
+                                       continue;
+                               out_switch(node, group, chname);
+
+                               for (port = node->ports; port; port = port->next, i++)
+                                       if (port->remoteport)
+                                               out_switch_port(port, group);
+                       }
+
+               }
+
+       }
+
+       /* Make pass on CAs */
+       for (node = nodesdist[MAXHOPS]; node; node = node->dnext) {
+
+               DEBUG("CA: dist %d node %p", dist, node);
+               if (!listtype) {
+                       /* Now, skip chassis based CAs */
+                       if (group && node->chrecord &&
+                           node->chrecord->chassisnum)
+                               continue;
+                       out_ca(node, group, chname);
+               } else {
+                       if (((listtype & LIST_CA_NODE) && (node->type == CA_NODE)) ||
+                           ((listtype & LIST_ROUTER_NODE) && (node->type == ROUTER_NODE)))
+                               list_node(node);
+                       continue;
+               }
+
+               for (port = node->ports; port; port = port->next, i++)
+                       if (port->remoteport)
+                               out_ca_port(port, group);
+       }
+
+       if (chname)
+               free(chname);
+
+       return i;
+}
+
+void dump_ports_report ()
+{
+       int b, n = 0, p;
+       Node *node;
+       Port *port;
+
+       // If switch and LID == 0, search of other switch ports with
+       // valid LID and assign it to all ports of that switch
+       for (b = 0; b <= MAXHOPS; b++)
+               for (node = nodesdist[b]; node; node = node->dnext)
+                       if (node->type == SWITCH_NODE) {
+                               int swlid = 0;
+                               for (p = 0, port = node->ports;
+                                    p < node->numports && port && !swlid;
+                                    port = port->next)
+                                       if (port->lid != 0)
+                                               swlid = port->lid;
+                               for (p = 0, port = node->ports;
+                                    p < node->numports && port;
+                                    port = port->next)
+                                       port->lid = swlid;
+                       }
+
+       for (b = 0; b <= MAXHOPS; b++)
+               for (node = nodesdist[b]; node; node = node->dnext) {
+                       for (p = 0, port = node->ports;
+                            p < node->numports && port;
+                            p++, port = port->next) {
+                               fprintf(stdout,
+                                       "%2s %5d %2d 0x%016" PRIx64 " %s %s",
+                                       node_type_str2(port->node), port->lid,
+                                       port->portnum,
+                                       port->portguid,
+                                       get_linkwidth_str(port->linkwidth),
+                                       get_linkspeed_str(port->linkspeed));
+                               if (port->remoteport)
+                                       fprintf(stdout,
+                                               " - %2s %5d %2d 0x%016" PRIx64
+                                               " ( '%s' - '%s' )\n",
+                                               node_type_str2(port->remoteport->node),
+                                               port->remoteport->lid,
+                                               port->remoteport->portnum,
+                                               port->remoteport->portguid,
+                                               port->node->nodedesc,
+                                               port->remoteport->node->nodedesc);
+                               else
+                                       fprintf(stdout, "%36s'%s'\n", "",
+                                               port->node->nodedesc);
+                       }
+                       n++;
+               }
+}
+
+static int list, group, ports_report;
+
+static int process_opt(void *context, int ch, char *optarg)
+{
+       switch (ch) {
+       case 1:
+               node_name_map_file = strdup(optarg);
+               break;
+       case 's':
+               dumplevel = 1;
+               break;
+       case 'l':
+               list = LIST_CA_NODE | LIST_SWITCH_NODE | LIST_ROUTER_NODE;
+               break;
+       case 'g':
+               group = 1;
+               break;
+       case 'S':
+               list = LIST_SWITCH_NODE;
+               break;
+       case 'H':
+               list = LIST_CA_NODE;
+               break;
+       case 'R':
+               list = LIST_ROUTER_NODE;
+               break;
+       case 'p':
+               ports_report = 1;
+               break;
+       default:
+               return -1;
+       }
+
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       int mgmt_classes[2] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS};
+       ib_portid_t my_portid = {0};
+
+       const struct ibdiag_opt opts[] = {
+               { "show", 's', 0, NULL, "show more information" },
+               { "list", 'l', 0, NULL, "list of connected nodes" },
+               { "grouping", 'g', 0, NULL, "show grouping" },
+               { "Hca_list", 'H', 0, NULL, "list of connected CAs" },
+               { "Switch_list", 'S', 0, NULL, "list of connected switches" },
+               { "Router_list", 'R', 0, NULL, "list of connected routers" },
+               { "node-name-map", 1, 1, "<file>", "node name map file" },
+               { "ports", 'p', 0, NULL, "obtain a ports report" },
+               { 0 }
+       };
+       char usage_args[] = "[topology-file]";
+
+       ibdiag_process_opts(argc, argv, NULL, "sGDL", opts, process_opt,
+                           usage_args, NULL);
+
+       f = stdout;
+
+       argc -= optind;
+       argv += optind;
+
+       if (ibd_timeout)
+               timeout = ibd_timeout;
+
+       if (ibverbose)
+               dumplevel = 1;
+
+       if (argc && !(f = fopen(argv[0], "w")))
+               IBERROR("can't open file %s for writing", argv[0]);
+
+       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 2);
+       node_name_map = open_node_name_map(node_name_map_file);
+
+       if (discover(&my_portid) < 0)
+               IBERROR("discover");
+
+       if (group)
+               chassis = group_nodes();
+
+       if (ports_report)
+               dump_ports_report();
+       else
+               dump_topology(list, group);
+
+       close_node_name_map(node_name_map);
+       exit(0);
+}
diff --git a/tools/infiniband-diags/src/ibnetdiscover/SOURCES b/tools/infiniband-diags/src/ibnetdiscover/SOURCES
new file mode 100644 (file)
index 0000000..300925b
--- /dev/null
@@ -0,0 +1,33 @@
+TARGETNAME = ibnetdiscover\r
+TARGETPATH = ..\..\..\..\bin\user\obj$(BUILD_ALT_DIR)\r
+TARGETTYPE = PROGRAM\r
+\r
+UMTYPE = console\r
+UMENTRY = main\r
+\r
+USE_MSVCRT = 1\r
+\r
+SOURCES = ..\ibnetdiscover.c ..\grouping.c ..\ibdiag_common.c ..\ibdiag_windows.c\\r
+                 ibnetdiscover.rc\r
+       \r
+INCLUDES = ..\..\include;..\..\include\windows;\\r
+                  ..\..\..\..\ulp\libibmad\include;\\r
+                  ..\..\..\..\ulp\libibumad\include;\\r
+                  ..\..\..\..\inc;..\..\..\..\inc\user;\\r
+                  ..\..\..\..\inc\user\linux;\r
+\r
+C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H\r
+\r
+TARGETLIBS = \\r
+       $(SDK_LIB_PATH)\kernel32.lib    \\r
+!if $(FREEBUILD)\r
+       $(TARGETPATH)\*\complib.lib             \\r
+       $(TARGETPATH)\*\libibmad.lib    \\r
+       $(TARGETPATH)\*\libibumad.lib   \r
+!else\r
+       $(TARGETPATH)\*\complibd.lib    \\r
+       $(TARGETPATH)\*\libibmadd.lib   \\r
+       $(TARGETPATH)\*\libibumadd.lib  \r
+!endif\r
+\r
+MSC_WARNING_LEVEL = /W3 /WX /wd4007
\ No newline at end of file
@@ -36,9 +36,9 @@
 #define VER_FILESUBTYPE                        VFT2_UNKNOWN\r
 \r
 #ifdef DBG\r
-#define VER_FILEDESCRIPTION_STR        "InfiniBand Fabric Topology Discovery (Debug)"\r
+#define VER_FILEDESCRIPTION_STR        "InfiniBand Network Topology Discovery (Debug)"\r
 #else\r
-#define VER_FILEDESCRIPTION_STR        "InfiniBand Fabric Topology Discovery"\r
+#define VER_FILEDESCRIPTION_STR        "InfiniBand Network Topology Discovery"\r
 #endif\r
 \r
 #define VER_INTERNALNAME_STR           "ibnetdiscover.exe"\r
similarity index 63%
rename from tools/infiniband_diags/src/ibping.c
rename to tools/infiniband-diags/src/ibping.c
index 2ade15a..210b648 100644 (file)
-/*\r
- * Copyright (c) 2004-2008 Voltaire Inc.  All rights reserved.\r
- *\r
- * This software is available to you under a choice of one of two\r
- * licenses.  You may choose to be licensed under the terms of the GNU\r
- * General Public License (GPL) Version 2, available from the file\r
- * COPYING in the main directory of this source tree, or the\r
- * OpenIB.org BSD license below:\r
- *\r
- *     Redistribution and use in source and binary forms, with or\r
- *     without modification, are permitted provided that the following\r
- *     conditions are met:\r
- *\r
- *      - Redistributions of source code must retain the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer.\r
- *\r
- *      - Redistributions in binary form must reproduce the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer in the documentation and/or other materials\r
- *        provided with the distribution.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- * SOFTWARE.\r
- *\r
- */\r
-\r
-#if HAVE_CONFIG_H\r
-#  include <config.h>\r
-#endif /* HAVE_CONFIG_H */\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-\r
-#include <infiniband/umad.h>\r
-#include <infiniband/mad.h>\r
-\r
-#include "ibdiag_common.h"\r
-\r
-#undef DEBUG\r
-#define        DEBUG   if (verbose) IBWARN\r
-\r
-static int dest_type = IB_DEST_LID;\r
-static int verbose;\r
-static char host_and_domain[IB_VENDOR_RANGE2_DATA_SIZE];\r
-static char last_host[IB_VENDOR_RANGE2_DATA_SIZE];\r
-\r
-char *argv0 = "ibping";\r
-\r
-static void\r
-get_host_and_domain(char *data, int sz)\r
-{\r
-       char *s = data;\r
-       int n;\r
-\r
-       if (gethostname(s, sz) < 0)\r
-               snprintf(s, sz, "?hostname?");\r
-\r
-       s[sz-1] = 0;\r
-       if ((n = strlen(s)) >= sz)\r
-               return;\r
-       s[n] = '.';\r
-       s += n + 1;\r
-       sz -= n + 1;\r
-\r
-       if (getdomainname(s, sz) < 0)\r
-               snprintf(s, sz, "?domainname?");\r
-       if (strlen(s) == 0)\r
-               s[-1] = 0;      /* no domain */\r
-}\r
-\r
-static char *\r
-ibping_serv(void)\r
-{\r
-       void *umad;\r
-       void *mad;\r
-       char *data;\r
-\r
-       DEBUG("starting to serve...");\r
-\r
-       while ((umad = mad_receive(0, -1))) {\r
-\r
-               mad = umad_get_mad(umad);\r
-               data = (char *)mad + IB_VENDOR_RANGE2_DATA_OFFS;\r
-\r
-               memcpy(data, host_and_domain, IB_VENDOR_RANGE2_DATA_SIZE);\r
-\r
-               DEBUG("Pong: %s", data);\r
-\r
-               if (mad_respond(umad, 0, 0) < 0)\r
-                       DEBUG("respond failed");\r
-\r
-               mad_free(umad);\r
-       }\r
-\r
-       DEBUG("server out");\r
-       return 0;\r
-}\r
-\r
-static uint64_t\r
-ibping(ib_portid_t *portid, int quiet)\r
-{\r
-       char data[IB_VENDOR_RANGE2_DATA_SIZE] = {0};\r
-       ib_vendor_call_t call;\r
-       uint64_t start, rtt;\r
-\r
-       DEBUG("Ping..");\r
-\r
-       start = getcurrenttime();\r
-\r
-       call.method = IB_MAD_METHOD_GET;\r
-       call.mgmt_class = IB_VENDOR_OPENIB_PING_CLASS;\r
-       call.attrid = 0;\r
-       call.mod = 0;\r
-       call.oui = IB_OPENIB_OUI;\r
-       call.timeout = 0;\r
-       memset(&call.rmpp, 0, sizeof call.rmpp);\r
-\r
-       if (!ib_vendor_call(data, portid, &call))\r
-               return ~0ULL;\r
-\r
-       rtt = getcurrenttime() - start;\r
-\r
-       if (!last_host[0])\r
-               memcpy(last_host, data, sizeof last_host);\r
-\r
-       if (!quiet)\r
-               printf("Pong from %s (%s): time %" PRIu64 ".%03" PRIu64 " ms\n",\r
-                       data, portid2str(portid), rtt/1000ULL, rtt%1000ULL);\r
-\r
-       return rtt;\r
-}\r
-\r
-static void\r
-usage(void)\r
-{\r
-       char *basename;\r
-\r
-       if (!(basename = strrchr(argv0, '/')))\r
-               basename = argv0;\r
-       else\r
-               basename++;\r
-\r
-       fprintf(stderr, "Usage: %s [-d(ebug) -e(rr_show) -v(erbose) -G(uid) -s smlid -V(ersion) -C ca_name -P ca_port "\r
-                       "-t(imeout) timeout_ms -c ping_count -f(lood) -o oui -S(erver)] <dest lid|guid>\n",\r
-                       basename);\r
-       exit(-1);\r
-}\r
-\r
-static uint64_t minrtt = ~0ull, maxrtt, total_rtt;\r
-static uint64_t start, total_time, replied, lost, ntrans;\r
-static ib_portid_t portid = {0};\r
-\r
-void\r
-report(int sig)\r
-{\r
-       total_time = getcurrenttime() - start;\r
-\r
-       DEBUG("out due signal %d", sig);\r
-\r
-       printf("\n--- %s (%s) ibping statistics ---\n", last_host, portid2str(&portid));\r
-       printf("%" PRIu64 " packets transmitted, %" PRIu64 " received, %" PRIu64 "%% packet loss, time %" PRIu64 " ms\n",\r
-               ntrans, replied,\r
-               (lost != 0) ?  lost * 100 / ntrans : 0, total_time / 1000);\r
-       printf("rtt min/avg/max = %" PRIu64 ".%03" PRIu64 "/%" PRIu64 ".%03" PRIu64 "/%" PRIu64 ".%03" PRIu64 " ms\n",\r
-               minrtt == ~0ull ? 0 : minrtt/1000,\r
-               minrtt == ~0ull ? 0 : minrtt%1000,\r
-               replied ? total_rtt/replied/1000 : 0,\r
-               replied ? (total_rtt/replied)%1000 : 0,\r
-               maxrtt/1000, maxrtt%1000);\r
-\r
-       exit(0);\r
-}\r
-\r
-int _CDECL\r
-main(int argc, char **argv)\r
-{\r
-       int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS};\r
-       int ping_class = IB_VENDOR_OPENIB_PING_CLASS;\r
-       ib_portid_t *sm_id = 0, sm_portid = {0};\r
-       int timeout = 0, udebug = 0, server = 0, flood = 0;\r
-       int oui = IB_OPENIB_OUI;\r
-       uint64_t rtt;\r
-       unsigned int count = ~0;\r
-       extern int ibdebug;\r
-       char *err;\r
-       char *ca = 0;\r
-       int ca_port = 0;\r
-\r
-       static char const str_opts[] = "C:P:t:s:c:o:devGfSVhu";\r
-       static const struct option long_opts[] = {\r
-               { "C", 1, 0, 'C'},\r
-               { "P", 1, 0, 'P'},\r
-               { "debug", 0, 0, 'd'},\r
-               { "err_show", 0, 0, 'e'},\r
-               { "verbose", 0, 0, 'v'},\r
-               { "Guid", 0, 0, 'G'},\r
-               { "s", 1, 0, 's'},\r
-               { "timeout", 1, 0, 't'},\r
-               { "c", 1, 0, 'c'},\r
-               { "flood", 0, 0, 'f'},\r
-               { "o", 1, 0, 'o'},\r
-               { "Server", 0, 0, 'S'},\r
-               { "Version", 0, 0, 'V'},\r
-               { "help", 0, 0, 'h'},\r
-               { "usage", 0, 0, 'u'},\r
-               { 0 }\r
-       };\r
-\r
-       argv0 = argv[0];\r
-\r
-       while (1) {\r
-               int ch = getopt_long(argc, argv, str_opts, long_opts, NULL);\r
-               if ( ch == -1 )\r
-                       break;\r
-               switch(ch) {\r
-               case 'C':\r
-                       ca = optarg;\r
-                       break;\r
-               case 'P':\r
-                       ca_port = strtoul(optarg, 0, 0);\r
-                       break;\r
-               case 'c':\r
-                       count = strtoul(optarg, 0, 0);\r
-                       break;\r
-               case 'd':\r
-                       ibdebug++;\r
-                       madrpc_show_errors(1);\r
-                       umad_debug(udebug);\r
-                       udebug++;\r
-                       break;\r
-               case 'e':\r
-                       madrpc_show_errors(1);\r
-                       break;\r
-               case 'f':\r
-                       flood++;\r
-                       break;\r
-               case 'G':\r
-                       dest_type = IB_DEST_GUID;\r
-                       break;\r
-               case 'o':\r
-                       oui = strtoul(optarg, 0, 0);\r
-                       break;\r
-               case 's':\r
-                       if (ib_resolve_portid_str(&sm_portid, optarg, IB_DEST_LID, 0) < 0)\r
-                               IBERROR("can't resolve SM destination port %s", optarg);\r
-                       sm_id = &sm_portid;\r
-                       break;\r
-               case 'S':\r
-                       server++;\r
-                       break;\r
-               case 't':\r
-                       timeout = strtoul(optarg, 0, 0);\r
-                       madrpc_set_timeout(timeout);\r
-                       break;\r
-               case 'v':\r
-                       verbose++;\r
-                       break;\r
-               case 'V':\r
-                       fprintf(stderr, "%s %s\n", argv0, get_build_version() );\r
-                       exit(-1);\r
-               default:\r
-                       usage();\r
-                       break;\r
-               }\r
-       }\r
-       argc -= optind;\r
-       argv += optind;\r
-\r
-       if (!argc && !server)\r
-               usage();\r
-\r
-       madrpc_init(ca, ca_port, mgmt_classes, 3);\r
-\r
-       if (server) {\r
-               if (mad_register_server(ping_class, 0, 0, oui) < 0)\r
-                       IBERROR("can't serve class %d on this port", ping_class);\r
-\r
-               get_host_and_domain(host_and_domain, sizeof host_and_domain);\r
-\r
-               if ((err = ibping_serv()))\r
-                       IBERROR("ibping to %s: %s", portid2str(&portid), err);\r
-               exit(0);\r
-       }\r
-\r
-       if (mad_register_client(ping_class, 0) < 0)\r
-               IBERROR("can't register ping class %d on this port", ping_class);\r
-\r
-       if (ib_resolve_portid_str(&portid, argv[0], dest_type, sm_id) < 0)\r
-               IBERROR("can't resolve destination port %s", argv[0]);\r
-\r
-       signal(SIGINT, report);\r
-       signal(SIGTERM, report);\r
-\r
-       start = getcurrenttime();\r
-\r
-       while (count-- > 0) {\r
-               ntrans++;\r
-               if ((rtt = ibping(&portid, flood)) == ~0ull) {\r
-                       DEBUG("ibping to %s failed", portid2str(&portid));\r
-                       lost++;\r
-               } else {\r
-                       if (rtt < minrtt)\r
-                               minrtt = rtt;\r
-                       if (rtt > maxrtt)\r
-                               maxrtt = rtt;\r
-                       total_rtt += rtt;\r
-                       replied++;\r
-               }\r
-\r
-               if (!flood)\r
-                       sleep(1);\r
-       }\r
-\r
-       report(0);\r
-\r
-       exit(-1);\r
-}\r
+/*
+ * Copyright (c) 2004-2008 Voltaire Inc.  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.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <getopt.h>
+
+#include <infiniband/umad.h>
+#include <infiniband/mad.h>
+#include <complib/cl_timer.h>
+
+#include "ibdiag_common.h"
+
+static char host_and_domain[IB_VENDOR_RANGE2_DATA_SIZE];
+static char last_host[IB_VENDOR_RANGE2_DATA_SIZE];
+
+static void
+get_host_and_domain(char *data, int sz)
+{
+       char *s = data;
+       int n;
+
+       if (gethostname(s, sz) < 0)
+               snprintf(s, sz, "?hostname?");
+
+       s[sz-1] = 0;
+       if ((n = strlen(s)) >= sz)
+               return;
+       s[n] = '.';
+       s += n + 1;
+       sz -= n + 1;
+
+       if (getdomainname(s, sz) < 0)
+               snprintf(s, sz, "?domainname?");
+       if (strlen(s) == 0)
+               s[-1] = 0;      /* no domain */
+}
+
+static char *
+ibping_serv(void)
+{
+       void *umad;
+       void *mad;
+       char *data;
+
+       DEBUG("starting to serve...");
+
+       while ((umad = mad_receive(0, -1))) {
+
+               mad = umad_get_mad(umad);
+               data = (char *)mad + IB_VENDOR_RANGE2_DATA_OFFS;
+
+               memcpy(data, host_and_domain, IB_VENDOR_RANGE2_DATA_SIZE);
+
+               DEBUG("Pong: %s", data);
+
+               if (mad_respond(umad, 0, 0) < 0)
+                       DEBUG("respond failed");
+
+               mad_free(umad);
+       }
+
+       DEBUG("server out");
+       return 0;
+}
+
+static uint64_t
+ibping(ib_portid_t *portid, int quiet)
+{
+       char data[IB_VENDOR_RANGE2_DATA_SIZE] = {0};
+       ib_vendor_call_t call;
+       uint64_t start, rtt;
+
+       DEBUG("Ping..");
+
+       start = cl_get_time_stamp();
+
+       call.method = IB_MAD_METHOD_GET;
+       call.mgmt_class = IB_VENDOR_OPENIB_PING_CLASS;
+       call.attrid = 0;
+       call.mod = 0;
+       call.oui = IB_OPENIB_OUI;
+       call.timeout = 0;
+       memset(&call.rmpp, 0, sizeof call.rmpp);
+
+       if (!ib_vendor_call(data, portid, &call))
+               return ~0ull;
+
+       rtt = cl_get_time_stamp() - start;
+
+       if (!last_host[0])
+               memcpy(last_host, data, sizeof last_host);
+
+       if (!quiet)
+               printf("Pong from %s (%s): time %" PRIu64 ".%03" PRIu64 " ms\n",
+                       data, portid2str(portid), rtt/1000, rtt%1000);
+
+       return rtt;
+}
+
+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)
+{
+       total_time = cl_get_time_stamp() - start;
+
+       DEBUG("out due signal %d", sig);
+
+       printf("\n--- %s (%s) ibping statistics ---\n", last_host, portid2str(&portid));
+       printf("%" PRIu64 " packets transmitted, %" PRIu64 " received, %" PRIu64 "%% packet loss, time %" PRIu64 " ms\n",
+               ntrans, replied,
+               (lost != 0) ?  lost * 100 / ntrans : 0, total_time / 1000);
+       printf("rtt min/avg/max = %" PRIu64 ".%03" PRIu64 "/%" PRIu64 ".%03" PRIu64 "/%" PRIu64 ".%03" PRIu64 " ms\n",
+               minrtt == ~0ull ? 0 : minrtt/1000,
+               minrtt == ~0ull ? 0 : minrtt%1000,
+               replied ? total_rtt/replied/1000 : 0,
+               replied ? (total_rtt/replied)%1000 : 0,
+               maxrtt/1000, maxrtt%1000);
+
+       exit(0);
+}
+
+static int server = 0, flood = 0, oui = IB_OPENIB_OUI;
+static unsigned count = ~0;
+
+static int process_opt(void *context, int ch, char *optarg)
+{
+       switch (ch) {
+       case 'c':
+               count = strtoul(optarg, 0, 0);
+               break;
+       case 'f':
+               flood++;
+               break;
+       case 'o':
+               oui = strtoul(optarg, 0, 0);
+               break;
+       case 'S':
+               server++;
+               break;
+       default:
+               return -1;
+       }
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS};
+       int ping_class = IB_VENDOR_OPENIB_PING_CLASS;
+       uint64_t rtt;
+       char *err;
+
+       const struct ibdiag_opt opts[] = {
+               { "count", 'c', 1, "<num>", "stop after count packets" },
+               { "flood", 'f', 0, NULL, "flood destination" },
+               { "oui", 'o', 1, NULL, "use specified OUI number" },
+               { "Server", 'S', 0, NULL, "start in server mode" },
+               { 0 }
+       };
+       char usage_args[] = "<dest lid|guid>";
+
+       ibdiag_process_opts(argc, argv, NULL, "D", opts, process_opt,
+                           usage_args, NULL);
+
+       argc -= optind;
+       argv += optind;
+
+       if (!argc && !server)
+               ibdiag_show_usage();
+
+       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+
+       if (server) {
+               if (mad_register_server(ping_class, 0, 0, oui) < 0)
+                       IBERROR("can't serve class %d on this port", ping_class);
+
+               get_host_and_domain(host_and_domain, sizeof host_and_domain);
+
+               if ((err = ibping_serv()))
+                       IBERROR("ibping to %s: %s", portid2str(&portid), err);
+               exit(0);
+       }
+
+       if (mad_register_client(ping_class, 0) < 0)
+               IBERROR("can't register ping class %d on this port", ping_class);
+
+       if (ib_resolve_portid_str(&portid, argv[0], ibd_dest_type, ibd_sm_id) < 0)
+               IBERROR("can't resolve destination port %s", argv[0]);
+
+       signal(SIGINT, report);
+       signal(SIGTERM, report);
+
+       start = cl_get_time_stamp();
+
+       while (count-- > 0) {
+               ntrans++;
+               if ((rtt = ibping(&portid, flood)) == ~0ull) {
+                       DEBUG("ibping to %s failed", portid2str(&portid));
+                       lost++;
+               } else {
+                       if (rtt < minrtt)
+                               minrtt = rtt;
+                       if (rtt > maxrtt)
+                               maxrtt = rtt;
+                       total_rtt += rtt;
+                       replied++;
+               }
+
+               if (!flood)
+                       sleep(1);
+       }
+
+       report(0);
+
+       exit(-1);
+}
diff --git a/tools/infiniband-diags/src/ibping/SOURCES b/tools/infiniband-diags/src/ibping/SOURCES
new file mode 100644 (file)
index 0000000..2b187a8
--- /dev/null
@@ -0,0 +1,33 @@
+TARGETNAME = ibping\r
+TARGETPATH = ..\..\..\..\bin\user\obj$(BUILD_ALT_DIR)\r
+TARGETTYPE = PROGRAM\r
+\r
+UMTYPE = console\r
+UMENTRY = main\r
+\r
+USE_MSVCRT = 1\r
+\r
+SOURCES = ..\ibping.c ..\ibdiag_common.c ..\ibdiag_windows.c ibping.rc\r
+       \r
+INCLUDES = ..\..\include;..\..\include\windows;\\r
+                  ..\..\..\..\ulp\libibmad\include;\\r
+                  ..\..\..\..\ulp\libibumad\include;\\r
+                  ..\..\..\..\inc;..\..\..\..\inc\user;\\r
+                  ..\..\..\..\inc\user\linux;\r
+\r
+C_DEFINES = $(C_DEFINES) /DHAVE_CONFIG_H\r
+\r
+TARGETLIBS = \\r
+       $(SDK_LIB_PATH)\kernel32.lib    \\r
+       $(SDK_LIB_PATH)\ws2_32.lib              \\r
+!if $(FREEBUILD)\r
+       $(TARGETPATH)\*\complib.lib             \\r
+       $(TARGETPATH)\*\libibmad.lib    \\r
+       $(TARGETPATH)\*\libibumad.lib   \r
+!else\r
+       $(TARGETPATH)\*\complibd.lib    \\r
+       $(TARGETPATH)\*\libibmadd.lib   \\r
+       $(TARGETPATH)\*\libibumadd.lib  \r
+!endif\r
+\r
+MSC_WARNING_LEVEL = /W3 /WX /wd4007\r
diff --git a/tools/infiniband-diags/src/ibping/ibping.rc b/tools/infiniband-diags/src/ibping/ibping.rc
new file mode 100644 (file)
index 0000000..62ee765
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+ * Copyright (c) 2009 Intel Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id$\r
+ */\r
+\r
+\r
+#include <oib_ver.h>\r
+\r
+#define VER_FILETYPE                   VFT_APP\r
+#define VER_FILESUBTYPE                        VFT2_UNKNOWN\r
+\r
+#ifdef DBG\r
+#define VER_FILEDESCRIPTION_STR        "InfiniBand MAD Ping (Debug)"\r
+#else\r
+#define VER_FILEDESCRIPTION_STR        "InfiniBand MAD Ping"\r
+#endif\r
+\r
+#define VER_INTERNALNAME_STR           "ibping.exe"\r
+#define VER_ORIGINALFILENAME_STR       "ibping.exe"\r
+\r
+#include <common.ver>\r
similarity index 78%
rename from tools/infiniband_diags/src/ibportstate.c
rename to tools/infiniband-diags/src/ibportstate.c
index eedfd70..c0b9b34 100644 (file)
-/*\r
- * Copyright (c) 2004-2008 Voltaire Inc.  All rights reserved.\r
- *\r
- * This software is available to you under a choice of one of two\r
- * licenses.  You may choose to be licensed under the terms of the GNU\r
- * General Public License (GPL) Version 2, available from the file\r
- * COPYING in the main directory of this source tree, or the\r
- * OpenIB.org BSD license below:\r
- *\r
- *     Redistribution and use in source and binary forms, with or\r
- *     without modification, are permitted provided that the following\r
- *     conditions are met:\r
- *\r
- *      - Redistributions of source code must retain the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer.\r
- *\r
- *      - Redistributions in binary form must reproduce the above\r
- *        copyright notice, this list of conditions and the following\r
- *        disclaimer in the documentation and/or other materials\r
- *        provided with the distribution.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- * SOFTWARE.\r
- *\r
- */\r
-\r
-#if HAVE_CONFIG_H\r
-#  include <config.h>\r
-#endif /* HAVE_CONFIG_H */\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <unistd.h>\r
-#include <stdarg.h>\r
-#include <time.h>\r
-#include <string.h>\r
-#include <getopt.h>\r
-\r
-#include <infiniband/umad.h>\r
-#include <infiniband/mad.h>\r
-\r
-#include "ibdiag_common.h"\r
-\r
-#undef DEBUG\r
-#define        DEBUG   if (verbose>1) IBWARN\r
-\r
-static int dest_type = IB_DEST_LID;\r
-static int verbose;\r
-\r
-char *argv0 = "ibportstate";\r
-\r
-/*******************************************/\r
-\r
-static int\r
-get_node_info(ib_portid_t *dest, uint8_t *data)\r
-{\r
-       int node_type;\r
-\r
-       if (!smp_query(data, dest, IB_ATTR_NODE_INFO, 0, 0))\r
-               return -1;\r
-\r
-       node_type = mad_get_field(data, 0, IB_NODE_TYPE_F);\r
-       if (node_type == IB_NODE_SWITCH)        /* Switch NodeType ? */\r
-               return 0;\r
-       else\r
-               return 1;\r
-}\r
-\r
-static int\r
-get_port_info(ib_portid_t *dest, uint8_t *data, int portnum, int port_op)\r
-{\r
-       char buf[2048];\r
-       char val[64];\r
-\r
-       if (!smp_query(data, dest, IB_ATTR_PORT_INFO, portnum, 0))\r
-               return -1;\r
-\r
-       if (port_op != 4) {\r
-               mad_dump_portstates(buf, sizeof buf, data, sizeof data);\r
-               mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F, val);\r
-               mad_dump_field(IB_PORT_LINK_WIDTH_SUPPORTED_F, buf + strlen(buf), sizeof buf - strlen(buf), val);\r
-               sprintf(buf+strlen(buf), "%s", "\n");\r
-               mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F, val);\r
-               mad_dump_field(IB_PORT_LINK_WIDTH_ENABLED_F, buf + strlen(buf), sizeof buf - strlen(buf), val);\r
-               sprintf(buf+strlen(buf), "%s", "\n");\r
-               mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F, val);\r
-               mad_dump_field(IB_PORT_LINK_WIDTH_ACTIVE_F, buf + strlen(buf), sizeof buf - strlen(buf), val);\r
-               sprintf(buf+strlen(buf), "%s", "\n");\r
-               mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F, val);\r
-               mad_dump_field(IB_PORT_LINK_SPEED_SUPPORTED_F, buf + strlen(buf), sizeof buf - strlen(buf), val);\r
-               sprintf(buf+strlen(buf), "%s", "\n");\r
-               mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val);\r
-               mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf + strlen(buf), sizeof buf - strlen(buf), val);\r
-               sprintf(buf+strlen(buf), "%s", "\n");\r
-               mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F, val);\r
-               mad_dump_field(IB_PORT_LINK_SPEED_ACTIVE_F, buf + strlen(buf), sizeof buf - strlen(buf), val);\r
-               sprintf(buf+strlen(buf), "%s", "\n");\r
-       } else {\r
-               mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val);\r
-               mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf, sizeof buf, val);\r
-               sprintf(buf+strlen(buf), "%s", "\n");\r
-       }\r
-\r
-       printf("# Port info: %s port %d\n%s", portid2str(dest), portnum, buf);\r
-       return 0;\r
-}\r
-\r
-static int\r
-set_port_info(ib_portid_t *dest, uint8_t *data, int portnum, int port_op)\r
-{\r
-       char buf[2048];\r
-       char val[64];\r
-\r
-       if (!smp_set(data, dest, IB_ATTR_PORT_INFO, portnum, 0))\r
-               return -1;\r
-\r
-       if (port_op != 4)\r
-               mad_dump_portstates(buf, sizeof buf, data, sizeof data);\r
-       else {\r
-               mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val);\r
-               mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf, sizeof buf, val);\r
-               sprintf(buf+strlen(buf), "%s", "\n");\r
-       }\r
-\r
-       printf("\nAfter PortInfo set:\n");\r
-       printf("# Port info: %s port %d\n%s", portid2str(dest), portnum, buf);\r
-       return 0;\r
-}\r
-\r
-static int\r
-get_link_width(int lwe, int lws)\r
-{\r
-       if (lwe == 255)\r
-               return lws;\r
-       else\r
-               return lwe;\r
-}\r
-\r
-static int\r
-get_link_speed(int lse, int lss)\r
-{\r
-       if (lse == 15)\r
-               return lss;\r
-       else\r
-               return lse;\r
-}\r
-\r
-static void\r
-validate_width(int width, int peerwidth, int lwa)\r
-{\r
-       if ((width & 0x8) && (peerwidth & 0x8)) {\r
-               if (lwa != 8)\r
-                       IBWARN("Peer ports operating at active width %d rather than 8 (12x)", lwa);\r
-       } else {\r
-               if ((width & 0x4) && (peerwidth & 0x4)) {\r
-                       if (lwa != 4)\r
-                               IBWARN("Peer ports operating at active width %d rather than 4 (8x)", lwa);\r
-               } else {\r
-                       if ((width & 0x2) && (peerwidth & 0x2)) {\r
-                               if (lwa != 2)\r
-                                       IBWARN("Peer ports operating at active width %d rather than 2 (4x)", lwa);\r
-                       } else {\r
-                               if ((width & 0x1) && (peerwidth & 0x1)) {\r
-                                       if (lwa != 1)\r
-                                               IBWARN("Peer ports operating at active width %d rather than 1 (1x)", lwa);\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-static void\r
-validate_speed(int speed, int peerspeed, int lsa)\r
-{\r
-       if ((speed & 0x4) && (peerspeed & 0x4)) {\r
-               if (lsa != 4)\r
-                       IBWARN("Peer ports operating at active speed %d rather than  4 (10.0 Gbps)", lsa);\r
-       } else {\r
-               if ((speed & 0x2) && (peerspeed & 0x2)) {\r
-                       if (lsa != 2)\r
-                               IBWARN("Peer ports operating at active speed %d rather than 2 (5.0 Gbps)", lsa);\r
-               } else {\r
-                       if ((speed & 0x1) && (peerspeed & 0x1)) {\r
-                               if (lsa != 1)\r
-                                       IBWARN("Peer ports operating at active speed %d rather than 1 (2.5 Gbps)", lsa);\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-void\r
-usage(void)\r
-{\r
-       char *basename;\r
-\r
-       if (!(basename = strrchr(argv0, '/')))\r
-               basename = argv0;\r
-       else\r
-               basename++;\r
-\r
-       fprintf(stderr, "Usage: %s [-d(ebug) -e(rr_show) -v(erbose) -D(irect) -G(uid) -s smlid -V(ersion) -C ca_name -P ca_port "\r
-                       "-t(imeout) timeout_ms] <dest dr_path|lid|guid> <portnum> [<op>]\n",\r
-                       basename);\r
-       fprintf(stderr, "\tsupported ops: enable, disable, reset, speed, query\n");\r
-       fprintf(stderr, "\n\texamples:\n");\r
-       fprintf(stderr, "\t\t%s 3 1 disable\t\t\t# by lid\n", basename);\r
-       fprintf(stderr, "\t\t%s -G 0x2C9000100D051 1 enable\t# by guid\n", basename);\r
-       fprintf(stderr, "\t\t%s -D 0 1\t\t\t# (query) by direct route\n", basename);\r
-       fprintf(stderr, "\t\t%s 3 1 reset\t\t\t# by lid\n", basename);\r
-       fprintf(stderr, "\t\t%s 3 1 speed 1\t\t\t# by lid\n", basename);\r
-       exit(-1);\r
-}\r
-\r
-int _CDECL\r
-main(int argc, char **argv)\r
-{\r
-       int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS};\r
-       ib_portid_t portid = {0};\r
-       ib_portid_t *sm_id = 0, sm_portid = {0};\r
-       extern int ibdebug;\r
-       int err;\r
-       int timeout = 0, udebug = 0;\r
-       char *ca = 0;\r
-       int ca_port = 0;\r
-       int port_op = 0;        /* default to query */\r
-       int speed = 15;\r
-       int is_switch = 1;\r
-       int state, physstate, lwe, lws, lwa, lse, lss, lsa;\r
-       int peerlocalportnum, peerlwe, peerlws, peerlwa, peerlse, peerlss, peerlsa;\r
-       int width, peerwidth, peerspeed;\r
-       uint8_t data[IB_SMP_DATA_SIZE];\r
-       ib_portid_t peerportid = {0};\r
-       int portnum = 0;\r
-       ib_portid_t selfportid = {0};\r
-       int selfport = 0;\r
-\r
-       static char const str_opts[] = "C:P:t:s:devDGVhu";\r
-       static const struct option long_opts[] = {\r
-               { "C", 1, 0, 'C'},\r
-               { "P", 1, 0, 'P'},\r
-               { "debug", 0, 0, 'd'},\r
-               { "err_show", 0, 0, 'e'},\r
-               { "verbose", 0, 0, 'v'},\r
-               { "Direct", 0, 0, 'D'},\r
-               { "Guid", 0, 0, 'G'},\r
-               { "timeout", 1, 0, 't'},\r
-               { "s", 1, 0, 's'},\r
-               { "Version", 0, 0, 'V'},\r
-               { "help", 0, 0, 'h'},\r
-               { "usage", 0, 0, 'u'},\r
-               { 0 }\r
-       };\r
-\r
-       argv0 = argv[0];\r
-\r
-       while (1) {\r
-               int ch = getopt_long(argc, argv, str_opts, long_opts, NULL);\r
-               if ( ch == -1 )\r
-                       break;\r
-               switch(ch) {\r
-               case 'd':\r
-                       ibdebug++;\r
-                       madrpc_show_errors(1);\r
-                       umad_debug(udebug);\r
-                       udebug++;\r
-                       break;\r
-               case 'e':\r
-                       madrpc_show_errors(1);\r
-                       break;\r
-               case 'D':\r
-                       dest_type = IB_DEST_DRPATH;\r
-                       break;\r
-               case 'G':\r
-                       dest_type = IB_DEST_GUID;\r
-                       break;\r
-               case 'C':\r
-                       ca = optarg;\r
-                       break;\r
-               case 'P':\r
-                       ca_port = strtoul(optarg, 0, 0);\r
-                       break;\r
-               case 's':\r
-                       if (ib_resolve_portid_str(&sm_portid, optarg, IB_DEST_LID, 0) < 0)\r
-                               IBERROR("can't resolve SM destination port %s", optarg);\r
-                       sm_id = &sm_portid;\r
-                       break;\r
-               case 't':\r
-                       timeout = strtoul(optarg, 0, 0);\r
-                       madrpc_set_timeout(timeout);\r
-                       break;\r
-               case 'v':\r
-                       verbose++;\r
-                       break;\r
-               case 'V':\r
-                       fprintf(stderr, "%s %s\n", argv0, get_build_version() );\r
-                       exit(-1);\r
-               default:\r
-                       usage();\r
-                       break;\r
-               }\r
-       }\r
-       argc -= optind;\r
-       argv += optind;\r
-\r
-       if (argc < 2)\r
-               usage();\r
-\r
-       madrpc_init(ca, ca_port, mgmt_classes, 3);\r
-\r
-       if (ib_resolve_portid_str(&portid, argv[0], dest_type, sm_id) < 0)\r
-               IBERROR("can't resolve destination port %s", argv[0]);\r
-\r
-       /* First, make sure it is a switch port if it is a "set" */\r
-       if (argc >= 3) {\r
-               if (!strcmp(argv[2], "enable"))\r
-                       port_op = 1;\r
-               else if (!strcmp(argv[2], "disable"))\r
-                       port_op = 2;\r
-               else if (!strcmp(argv[2], "reset"))\r
-                       port_op = 3;\r
-               else if (!strcmp(argv[2], "speed")) {\r
-                       if (argc < 4)\r
-                               IBERROR("speed requires an additional parameter");\r
-                       port_op = 4;\r
-                       /* Parse speed value */\r
-                       speed = strtoul(argv[3], 0, 0);\r
-                       if (speed > 15)\r
-                               IBERROR("invalid speed value %d", speed);\r
-               }\r
-       }\r
-\r
-       err = get_node_info(&portid, data);\r
-       if (err < 0)\r
-               IBERROR("smp query nodeinfo failed");\r
-       if (err) {              /* not switch */\r
-               if (port_op == 0)       /* query op */\r
-                       is_switch = 0;\r
-               else if (port_op != 4)  /* other than speed op */\r
-                       IBERROR("smp query nodeinfo: Node type not switch");\r
-       }\r
-\r
-       if (argc-1 > 0)\r
-               portnum = strtol(argv[1], 0, 0);\r
-\r
-       if (port_op)\r
-               printf("Initial PortInfo:\n");\r
-       else\r
-               printf("PortInfo:\n");\r
-       err = get_port_info(&portid, data, portnum, port_op);\r
-       if (err < 0)\r
-               IBERROR("smp query portinfo failed");\r
-\r
-       /* Only if one of the "set" options is chosen */\r
-       if (port_op) {\r
-               if (port_op == 1)               /* Enable port */\r
-                       mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 2);        /* Polling */\r
-               else if ((port_op == 2) || (port_op == 3)) { /* Disable port */\r
-                       mad_set_field(data, 0, IB_PORT_STATE_F, 1);             /* Down */\r
-                       mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 3);        /* Disabled */\r
-               } else if (port_op == 4) {      /* Set speed */\r
-                       mad_set_field(data, 0, IB_PORT_LINK_SPEED_ENABLED_F, speed);\r
-                       mad_set_field(data, 0, IB_PORT_STATE_F, 0);\r
-                       mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 0);\r
-               }\r
-\r
-               err = set_port_info(&portid, data, portnum, port_op);\r
-               if (err < 0)\r
-                       IBERROR("smp set portinfo failed");\r
-\r
-               if (port_op == 3) {     /* Reset port - so also enable */\r
-                       mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 2);        /* Polling */\r
-                       err = set_port_info(&portid, data, portnum, port_op);\r
-                       if (err < 0)\r
-                               IBERROR("smp set portinfo failed");\r
-               }\r
-       } else {        /* query op */\r
-               /* only compare peer port if switch port */\r
-               if (is_switch) {\r
-                       /* First, exclude SP0 */\r
-                       if (portnum) {\r
-                               /* Now, make sure PortState is Active */\r
-                               /* Or is PortPhysicalState LinkUp sufficient ? */\r
-                               mad_decode_field(data, IB_PORT_STATE_F, &state);\r
-                               mad_decode_field(data, IB_PORT_PHYS_STATE_F, &physstate);\r
-                               if (state == 4) {       /* Active */\r
-                                       mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F, &lwe );\r
-                                       mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F, &lws);\r
-                                       mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F, &lwa);\r
-                                       mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F, &lss);\r
-                                       mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F, &lsa);\r
-                                       mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, &lse);\r
-\r
-                                       /* Setup portid for peer port */\r
-                                       memcpy(&peerportid, &portid, sizeof(peerportid));\r
-                                       peerportid.drpath.cnt = 1;\r
-                                       peerportid.drpath.p[1] = (uint8_t) portnum;\r
-\r
-                                       /* Set DrSLID to local lid */\r
-                                       if (ib_resolve_self(&selfportid, &selfport, 0) < 0)\r
-                                               IBERROR("could not resolve self");\r
-                                       peerportid.drpath.drslid = (uint16_t) selfportid.lid;\r
-                                       peerportid.drpath.drdlid = 0xffff;\r
-\r
-                                       /* Get peer port NodeInfo to obtain peer port number */\r
-                                       err = get_node_info(&peerportid, data);\r
-                                       if (err < 0)\r
-                                               IBERROR("smp query nodeinfo failed");\r
-\r
-                                       mad_decode_field(data, IB_NODE_LOCAL_PORT_F, &peerlocalportnum);\r
-\r
-                                       printf("Peer PortInfo:\n");\r
-                                       /* Get peer port characteristics */\r
-                                       err = get_port_info(&peerportid, data, peerlocalportnum, port_op);\r
-                                       if (err < 0)\r
-                                               IBERROR("smp query peer portinfofailed");\r
-\r
-                                       mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F, &peerlwe );\r
-                                       mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F, &peerlws);\r
-                                       mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F, &peerlwa);\r
-                                       mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F, &peerlss);\r
-                                       mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F, &peerlsa);\r
-                                       mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, &peerlse);\r
-\r
-                                       /* Now validate peer port characteristics */\r
-                                       /* Examine Link Width */\r
-                                       width = get_link_width(lwe, lws);\r
-                                       peerwidth = get_link_width(peerlwe, peerlws);\r
-                                       validate_width(width, peerwidth, lwa);\r
-\r
-                                       /* Examine Link Speed */\r
-                                       speed = get_link_speed(lse, lss);\r
-                                       peerspeed = get_link_speed(peerlse, peerlss);\r
-                                       validate_speed(speed, peerspeed, lsa);\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-       exit(0);\r
-}\r
+/*
+ * Copyright (c) 2004-2008 Voltaire Inc.  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.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <infiniband/umad.h>
+#include <infiniband/mad.h>
+
+#include "ibdiag_common.h"
+
+/*******************************************/
+
+static int
+get_node_info(ib_portid_t *dest, uint8_t *data)
+{
+       int node_type;
+
+       if (!smp_query(data, dest, IB_ATTR_NODE_INFO, 0, 0))
+               return -1;
+
+       node_type = mad_get_field(data, 0, IB_NODE_TYPE_F);
+       if (node_type == IB_NODE_SWITCH)        /* Switch NodeType ? */
+               return 0;
+       else
+               return 1;
+}
+
+static int
+get_port_info(ib_portid_t *dest, uint8_t *data, int portnum, int port_op)
+{
+       char buf[2048];
+       char val[64];
+
+       if (!smp_query(data, dest, IB_ATTR_PORT_INFO, portnum, 0))
+               return -1;
+
+       if (port_op != 4) {
+               mad_dump_portstates(buf, sizeof buf, data, sizeof data);
+               mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F, val);
+               mad_dump_field(IB_PORT_LINK_WIDTH_SUPPORTED_F, buf + strlen(buf), sizeof buf - strlen(buf), val);
+               sprintf(buf+strlen(buf), "%s", "\n");
+               mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F, val);
+               mad_dump_field(IB_PORT_LINK_WIDTH_ENABLED_F, buf + strlen(buf), sizeof buf - strlen(buf), val);
+               sprintf(buf+strlen(buf), "%s", "\n");
+               mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F, val);
+               mad_dump_field(IB_PORT_LINK_WIDTH_ACTIVE_F, buf + strlen(buf), sizeof buf - strlen(buf), val);
+               sprintf(buf+strlen(buf), "%s", "\n");
+               mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F, val);
+               mad_dump_field(IB_PORT_LINK_SPEED_SUPPORTED_F, buf + strlen(buf), sizeof buf - strlen(buf), val);
+               sprintf(buf+strlen(buf), "%s", "\n");
+               mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val);
+               mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf + strlen(buf), sizeof buf - strlen(buf), val);
+               sprintf(buf+strlen(buf), "%s", "\n");
+               mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F, val);
+               mad_dump_field(IB_PORT_LINK_SPEED_ACTIVE_F, buf + strlen(buf), sizeof buf - strlen(buf), val);
+               sprintf(buf+strlen(buf), "%s", "\n");
+       } else {
+               mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val);
+               mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf, sizeof buf, val);
+               sprintf(buf+strlen(buf), "%s", "\n");
+       }
+
+       printf("# Port info: %s port %d\n%s", portid2str(dest), portnum, buf);
+       return 0;
+}
+
+static int
+set_port_info(ib_portid_t *dest, uint8_t *data, int portnum, int port_op)
+{
+       char buf[2048];
+       char val[64];
+
+       if (!smp_set(data, dest, IB_ATTR_PORT_INFO, portnum, 0))
+               return -1;
+
+       if (port_op != 4)
+               mad_dump_portstates(buf, sizeof buf, data, sizeof data);
+       else {
+               mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val);
+               mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf, sizeof buf, val);
+               sprintf(buf+strlen(buf), "%s", "\n");
+       }
+
+       printf("\nAfter PortInfo set:\n");
+       printf("# Port info: %s port %d\n%s", portid2str(dest), portnum, buf);
+       return 0;
+}
+
+static int
+get_link_width(int lwe, int lws)
+{
+       if (lwe == 255)
+               return lws;
+       else
+               return lwe;
+}
+
+static int
+get_link_speed(int lse, int lss)
+{
+       if (lse == 15)
+               return lss;
+       else
+               return lse;
+}
+
+static void
+validate_width(int width, int peerwidth, int lwa)
+{
+       if ((width & 0x8) && (peerwidth & 0x8)) {
+               if (lwa != 8)
+                       IBWARN("Peer ports operating at active width %d rather than 8 (12x)", lwa);
+       } else {
+               if ((width & 0x4) && (peerwidth & 0x4)) {
+                       if (lwa != 4)
+                               IBWARN("Peer ports operating at active width %d rather than 4 (8x)", lwa);
+               } else {
+                       if ((width & 0x2) && (peerwidth & 0x2)) {
+                               if (lwa != 2)
+                                       IBWARN("Peer ports operating at active width %d rather than 2 (4x)", lwa);
+                       } else {
+                               if ((width & 0x1) && (peerwidth & 0x1)) {
+                                       if (lwa != 1)
+                                               IBWARN("Peer ports operating at active width %d rather than 1 (1x)", lwa);
+                               }
+                       }
+               }
+       }
+}
+
+static void
+validate_speed(int speed, int peerspeed, int lsa)
+{
+       if ((speed & 0x4) && (peerspeed & 0x4)) {
+               if (lsa != 4)
+                       IBWARN("Peer ports operating at active speed %d rather than  4 (10.0 Gbps)", lsa);
+       } else {
+               if ((speed & 0x2) && (peerspeed & 0x2)) {
+                       if (lsa != 2)
+                               IBWARN("Peer ports operating at active speed %d rather than 2 (5.0 Gbps)", lsa);
+               } else {
+                       if ((speed & 0x1) && (peerspeed & 0x1)) {
+                               if (lsa != 1)
+                                       IBWARN("Peer ports operating at active speed %d rather than 1 (2.5 Gbps)", lsa);
+                       }
+               }
+       }
+}
+
+int main(int argc, char **argv)
+{
+       int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS};
+       ib_portid_t portid = {0};
+       int err;
+       int port_op = 0;        /* default to query */
+       int speed = 15;
+       int is_switch = 1;
+       int state, physstate, lwe, lws, lwa, lse, lss, lsa;
+       int peerlocalportnum, peerlwe, peerlws, peerlwa, peerlse, peerlss, peerlsa;
+       int width, peerwidth, peerspeed;
+       uint8_t data[IB_SMP_DATA_SIZE];
+       ib_portid_t peerportid = {0};
+       int portnum = 0;
+       ib_portid_t selfportid = {0};
+       int selfport = 0;
+
+       char usage_args[] = "<dest dr_path|lid|guid> <portnum> [<op>]\n"
+               "\nSupported ops: enable, disable, reset, speed, query";
+       const char *usage_examples[] = {
+               "3 1 disable\t\t\t# by lid",
+               "-G 0x2C9000100D051 1 enable\t# by guid",
+               "-D 0 1\t\t\t# (query) by direct route",
+               "3 1 reset\t\t\t# by lid",
+               "3 1 speed 1\t\t\t# by lid",
+               NULL
+       };
+
+
+       ibdiag_process_opts(argc, argv, NULL, NULL, NULL, NULL,
+                           usage_args, usage_examples);
+
+       argc -= optind;
+       argv += optind;
+
+       if (argc < 2)
+               ibdiag_show_usage();
+
+       madrpc_init(ibd_ca, ibd_ca_port, mgmt_classes, 3);
+
+       if (ib_resolve_portid_str(&portid, argv[0], ibd_dest_type, ibd_sm_id) < 0)
+               IBERROR("can't resolve destination port %s", argv[0]);
+
+       /* First, make sure it is a switch port if it is a "set" */
+       if (argc >= 3) {
+               if (!strcmp(argv[2], "enable"))
+                       port_op = 1;
+               else if (!strcmp(argv[2], "disable"))
+                       port_op = 2;
+               else if (!strcmp(argv[2], "reset"))
+                       port_op = 3;
+               else if (!strcmp(argv[2], "speed")) {
+                       if (argc < 4)
+                               IBERROR("speed requires an additional parameter");
+                       port_op = 4;
+                       /* Parse speed value */
+                       speed = strtoul(argv[3], 0, 0);
+                       if (speed > 15)
+                               IBERROR("invalid speed value %d", speed);
+               }
+       }
+
+       err = get_node_info(&portid, data);
+       if (err < 0)
+               IBERROR("smp query nodeinfo failed");
+       if (err) {              /* not switch */
+               if (port_op == 0)       /* query op */
+                       is_switch = 0;
+               else if (port_op != 4)  /* other than speed op */
+                       IBERROR("smp query nodeinfo: Node type not switch");
+       }
+
+       if (argc-1 > 0)
+               portnum = strtol(argv[1], 0, 0);
+
+       if (port_op)
+               printf("Initial PortInfo:\n");
+       else
+               printf("PortInfo:\n");
+       err = get_port_info(&portid, data, portnum, port_op);
+       if (err < 0)
+               IBERROR("smp query portinfo failed");
+
+       /* Only if one of the "set" options is chosen */
+       if (port_op) {
+               if (port_op == 1)               /* Enable port */
+                       mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 2);        /* Polling */
+               else if ((port_op == 2) || (port_op == 3)) { /* Disable port */
+                       mad_set_field(data, 0, IB_PORT_STATE_F, 1);             /* Down */
+                       mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 3);        /* Disabled */
+               } else if (port_op == 4) {      /* Set speed */
+                       mad_set_field(data, 0, IB_PORT_LINK_SPEED_ENABLED_F, speed);
+                       mad_set_field(data, 0, IB_PORT_STATE_F, 0);
+                       mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 0);
+               }
+
+               err = set_port_info(&portid, data, portnum, port_op);
+               if (err < 0)
+                       IBERROR("smp set portinfo failed");
+
+               if (port_op == 3) {     /* Reset port - so also enable */
+                       mad_set_field(data, 0, IB_PORT_PHYS_STATE_F, 2);        /* Polling */
+                       err = set_port_info(&portid, data, portnum, port_op);
+                       if (err < 0)
+                               IBERROR("smp set portinfo failed");
+               }
+    &n