[OpenSM] OFED version 3.3.3 ported to Windows - vendor == IBAL for now; umad in the...
authorstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 7 Dec 2009 23:01:20 +0000 (23:01 +0000)
committerstansmith <stansmith@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 7 Dec 2009 23:01:20 +0000 (23:01 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@2627 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

251 files changed:
ulp/opensm/user/AUTHORS [new file with mode: 0644]
ulp/opensm/user/README [new file with mode: 0644]
ulp/opensm/user/README.windows [new file with mode: 0644]
ulp/opensm/user/complib/README.txt [new file with mode: 0644]
ulp/opensm/user/complib/cl_dispatcher.c [new file with mode: 0644]
ulp/opensm/user/complib/cl_event_wheel.c [new file with mode: 0644]
ulp/opensm/user/config.h
ulp/opensm/user/dirs
ulp/opensm/user/doc/OpenSM_PKey_Mgr.txt
ulp/opensm/user/doc/OpenSM_RN.pdf [new file with mode: 0644]
ulp/opensm/user/doc/OpenSM_RN_0_3_1.pdf [deleted file]
ulp/opensm/user/doc/OpenSM_UM.pdf [new file with mode: 0644]
ulp/opensm/user/doc/OpenSM_UM_0_3.pdf [deleted file]
ulp/opensm/user/doc/QoS_management_in_OpenSM.txt [new file with mode: 0644]
ulp/opensm/user/doc/current-routing.txt
ulp/opensm/user/doc/opensm_release_notes-3.3.txt [new file with mode: 0644]
ulp/opensm/user/doc/partition-config.txt [new file with mode: 0644]
ulp/opensm/user/doc/perf-manager-arch.txt [new file with mode: 0644]
ulp/opensm/user/doc/performance-manager-HOWTO.txt [new file with mode: 0644]
ulp/opensm/user/doc/qos-config.txt
ulp/opensm/user/ibtrapgen/Makefile
ulp/opensm/user/ibtrapgen/SOURCES
ulp/opensm/user/ibtrapgen/ibtrapgen.c
ulp/opensm/user/ibtrapgen/osm_files.c [new file with mode: 0644]
ulp/opensm/user/include/complib/cl_dispatcher.h
ulp/opensm/user/include/complib/cl_event_wheel.h
ulp/opensm/user/include/iba/ib_cm_types.h [new file with mode: 0644]
ulp/opensm/user/include/iba/ib_types.h
ulp/opensm/user/include/opensm/osm_attrib_req.h
ulp/opensm/user/include/opensm/osm_base.h
ulp/opensm/user/include/opensm/osm_config.h [new file with mode: 0644]
ulp/opensm/user/include/opensm/osm_config.h.in [new file with mode: 0644]
ulp/opensm/user/include/opensm/osm_console.h
ulp/opensm/user/include/opensm/osm_console_io.h [new file with mode: 0644]
ulp/opensm/user/include/opensm/osm_db.h
ulp/opensm/user/include/opensm/osm_db_pack.h
ulp/opensm/user/include/opensm/osm_errors.h
ulp/opensm/user/include/opensm/osm_event_plugin.h [new file with mode: 0644]
ulp/opensm/user/include/opensm/osm_helper.h
ulp/opensm/user/include/opensm/osm_inform.h
ulp/opensm/user/include/opensm/osm_lid_mgr.h
ulp/opensm/user/include/opensm/osm_log.h
ulp/opensm/user/include/opensm/osm_mad_pool.h
ulp/opensm/user/include/opensm/osm_madw.h
ulp/opensm/user/include/opensm/osm_mcast_tbl.h
ulp/opensm/user/include/opensm/osm_mcm_port.h
ulp/opensm/user/include/opensm/osm_mesh.h [new file with mode: 0644]
ulp/opensm/user/include/opensm/osm_msgdef.h
ulp/opensm/user/include/opensm/osm_mtree.h
ulp/opensm/user/include/opensm/osm_multicast.h
ulp/opensm/user/include/opensm/osm_node.h
ulp/opensm/user/include/opensm/osm_opensm.h
ulp/opensm/user/include/opensm/osm_partition.h
ulp/opensm/user/include/opensm/osm_path.h
ulp/opensm/user/include/opensm/osm_perfmgr.h [new file with mode: 0644]
ulp/opensm/user/include/opensm/osm_perfmgr_db.h [new file with mode: 0644]
ulp/opensm/user/include/opensm/osm_pkey.h
ulp/opensm/user/include/opensm/osm_port.h
ulp/opensm/user/include/opensm/osm_port_profile.h
ulp/opensm/user/include/opensm/osm_prefix_route.h [new file with mode: 0644]
ulp/opensm/user/include/opensm/osm_qos_policy.h [new file with mode: 0644]
ulp/opensm/user/include/opensm/osm_remote_sm.h
ulp/opensm/user/include/opensm/osm_router.h
ulp/opensm/user/include/opensm/osm_sa.h
ulp/opensm/user/include/opensm/osm_sa_mad_ctrl.h
ulp/opensm/user/include/opensm/osm_service.h
ulp/opensm/user/include/opensm/osm_sm.h
ulp/opensm/user/include/opensm/osm_sm_mad_ctrl.h
ulp/opensm/user/include/opensm/osm_stats.h
ulp/opensm/user/include/opensm/osm_subnet.h
ulp/opensm/user/include/opensm/osm_switch.h
ulp/opensm/user/include/opensm/osm_ucast_cache.h [new file with mode: 0644]
ulp/opensm/user/include/opensm/osm_ucast_lash.h [new file with mode: 0644]
ulp/opensm/user/include/opensm/osm_ucast_mgr.h
ulp/opensm/user/include/opensm/osm_version.h
ulp/opensm/user/include/opensm/osm_version.h.in [new file with mode: 0644]
ulp/opensm/user/include/opensm/osm_vl15intf.h
ulp/opensm/user/include/opensm/st.h
ulp/opensm/user/include/vendor/osm_mtl_bind.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_pkt_randomizer.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_ts_useraccess.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_umadt.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor.h
ulp/opensm/user/include/vendor/osm_vendor_al.h
ulp/opensm/user/include/vendor/osm_vendor_api.h
ulp/opensm/user/include/vendor/osm_vendor_ibumad.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mlx.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mlx_defs.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mlx_dispatcher.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mlx_hca.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mlx_inout.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mlx_rmpp_ctx.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mlx_sar.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mlx_sender.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mlx_svc.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mlx_transport.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mlx_transport_anafa.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mlx_txn.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mtl.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mtl_hca_guid.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_mtl_transaction_mgr.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_sa_api.h
ulp/opensm/user/include/vendor/osm_vendor_test.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_ts.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/osm_vendor_umadt.h [new file with mode: 0644]
ulp/opensm/user/include/vendor/winosm_common.h
ulp/opensm/user/libvendor/Makefile
ulp/opensm/user/libvendor/SOURCES
ulp/opensm/user/libvendor/complib_files.c [new file with mode: 0644]
ulp/opensm/user/libvendor/libosmvendor.ver [new file with mode: 0644]
ulp/opensm/user/libvendor/osm_pkt_randomizer.c [new file with mode: 0644]
ulp/opensm/user/libvendor/osm_vendor_al.c
ulp/opensm/user/libvendor/osm_vendor_ibumad.c [new file with mode: 0644]
ulp/opensm/user/libvendor/osm_vendor_ibumad_sa.c [new file with mode: 0644]
ulp/opensm/user/libvendor/osm_vendor_mlx.c [new file with mode: 0644]
ulp/opensm/user/libvendor/osm_vendor_mlx_dispatcher.c [new file with mode: 0644]
ulp/opensm/user/libvendor/osm_vendor_mlx_hca.c [new file with mode: 0644]
ulp/opensm/user/libvendor/osm_vendor_mlx_hca_sim.c [new file with mode: 0644]
ulp/opensm/user/libvendor/osm_vendor_mlx_ibmgt.c [new file with mode: 0644]
ulp/opensm/user/libvendor/osm_vendor_mlx_rmpp_ctx.c [new file with mode: 0644]
ulp/opensm/user/libvendor/osm_vendor_mlx_sa.c
ulp/opensm/user/libvendor/osm_vendor_mlx_sar.c [new file with mode: 0644]
ulp/opensm/user/libvendor/osm_vendor_mlx_sender.c [new file with mode: 0644]
ulp/opensm/user/libvendor/osm_vendor_mlx_sim.c [new file with mode: 0644]
ulp/opensm/user/libvendor/osm_vendor_mlx_ts.c [new file with mode: 0644]
ulp/opensm/user/libvendor/osm_vendor_mlx_txn.c [new file with mode: 0644]
ulp/opensm/user/libvendor/osmv_ibal.exports [new file with mode: 0644]
ulp/opensm/user/libvendor/osmv_openib.exports [new file with mode: 0644]
ulp/opensm/user/libvendor/vendor-ibal.inc [new file with mode: 0644]
ulp/opensm/user/libvendor/vendor-umad.inc [new file with mode: 0644]
ulp/opensm/user/libvendor/winosm_common.c
ulp/opensm/user/man/opensm.8.in [new file with mode: 0644]
ulp/opensm/user/man/osmtest.8 [new file with mode: 0644]
ulp/opensm/user/opensm/Makefile [new file with mode: 0644]
ulp/opensm/user/opensm/SOURCES
ulp/opensm/user/opensm/dlfcn.h [new file with mode: 0644]
ulp/opensm/user/opensm/libopensm.map [new file with mode: 0644]
ulp/opensm/user/opensm/libopensm.ver [new file with mode: 0644]
ulp/opensm/user/opensm/main.c
ulp/opensm/user/opensm/opensm.rc
ulp/opensm/user/opensm/osm.mc [new file with mode: 0644]
ulp/opensm/user/opensm/osm_console.c
ulp/opensm/user/opensm/osm_console_io.c [new file with mode: 0644]
ulp/opensm/user/opensm/osm_db_files.c
ulp/opensm/user/opensm/osm_db_pack.c
ulp/opensm/user/opensm/osm_drop_mgr.c
ulp/opensm/user/opensm/osm_dump.c [new file with mode: 0644]
ulp/opensm/user/opensm/osm_event_plugin.c [new file with mode: 0644]
ulp/opensm/user/opensm/osm_helper.c [new file with mode: 0644]
ulp/opensm/user/opensm/osm_inform.c
ulp/opensm/user/opensm/osm_lid_mgr.c
ulp/opensm/user/opensm/osm_lin_fwd_rcv.c
ulp/opensm/user/opensm/osm_link_mgr.c
ulp/opensm/user/opensm/osm_log.c [new file with mode: 0644]
ulp/opensm/user/opensm/osm_mad_pool.c [new file with mode: 0644]
ulp/opensm/user/opensm/osm_mcast_fwd_rcv.c
ulp/opensm/user/opensm/osm_mcast_mgr.c
ulp/opensm/user/opensm/osm_mcast_tbl.c
ulp/opensm/user/opensm/osm_mcm_port.c
ulp/opensm/user/opensm/osm_mesh.c [new file with mode: 0644]
ulp/opensm/user/opensm/osm_mtree.c
ulp/opensm/user/opensm/osm_multicast.c
ulp/opensm/user/opensm/osm_node.c
ulp/opensm/user/opensm/osm_node_desc_rcv.c
ulp/opensm/user/opensm/osm_node_info_rcv.c
ulp/opensm/user/opensm/osm_opensm.c
ulp/opensm/user/opensm/osm_perfmgr.c [new file with mode: 0644]
ulp/opensm/user/opensm/osm_perfmgr_db.c [new file with mode: 0644]
ulp/opensm/user/opensm/osm_pkey.c
ulp/opensm/user/opensm/osm_pkey_mgr.c
ulp/opensm/user/opensm/osm_pkey_rcv.c
ulp/opensm/user/opensm/osm_port.c
ulp/opensm/user/opensm/osm_port_info_rcv.c
ulp/opensm/user/opensm/osm_prtn.c
ulp/opensm/user/opensm/osm_prtn_config.c
ulp/opensm/user/opensm/osm_qos.c
ulp/opensm/user/opensm/osm_qos_parser_l.c [new file with mode: 0644]
ulp/opensm/user/opensm/osm_qos_parser_l.l [new file with mode: 0644]
ulp/opensm/user/opensm/osm_qos_parser_y.c [new file with mode: 0644]
ulp/opensm/user/opensm/osm_qos_parser_y.h [new file with mode: 0644]
ulp/opensm/user/opensm/osm_qos_parser_y.y [new file with mode: 0644]
ulp/opensm/user/opensm/osm_qos_policy.c [new file with mode: 0644]
ulp/opensm/user/opensm/osm_remote_sm.c
ulp/opensm/user/opensm/osm_req.c
ulp/opensm/user/opensm/osm_resp.c
ulp/opensm/user/opensm/osm_router.c
ulp/opensm/user/opensm/osm_sa.c
ulp/opensm/user/opensm/osm_sa_class_port_info.c
ulp/opensm/user/opensm/osm_sa_guidinfo_record.c
ulp/opensm/user/opensm/osm_sa_informinfo.c
ulp/opensm/user/opensm/osm_sa_lft_record.c
ulp/opensm/user/opensm/osm_sa_link_record.c
ulp/opensm/user/opensm/osm_sa_mad_ctrl.c
ulp/opensm/user/opensm/osm_sa_mcmember_record.c
ulp/opensm/user/opensm/osm_sa_mft_record.c
ulp/opensm/user/opensm/osm_sa_multipath_record.c
ulp/opensm/user/opensm/osm_sa_node_record.c
ulp/opensm/user/opensm/osm_sa_path_record.c
ulp/opensm/user/opensm/osm_sa_pkey_record.c
ulp/opensm/user/opensm/osm_sa_portinfo_record.c
ulp/opensm/user/opensm/osm_sa_service_record.c
ulp/opensm/user/opensm/osm_sa_slvl_record.c
ulp/opensm/user/opensm/osm_sa_sminfo_record.c
ulp/opensm/user/opensm/osm_sa_sw_info_record.c
ulp/opensm/user/opensm/osm_sa_vlarb_record.c
ulp/opensm/user/opensm/osm_service.c
ulp/opensm/user/opensm/osm_slvl_map_rcv.c
ulp/opensm/user/opensm/osm_sm.c
ulp/opensm/user/opensm/osm_sm_mad_ctrl.c
ulp/opensm/user/opensm/osm_sm_state_mgr.c
ulp/opensm/user/opensm/osm_sminfo_rcv.c
ulp/opensm/user/opensm/osm_state_mgr.c
ulp/opensm/user/opensm/osm_subnet.c
ulp/opensm/user/opensm/osm_sw_info_rcv.c
ulp/opensm/user/opensm/osm_switch.c
ulp/opensm/user/opensm/osm_trap_rcv.c
ulp/opensm/user/opensm/osm_ucast_cache.c [new file with mode: 0644]
ulp/opensm/user/opensm/osm_ucast_file.c
ulp/opensm/user/opensm/osm_ucast_ftree.c
ulp/opensm/user/opensm/osm_ucast_lash.c [new file with mode: 0644]
ulp/opensm/user/opensm/osm_ucast_mgr.c
ulp/opensm/user/opensm/osm_ucast_updn.c
ulp/opensm/user/opensm/osm_vl15intf.c
ulp/opensm/user/opensm/osm_vl_arb_rcv.c
ulp/opensm/user/opensm/st.c
ulp/opensm/user/opensm/vendor-ibal.inc [new file with mode: 0644]
ulp/opensm/user/opensm/vendor-umad.inc [new file with mode: 0644]
ulp/opensm/user/osmeventplugin/libosmeventplugin.map [new file with mode: 0644]
ulp/opensm/user/osmeventplugin/libosmeventplugin.ver [new file with mode: 0644]
ulp/opensm/user/osmeventplugin/src/osmeventplugin.c [new file with mode: 0644]
ulp/opensm/user/osmtest/Makefile
ulp/opensm/user/osmtest/SOURCES
ulp/opensm/user/osmtest/include/osmt_inform.h
ulp/opensm/user/osmtest/include/osmt_mtl_regular_qp.h
ulp/opensm/user/osmtest/include/osmtest.h
ulp/opensm/user/osmtest/include/osmtest_base.h
ulp/opensm/user/osmtest/include/osmtest_subnet.h
ulp/opensm/user/osmtest/main.c
ulp/opensm/user/osmtest/osmt_files.c [new file with mode: 0644]
ulp/opensm/user/osmtest/osmt_inform.c
ulp/opensm/user/osmtest/osmt_mtl_regular_qp.c
ulp/opensm/user/osmtest/osmt_multicast.c
ulp/opensm/user/osmtest/osmt_service.c
ulp/opensm/user/osmtest/osmt_slvl_vl_arb.c
ulp/opensm/user/osmtest/osmtest.c
ulp/opensm/user/osmtest/osmtest.rc [new file with mode: 0644]
ulp/opensm/user/scripts/opensm.init.in [new file with mode: 0644]
ulp/opensm/user/scripts/opensm.logrotate [new file with mode: 0644]
ulp/opensm/user/scripts/opensm.sysconfig [new file with mode: 0644]
ulp/opensm/user/scripts/redhat-opensm.init.in [new file with mode: 0644]
ulp/opensm/user/scripts/sldd.sh.in [new file with mode: 0644]

diff --git a/ulp/opensm/user/AUTHORS b/ulp/opensm/user/AUTHORS
new file mode 100644 (file)
index 0000000..7f5d6cb
--- /dev/null
@@ -0,0 +1,9 @@
+\r
+By the chronological order of involvement:\r
+Steve King,          Intel\r
+Anil Keshavamurthy,  Intel\r
+Eitan Zahavi,        Mellanox Technologies,  eitan@mellanox.co.il\r
+Yael Kalka,          Mellanox Technologies,  yael@mellanox.co.il\r
+Shahar Frank,        Voltaire\r
+Hal Rosenstock,      Voltaire,               halr@voltaire.com\r
+Sasha Khapyorsky,    Voltaire,               sashak@voltaire.com\r
diff --git a/ulp/opensm/user/README b/ulp/opensm/user/README
new file mode 100644 (file)
index 0000000..55a837f
--- /dev/null
@@ -0,0 +1,25 @@
+OpenSM README:\r
+--------------\r
+\r
+OpenSM provides an implementation for an InfiniBand Subnet Manager and\r
+Administrator. Such a software entity is required to run for in order\r
+to initialize the InfiniBand hardware (at least one per each\r
+InfiniBand subnet).\r
+\r
+The full list of OpenSM features is described in the user manual\r
+provided in the doc sub directory.\r
+\r
+The installation of OpenSM includes:\r
+\r
+sbin/\r
+   opensm - the SM/SA executable\r
+   osmtest - a test program for the SM/SA\r
+lib/\r
+   libosmcomp.{a,so} - component library with generic services and containers\r
+   libopensm.{a,so} - opensm services for logs and mad buffer pool\r
+   libosmvendor.{a,so} - interface to the user mad service of the driver\r
+include/\r
+   iba/ib_types.h - IBA types header file\r
+   complib/ - component library includes\r
+   vendor/  - vendor library includes\r
+   opensm/  - public opensm library includes\r
diff --git a/ulp/opensm/user/README.windows b/ulp/opensm/user/README.windows
new file mode 100644 (file)
index 0000000..17f8631
--- /dev/null
@@ -0,0 +1,93 @@
+OpenSM for Windows: last updated [12-07-09]\r
+--------------------------------------------------\r
+\r
+OpenSM provides a user-mode implementation for an InfiniBand Subnet Manager and\r
+Administrator. Such a software entity is required to run in order to\r
+initialize the InfiniBand hardware (at least one per each InfiniBand subnet).\r
+\r
+The full list of OpenSM features is described in the user manual\r
+provided in the doc sub directory.\r
+\r
+The installation of OpenSM includes:\r
+\r
+%ProgramFiles%\Winof\\r
+   opensm.exe - the SM/SA executable\r
+   osmtest.exe - a test program for the SM/SA\r
+\r
+The standard WinOF installation creates an OpenSM Windows Service which is\r
+inactive by default. If one chooses the install feature 'Startup OpenSM' then\r
+the OpenSM Windows Service is reset to start automatically at System boot.\r
+Multiple OpenSM instances within a fabric are supported; the 1st OpenSM instance\r
+will be the MASTER opensm, while others will be in STANDBY mode awaiting\r
+the demise of the MASTER opensm instance.\r
+\r
+\r
+Building opensm.exe, osmtest.exe from the SVN tree with MSFT WDK 7600+\r
+----------------------------------------------------------------------\r
+  cd trunk\ulp\opensm\r
+  build /wg\r
+\r
+\r
+OpenSM 3.3.3 status\r
+-------------\r
+\r
+openSM 3.3.3 configured a 53 node HPC fabric runing Intel MPI regression tests.\r
+The openSM as a service is functioning well; log file resides in\r
+%TEMP\osm.log which translates to %windir%\temp\osm.log when run as a service.\r
+\r
+The log path is now static in definition as the usage output changed which no\r
+longer allowed calls to GetTempPath(). In order to work around this I used\r
+strdup_expand() in places where the static paths were dup()'ed. strdup_expand()\r
+will expand environment vars encountered during the string dup operation; a\r
+solution although likely not the final solution, as when the static paths\r
+printf() the '%' char of the environment vars are incorrectly treated as a\r
+printf() control char...sigh.\r
+\r
+The osm vendor is 'IBAL' until UMAD QP1/SA read() interface is working.\r
+The include files vendor.* define which osm vendor is being built.\r
+Make sure all SOURCES files are using the same vendor!\r
+nmake/build pre-processing leaves much to be desired... :-(\r
+\r
+\r
+\r
+OpenSM Code Base\r
+----------------\r
+\r
+OpenSM src is based on the OFED management\opensm sources for 3.3.3 release.\r
+\r
+Based-on implies the following process:\r
+\r
+  From the OFED management maintainers git repository on a Linux system\r
+    1) git clone git://git.openfabrics.org/~sashak/management\r
+    2) cd management/libibumad; ./autogen.sh && ./configure && make\r
+    3) cd management/libibmad; ./autogen.sh && ./configure && make\r
+    4) cd management/opensm; ./autogen.sh && ./configure && make\r
+    5) remove *.o *.po *.lo .deps/ .libs/\r
+    6) tar zcf ofed-mgmt.tgz management\r
+    7) Move the ofed-mgmt.tgz tarball to a Windows system where current \r
+       Windows opensm src resides.\r
+    8) unzip tar ball\r
+    9) diff trunk\ulp\opensm management\opensm\r
+\r
+    10) Carefully apply/reject changes.\r
+         There are a few (<30) differing files which the OFED community\r
+         declined to accept due to Windows orientation; an onogin story...sigh.\r
+         The bigger change blocks are found in the following files:\r
+           opensm\main.c OpenSM as a Windows service support.\r
+           opensm\console.c Windows console support without poll().\r
+           libvendor\osm_vendor_al.c\r
+         Makefile(s) are Windows specific; leave'em be.\r
+\r
+    10) Due to the usage of Linux only tools AutoTools, lex & yacc, the\r
+        following files are static in the windows src. Static in the sense the\r
+        files are configured in the Linux environment with the resultant .c .h\r
+        files moved into the Windows opensm src tree.\r
+        Watch out for differing versions of yacc/bison/lex. The .y & .l files\r
+        are modified in the Windows src to emphasize changes required in the\r
+        .c & .h files; basically minor changes.\r
+\r
+        a) management/opensm/opensm/osm_qow_parser_y.y\r
+        b) management/opensm/opensm/osm_qos_parser_l.l\r
+        c) management/opensm/opensm/configure.h\r
+        d) management/opensm/include/opensm/osm_version.h \r
+\r
diff --git a/ulp/opensm/user/complib/README.txt b/ulp/opensm/user/complib/README.txt
new file mode 100644 (file)
index 0000000..abc98b4
--- /dev/null
@@ -0,0 +1,6 @@
+\r
+\r
+******* DO NOT Confuse this complib\ with trunk\core\complib; trunk\core\complib\ and\r
+        trunk\inc\complib are the prefered versions and searched 1st.\r
+\r
+This complib\ exists only for OFED openSM code compatibility.
\ No newline at end of file
diff --git a/ulp/opensm/user/complib/cl_dispatcher.c b/ulp/opensm/user/complib/cl_dispatcher.c
new file mode 100644 (file)
index 0000000..d0faea2
--- /dev/null
@@ -0,0 +1,375 @@
+/*\r
+ * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.\r
+ * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.\r
+ * Copyright (c) 1996-2003 Intel Corporation. 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
+ * Abstract:\r
+ *    Implementation of Dispatcher abstraction.\r
+ *\r
+ */\r
+\r
+#if HAVE_CONFIG_H\r
+#  include <config.h>\r
+#endif                         /* HAVE_CONFIG_H */\r
+\r
+#include <stdlib.h>\r
+#include <complib/cl_dispatcher.h>\r
+#include <complib/cl_thread.h>\r
+#include <complib/cl_timer.h>\r
+\r
+/* give some guidance when we build our cl_pool of messages */\r
+#define CL_DISP_INITIAL_MSG_COUNT   256\r
+#define CL_DISP_MSG_GROW_SIZE       64\r
+\r
+/* give some guidance when we build our cl_pool of registration elements */\r
+#define CL_DISP_INITIAL_REG_COUNT   16\r
+#define CL_DISP_REG_GROW_SIZE       16\r
+\r
+/********************************************************************\r
+   __cl_disp_worker\r
+\r
+   Description:\r
+   This function takes messages off the FIFO and calls Processmsg()\r
+   This function executes as passive level.\r
+\r
+   Inputs:\r
+   p_disp - Pointer to Dispatcher object\r
+\r
+   Outputs:\r
+   None\r
+\r
+   Returns:\r
+   None\r
+********************************************************************/\r
+void __cl_disp_worker(IN void *context)\r
+{\r
+       cl_disp_msg_t *p_msg;\r
+       cl_dispatcher_t *p_disp = (cl_dispatcher_t *) context;\r
+\r
+       cl_spinlock_acquire(&p_disp->lock);\r
+\r
+       /* Process the FIFO until we drain it dry. */\r
+       while (cl_qlist_count(&p_disp->msg_fifo)) {\r
+               /* Pop the message at the head from the FIFO. */\r
+               p_msg =\r
+                   (cl_disp_msg_t *) cl_qlist_remove_head(&p_disp->msg_fifo);\r
+\r
+               /* we track the tim ethe last message spent in the queue */\r
+               p_disp->last_msg_queue_time_us =\r
+                   cl_get_time_stamp() - p_msg->in_time;\r
+\r
+               /*\r
+                * Release the spinlock while the message is processed.\r
+                * The user's callback may reenter the dispatcher\r
+                * and cause the lock to be reaquired.\r
+                */\r
+               cl_spinlock_release(&p_disp->lock);\r
+               p_msg->p_dest_reg->pfn_rcv_callback((void *)p_msg->p_dest_reg->\r
+                                                   context,\r
+                                                   (void *)p_msg->p_data);\r
+\r
+               cl_atomic_dec(&p_msg->p_dest_reg->ref_cnt);\r
+\r
+               /* The client has seen the data.  Notify the sender as appropriate. */\r
+               if (p_msg->pfn_xmt_callback) {\r
+                       p_msg->pfn_xmt_callback((void *)p_msg->context,\r
+                                               (void *)p_msg->p_data);\r
+                       cl_atomic_dec(&p_msg->p_src_reg->ref_cnt);\r
+               }\r
+\r
+               /* Grab the lock for the next iteration through the list. */\r
+               cl_spinlock_acquire(&p_disp->lock);\r
+\r
+               /* Return this message to the pool. */\r
+               cl_qpool_put(&p_disp->msg_pool, (cl_pool_item_t *) p_msg);\r
+       }\r
+\r
+       cl_spinlock_release(&p_disp->lock);\r
+}\r
+\r
+/********************************************************************\r
+ ********************************************************************/\r
+void cl_disp_construct(IN cl_dispatcher_t * const p_disp)\r
+{\r
+       CL_ASSERT(p_disp);\r
+\r
+       cl_qlist_init(&p_disp->reg_list);\r
+       cl_ptr_vector_construct(&p_disp->reg_vec);\r
+       cl_qlist_init(&p_disp->msg_fifo);\r
+       cl_spinlock_construct(&p_disp->lock);\r
+       cl_qpool_construct(&p_disp->msg_pool);\r
+}\r
+\r
+/********************************************************************\r
+ ********************************************************************/\r
+void cl_disp_shutdown(IN cl_dispatcher_t * const p_disp)\r
+{\r
+       CL_ASSERT(p_disp);\r
+\r
+       /* Stop the thread pool. */\r
+       cl_thread_pool_destroy(&p_disp->worker_threads);\r
+\r
+       /* Process all outstanding callbacks. */\r
+       __cl_disp_worker(p_disp);\r
+\r
+       /* Free all registration info. */\r
+       while (!cl_is_qlist_empty(&p_disp->reg_list))\r
+               free(cl_qlist_remove_head(&p_disp->reg_list));\r
+}\r
+\r
+/********************************************************************\r
+ ********************************************************************/\r
+void cl_disp_destroy(IN cl_dispatcher_t * const p_disp)\r
+{\r
+       CL_ASSERT(p_disp);\r
+\r
+       cl_spinlock_destroy(&p_disp->lock);\r
+       /* Destroy the message pool */\r
+       cl_qpool_destroy(&p_disp->msg_pool);\r
+       /* Destroy the pointer vector of registrants. */\r
+       cl_ptr_vector_destroy(&p_disp->reg_vec);\r
+}\r
+\r
+/********************************************************************\r
+ ********************************************************************/\r
+cl_status_t cl_disp_init(IN cl_dispatcher_t * const p_disp,\r
+                        IN const uint32_t thread_count,\r
+                        IN const char *const name)\r
+{\r
+       cl_status_t status;\r
+\r
+       CL_ASSERT(p_disp);\r
+\r
+       cl_disp_construct(p_disp);\r
+\r
+       status = cl_spinlock_init(&p_disp->lock);\r
+       if (status != CL_SUCCESS) {\r
+               cl_disp_destroy(p_disp);\r
+               return (status);\r
+       }\r
+\r
+       /* Specify no upper limit to the number of messages in the pool */\r
+       status = cl_qpool_init(&p_disp->msg_pool, CL_DISP_INITIAL_MSG_COUNT,\r
+                              0, CL_DISP_MSG_GROW_SIZE, sizeof(cl_disp_msg_t),\r
+                              NULL, NULL, NULL);\r
+       if (status != CL_SUCCESS) {\r
+               cl_disp_destroy(p_disp);\r
+               return (status);\r
+       }\r
+\r
+       status = cl_ptr_vector_init(&p_disp->reg_vec, CL_DISP_INITIAL_REG_COUNT,\r
+                                   CL_DISP_REG_GROW_SIZE);\r
+       if (status != CL_SUCCESS) {\r
+               cl_disp_destroy(p_disp);\r
+               return (status);\r
+       }\r
+\r
+       status = cl_thread_pool_init(&p_disp->worker_threads, thread_count,\r
+                                    __cl_disp_worker, p_disp, name);\r
+       if (status != CL_SUCCESS)\r
+               cl_disp_destroy(p_disp);\r
+\r
+       return (status);\r
+}\r
+\r
+/********************************************************************\r
+ ********************************************************************/\r
+cl_disp_reg_handle_t cl_disp_register(IN cl_dispatcher_t * const p_disp,\r
+                                     IN const cl_disp_msgid_t msg_id,\r
+                                     IN cl_pfn_msgrcv_cb_t pfn_callback\r
+                                     OPTIONAL,\r
+                                     IN const void *const context OPTIONAL)\r
+{\r
+       cl_disp_reg_info_t *p_reg;\r
+       cl_status_t status;\r
+\r
+       CL_ASSERT(p_disp);\r
+\r
+       /* Check that the requested registrant ID is available. */\r
+       cl_spinlock_acquire(&p_disp->lock);\r
+       if ((msg_id != CL_DISP_MSGID_NONE) &&\r
+           (msg_id < cl_ptr_vector_get_size(&p_disp->reg_vec)) &&\r
+           (cl_ptr_vector_get(&p_disp->reg_vec, msg_id))) {\r
+               cl_spinlock_release(&p_disp->lock);\r
+               return (NULL);\r
+       }\r
+\r
+       /* Get a registration info from the pool. */\r
+       p_reg = (cl_disp_reg_info_t *) malloc(sizeof(cl_disp_reg_info_t));\r
+       if (!p_reg) {\r
+               cl_spinlock_release(&p_disp->lock);\r
+               return (NULL);\r
+       } else {\r
+               memset(p_reg, 0, sizeof(cl_disp_reg_info_t));\r
+       }\r
+\r
+       p_reg->p_disp = p_disp;\r
+       p_reg->ref_cnt = 0;\r
+       p_reg->pfn_rcv_callback = pfn_callback;\r
+       p_reg->context = context;\r
+       p_reg->msg_id = msg_id;\r
+\r
+       /* Insert the registration in the list. */\r
+       cl_qlist_insert_tail(&p_disp->reg_list, (cl_list_item_t *) p_reg);\r
+\r
+       /* Set the array entry to the registrant. */\r
+       /* The ptr_vector grow automatically as necessary. */\r
+       if (msg_id != CL_DISP_MSGID_NONE) {\r
+               status = cl_ptr_vector_set(&p_disp->reg_vec, msg_id, p_reg);\r
+               if (status != CL_SUCCESS) {\r
+                       free(p_reg);\r
+                       cl_spinlock_release(&p_disp->lock);\r
+                       return (NULL);\r
+               }\r
+       }\r
+\r
+       cl_spinlock_release(&p_disp->lock);\r
+\r
+       return (p_reg);\r
+}\r
+\r
+/********************************************************************\r
+ ********************************************************************/\r
+void cl_disp_unregister(IN const cl_disp_reg_handle_t handle)\r
+{\r
+       cl_disp_reg_info_t *p_reg;\r
+       cl_dispatcher_t *p_disp;\r
+\r
+       if (handle == CL_DISP_INVALID_HANDLE)\r
+               return;\r
+\r
+       p_reg = (cl_disp_reg_info_t *) handle;\r
+       p_disp = p_reg->p_disp;\r
+       CL_ASSERT(p_disp);\r
+\r
+       cl_spinlock_acquire(&p_disp->lock);\r
+       /*\r
+        * Clear the registrant vector entry.  This will cause any further\r
+        * post calls to fail.\r
+        */\r
+       if (p_reg->msg_id != CL_DISP_MSGID_NONE) {\r
+               CL_ASSERT(p_reg->msg_id <\r
+                         cl_ptr_vector_get_size(&p_disp->reg_vec));\r
+               cl_ptr_vector_set(&p_disp->reg_vec, p_reg->msg_id, NULL);\r
+       }\r
+       cl_spinlock_release(&p_disp->lock);\r
+\r
+       while (p_reg->ref_cnt > 0)\r
+               cl_thread_suspend(1);\r
+\r
+       cl_spinlock_acquire(&p_disp->lock);\r
+       /* Remove the registrant from the list. */\r
+       cl_qlist_remove_item(&p_disp->reg_list, (cl_list_item_t *) p_reg);\r
+       /* Return the registration info to the pool */\r
+       free(p_reg);\r
+\r
+       cl_spinlock_release(&p_disp->lock);\r
+}\r
+\r
+/********************************************************************\r
+ ********************************************************************/\r
+cl_status_t cl_disp_post(IN const cl_disp_reg_handle_t handle,\r
+                        IN const cl_disp_msgid_t msg_id,\r
+                        IN const void *const p_data,\r
+                        IN cl_pfn_msgdone_cb_t pfn_callback OPTIONAL,\r
+                        IN const void *const context OPTIONAL)\r
+{\r
+       cl_disp_reg_info_t *p_src_reg = (cl_disp_reg_info_t *) handle;\r
+       cl_disp_reg_info_t *p_dest_reg;\r
+       cl_dispatcher_t *p_disp;\r
+       cl_disp_msg_t *p_msg;\r
+\r
+       p_disp = handle->p_disp;\r
+       CL_ASSERT(p_disp);\r
+       CL_ASSERT(msg_id != CL_DISP_MSGID_NONE);\r
+\r
+       cl_spinlock_acquire(&p_disp->lock);\r
+       /* Check that the recipient exists. */\r
+       p_dest_reg = cl_ptr_vector_get(&p_disp->reg_vec, msg_id);\r
+       if (!p_dest_reg) {\r
+               cl_spinlock_release(&p_disp->lock);\r
+               return (CL_NOT_FOUND);\r
+       }\r
+\r
+       /* Get a free message from the pool. */\r
+       p_msg = (cl_disp_msg_t *) cl_qpool_get(&p_disp->msg_pool);\r
+       if (!p_msg) {\r
+               cl_spinlock_release(&p_disp->lock);\r
+               return (CL_INSUFFICIENT_MEMORY);\r
+       }\r
+\r
+       /* Initialize the message */\r
+       p_msg->p_src_reg = p_src_reg;\r
+       p_msg->p_dest_reg = p_dest_reg;\r
+       p_msg->p_data = p_data;\r
+       p_msg->pfn_xmt_callback = pfn_callback;\r
+       p_msg->context = context;\r
+       p_msg->in_time = cl_get_time_stamp();\r
+\r
+       /*\r
+        * Increment the sender's reference count if they request a completion\r
+        * notification.\r
+        */\r
+       if (pfn_callback)\r
+               cl_atomic_inc(&p_src_reg->ref_cnt);\r
+\r
+       /* Increment the recipient's reference count. */\r
+       cl_atomic_inc(&p_dest_reg->ref_cnt);\r
+\r
+       /* Queue the message in the FIFO. */\r
+       cl_qlist_insert_tail(&p_disp->msg_fifo, (cl_list_item_t *) p_msg);\r
+       cl_spinlock_release(&p_disp->lock);\r
+\r
+       /* Signal the thread pool that there is work to be done. */\r
+       cl_thread_pool_signal(&p_disp->worker_threads);\r
+       return (CL_SUCCESS);\r
+}\r
+\r
+void cl_disp_get_queue_status(IN const cl_disp_reg_handle_t handle,\r
+                             OUT uint32_t * p_num_queued_msgs,\r
+                             OUT uint64_t * p_last_msg_queue_time_ms)\r
+{\r
+       cl_dispatcher_t *p_disp = ((cl_disp_reg_info_t *) handle)->p_disp;\r
+\r
+       cl_spinlock_acquire(&p_disp->lock);\r
+\r
+       if (p_last_msg_queue_time_ms)\r
+               *p_last_msg_queue_time_ms =\r
+                   p_disp->last_msg_queue_time_us / 1000;\r
+\r
+       if (p_num_queued_msgs)\r
+               *p_num_queued_msgs = cl_qlist_count(&p_disp->msg_fifo);\r
+\r
+       cl_spinlock_release(&p_disp->lock);\r
+}\r
diff --git a/ulp/opensm/user/complib/cl_event_wheel.c b/ulp/opensm/user/complib/cl_event_wheel.c
new file mode 100644 (file)
index 0000000..03e27b3
--- /dev/null
@@ -0,0 +1,566 @@
+/*\r
+ * Copyright (c) 2004-2007 Voltaire, Inc. All rights reserved.\r
+ * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.\r
+ * Copyright (c) 1996-2003 Intel Corporation. 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 <math.h>\r
+#include <stdlib.h>\r
+#include <complib/cl_event_wheel.h>\r
+#include <complib/cl_debug.h>\r
+\r
+#define CL_DBG(fmt, ...)\r
+\r
+static cl_status_t __event_will_age_before(IN const cl_list_item_t *\r
+                                          const p_list_item, IN void *context)\r
+{\r
+       uint64_t aging_time = *((uint64_t *) context);\r
+       cl_event_wheel_reg_info_t *p_event;\r
+\r
+       p_event =\r
+           PARENT_STRUCT(p_list_item, cl_event_wheel_reg_info_t, list_item);\r
+\r
+       if (p_event->aging_time < aging_time)\r
+               return CL_SUCCESS;\r
+       else\r
+               return CL_NOT_FOUND;\r
+}\r
+\r
+static void __cl_event_wheel_callback(IN void *context)\r
+{\r
+       cl_event_wheel_t *p_event_wheel = (cl_event_wheel_t *) context;\r
+       cl_list_item_t *p_list_item, *p_prev_event_list_item;\r
+       cl_list_item_t *p_list_next_item;\r
+       cl_event_wheel_reg_info_t *p_event;\r
+       uint64_t current_time;\r
+       uint64_t next_aging_time;\r
+       uint32_t new_timeout;\r
+       cl_status_t cl_status;\r
+\r
+       /* might be during closing ...  */\r
+       if (p_event_wheel->closing)\r
+               return;\r
+\r
+       current_time = cl_get_time_stamp();\r
+\r
+       if (NULL != p_event_wheel->p_external_lock)\r
+\r
+               /* Take care of the order of acquiring locks to avoid the deadlock!\r
+                * The external lock goes first.\r
+                */\r
+               cl_spinlock_acquire(p_event_wheel->p_external_lock);\r
+\r
+       cl_spinlock_acquire(&p_event_wheel->lock);\r
+\r
+       p_list_item = cl_qlist_head(&p_event_wheel->events_wheel);\r
+       if (p_list_item == cl_qlist_end(&p_event_wheel->events_wheel))\r
+               /* the list is empty - nothing to do */\r
+               goto Exit;\r
+\r
+       /* we found such an item.  get the p_event */\r
+       p_event =\r
+           PARENT_STRUCT(p_list_item, cl_event_wheel_reg_info_t, list_item);\r
+\r
+       while (p_event->aging_time <= current_time) {\r
+               /* this object has aged - invoke it's callback */\r
+               if (p_event->pfn_aged_callback)\r
+                       next_aging_time =\r
+                           p_event->pfn_aged_callback(p_event->key,\r
+                                                      p_event->num_regs,\r
+                                                      p_event->context);\r
+               else\r
+                       next_aging_time = 0;\r
+\r
+               /* point to the next object in the wheel */\r
+               p_list_next_item = cl_qlist_next(p_list_item);\r
+\r
+               /* We need to retire the event if the next aging time passed */\r
+               if (next_aging_time < current_time) {\r
+                       /* remove it from the map */\r
+                       cl_qmap_remove_item(&p_event_wheel->events_map,\r
+                                           &(p_event->map_item));\r
+\r
+                       /* pop p_event from the wheel */\r
+                       cl_qlist_remove_head(&p_event_wheel->events_wheel);\r
+\r
+                       /* delete the event info object - allocated by cl_event_wheel_reg */\r
+                       free(p_event);\r
+               } else {\r
+                       /* update the required aging time */\r
+                       p_event->aging_time = next_aging_time;\r
+                       p_event->num_regs++;\r
+\r
+                       /* do not remove from the map  - but remove from the list head and\r
+                          place in the correct position */\r
+\r
+                       /* pop p_event from the wheel */\r
+                       cl_qlist_remove_head(&p_event_wheel->events_wheel);\r
+\r
+                       /* find the event that ages just before */\r
+                       p_prev_event_list_item =\r
+                           cl_qlist_find_from_tail(&p_event_wheel->\r
+                                                   events_wheel,\r
+                                                   __event_will_age_before,\r
+                                                   &p_event->aging_time);\r
+\r
+                       /* insert just after */\r
+                       cl_qlist_insert_next(&p_event_wheel->events_wheel,\r
+                                            p_prev_event_list_item,\r
+                                            &p_event->list_item);\r
+\r
+                       /* as we have modified the list - restart from first item: */\r
+                       p_list_next_item =\r
+                           cl_qlist_head(&p_event_wheel->events_wheel);\r
+               }\r
+\r
+               /* advance to next event */\r
+               p_list_item = p_list_next_item;\r
+               if (p_list_item == cl_qlist_end(&p_event_wheel->events_wheel))\r
+                       /* the list is empty - nothing to do */\r
+                       break;\r
+\r
+               /* get the p_event */\r
+               p_event =\r
+                   PARENT_STRUCT(p_list_item, cl_event_wheel_reg_info_t,\r
+                                 list_item);\r
+       }\r
+\r
+       /* We need to restart the timer only if the list is not empty now */\r
+       if (p_list_item != cl_qlist_end(&p_event_wheel->events_wheel)) {\r
+               /* get the p_event */\r
+               p_event =\r
+                   PARENT_STRUCT(p_list_item, cl_event_wheel_reg_info_t,\r
+                                 list_item);\r
+\r
+               /* start the timer to the timeout [msec] */\r
+               new_timeout =\r
+                   (uint32_t) (((p_event->aging_time - current_time) / 1000) +\r
+                               0.5);\r
+               CL_DBG("__cl_event_wheel_callback: Restart timer in: "\r
+                      "%u [msec]\n", new_timeout);\r
+               cl_status = cl_timer_start(&p_event_wheel->timer, new_timeout);\r
+               if (cl_status != CL_SUCCESS) {\r
+                       CL_DBG("__cl_event_wheel_callback : ERR 6100: "\r
+                              "Failed to start timer\n");\r
+               }\r
+       }\r
+\r
+       /* release the lock */\r
+Exit:\r
+       cl_spinlock_release(&p_event_wheel->lock);\r
+       if (NULL != p_event_wheel->p_external_lock)\r
+               cl_spinlock_release(p_event_wheel->p_external_lock);\r
+}\r
+\r
+/*\r
+ * Construct and Initialize\r
+ */\r
+void cl_event_wheel_construct(IN cl_event_wheel_t * const p_event_wheel)\r
+{\r
+       cl_spinlock_construct(&(p_event_wheel->lock));\r
+       cl_timer_construct(&(p_event_wheel->timer));\r
+}\r
+\r
+cl_status_t cl_event_wheel_init(IN cl_event_wheel_t * const p_event_wheel)\r
+{\r
+       cl_status_t cl_status = CL_SUCCESS;\r
+\r
+       /* initialize */\r
+       p_event_wheel->p_external_lock = NULL;\r
+       p_event_wheel->closing = FALSE;\r
+       cl_status = cl_spinlock_init(&(p_event_wheel->lock));\r
+       if (cl_status != CL_SUCCESS)\r
+               return cl_status;\r
+       cl_qlist_init(&p_event_wheel->events_wheel);\r
+       cl_qmap_init(&p_event_wheel->events_map);\r
+\r
+       /* init the timer with timeout */\r
+       cl_status = cl_timer_init(&p_event_wheel->timer, __cl_event_wheel_callback, p_event_wheel);     /* cb context */\r
+\r
+       return cl_status;\r
+}\r
+\r
+cl_status_t cl_event_wheel_init_ex(IN cl_event_wheel_t * const p_event_wheel,\r
+                                  IN cl_spinlock_t * p_external_lock)\r
+{\r
+       cl_status_t cl_status;\r
+\r
+       cl_status = cl_event_wheel_init(p_event_wheel);\r
+       if (CL_SUCCESS != cl_status)\r
+               return cl_status;\r
+\r
+       p_event_wheel->p_external_lock = p_external_lock;\r
+       return cl_status;\r
+}\r
+\r
+void cl_event_wheel_dump(IN cl_event_wheel_t * const p_event_wheel)\r
+{\r
+       cl_list_item_t *p_list_item;\r
+       cl_event_wheel_reg_info_t *p_event;\r
+\r
+       p_list_item = cl_qlist_head(&p_event_wheel->events_wheel);\r
+\r
+       while (p_list_item != cl_qlist_end(&p_event_wheel->events_wheel)) {\r
+               p_event =\r
+                   PARENT_STRUCT(p_list_item, cl_event_wheel_reg_info_t,\r
+                                 list_item);\r
+               CL_DBG("cl_event_wheel_dump: Found event key:<0x%"\r
+                      PRIx64 ">, aging time:%" PRIu64 "\n",\r
+                      p_event->key, p_event->aging_time);\r
+               p_list_item = cl_qlist_next(p_list_item);\r
+       }\r
+}\r
+\r
+void cl_event_wheel_destroy(IN cl_event_wheel_t * const p_event_wheel)\r
+{\r
+       cl_list_item_t *p_list_item;\r
+       cl_map_item_t *p_map_item;\r
+       cl_event_wheel_reg_info_t *p_event;\r
+\r
+       /* we need to get a lock */\r
+       cl_spinlock_acquire(&p_event_wheel->lock);\r
+\r
+       cl_event_wheel_dump(p_event_wheel);\r
+\r
+       /* go over all the items in the list and remove them */\r
+       p_list_item = cl_qlist_remove_head(&p_event_wheel->events_wheel);\r
+       while (p_list_item != cl_qlist_end(&p_event_wheel->events_wheel)) {\r
+               p_event =\r
+                   PARENT_STRUCT(p_list_item, cl_event_wheel_reg_info_t,\r
+                                 list_item);\r
+\r
+               CL_DBG("cl_event_wheel_destroy: Found outstanding event"\r
+                      " key:<0x%" PRIx64 ">\n", p_event->key);\r
+\r
+               /* remove it from the map */\r
+               p_map_item = &(p_event->map_item);\r
+               cl_qmap_remove_item(&p_event_wheel->events_map, p_map_item);\r
+               free(p_event);  /* allocated by cl_event_wheel_reg */\r
+               p_list_item =\r
+                   cl_qlist_remove_head(&p_event_wheel->events_wheel);\r
+       }\r
+\r
+       /* destroy the timer */\r
+       cl_timer_destroy(&p_event_wheel->timer);\r
+\r
+       /* destroy the lock (this should be done without releasing - we don't want\r
+          any other run to grab the lock at this point. */\r
+       cl_spinlock_release(&p_event_wheel->lock);\r
+       cl_spinlock_destroy(&(p_event_wheel->lock));\r
+}\r
+\r
+cl_status_t cl_event_wheel_reg(IN cl_event_wheel_t * const p_event_wheel,\r
+                              IN const uint64_t key,\r
+                              IN const uint64_t aging_time_usec,\r
+                              IN cl_pfn_event_aged_cb_t pfn_callback,\r
+                              IN void *const context)\r
+{\r
+       cl_event_wheel_reg_info_t *p_event;\r
+       uint64_t timeout;\r
+       uint32_t to;\r
+       cl_status_t cl_status = CL_SUCCESS;\r
+       cl_list_item_t *prev_event_list_item;\r
+       cl_map_item_t *p_map_item;\r
+\r
+       /* Get the lock on the manager */\r
+       cl_spinlock_acquire(&(p_event_wheel->lock));\r
+\r
+       cl_event_wheel_dump(p_event_wheel);\r
+\r
+       /* Make sure such a key does not exists */\r
+       p_map_item = cl_qmap_get(&p_event_wheel->events_map, key);\r
+       if (p_map_item != cl_qmap_end(&p_event_wheel->events_map)) {\r
+               CL_DBG("cl_event_wheel_reg: Already exists key:0x%"\r
+                      PRIx64 "\n", key);\r
+\r
+               /* already there - remove it from the list as it is getting a new time */\r
+               p_event =\r
+                   PARENT_STRUCT(p_map_item, cl_event_wheel_reg_info_t,\r
+                                 map_item);\r
+\r
+               /* remove the item from the qlist */\r
+               cl_qlist_remove_item(&p_event_wheel->events_wheel,\r
+                                    &p_event->list_item);\r
+               /* and the qmap */\r
+               cl_qmap_remove_item(&p_event_wheel->events_map,\r
+                                   &p_event->map_item);\r
+       } else {\r
+               /* make a new one */\r
+               p_event = (cl_event_wheel_reg_info_t *)\r
+                   malloc(sizeof(cl_event_wheel_reg_info_t));\r
+               p_event->num_regs = 0;\r
+       }\r
+\r
+       p_event->key = key;\r
+       p_event->aging_time = aging_time_usec;\r
+       p_event->pfn_aged_callback = pfn_callback;\r
+       p_event->context = context;\r
+       p_event->num_regs++;\r
+\r
+       CL_DBG("cl_event_wheel_reg: Registering event key:0x%" PRIx64\r
+              " aging in %u [msec]\n", p_event->key,\r
+              (uint32_t) ((p_event->aging_time - cl_get_time_stamp()) / 1000));\r
+\r
+       /* If the list is empty - need to start the timer */\r
+       if (cl_is_qlist_empty(&p_event_wheel->events_wheel)) {\r
+               /* Edward Bortnikov 03/29/2003\r
+                * ++TBD Consider moving the timer manipulation behind the list manipulation.\r
+                */\r
+\r
+               /* calculate the new timeout */\r
+               timeout =\r
+                   (p_event->aging_time - cl_get_time_stamp() + 500) / 1000;\r
+\r
+               /* stop the timer if it is running */\r
+\r
+               /* Edward Bortnikov 03/29/2003\r
+                * Don't call cl_timer_stop() because it spins forever.\r
+                * cl_timer_start() will invoke cl_timer_stop() by itself.\r
+                *\r
+                * The problematic scenario is when __cl_event_wheel_callback()\r
+                * is in race condition with this code. It sets timer.in_timer_cb\r
+                * to TRUE and then blocks on p_event_wheel->lock. Following this,\r
+                * the call to cl_timer_stop() hangs. Following this, the whole system\r
+                * enters into a deadlock.\r
+                *\r
+                * cl_timer_stop(&p_event_wheel->timer);\r
+                */\r
+\r
+               /* The timeout for the cl_timer_start should be given as uint32_t.\r
+                  if there is an overflow - warn about it. */\r
+               to = (uint32_t) timeout;\r
+               if (timeout > (uint32_t) timeout) {\r
+                       to = 0xffffffff;        /* max 32 bit timer */\r
+                       CL_DBG("cl_event_wheel_reg: timeout requested is "\r
+                              "too large. Using timeout: %u\n", to);\r
+               }\r
+\r
+               /* start the timer to the timeout [msec] */\r
+               cl_status = cl_timer_start(&p_event_wheel->timer, to);\r
+               if (cl_status != CL_SUCCESS) {\r
+                       CL_DBG("cl_event_wheel_reg : ERR 6103: "\r
+                              "Failed to start timer\n");\r
+                       goto Exit;\r
+               }\r
+       }\r
+\r
+       /* insert the object to the qlist and the qmap */\r
+\r
+       /* BUT WE MUST INSERT IT IN A SORTED MANNER */\r
+       prev_event_list_item =\r
+           cl_qlist_find_from_tail(&p_event_wheel->events_wheel,\r
+                                   __event_will_age_before,\r
+                                   &p_event->aging_time);\r
+\r
+       cl_qlist_insert_next(&p_event_wheel->events_wheel,\r
+                            prev_event_list_item, &p_event->list_item);\r
+\r
+       cl_qmap_insert(&p_event_wheel->events_map, key, &(p_event->map_item));\r
+\r
+Exit:\r
+       cl_spinlock_release(&p_event_wheel->lock);\r
+\r
+       return cl_status;\r
+}\r
+\r
+void cl_event_wheel_unreg(IN cl_event_wheel_t * const p_event_wheel,\r
+                         IN uint64_t key)\r
+{\r
+       cl_event_wheel_reg_info_t *p_event;\r
+       cl_map_item_t *p_map_item;\r
+\r
+       CL_DBG("cl_event_wheel_unreg: " "Removing key:0x%" PRIx64 "\n", key);\r
+\r
+       cl_spinlock_acquire(&p_event_wheel->lock);\r
+       p_map_item = cl_qmap_get(&p_event_wheel->events_map, key);\r
+       if (p_map_item != cl_qmap_end(&p_event_wheel->events_map)) {\r
+               /* we found such an item. */\r
+               p_event =\r
+                   PARENT_STRUCT(p_map_item, cl_event_wheel_reg_info_t,\r
+                                 map_item);\r
+\r
+               /* remove the item from the qlist */\r
+               cl_qlist_remove_item(&p_event_wheel->events_wheel,\r
+                                    &(p_event->list_item));\r
+               /* remove the item from the qmap */\r
+               cl_qmap_remove_item(&p_event_wheel->events_map,\r
+                                   &(p_event->map_item));\r
+\r
+               CL_DBG("cl_event_wheel_unreg: Removed key:0x%" PRIx64 "\n",\r
+                      key);\r
+\r
+               /* free the item */\r
+               free(p_event);\r
+       } else {\r
+               CL_DBG("cl_event_wheel_unreg: did not find key:0x%" PRIx64\r
+                      "\n", key);\r
+       }\r
+\r
+       cl_spinlock_release(&p_event_wheel->lock);\r
+}\r
+\r
+uint32_t cl_event_wheel_num_regs(IN cl_event_wheel_t * const p_event_wheel,\r
+                                IN uint64_t key)\r
+{\r
+\r
+       cl_event_wheel_reg_info_t *p_event;\r
+       cl_map_item_t *p_map_item;\r
+       uint32_t num_regs = 0;\r
+\r
+       /* try to find the key in the map */\r
+       CL_DBG("cl_event_wheel_num_regs: Looking for key:0x%" PRIx64 "\n", key);\r
+\r
+       cl_spinlock_acquire(&p_event_wheel->lock);\r
+       p_map_item = cl_qmap_get(&p_event_wheel->events_map, key);\r
+       if (p_map_item != cl_qmap_end(&p_event_wheel->events_map)) {\r
+               /* ok so we can simply return it's num_regs */\r
+               p_event =\r
+                   PARENT_STRUCT(p_map_item, cl_event_wheel_reg_info_t,\r
+                                 map_item);\r
+               num_regs = p_event->num_regs;\r
+       }\r
+\r
+       cl_spinlock_release(&p_event_wheel->lock);\r
+       return (num_regs);\r
+}\r
+\r
+#ifdef __CL_EVENT_WHEEL_TEST__\r
+\r
+/* Dump out the complete state of the event wheel */\r
+void __cl_event_wheel_dump(IN cl_event_wheel_t * const p_event_wheel)\r
+{\r
+       cl_list_item_t *p_list_item;\r
+       cl_map_item_t *p_map_item;\r
+       cl_event_wheel_reg_info_t *p_event;\r
+\r
+       printf("************** Event Wheel Dump ***********************\n");\r
+       printf("Event Wheel List has %u items:\n",\r
+              cl_qlist_count(&p_event_wheel->events_wheel));\r
+\r
+       p_list_item = cl_qlist_head(&p_event_wheel->events_wheel);\r
+       while (p_list_item != cl_qlist_end(&p_event_wheel->events_wheel)) {\r
+               p_event =\r
+                   PARENT_STRUCT(p_list_item, cl_event_wheel_reg_info_t,\r
+                                 list_item);\r
+               printf("Event key:0x%" PRIx64 " Context:%s NumRegs:%u\n",\r
+                      p_event->key, (char *)p_event->context,\r
+                      p_event->num_regs);\r
+\r
+               /* next */\r
+               p_list_item = cl_qlist_next(p_list_item);\r
+       }\r
+\r
+       printf("Event Map has %u items:\n",\r
+              cl_qmap_count(&p_event_wheel->events_map));\r
+\r
+       p_map_item = cl_qmap_head(&p_event_wheel->events_map);\r
+       while (p_map_item != cl_qmap_end(&p_event_wheel->events_map)) {\r
+               p_event =\r
+                   PARENT_STRUCT(p_map_item, cl_event_wheel_reg_info_t,\r
+                                 map_item);\r
+               printf("Event key:0x%" PRIx64 " Context:%s NumRegs:%u\n",\r
+                      p_event->key, (char *)p_event->context,\r
+                      p_event->num_regs);\r
+\r
+               /* next */\r
+               p_map_item = cl_qmap_next(p_map_item);\r
+       }\r
+\r
+}\r
+\r
+/* The callback for aging event */\r
+/* We assume we pass a text context */\r
+void __test_event_aging(uint64_t key, void *context)\r
+{\r
+       printf("*****************************************************\n");\r
+       printf("Aged key: 0x%" PRIx64 " Context:%s\n", key, (char *)context);\r
+}\r
+\r
+int main()\r
+{\r
+       cl_event_wheel_t event_wheel;\r
+       /*  uint64_t key; */\r
+\r
+       /* construct */\r
+       cl_event_wheel_construct(&event_wheel);\r
+\r
+       /* init */\r
+       cl_event_wheel_init(&event_wheel);\r
+\r
+       /* Start Playing */\r
+       cl_event_wheel_reg(&event_wheel, 1,     /*  key */\r
+                          cl_get_time_stamp() + 3000000,       /*  3 sec lifetime */\r
+                          __test_event_aging,  /*  cb */\r
+                          "The first Aging Event");\r
+\r
+       cl_event_wheel_reg(&event_wheel, 2,     /*  key */\r
+                          cl_get_time_stamp() + 3000000,       /*  3 sec lifetime */\r
+                          __test_event_aging,  /*  cb */\r
+                          "The Second Aging Event");\r
+\r
+       cl_event_wheel_reg(&event_wheel, 3,     /*  key */\r
+                          cl_get_time_stamp() + 3500000,       /*  3 sec lifetime */\r
+                          __test_event_aging,  /*  cb */\r
+                          "The Third Aging Event");\r
+\r
+       __cl_event_wheel_dump(&event_wheel);\r
+\r
+       sleep(2);\r
+       cl_event_wheel_reg(&event_wheel, 2,     /*  key */\r
+                          cl_get_time_stamp() + 8000000,       /*  3 sec lifetime */\r
+                          __test_event_aging,  /*  cb */\r
+                          "The Second Aging Event Moved");\r
+\r
+       __cl_event_wheel_dump(&event_wheel);\r
+\r
+       sleep(1);\r
+       /* remove the third event */\r
+       cl_event_wheel_unreg(&event_wheel, 3);  /*  key */\r
+\r
+       /* get the number of registrations for the keys */\r
+       printf("Event 1 Registered: %u\n",\r
+              cl_event_wheel_num_regs(&event_wheel, 1));\r
+       printf("Event 2 Registered: %u\n",\r
+              cl_event_wheel_num_regs(&event_wheel, 2));\r
+\r
+       sleep(5);\r
+       /* destroy */\r
+       cl_event_wheel_destroy(&event_wheel);\r
+\r
+       return (0);\r
+}\r
+\r
+#endif                         /* __CL_EVENT_WHEEL_TEST__ */\r
index 5d7c42d..946cad1 100644 (file)
 #ifndef _CONFIG_h_
 #define _CONFIG_h_
 
-#include <sys/stat.h>
-#include <stdio.h>
-#include <io.h>
-
-#define chmod(a,b) _chmod(a,b)
-#define S_IRUSR _S_IREAD
-#define S_IWUSR _S_IWRITE
-
-#define snprintf _snprintf
-#define fileno _fileno
-
-#define stat _stat
-#define fstat(a,b) fstat_alias((a),(b))
-
-inline int 
-fstat_alias(int filedes, struct _stat *buf)
-{
-    return _fstat(filedes, buf);
-}
+#include <opensm/osm_config.h>
+#include <vendor/winosm_common.h>
 
 #endif /*_CONFIG_h_ */
 
-
-
-
index d7822e5..e08ed5e 100644 (file)
@@ -1,7 +1,6 @@
-DIRS=\
-   libvendor \
-   libopensm \
-   opensm \
-   osmtest \
-   ibtrapgen
-
+DIRS=\\r
+   libvendor \\r
+   opensm \\r
+   osmtest \\r
+   ibtrapgen\r
+\r
index df4031c..e0706e0 100644 (file)
@@ -1,79 +1,78 @@
-OpenSM Partition Management
----------------------------
-
-Roadmap:
-Phase 1 - provide partition management at the EndPort (HCA, Router and Switch 
-          Port 0) level with no routing affects.
-Phase 2 - routing engine should take partitions into account.
-
-Phase 1 functionality:
-
-Supported Policy:
-
-1. EndPort partition groups are to be defined by listing the 
-   PortGUIDs as full and limited members.
-
-2. Each partition group might be assigned an explicit P_Key (only the 15 
-   LSB bits are valid) or the SM should assign it randomly. 
-
-3. A flag should control the generation of IPoIB broadcast group for
-   that partition. Extra optional MGIDs can be provided to be setup (on
-   top of the IPoIB broadcast group). 
-
-4. A global flag "Disconnect Unconfigured EndPorts": If TRUE prevents
-   EndPorts that are not explicitly defined as part of any partition
-   (thus "unconfigured") to communicate with any other EndPort. Otherwise, it
-   will let these EndPorts send packets to all other EndPorts.
-
-Functionality:
-
-1. The policy should be updated:
-   - during SM bringup
-   - after kill -HUP
-   - through SNMP (once it is supported)
-
-2. Partition tables will be updated on full sweep (new port/trap etc).
-   As a first step, the policy feasibility should be
-   verified. Feasibility could be limited by the EndPorts supports for
-   number of partitions, etc. Unrealizable policy should be reported
-   and extra rules ignored after providing error messages. 
-
-3. Each EndPort will be assigned P_Keys as follows:
-
-   a. Default partition group limited membership as defined by rule #4 below.
-     (only the SM port will get 0xffff).
-
-   b. P_Keys for all partition groups it is part of as defined in 
-      the policy.
-
-   c. P_Key update will preserve index for the existing P_Keys on the
-      port. If port has limited resources that will require reuse of,
-      on index a message will be provided and some of the settings will be
-      ommitted. P_Key indexes will not change under any circumstances.
-
-4. Each Switch Leaf Port (a switch port that is connected to an
-   EndPort) should be configured according to the same rules that
-   apply to the EndPort connected to that switch port. 
-   This actually enables unauthorized port isolation (with future
-   usage of M_Key and ProtectBits). 
-
-5. Policy entries matching a non EndPort will be flagged as
-   erroneous in the log file and ignored. 
-
-6. At the end of the P_Key setting phase, a check for successful
-   setting should be made.
-   Errors should be clearly logged and cause a new sweep. 
-   
-7. Each partition that is marked to support IPoIB should define a
-   broadcast MGRP. If the partition does not support IPoIB, it should 
-   define a dummy MGRP with parameters blocking IPoIB drivers from 
-   registering to it.
-
-Phase 2 functionality:
-
-The partition policy should be considered during the routing such that
-links are associated with particular partition or a set of
-partitions. Policy should be enhanced to provide hints for how to do
-that (correlating to QoS too). The exact algorithm is TBD. 
-
-
+OpenSM Partition Management\r
+---------------------------\r
+\r
+Roadmap:\r
+Phase 1 - provide partition management at the EndPort (HCA, Router and Switch\r
+          Port 0) level with no routing affects.\r
+Phase 2 - routing engine should take partitions into account.\r
+\r
+Phase 1 functionality:\r
+\r
+Supported Policy:\r
+\r
+1. EndPort partition groups are to be defined by listing the\r
+   PortGUIDs as full and limited members.\r
+\r
+2. Each partition group might be assigned an explicit P_Key (only the 15\r
+   LSB bits are valid) or the SM should assign it randomly.\r
+\r
+3. A flag should control the generation of IPoIB broadcast group for\r
+   that partition. Extra optional MGIDs can be provided to be setup (on\r
+   top of the IPoIB broadcast group).\r
+\r
+4. A global flag "Disconnect Unconfigured EndPorts": If TRUE prevents\r
+   EndPorts that are not explicitly defined as part of any partition\r
+   (thus "unconfigured") to communicate with any other EndPort. Otherwise, it\r
+   will let these EndPorts send packets to all other EndPorts.\r
+\r
+Functionality:\r
+\r
+1. The policy should be updated:\r
+   - during SM bringup\r
+   - after kill -HUP\r
+   - through SNMP (once it is supported)\r
+\r
+2. Partition tables will be updated on full sweep (new port/trap etc).\r
+   As a first step, the policy feasibility should be\r
+   verified. Feasibility could be limited by the EndPorts supports for\r
+   number of partitions, etc. Unrealizable policy should be reported\r
+   and extra rules ignored after providing error messages.\r
+\r
+3. Each EndPort will be assigned P_Keys as follows:\r
+\r
+   a. Default partition group limited membership as defined by rule #4 below.\r
+     (only the SM port will get 0xffff).\r
+\r
+   b. P_Keys for all partition groups it is part of as defined in\r
+      the policy.\r
+\r
+   c. P_Key update will preserve index for the existing P_Keys on the\r
+      port. If port has limited resources that will require reuse of,\r
+      on index a message will be provided and some of the settings will be\r
+      ommitted. P_Key indexes will not change under any circumstances.\r
+\r
+4. Each Switch Leaf Port (a switch port that is connected to an\r
+   EndPort) should be configured according to the same rules that\r
+   apply to the EndPort connected to that switch port.\r
+   This actually enables unauthorized port isolation (with future\r
+   usage of M_Key and ProtectBits).\r
+\r
+5. Policy entries matching a non EndPort will be flagged as\r
+   erroneous in the log file and ignored.\r
+\r
+6. At the end of the P_Key setting phase, a check for successful\r
+   setting should be made.\r
+   Errors should be clearly logged and cause a new sweep.\r
+\r
+7. Each partition that is marked to support IPoIB should define a\r
+   broadcast MGRP. If the partition does not support IPoIB, it should\r
+   define a dummy MGRP with parameters blocking IPoIB drivers from\r
+   registering to it.\r
+\r
+Phase 2 functionality:\r
+\r
+The partition policy should be considered during the routing such that\r
+links are associated with particular partition or a set of\r
+partitions. Policy should be enhanced to provide hints for how to do\r
+that (correlating to QoS too). The exact algorithm is TBD.\r
+\r
diff --git a/ulp/opensm/user/doc/OpenSM_RN.pdf b/ulp/opensm/user/doc/OpenSM_RN.pdf
new file mode 100644 (file)
index 0000000..700924f
Binary files /dev/null and b/ulp/opensm/user/doc/OpenSM_RN.pdf differ
diff --git a/ulp/opensm/user/doc/OpenSM_RN_0_3_1.pdf b/ulp/opensm/user/doc/OpenSM_RN_0_3_1.pdf
deleted file mode 100644 (file)
index 4eaacf8..0000000
Binary files a/ulp/opensm/user/doc/OpenSM_RN_0_3_1.pdf and /dev/null differ
diff --git a/ulp/opensm/user/doc/OpenSM_UM.pdf b/ulp/opensm/user/doc/OpenSM_UM.pdf
new file mode 100644 (file)
index 0000000..ae32826
Binary files /dev/null and b/ulp/opensm/user/doc/OpenSM_UM.pdf differ
diff --git a/ulp/opensm/user/doc/OpenSM_UM_0_3.pdf b/ulp/opensm/user/doc/OpenSM_UM_0_3.pdf
deleted file mode 100644 (file)
index 9951171..0000000
Binary files a/ulp/opensm/user/doc/OpenSM_UM_0_3.pdf and /dev/null differ
diff --git a/ulp/opensm/user/doc/QoS_management_in_OpenSM.txt b/ulp/opensm/user/doc/QoS_management_in_OpenSM.txt
new file mode 100644 (file)
index 0000000..fef8a62
--- /dev/null
@@ -0,0 +1,492 @@
+\r
+                    QoS Management in OpenSM\r
+\r
+==============================================================================\r
+ Table of contents\r
+==============================================================================\r
+\r
+1. Overview\r
+2. Full QoS Policy File\r
+3. Simplified QoS Policy Definition\r
+4. Policy File Syntax Guidelines\r
+5. Examples of Full Policy File\r
+6. Simplified QoS Policy - Details and Examples\r
+7. SL2VL Mapping and VL Arbitration\r
+\r
+\r
+==============================================================================\r
+ 1. Overview\r
+==============================================================================\r
+\r
+When QoS in OpenSM is enabled (-Q or --qos), OpenSM looks for QoS Policy file.\r
+The default name of OpenSM QoS policy file is\r
+/usr/local/etc/opensm/qos-policy.conf. The default may be changed by using -Y\r
+or --qos_policy_file option with OpenSM.\r
+\r
+During fabric initialization and at every heavy sweep OpenSM parses the QoS\r
+policy file, applies its settings to the discovered fabric elements, and\r
+enforces the provided policy on client requests. The overall flow for such\r
+requests is:\r
+ - The request is matched against the defined matching rules such that the\r
+   QoS Level definition is found.\r
+ - Given the QoS Level, path(s) search is performed with the given\r
+   restrictions imposed by that level.\r
+\r
+There are two ways to define QoS policy:\r
+ - Full policy, where the policy file syntax provides an administrator\r
+   various ways to match PathRecord/MultiPathRecord (PR/MPR) request and\r
+   enforce various QoS constraints on the requested PR/MPR\r
+ - Simplified QoS policy definition, where an administrator would be able to\r
+   match PR/MPR requests by various ULPs and applications running on top of\r
+   these ULPs.\r
+\r
+While the full policy syntax is very flexible, in many cases the simplified\r
+policy definition would be sufficient.\r
+\r
+\r
+==============================================================================\r
+ 2. Full QoS Policy File\r
+==============================================================================\r
+\r
+QoS policy file has the following sections:\r
+\r
+I) Port Groups (denoted by port-groups).\r
+This section defines zero or more port groups that can be referred later by\r
+matching rules (see below). Port group lists ports by:\r
+  - Port GUID\r
+  - Port name, which is a combination of NodeDescription and IB port number\r
+  - PKey, which means that all the ports in the subnet that belong to\r
+    partition with a given PKey belong to this port group\r
+  - Partition name, which means that all the ports in the subnet that belong\r
+    to partition with a given name belong to this port group\r
+  - Node type, where possible node types are: CA, SWITCH, ROUTER, ALL, and\r
+    SELF (SM's port).\r
+\r
+II) QoS Setup (denoted by qos-setup).\r
+This section describes how to set up SL2VL and VL Arbitration tables on\r
+various nodes in the fabric.\r
+However, this is not supported in OpenSM currently.\r
+SL2VL and VLArb tables should be configured in the OpenSM options file\r
+(default location - /usr/local/etc/opensm/opensm.conf).\r
+\r
+III) QoS Levels (denoted by qos-levels).\r
+Each QoS Level defines Service Level (SL) and a few optional fields:\r
+  - MTU limit\r
+  - Rate limit\r
+  - PKey\r
+  - Packet lifetime\r
+When path(s) search is performed, it is done with regards to restriction that\r
+these QoS Level parameters impose.\r
+One QoS level that is mandatory to define is a DEFAULT QoS level. It is\r
+applied to a PR/MPR query that does not match any existing match rule.\r
+Similar to any other QoS Level, it can also be explicitly referred by any\r
+match rule.\r
+\r
+IV) QoS Matching Rules (denoted by qos-match-rules).\r
+Each PathRecord/MultiPathRecord query that OpenSM receives is matched against\r
+the set of matching rules. Rules are scanned in order of appearance in the QoS\r
+policy file such as the first match takes precedence.\r
+Each rule has a name of QoS level that will be applied to the matching query.\r
+A default QoS level is applied to a query that did not match any rule.\r
+Queries can be matched by:\r
+ - Source port group (whether a source port is a member of a specified group)\r
+ - Destination port group (same as above, only for destination port)\r
+ - PKey\r
+ - QoS class\r
+ - Service ID\r
+To match a certain matching rule, PR/MPR query has to match ALL the rule's\r
+criteria. However, not all the fields of the PR/MPR query have to appear in\r
+the matching rule.\r
+For instance, if the rule has a single criterion - Service ID, it will match\r
+any query that has this Service ID, disregarding rest of the query fields.\r
+However, if a certain query has only Service ID (which means that this is the\r
+only bit in the PR/MPR component mask that is on), it will not match any rule\r
+that has other matching criteria besides Service ID.\r
+\r
+\r
+==============================================================================\r
+ 3. Simplified QoS Policy Definition\r
+==============================================================================\r
+\r
+Simplified QoS policy definition comprises of a single section denoted by\r
+qos-ulps. Similar to the full QoS policy, it has a list of match rules and\r
+their QoS Level, but in this case a match rule has only one criterion - its\r
+goal is to match a certain ULP (or a certain application on top of this ULP)\r
+PR/MPR request, and QoS Level has only one constraint - Service Level (SL).\r
+The simplified policy section may appear in the policy file in combine with\r
+the full policy, or as a stand-alone policy definition.\r
+See more details and list of match rule criteria below.\r
+\r
+\r
+==============================================================================\r
+ 4. Policy File Syntax Guidelines\r
+==============================================================================\r
+\r
+- Empty lines are ignored.\r
+- Leading and trailing blanks, as well as empty lines, are ignored, so\r
+  the indentation in the example is just for better readability.\r
+- Comments are started with the pound sign (#) and terminated by EOL.\r
+- Any keyword should be the first non-blank in the line, unless it's a\r
+  comment.\r
+- Keywords that denote section/subsection start have matching closing\r
+  keywords.\r
+- Having a QoS Level named "DEFAULT" is a must - it is applied to PR/MPR\r
+  requests that didn't match any of the matching rules.\r
+- Any section/subsection of the policy file is optional.\r
+\r
+\r
+==============================================================================\r
+ 5. Examples of Full Policy File\r
+==============================================================================\r
+\r
+As mentioned earlier, any section of the policy file is optional, and\r
+the only mandatory part of the policy file is a default QoS Level.\r
+Here's an example of the shortest policy file:\r
+\r
+    qos-levels\r
+        qos-level\r
+            name: DEFAULT\r
+            sl: 0\r
+        end-qos-level\r
+    end-qos-levels\r
+\r
+Port groups section is missing because there are no match rules, which means\r
+that port groups are not referred anywhere, and there is no need defining\r
+them. And since this policy file doesn't have any matching rules, PR/MPR query\r
+won't match any rule, and OpenSM will enforce default QoS level.\r
+Essentially, the above example is equivalent to not having QoS policy file\r
+at all.\r
+\r
+The following example shows all the possible options and keywords in the\r
+policy file and their syntax:\r
+\r
+    #\r
+    # See the comments in the following example.\r
+    # They explain different keywords and their meaning.\r
+    #\r
+    port-groups\r
+\r
+        port-group # using port GUIDs\r
+            name: Storage\r
+            # "use" is just a description that is used for logging\r
+            #  Other than that, it is just a comment\r
+            use: SRP Targets\r
+            port-guid: 0x10000000000001, 0x10000000000005-0x1000000000FFFA\r
+            port-guid: 0x1000000000FFFF\r
+        end-port-group\r
+\r
+        port-group\r
+            name: Virtual Servers\r
+            # The syntax of the port name is as follows:\r
+            #   "node_description/Pnum".\r
+            # node_description is compared to the NodeDescription of the node,\r
+            # and "Pnum" is a port number on that node.\r
+            port-name: vs1 HCA-1/P1, vs2 HCA-1/P1\r
+        end-port-group\r
+\r
+        # using partitions defined in the partition policy\r
+        port-group\r
+            name: Partitions\r
+            partition: Part1\r
+            pkey: 0x1234\r
+        end-port-group\r
+\r
+        # using node types: CA, ROUTER, SWITCH, SELF (for node that runs SM)\r
+        # or ALL (for all the nodes in the subnet)\r
+        port-group\r
+            name: CAs and SM\r
+            node-type: CA, SELF\r
+        end-port-group\r
+\r
+    end-port-groups\r
+\r
+    qos-setup\r
+        # This section of the policy file describes how to set up SL2VL and VL\r
+        # Arbitration tables on various nodes in the fabric.\r
+        # However, this is not supported in OpenSM currently - the section is\r
+        # parsed and ignored. SL2VL and VLArb tables should be configured in the\r
+        # OpenSM options file (by default - /usr/local/etc/opensm/opensm.conf).\r
+    end-qos-setup\r
+\r
+    qos-levels\r
+\r
+        # Having a QoS Level named "DEFAULT" is a must - it is applied to\r
+        # PR/MPR requests that didn't match any of the matching rules.\r
+        qos-level\r
+            name: DEFAULT\r
+            use: default QoS Level\r
+            sl: 0\r
+        end-qos-level\r
+\r
+        # the whole set: SL, MTU-Limit, Rate-Limit, PKey, Packet Lifetime\r
+        qos-level\r
+            name: WholeSet\r
+            sl: 1\r
+            mtu-limit: 4\r
+            rate-limit: 5\r
+            pkey: 0x1234\r
+            packet-life: 8\r
+        end-qos-level\r
+\r
+    end-qos-levels\r
+\r
+    # Match rules are scanned in order of their apperance in the policy file.\r
+    # First matched rule takes precedence.\r
+    qos-match-rules\r
+\r
+        # matching by single criteria: QoS class\r
+        qos-match-rule\r
+            use: by QoS class\r
+            qos-class: 7-9,11\r
+            # Name of qos-level to apply to the matching PR/MPR\r
+            qos-level-name: WholeSet\r
+        end-qos-match-rule\r
+\r
+        # show matching by destination group and service id\r
+        qos-match-rule\r
+            use: Storage targets\r
+            destination: Storage\r
+            service-id: 0x10000000000001, 0x10000000000008-0x10000000000FFF\r
+            qos-level-name: WholeSet\r
+        end-qos-match-rule\r
+\r
+        qos-match-rule\r
+            source: Storage\r
+            use: match by source group only\r
+            qos-level-name: DEFAULT\r
+        end-qos-match-rule\r
+\r
+        qos-match-rule\r
+            use: match by all parameters\r
+            qos-class: 7-9,11\r
+            source: Virtual Servers\r
+            destination: Storage\r
+            service-id: 0x0000000000010000-0x000000000001FFFF\r
+            pkey: 0x0F00-0x0FFF\r
+            qos-level-name: WholeSet\r
+        end-qos-match-rule\r
+\r
+    end-qos-match-rules\r
+\r
+\r
+==============================================================================\r
+ 6. Simplified QoS Policy - Details and Examples\r
+==============================================================================\r
+\r
+Simplified QoS policy match rules are tailored for matching ULPs (or some\r
+application on top of a ULP) PR/MPR requests. This section has a list of\r
+per-ULP (or per-application) match rules and the SL that should be enforced\r
+on the matched PR/MPR query.\r
+\r
+Match rules include:\r
+ - Default match rule that is applied to PR/MPR query that didn't match any\r
+   of the other match rules\r
+ - SDP\r
+ - SDP application with a specific target TCP/IP port range\r
+ - SRP with a specific target IB port GUID\r
+ - RDS\r
+ - iSER\r
+ - iSER application with a specific target TCP/IP port range\r
+ - IPoIB with a default PKey\r
+ - IPoIB with a specific PKey\r
+ - any ULP/application with a specific Service ID in the PR/MPR query\r
+ - any ULP/application with a specific PKey in the PR/MPR query\r
+ - any ULP/application with a specific target IB port GUID in the PR/MPR query\r
+\r
+Since any section of the policy file is optional, as long as basic rules of\r
+the file are kept (such as no referring to nonexisting port group, having\r
+default QoS Level, etc), the simplified policy section (qos-ulps) can serve\r
+as a complete QoS policy file.\r
+The shortest policy file in this case would be as follows:\r
+\r
+    qos-ulps\r
+        default  : 0 #default SL\r
+    end-qos-ulps\r
+\r
+It is equivalent to the previous example of the shortest policy file, and it\r
+is also equivalent to not having policy file at all.\r
+\r
+Below is an example of simplified QoS policy with all the possible keywords:\r
+\r
+    qos-ulps\r
+        default                       : 0 # default SL\r
+        sdp, port-num 30000           : 0 # SL for application running on top\r
+                                          # of SDP when a destination\r
+                                          # TCP/IPport is 30000\r
+        sdp, port-num 10000-20000     : 0\r
+        sdp                           : 1 # default SL for any other\r
+                                          # application running on top of SDP\r
+        rds                           : 2 # SL for RDS traffic\r
+        iser, port-num 900            : 0 # SL for iSER with a specific target\r
+                                          # port\r
+        iser                          : 3 # default SL for iSER\r
+        ipoib, pkey 0x0001            : 0 # SL for IPoIB on partition with\r
+                                          # pkey 0x0001\r
+        ipoib                         : 4 # default IPoIB partition,\r
+                                          # pkey=0x7FFF\r
+        any, service-id 0x6234        : 6 # match any PR/MPR query with a\r
+                                          # specific Service ID\r
+        any, pkey 0x0ABC              : 6 # match any PR/MPR query with a\r
+                                          # specific PKey\r
+        srp, target-port-guid 0x1234  : 5 # SRP when SRP Target is located on\r
+                                          # a specified IB port GUID\r
+        any, target-port-guid 0x0ABC-0xFFFFF : 6 # match any PR/MPR query with\r
+                                          # a specific target port GUID\r
+    end-qos-ulps\r
+\r
+\r
+Similar to the full policy definition, matching of PR/MPR queries is done in\r
+order of appearance in the QoS policy file such as the first match takes\r
+precedence, except for the "default" rule, which is applied only if the query\r
+didn't match any other rule.\r
+\r
+All other sections of the QoS policy file take precedence over the qos-ulps\r
+section. That is, if a policy file has both qos-match-rules and qos-ulps\r
+sections, then any query is matched first against the rules in the\r
+qos-match-rules section, and only if there was no match, the query is matched\r
+against the rules in qos-ulps section.\r
+\r
+Note that some of these match rules may overlap, so in order to use the\r
+simplified QoS definition effectively, it is important to understand how each\r
+of the ULPs is matched:\r
+\r
+6.1  IPoIB\r
+IPoIB query is matched by PKey. Default PKey for IPoIB partition is 0x7fff, so\r
+the following three match rules are equivalent:\r
+\r
+    ipoib              : <SL>\r
+    ipoib, pkey 0x7fff : <SL>\r
+    any,   pkey 0x7fff : <SL>\r
+\r
+6.2  SDP\r
+SDP PR query is matched by Service ID. The Service-ID for SDP is\r
+0x000000000001PPPP, where PPPP are 4 hex digits holding the remote TCP/IP Port\r
+Number to connect to. The following two match rules are equivalent:\r
+\r
+    sdp                                                   : <SL>\r
+    any, service-id 0x0000000000010000-0x000000000001ffff : <SL>\r
+\r
+6.3  RDS\r
+Similar to SDP, RDS PR query is matched by Service ID. The Service ID for RDS\r
+is 0x000000000106PPPP, where PPPP are 4 hex digits holding the remote TCP/IP\r
+Port Number to connect to. Default port number for RDS is 0x48CA, which makes\r
+a default Service-ID 0x00000000010648CA. The following two match rules are\r
+equivalent:\r
+\r
+    rds                                : <SL>\r
+    any, service-id 0x00000000010648CA : <SL>\r
+\r
+6.4  iSER\r
+Similar to RDS, iSER query is matched by Service ID, where the the Service ID\r
+is also 0x000000000106PPPP. Default port number for iSER is 0x0CBC, which makes\r
+a default Service-ID 0x0000000001060CBC. The following two match rules are\r
+equivalent:\r
+\r
+    iser                               : <SL>\r
+    any, service-id 0x0000000001060CBC : <SL>\r
+\r
+6.5  SRP\r
+Service ID for SRP varies from storage vendor to vendor, thus SRP query is\r
+matched by the target IB port GUID. The following two match rules are\r
+equivalent:\r
+\r
+    srp, target-port-guid 0x1234  : <SL>\r
+    any, target-port-guid 0x1234  : <SL>\r
+\r
+Note that any of the above ULPs might contain target port GUID in the PR\r
+query, so in order for these queries not to be recognized by the QoS manager\r
+as SRP, the SRP match rule (or any match rule that refers to the target port\r
+guid only) should be placed at the end of the qos-ulps match rules.\r
+\r
+6.6  MPI\r
+SL for MPI is manually configured by MPI admin. OpenSM is not forcing any SL\r
+on the MPI traffic, and that's why it is the only ULP that did not appear in\r
+the qos-ulps section.\r
+\r
+\r
+==============================================================================\r
+ 7. SL2VL Mapping and VL Arbitration\r
+==============================================================================\r
+\r
+OpenSM cached options file has a set of QoS related configuration parameters,\r
+that are used to configure SL2VL mapping and VL arbitration on IB ports.\r
+These parameters are:\r
+ - Max VLs: the maximum number of VLs that will be on the subnet.\r
+ - High limit: the limit of High Priority component of VL Arbitration\r
+   table (IBA 7.6.9).\r
+ - VLArb low table: Low priority VL Arbitration table (IBA 7.6.9) template.\r
+ - VLArb high table: High priority VL Arbitration table (IBA 7.6.9) template.\r
+ - SL2VL: SL2VL Mapping table (IBA 7.6.6) template. It is a list of VLs\r
+   corresponding to SLs 0-15 (Note that VL15 used here means drop this SL).\r
+\r
+There are separate QoS configuration parameters sets for various target types:\r
+CAs, routers, switch external ports, and switch's enhanced port 0. The names\r
+of such parameters are prefixed by "qos_<type>_" string. Here is a full list\r
+of the currently supported sets:\r
+\r
+    qos_ca_  - QoS configuration parameters set for CAs.\r
+    qos_rtr_ - parameters set for routers.\r
+    qos_sw0_ - parameters set for switches' port 0.\r
+    qos_swe_ - parameters set for switches' external ports.\r
+\r
+Here's the example of typical default values for CAs and switches' external\r
+ports (hard-coded in OpenSM initialization):\r
+\r
+    qos_ca_max_vls 15\r
+    qos_ca_high_limit 0\r
+    qos_ca_vlarb_high 0:4,1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0\r
+    qos_ca_vlarb_low 0:0,1:4,2:4,3:4,4:4,5:4,6:4,7:4,8:4,9:4,10:4,11:4,12:4,13:4,14:4\r
+    qos_ca_sl2vl 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7\r
+\r
+    qos_swe_max_vls 15\r
+    qos_swe_high_limit 0\r
+    qos_swe_vlarb_high 0:4,1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0\r
+    qos_swe_vlarb_low 0:0,1:4,2:4,3:4,4:4,5:4,6:4,7:4,8:4,9:4,10:4,11:4,12:4,13:4,14:4\r
+    qos_swe_sl2vl 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7\r
+\r
+VL arbitration tables (both high and low) are lists of VL/Weight pairs.\r
+Each list entry contains a VL number (values from 0-14), and a weighting value\r
+(values 0-255), indicating the number of 64 byte units (credits) which may be\r
+transmitted from that VL when its turn in the arbitration occurs. A weight\r
+of 0 indicates that this entry should be skipped. If a list entry is\r
+programmed for VL15 or for a VL that is not supported or is not currently\r
+configured by the port, the port may either skip that entry or send from any\r
+supported VL for that entry.\r
+\r
+Note, that the same VLs may be listed multiple times in the High or Low\r
+priority arbitration tables, and, further, it can be listed in both tables.\r
+\r
+The limit of high-priority VLArb table (qos_<type>_high_limit) indicates the\r
+number of high-priority packets that can be transmitted without an opportunity\r
+to send a low-priority packet. Specifically, the number of bytes that can be\r
+sent is high_limit times 4K bytes.\r
+\r
+A high_limit value of 255 indicates that the byte limit is unbounded.\r
+Note: if the 255 value is used, the low priority VLs may be starved.\r
+A value of 0 indicates that only a single packet from the high-priority table\r
+may be sent before an opportunity is given to the low-priority table.\r
+\r
+Keep in mind that ports usually transmit packets of size equal to MTU.\r
+For instance, for 4KB MTU a single packet will require 64 credits, so in order\r
+to achieve effective VL arbitration for packets of 4KB MTU, the weighting\r
+values for each VL should be multiples of 64.\r
+\r
+Below is an example of SL2VL and VL Arbitration configuration on subnet:\r
+\r
+    qos_ca_max_vls 15\r
+    qos_ca_high_limit 6\r
+    qos_ca_vlarb_high 0:4\r
+    qos_ca_vlarb_low 0:0,1:64,2:128,3:192,4:0,5:64,6:64,7:64\r
+    qos_ca_sl2vl 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7\r
+\r
+    qos_swe_max_vls 15\r
+    qos_swe_high_limit 6\r
+    qos_swe_vlarb_high 0:4\r
+    qos_swe_vlarb_low 0:0,1:64,2:128,3:192,4:0,5:64,6:64,7:64\r
+    qos_swe_sl2vl 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7\r
+\r
+In this example, there are 8 VLs configured on subnet: VL0 to VL7. VL0 is\r
+defined as a high priority VL, and it is limited to 6 x 4KB = 24KB in a single\r
+transmission burst. Such configuration would suilt VL that needs low latency\r
+and uses small MTU when transmitting packets. Rest of VLs are defined as low\r
+priority VLs with different weights, while VL4 is effectively turned off.\r
index 3cc6f99..b767518 100644 (file)
-Current OpenSM Routing
-1/2/07
-
-OpenSM offers three routing engines:
-
-1.  Min Hop Algorithm - based on the minimum hops to each node where the 
-path length is optimized.
-
-2.  UPDN Unicast routing algorithm - also based on the minimum hops to each 
-node, but it is constrained to ranking rules. This algorithm should be chosen 
-if the subnet is not a pure Fat Tree, and deadlock may occur due to a 
-loop in the subnet.
-
-3.  Fat-tree Unicast routing algorithm - this algorithm optimizes routing
-of fat-trees for congestion-free "shift" communication pattern. 
-It should be chosen if a subnet is a symmetrical fat-tree. 
-Similar to UPDN routing, Fat-tree routing is credit-loop-free.
-
-OpenSM now also offers a file method which can load routes from a table. See 
-modular-routing.txt for more information on this.
-
-The basic routing algorithm is comprised of two stages:
-1. MinHop matrix calculation
-   How many hops are required to get from each port to each LID ?
-   The algorithm to fill these tables is different if you run standard
-(min hop) or Up/Down.
-   For standard routing, a "relaxation" algorithm is used to propagate
-min hop from every destination LID through neighbor switches
-   For Up/Down routing, a BFS from every target is used. The BFS tracks link
-direction (up or down) and avoid steps that will perform up after a down
-step was used.
-
-2. Once MinHop matrices exist, each switch is visited and for each target LID a
-decision is made as to what port should be used to get to that LID.
-   This step is common to standard and Up/Down routing. Each port has a
-counter counting the number of target LIDs going through it.
-   When there are multiple alternative ports with same MinHop to a LID,
-the one with less previously assigned ports is selected. 
-   If LMC > 0, more checks are added: Within each group of LIDs assigned to 
-same target port, 
-   a. use only ports which have same MinHop 
-   b. first prefer the ones that go to different systemImageGuid (then
-the previous LID of the same LMC group)
-   c. if none - prefer those which go through another NodeGuid
-   d. fall back to the number of paths method (if all go to same node).
-
-
-Effect of Topology Changes
-
-OpenSM will preserve existing routing in any case where there is no change in
-the fabric switches unless the -r (--reassign_lids) option is specified.
-
--r
---reassign_lids
-          This option causes OpenSM to reassign LIDs to all
-          end nodes. Specifying -r on a running subnet
-          may disrupt subnet traffic.
-          Without -r, OpenSM attempts to preserve existing
-          LID assignments resolving multiple use of same LID.
-
-If a link is added or removed, OpenSM does not recalculate
-the routes that do not have to change. A route has to change 
-if the port is no longer UP or no longer the MinHop. When routing changes 
-are performed, the same algorithm for balancing the routes is invoked.
-
-In the case of using the file based routing, any topology changes are
-currently ignored The 'file' routing engine just loads the LFTs from the file 
-specified, with no reaction to real topology. Obviously, this will not be able 
-to recheck LIDs (by GUID) for disconnected nodes, and LFTs for non-existent 
-switches will be skipped. Multicast is not affected by 'file' routing engine 
-(this uses min hop tables).
-
-
-Min Hop Algorithm
------------------
-
-The Min Hop algorithm is invoked when neither UPDN or the file method are
-specified.
-The Min Hop algorithm is divided into two stages: computation of
-min-hop tables on every switch and LFT output port assignment. Link
-subscription is also equalized with the ability to override based on
-port GUID. The latter is supplied by:
-
--i <equalize-ignore-guids-file>
--ignore-guids <equalize-ignore-guids-file>
-          This option provides the means to define a set of ports
-          (by guids) that will be ignored by the link load
-          equalization algorithm.
-
-LMC awareness routes based on (remote) system or switch basis.
-
-
-UPDN Routing Algorithm
-----------------------
-
-Purpose of UPDN Algorithm
-
-The UPDN algorithm is designed to prevent deadlocks from occurring in loops 
-of the subnet. A loop-deadlock is a situation in which it is no longer 
-possible to send data between any two hosts connected through the loop. As 
-such, the UPDN routing algorithm should be used if the subnet is not a pure 
-Fat Tree, and one of its loops may experience a deadlock (due, for example, 
-to high pressure).
-
-The UPDN algorithm is based on the following main stages:
-
-1.  Auto-detect root nodes - based on the CA hop length from any switch in 
-the subnet, a statistical histogram is built for each switch (hop num vs 
-number of occurrences). If the histogram reflects a specific column (higher
-than others) for a certain node, then it is marked as a root node. Since 
-the algorithm is statistical, it may not find any root nodes. The list of 
-the root nodes found by this auto-detect stage is used by the ranking 
-process stage.
-
-    Note 1: The user can override the node list manually.
-    Note 2: If this stage cannot find any root nodes, and the user did not 
-            specify a guid list file, OpenSM defaults back to the Min Hop 
-            routing algorithm.
-
-2.  Ranking process - All root switch nodes (found in stage 1) are assigned 
-a rank of 0. Using the BFS algorithm, the rest of the switch nodes in the 
-subnet are ranked incrementally. This ranking aids in the process of enforcing 
-rules that ensure loop-free paths.
-
-3.  Min Hop Table setting - after ranking is done, a BFS algorithm is run from 
-each (CA or switch) node in the subnet. During the BFS process, the FDB table 
-of each switch node traversed by BFS is updated, in reference to the starting 
-node, based on the ranking rules and guid values.
-
-At the end of the process, the updated FDB tables ensure loop-free paths 
-through the subnet.
-
-
-UPDN Algorithm Usage
-
-Activation through OpenSM
-
-Use '-R updn' option (instead of old '-u') to activate the UPDN algorithm.
-Use `-a <guid_list_file>' for adding an UPDN guid file that contains the 
-root nodes for ranking.
-If the `-a' option is not used, OpenSM uses its auto-detect root nodes 
-algorithm.
-
-Notes on the guid list file:
-1.   A valid guid file specifies one guid in each line. Lines with an invalid 
-format will be discarded.
-2.   The user should specify the root switch guids. However, it is also 
-possible to specify CA guids; OpenSM will use the guid of the switch (if 
-it exists) that connects the CA to the subnet as a root node.
-
-
-To learn more about deadlock-free routing, see the article 
-"Deadlock Free Message Routing in Multiprocessor Interconnection Networks" 
-by William J Dally and Charles L Seitz (1985).
-
-
-Fat-tree Routing Algorithm
---------------------------
-
-Purpose:
-
-The fat-tree algorithm optimizes routing for "shift" communication pattern. 
-It should be chosen if a subnet is a symmetrical fat-tree of various types.
-It supports not just K-ary-N-Trees, by handling for non-constant K, 
-cases where not all leafs (CAs) are present, any CBB ratio.
-As in UPDN, fat-tree also prevents credit-loop-deadlocks.
-Fat-tree algorithm supports topologies that comply with the following rules:
-  - Tree rank should be between two and eight (inclusively)
-  - Switches of the same rank should have the same number
-    of UP-going port groups*, unless they are root switches,
-    in which case the shouldn't have UP-going ports at all.
-  - Switches of the same rank should have the same number
-    of DOWN-going port groups, unless they are leaf switches.
-  - Switches of the same rank should have the same number
-    of ports in each UP-going port group.
-  - Switches of the same rank should have the same number
-    of ports in each DOWN-going port group.
-*ports that are connected to the same remote switch are referenced as
-'port group'. 
-
-Note that although fat-tree algorithm supports trees with non-integer CBB 
-ratio, the routing will not be as balanced as in case of integer CBB ratio.
-In addition to this, although the algorithm allows leaf switches to have any 
-number of CAs, the closer the tree is to be fully populated, the more effective
-the "shift" communication pattern will be.
-
-The algorithm also dumps CA ordering file (osm-ftree-ca-order.dump) in the
-same directory where the OpenSM log resides. This ordering file provides the 
-CA order that may be used to create efficient communication pattern, that
-will match the routing tables.
-
-
-Usage:
-
-Activation through OpenSM
-
-Use '-R ftree' option to activate the fat-tree algorithm.
-
-Note: LMC > 0 is not supported by fat-tree routing. If this is
-specified, the default routing algorithm is invoked instead.
-
+Current OpenSM Routing\r
+7/9/07\r
+\r
+OpenSM offers five routing engines:\r
+\r
+1.  Min Hop Algorithm - based on the minimum hops to each node where the\r
+path length is optimized.\r
+\r
+2.  UPDN Unicast routing algorithm - also based on the minimum hops to each\r
+node, but it is constrained to ranking rules. This algorithm should be chosen\r
+if the subnet is not a pure Fat Tree, and deadlock may occur due to a\r
+loop in the subnet.\r
+\r
+3.  Fat-tree Unicast routing algorithm - this algorithm optimizes routing\r
+of fat-trees for congestion-free "shift" communication pattern.\r
+It should be chosen if a subnet is a symmetrical fat-tree.\r
+Similar to UPDN routing, Fat-tree routing is credit-loop-free.\r
+\r
+4. LASH unicast routing algorithm - uses Infiniband virtual layers\r
+(SL) to provide deadlock-free shortest-path routing while also\r
+distributing the paths between layers. LASH is an alternative\r
+deadlock-free topology-agnostic routing algorithm to the non-minimal\r
+UPDN algorithm avoiding the use of a potentially congested root node.\r
+\r
+5. DOR Unicast routing algorithm - based on the Min Hop algorithm, but\r
+avoids port equalization except for redundant links between the same\r
+two switches.  This provides deadlock free routes for hypercubes when\r
+the fabric is cabled as a hypercube and for meshes when cabled as a\r
+mesh (see details below).\r
+\r
+OpenSM provides an optional unicast routing cache (enabled by -A or\r
+--ucast_cache options). When enabled, unicast routing cache prevents\r
+routing recalculation (which is a heavy task in a large cluster) when\r
+there was no topology change detected during the heavy sweep, or when\r
+the topology change does not require new routing calculation, e.g. when\r
+one or more CAs/RTRs/leaf switches going down, or one or more of these\r
+nodes coming back after being down.\r
+A very common case that is handled by the unicast routing cache is host\r
+reboot, which otherwise would cause two full routing recalculations: one\r
+when the host goes down, and the other when the host comes back online.\r
+\r
+OpenSM also supports a file method which can load routes from a table. See\r
+modular-routing.txt for more information on this.\r
+\r
+The basic routing algorithm is comprised of two stages:\r
+1. MinHop matrix calculation\r
+   How many hops are required to get from each port to each LID ?\r
+   The algorithm to fill these tables is different if you run standard\r
+(min hop) or Up/Down.\r
+   For standard routing, a "relaxation" algorithm is used to propagate\r
+min hop from every destination LID through neighbor switches\r
+   For Up/Down routing, a BFS from every target is used. The BFS tracks link\r
+direction (up or down) and avoid steps that will perform up after a down\r
+step was used.\r
+\r
+2. Once MinHop matrices exist, each switch is visited and for each target LID,\r
+a decision is made as to what port should be used to get to that LID.\r
+   This step is common to standard and Up/Down routing. Each port has a\r
+counter counting the number of target LIDs going through it.\r
+   When there are multiple alternative ports with same MinHop to a LID,\r
+the one with less previously assigned ports is selected.\r
+   If LMC > 0, more checks are added: Within each group of LIDs assigned to\r
+same target port,\r
+   a. use only ports which have same MinHop\r
+   b. first prefer the ones that go to different systemImageGuid (then\r
+the previous LID of the same LMC group)\r
+   c. if none - prefer those which go through another NodeGuid\r
+   d. fall back to the number of paths method (if all go to same node).\r
+\r
+\r
+Effect of Topology Changes\r
+\r
+OpenSM will preserve existing routing in any case where there is no change in\r
+the fabric switches unless the -r (--reassign_lids) option is specified.\r
+\r
+-r\r
+--reassign_lids\r
+          This option causes OpenSM to reassign LIDs to all\r
+          end nodes. Specifying -r on a running subnet\r
+          may disrupt subnet traffic.\r
+          Without -r, OpenSM attempts to preserve existing\r
+          LID assignments resolving multiple use of same LID.\r
+\r
+If a link is added or removed, OpenSM does not recalculate\r
+the routes that do not have to change. A route has to change\r
+if the port is no longer UP or no longer the MinHop. When routing changes\r
+are performed, the same algorithm for balancing the routes is invoked.\r
+\r
+In the case of using the file based routing, any topology changes are\r
+currently ignored The 'file' routing engine just loads the LFTs from the file\r
+specified, with no reaction to real topology. Obviously, this will not be able\r
+to recheck LIDs (by GUID) for disconnected nodes, and LFTs for non-existent\r
+switches will be skipped. Multicast is not affected by 'file' routing engine\r
+(this uses min hop tables).\r
+\r
+\r
+Min Hop Algorithm\r
+-----------------\r
+\r
+The Min Hop algorithm is invoked by default if no routing algorithm is\r
+specified.  It can also be invoked by specifying '-R minhop'.\r
+\r
+The Min Hop algorithm is divided into two stages: computation of\r
+min-hop tables on every switch and LFT output port assignment. Link\r
+subscription is also equalized with the ability to override based on\r
+port GUID. The latter is supplied by:\r
+\r
+-i <equalize-ignore-guids-file>\r
+-ignore-guids <equalize-ignore-guids-file>\r
+          This option provides the means to define a set of ports\r
+          (by guids) that will be ignored by the link load\r
+          equalization algorithm.\r
+\r
+LMC awareness routes based on (remote) system or switch basis.\r
+\r
+\r
+UPDN Routing Algorithm\r
+----------------------\r
+\r
+Purpose of UPDN Algorithm\r
+\r
+The UPDN algorithm is designed to prevent deadlocks from occurring in loops\r
+of the subnet. A loop-deadlock is a situation in which it is no longer\r
+possible to send data between any two hosts connected through the loop. As\r
+such, the UPDN routing algorithm should be used if the subnet is not a pure\r
+Fat Tree, and one of its loops may experience a deadlock (due, for example,\r
+to high pressure).\r
+\r
+The UPDN algorithm is based on the following main stages:\r
+\r
+1.  Auto-detect root nodes - based on the CA hop length from any switch in\r
+the subnet, a statistical histogram is built for each switch (hop num vs\r
+number of occurrences). If the histogram reflects a specific column (higher\r
+than others) for a certain node, then it is marked as a root node. Since\r
+the algorithm is statistical, it may not find any root nodes. The list of\r
+the root nodes found by this auto-detect stage is used by the ranking\r
+process stage.\r
+\r
+    Note 1: The user can override the node list manually.\r
+    Note 2: If this stage cannot find any root nodes, and the user did not\r
+            specify a guid list file, OpenSM defaults back to the Min Hop\r
+            routing algorithm.\r
+\r
+2.  Ranking process - All root switch nodes (found in stage 1) are assigned\r
+a rank of 0. Using the BFS algorithm, the rest of the switch nodes in the\r
+subnet are ranked incrementally. This ranking aids in the process of enforcing\r
+rules that ensure loop-free paths.\r
+\r
+3.  Min Hop Table setting - after ranking is done, a BFS algorithm is run from\r
+each (CA or switch) node in the subnet. During the BFS process, the FDB table\r
+of each switch node traversed by BFS is updated, in reference to the starting\r
+node, based on the ranking rules and guid values.\r
+\r
+At the end of the process, the updated FDB tables ensure loop-free paths\r
+through the subnet.\r
+\r
+Note: Up/Down routing does not allow LID routing communication between\r
+switches that are located inside spine "switch systems".\r
+The reason is that there is no way to allow a LID route between them\r
+that does not break the Up/Down rule.\r
+One ramification of this is that you cannot run SM on switches other\r
+than the leaf switches of the fabric.\r
+\r
+\r
+UPDN Algorithm Usage\r
+\r
+Activation through OpenSM\r
+\r
+Use '-R updn' option (instead of old '-u') to activate the UPDN algorithm.\r
+Use `-a <guid_list_file>' for adding an UPDN guid file that contains the\r
+root nodes for ranking.\r
+If the `-a' option is not used, OpenSM uses its auto-detect root nodes\r
+algorithm.\r
+\r
+Notes on the guid list file:\r
+1.   A valid guid file specifies one guid in each line. Lines with an invalid\r
+format will be discarded.\r
+2.   The user should specify the root switch guids. However, it is also\r
+possible to specify CA guids; OpenSM will use the guid of the switch (if\r
+it exists) that connects the CA to the subnet as a root node.\r
+\r
+\r
+To learn more about deadlock-free routing, see the article\r
+"Deadlock Free Message Routing in Multiprocessor Interconnection Networks"\r
+by William J Dally and Charles L Seitz (1985).\r
+\r
+\r
+Fat-tree Routing Algorithm\r
+--------------------------\r
+\r
+Purpose:\r
+\r
+The fat-tree algorithm optimizes routing for "shift" communication pattern.\r
+It should be chosen if a subnet is a symmetrical or almost symmetrical\r
+fat-tree of various types.\r
+It supports not just K-ary-N-Trees, by handling for non-constant K,\r
+cases where not all leafs (CAs) are present, any Constant\r
+Bisectional Ratio (CBB) ratio.  As in UPDN, fat-tree also prevents\r
+credit-loop-deadlocks.\r
+\r
+If the root guid file is not provided ('-a' or '--root_guid_file' options),\r
+the topology has to be pure fat-tree that complies with the following rules:\r
+  - Tree rank should be between two and eight (inclusively)\r
+  - Switches of the same rank should have the same number\r
+    of UP-going port groups*, unless they are root switches,\r
+    in which case the shouldn't have UP-going ports at all.\r
+  - Switches of the same rank should have the same number\r
+    of DOWN-going port groups, unless they are leaf switches.\r
+  - Switches of the same rank should have the same number\r
+    of ports in each UP-going port group.\r
+  - Switches of the same rank should have the same number\r
+    of ports in each DOWN-going port group.\r
+  - All the CAs have to be at the same tree level (rank).\r
+\r
+If the root guid file is provided, the topology doesn't have to be pure\r
+fat-tree, and it should only comply with the following rules:\r
+  - Tree rank should be between two and eight (inclusively)\r
+  - All the Compute Nodes** have to be at the same tree level (rank).\r
+    Note that non-compute node CAs are allowed here to be at different\r
+    tree ranks.\r
+\r
+* ports that are connected to the same remote switch are referenced as\r
+'port group'.\r
+** list of compute nodes (CNs) can be specified by '-u' or '--cn_guid_file'\r
+OpenSM options.\r
+\r
+Note that although fat-tree algorithm supports trees with non-integer CBB\r
+ratio, the routing will not be as balanced as in case of integer CBB ratio.\r
+In addition to this, although the algorithm allows leaf switches to have any\r
+number of CAs, the closer the tree is to be fully populated, the more effective\r
+the "shift" communication pattern will be.\r
+In general, even if the root list is provided, the closer the topology to a\r
+pure and symmetrical fat-tree, the more optimal the routing will be.\r
+\r
+The algorithm also dumps compute node ordering file (opensm-ftree-ca-order.dump)\r
+in the same directory where the OpenSM log resides. This ordering file provides\r
+the CN order that may be used to create efficient communication pattern, that\r
+will match the routing tables.\r
+\r
+Routing between non-CN nodes\r
+\r
+\r
+The use of the cn_guid_file option allows non-CN nodes to be located on different levels in the fat tree.\r
+In such case, it is not guaranteed that the Fat Tree algorithm will route between two non-CN nodes.\r
+In the scheme below, N1, N2 and N3 are non-CN nodes. Although all the CN have routes to and from them,\r
+there will not necessarily be a route between N1,N2 and N3.\r
+Such routes would require to use at least one of the Switch the wrong way around\r
+(In fact, go out of one of the top Switch through a downgoing port while we are supposed to go up).\r
+\r
+  Spine1   Spine2    Spine 3\r
+   / \     /  |  \    /   \\r
+  /   \   /   |   \  /     \\r
+ N1  Switch   N2  Switch    N3\r
+      /|\          /|\\r
+     / | \        / | \\r
+    Going down to compute nodes\r
+\r
+To solve this problem, a list of non-CN nodes can be specified by \'-G\' or \'--io_guid_file\' option.\r
+Theses nodes will be allowed to use switches the wrong way around a specific number of times (specified by \'-H\' or \'--max_reverse_hops\'.\r
+With the proper max_reverse_hops and io_guid_file values, you can ensure full connectivity in the Fat Tree.\r
+\r
+In the scheme above, with a max_reverse_hop of 1, routes will be instanciated between N1<->N2 and N2<->N3.\r
+With a max_reverse_hops value of 2, N1,N2 and N3 will all have routes between them.\r
+\r
+Please note that using max_reverse_hops creates routes that use the switch in a counter-stream way.\r
+This option should never be used to connect nodes with high bandwidth traffic between them ! It should only be used\r
+to allow connectivity for HA purposes or similar.\r
+Also having routes the other way around can in theory cause credit loops.\r
+\r
+Use these options with extreme care !\r
+\r
+\r
+Usage:\r
+\r
+Activation through OpenSM\r
+\r
+Use '-R ftree' option to activate the fat-tree algorithm.\r
+\r
+Note: LMC > 0 is not supported by fat-tree routing. If this is\r
+specified, the default routing algorithm is invoked instead.\r
+\r
+\r
+LASH Routing Algorithm\r
+----------------------\r
+\r
+LASH is an acronym for LAyered SHortest Path Routing. It is a\r
+deterministic shortest path routing algorithm that enables topology\r
+agnostic deadlock-free routing within communication networks.\r
+\r
+When computing the routing function, LASH analyzes the network\r
+topology for the shortest-path routes between all pairs of sources /\r
+destinations and groups these paths into virtual layers in such a way\r
+as to avoid deadlock.\r
+\r
+Note LASH analyzes routes and ensures deadlock freedom between switch\r
+pairs. The link from HCA between and switch does not need virtual\r
+layers as deadlock will not arise between switch and HCA.\r
+\r
+In more detail, the algorithm works as follows:\r
+\r
+1) LASH determines the shortest-path between all pairs of source /\r
+destination switches. Note, LASH ensures the same SL is used for all\r
+SRC/DST - DST/SRC pairs and there is no guarantee that the return\r
+path for a given DST/SRC will be the reverse of the route SRC/DST.\r
+\r
+2) LASH then begins an SL assignment process where a route is assigned\r
+to a layer (SL) if the addition of that route does not cause deadlock\r
+within that layer. This is achieved by maintaining and analysing a\r
+channel dependency graph for each layer. Once the potential addition\r
+of a path could lead to deadlock, LASH opens a new layer and continues\r
+the process.\r
+\r
+3) Once this stage has been completed, it is highly likely that the\r
+first layers processed will contain more paths than the latter ones.\r
+To better balance the use of layers, LASH moves paths from one layer\r
+to another so that the number of paths in each layer averages out.\r
+\r
+Note, the implementation of LASH in opensm attempts to use as few layers\r
+as possible. This number can be less than the number of actual layers\r
+available.\r
+\r
+In general LASH is a very flexible algorithm. It can, for example,\r
+reduce to Dimension Order Routing in certain topologies, it is topology\r
+agnostic and fares well in the face of faults.\r
+\r
+It has been shown that for both regular and irregular topologies, LASH\r
+outperforms Up/Down. The reason for this is that LASH distributes the\r
+traffic more evenly through a network, avoiding the bottleneck issues\r
+related to a root node and always routes shortest-path.\r
+\r
+The algorithm was developed by Simula Research Laboratory.\r
+\r
+To learn more about LASH and the flexibility behind it, the requirement\r
+for layers, performance comparisons to other algorithms, see the\r
+following articles:\r
+\r
+"Layered Routing in Irregular Networks", Lysne et al, IEEE\r
+Transactions on Parallel and Distributed Systems, VOL.16, No12,\r
+December 2005.\r
+\r
+"Routing for the ASI Fabric Manager", Solheim et al. IEEE\r
+Communications Magazine, Vol.44, No.7, July 2006.\r
+\r
+"Layered Shortest Path (LASH) Routing in Irregular System Area\r
+Networks", Skeie et al. IEEE Computer Society Communication\r
+Architecture for Clusters 2002.\r
+\r
+\r
+Use '-R lash -Q ' option to activate the LASH algorithm.\r
+\r
+Note: QoS support has to be turned on in order that SL/VL mappings are\r
+used.\r
+\r
+Note: LMC > 0 is not supported by the LASH routing. If this is\r
+specified, the default routing algorithm is invoked instead.\r
+\r
+For open regular cartesian meshes the DOR algorithm is the ideal\r
+routing algorithm. For toroidal meshes on the other hand there\r
+are routing loops that can cause deadlocks. LASH can be used to\r
+route these cases. The performance of LASH can be improved by\r
+preconditioning the mesh in cases where there are multiple links\r
+connecting switches and also in cases where the switches are not\r
+cabled consistently. An option exists for LASH to do this. To\r
+invoke this use '-R lash -Q --do_mesh_analysis'. This will\r
+add an additional phase that analyses the mesh to try to determine\r
+the dimension and size of a mesh. If it determines that the mesh\r
+looks like an open or closed cartesian mesh it reorders the ports\r
+in dimension order before the rest of the LASH algorithm runs.\r
+\r
+DOR Routing Algorithm\r
+---------------------\r
+\r
+The Dimension Order Routing algorithm is based on the Min Hop\r
+algorithm and so uses shortest paths.  Instead of spreading traffic\r
+out across different paths with the same shortest distance, it chooses\r
+among the available shortest paths based on an ordering of dimensions.\r
+Each port must be consistently cabled to represent a hypercube\r
+dimension or a mesh dimension.  Paths are grown from a destination\r
+back to a source using the lowest dimension (port) of available paths\r
+at each step.  This provides the ordering necessary to avoid deadlock.\r
+When there are multiple links between any two switches, they still\r
+represent only one dimension and traffic is balanced across them\r
+unless port equalization is turned off.  In the case of hypercubes,\r
+the same port must be used throughout the fabric to represent the\r
+hypercube dimension and match on both ends of the cable.  In the case\r
+of meshes, the dimension should consistently use the same pair of\r
+ports, one port on one end of the cable, and the other port on the\r
+other end, continuing along the mesh dimension.\r
+\r
+Use '-R dor' option to activate the DOR algorithm.\r
diff --git a/ulp/opensm/user/doc/opensm_release_notes-3.3.txt b/ulp/opensm/user/doc/opensm_release_notes-3.3.txt
new file mode 100644 (file)
index 0000000..2901355
--- /dev/null
@@ -0,0 +1,663 @@
+                        OpenSM Release Notes 3.3\r
+                       =============================\r
+\r
+Version: OpenSM 3.3.x\r
+Repo:    git://git.openfabrics.org/~sashak/management.git\r
+Date:    Nov 2009\r
+\r
+1 Overview\r
+----------\r
+This document describes the contents of the OpenSM 3.3 release.\r
+OpenSM is an InfiniBand compliant Subnet Manager and Administration,\r
+and runs on top of OpenIB. The OpenSM version for this release\r
+is opensm-3.3.3.\r
+\r
+This document includes the following sections:\r
+1 This Overview section (describing new features and software\r
+  dependencies)\r
+2 Known Issues And Limitations\r
+3 Unsupported IB compliance statements\r
+4 Bug Fixes\r
+5 Main Verification Flows\r
+6 Qualified Software Stacks and Devices\r
+\r
+1.1 Major New Features\r
+\r
+* Mesh Analysis for LASH routing algorithm.\r
+  The performance of LASH can be improved by preconditioning the mesh in\r
+  cases where there are multiple links connecting switches and also in\r
+  cases where the switches are not cabled consistently.\r
+  Activated with --do_mesh_analysis command line and config file option.\r
+\r
+* Reloadable OpenSM configuration (preliminary implemented)\r
+  This is possible now to reload OpenSM configuration parameters on the\r
+  fly without restarting.\r
+\r
+* Routing paths sorted balancing (for UpDown and MinHops)\r
+  This sorts the port order in which routing paths balancing is performed\r
+  by OpenSM. Helps to improve performance dramatically (40-50%) for most\r
+  popular application communication patterns.\r
+  To overwrite this behavior use --guid_routing_order_file command line\r
+  option.\r
+\r
+* Weighted Lid Matrices calculation (for UpDown, MinHop and DOR).\r
+  This low level routing fine-tuning feature provides the means to\r
+  define a weighting factor per port for customizing the least weight\r
+  hops for the routing. Custom weights are provided using file specified\r
+  with '--hop_weights_file' command line option.\r
+\r
+* I/O nodes connectivity (for FatTree).\r
+  This provides possibility to define the set of I/O nodes for the\r
+  Fat-Tree routing algorithm. I/O nodes are non-CN nodes allowed to use\r
+  up to N (specified using --max_reverse_hops) switches the wrong way\r
+  around to improve connectivity. I/O nodes list is provided using file\r
+  and --io_guid_file command line option.\r
+\r
+* Many code improvements, optimizations and cleanups.\r
+\r
+* Windows support (very early stage yet).\r
+\r
+1.2 Minor New Features:\r
+\r
+cde0c0d opensm: Convert remaining helper routines for GID printing format\r
+bc5743c opensm: Add support for MaxCreditHint and LinkRoundTripLatency to\r
+       osm_dump_port_info\r
+6cd34ab opensm: Add Dell to known vendor list\r
+003d6bd opensm: Add more info for traps 144 and 256-259 in osm_dump_notice\r
+5b0c5de opensm/osm_ucat_ftree.c Enhance min hops counters usage\r
+0715b92 ib_types.h: Add ib_switch_info_get_state_opt_sl2vlmapping routine\r
+2ddba79 opensm: Remove some __ and __osm_ prefixes\r
+ea0691f opensm/iba/ib_types.h: Add PortXmit/RcvDataSL PerfMgt attributes\r
+9c79be5 ib_types.h: Adding BKEY violation trap (259)\r
+c608ea6 opensm: Add and utilize ib_gid_is_notzero routine\r
+b639e64 opensm: Handle trap repress on trap 144 generation\r
+b034205 Add pkey table support to osm_get_all_port_attr\r
+876605b opensm/ib_types.h: Add attribute ID for PortCountersExtended\r
+aae3bbc opensm: PortInfo requests for discovered switches\r
+0147b09 opensm/osm_lid_mgr: use single array for used_lids\r
+a9225b0 opensm/Makefile.am: remove osm_build_id.h junk file generation\r
+8e3a57d opensm/osm_console.c: Add list of SMs to status command\r
+3d664b9 opensm/osm_console.c : Added dump_portguid function to console to\r
+       generate a list of port guids matching one or more regexps\r
+85b35bc opensm/osm_helper.c: print port number as decimal\r
+8674cb7 opensm: sort port order for routing by switch loads\r
+80c0d48 opensm: rescan config file even in standby\r
+8b7aa5e opensm/osm_subnet.c enable log_max_size opt update\r
+8558ee5 opensm/include/iba/ib_types.h: Add xmit_wait for PortCounters\r
+ecde2f7 opensm/osm_subnet.c support subnet configuration rescan and update\r
+58c45e4 opensm/osm_log.c save log_max_size in subnet opt in MB\r
+cf88e93 opensm: Add new partition keyword for all hca, switches and routers\r
+4bfd4e0 opensm: remove libibcommon build dependencies\r
+3718fc4 opensm/event_plugin: link opensm with -rdynamic flag\r
+587ce14 opensm/osm_inform.c report IB traps to plugin\r
+ced5a6e opensm/opensm/osm_console.c: move reporting of plugins to "status"\r
+       command.\r
+696aca2 opensm: Add configurable retries for transactions\r
+0d932ff opensm/osm_sa_mcmember_record.c: optimization in zero mgid comparison\r
+254c2ef opensm/osm_sm_mad_ctrl.c: In sm_mad_ctrl_send_err_cb, set init\r
+       failure on PKeyTable and QoS initialization failure\r
+83bd10a opensm: Reduce heap consumption by multicast routing tables (MFTs)\r
+cd33bc5 opensm: Add some additional HP vendor IDs/OUIs\r
+f78ec3a opensm/osm_mcast_tbl.(h c): Make max_mlid_ho be maximum MLID configured\r
+2d13530 opensm: Add infrastructure support for PortInfo\r
+       IsMulticastPkeyTrapSuppressionSupported\r
+3ace760 opensm: Reduce heap consumption by unicast routing tables (LFTs)\r
+eec568e osmtest: Add SA get PathRecord stress test\r
+aabc476 opensm: Add infrastructure support for more newly allocated PortInfo\r
+       CapabilityMask bits\r
+c83c331 opensm: improve multicast re-routing requests processing\r
+46db92f opensm: Parallelize (Stripe) MFT sets across switches\r
+00c6a6e opensm: Parallelize (Stripe) LFT sets across switches\r
+e21c651 opensm/osm_base.h: Add new SA ClassPortInfo:CapabilityMask2 bit\r
+       allocations\r
+09056b1 opensm/ib_types.h: Add CounterSelect2 field to PortCounters attribute\r
+6a63003 opensm: Add ability to configure SMSL\r
+25f071f opensm/lash: Set minimum VL for LASH to use\r
+622d853 opensm/osm_ucast_ftree.cd: Added support for same level links\r
+8146ba7 opensm: Add new Sun vendor ID\r
+1d7dd18 opensm/osm_ucast_ftree.c: Enhanced Fat-Tree algorithm\r
+e07a2f1 Add LMC support to DOR routing\r
+1acfe8a opensm: Add SuperMicro to list of recognized vendors\r
+\r
+1.3 Library API Changes\r
+\r
+  None\r
+\r
+1.4 Software Dependencies\r
+\r
+OpenSM depends on the installation of libibumad package (distributed as\r
+part of OFA IB management together with OpenSM) and IB stack presence,\r
+in particular libibumad uses user_mad kernel interface ('ib_umad' kernel\r
+module). The qualified driver versions are provided in Table 2,\r
+"Qualified IB Stacks".\r
+\r
+Also, building of QoS manager policy file parser requires flex, and either\r
+bison or byacc installed.\r
+\r
+1.5 Supported Devices Firmware\r
+\r
+The main task of OpenSM is to initialize InfiniBand devices. The\r
+qualified devices and their corresponding firmware versions\r
+are listed in Table 3.\r
+\r
+2 Known Issues And Limitations\r
+------------------------------\r
+\r
+* No Service / Key associations:\r
+  There is no way to manage Service access by Keys.\r
+\r
+* No SM to SM SMDB synchronization:\r
+  Puts the burden of re-registering services, multicast groups, and\r
+  inform-info on the client application (or IB access layer core).\r
+\r
+3 Unsupported IB Compliance Statements\r
+--------------------------------------\r
+The following section lists all the IB compliance statements which\r
+OpenSM does not support. Please refer to the IB specification for detailed\r
+information regarding each compliance statement.\r
+\r
+* C14-22 (Authentication):\r
+  M_Key M_KeyProtectBits and M_KeyLeasePeriod shall be set in one\r
+  SubnSet method. As a work-around, an OpenSM option is provided for\r
+  defining the protect bits.\r
+\r
+* C14-67 (Authentication):\r
+  On SubnGet(SMInfo) and SubnSet(SMInfo) - if M_Key is not zero then\r
+  the SM shall generate a SubnGetResp if the M_Key matches, or\r
+  silently drop the packet if M_Key does not match.\r
+\r
+* C15-0.1.23.4 (Authentication):\r
+  InformInfoRecords shall always be provided with the QPN set to 0,\r
+  except for the case of a trusted request, in which case the actual\r
+  subscriber QPN shall be returned.\r
+\r
+* o13-17.1.2 (Event-FWD):\r
+  If no permission to forward, the subscription should be removed and\r
+  no further forwarding should occur.\r
+\r
+* C14-24.1.1.5 and C14-62.1.1.22 (Initialization):\r
+  GUIDInfo - SM should enable assigning Port GUIDInfo.\r
+\r
+* C14-44 (Initialization):\r
+  If the SM discovers that it is missing an M_Key to update CA/RT/SW,\r
+  it should notify the higher level.\r
+\r
+* C14-62.1.1.12 (Initialization):\r
+  PortInfo:M_Key - Set the M_Key to a node based random value.\r
+\r
+* C14-62.1.1.13 (Initialization):\r
+  PortInfo:M_KeyProtectBits - set according to an optional policy.\r
+\r
+* C14-62.1.1.24 (Initialization):\r
+  SwitchInfo:DefaultPort - should be configured for random FDB.\r
+\r
+* C14-62.1.1.32 (Initialization):\r
+  RandomForwardingTable should be configured.\r
+\r
+* o15-0.1.12 (Multicast):\r
+  If the JoinState is SendOnlyNonMember = 1 (only), then the endport\r
+  should join as sender only.\r
+\r
+* o15-0.1.8 (Multicast):\r
+  If a request for creating an MCG with fields that cannot be met,\r
+  return ERR_REQ_INVALID (currently ignores SL and FlowLabelTClass).\r
+\r
+* C15-0.1.8.6 (SA-Query):\r
+  Respond to SubnAdmGetTraceTable - this is an optional attribute.\r
+\r
+* C15-0.1.13 Services:\r
+  Reject ServiceRecord create, modify or delete if the given\r
+  ServiceP_Key does not match the one included in the ServiceGID port\r
+  and the port that sent the request.\r
+\r
+* C15-0.1.14 (Services):\r
+  Provide means to associate service name and ServiceKeys.\r
+\r
+4 Bug Fixes\r
+-----------\r
+\r
+4.1 Major Bug Fixes\r
+\r
+18990fa opensm: set IS_SM bit during opensm init\r
+3551389 fix local port smlid in osm_send_trap144()\r
+a6de48d opensm/osm_link_mgr.c initialize SMSL\r
+82df467 opensm/osm_req.c: Shouldn't reveal port's MKey on Trap method\r
+45ebff9 opensm/osm_console_io.h: Modify osm_console_exit so only the\r
+       connection is killed, not the socket\r
+d10660a opensm/osm_req.c: In osm_send_trap144, set producer type according\r
+       to node type\r
+8a2d2dd opensm/osm_node_info_rcv.c: create physp for the newly discovered\r
+       port of the known node\r
+39b241f opensm/lid_mgr: fix duplicated lid assignment\r
+b44c398 opensm: invalidate routing cache when entering master state\r
+595f2e3 opensm: update LFTs when entering master\r
+\r
+4.2 Other Bug Fixes\r
+\r
+4911e0b performance-manager-HOWTO.txt: Indicate master state\r
+86ccaa4 opensm/osm_pkey_mgr.c: Fix pkey endian in log message\r
+b79b079 opensm.8.in: Add mention of backing documentation for QoS policy\r
+       file and performance manager\r
+b4d92af opensm/osm_perfmgr.c: Eliminate duplicated error number\r
+a10b57a opensm/osm_ucast_ftree.c: lids are always handled in host order\r
+44273a2 opensm/osm_ucast_ftree.c: fixing bug in indexing\r
+5cd98f7 Fix further bugs around console closure and clean up code.\r
+6b34339 opensm/osm_opensm.c: add newline to log message\r
+68c241c send trap144 when local priority is higher than master priority\r
+6462999 opensm/osm_inform.c: In __osm_send_report, make sure p_report_madw\r
+       valid before using\r
+9b8561a opensm/console: Fixed osm_console poll to handle POLLHUP\r
+91d0700 osm_vendor_ibumad.c: In clear_madw, fix tid endian in message\r
+5a5136b osm_switch.h : Fixed wrong comment about return value of\r
+       osm_switch_set_hops\r
+c1ec8c0 osm_ucast_ftree.c: Removed useless initialization on switch indexes\r
+418d01f opensm/osm_helper.c: use single buffer in osm_dump_dr_smp()\r
+2c9153c opensm/osm_helper.c: consolidate dr path printing code\r
+048c447 opensm/osm_helper.c: return then log is inactive\r
+dd3ef0c opensm: Return error status when cl_disp_register fails\r
+0143bf7 opensm/osm_perfmgr.c: Improve assert in osm_pc_rcv_process\r
+6622504 osm_perfmgr.c: In osm_perfmgr_shutdown, add missing cl_disp_unregister\r
+7b66dee opensm: remove unneeded anymore physp initializations\r
+f11274a opensm/partition-config.txt: Update for defmember feature\r
+d240e7d opensm/osm_sm_state_mgr.c: Remove unneeded return statement\r
+898fb8c opensm: Improve some snprintf uses\r
+6820e63 opensm/osm_sa_link_record.c: improve get_base_lid()\r
+64c8d31 opensm: initialize all switch ports\r
+555fae8 opensm/sweep: add log message before lid assignment\r
+8e22307 opensm/console: Enhance perfmgr print_counters for better nodenames\r
+b9721a1 opensm/osm_console.c: Improve perfmgr print_counters error message\r
+4d8dc72 opensm/osm_inform.c: Fix sense of zero GID compare in __match_inf_rec\r
+a98dd82 opensm/main.c: remove enable_stack_dump() call\r
+db6d51e opensm/osm_subnet: fix crash in qos string config parameters reloading\r
+e5111c8 opensm: proper config file rescan\r
+e5295b2 opensm: pre-scan command line for config file option\r
+e2f549e opensm/osm_console.c: Eliminate some extraneous parentheses\r
+0a265dc opensm/console: dump_portguid - don't duplicate matched guids\r
+540fefb opensm/console: dump_portguid command fixes\r
+d96202c opensm/osm_console.c: Add missing command in help_perfmgr\r
+ae1bd3c opensm/osm_helper.c: Add port counters to __osm_disp_msg_str\r
+1d38b31 opensm/osm_ucast_mgr.c: Add error numbers for some OSM_LOG prin\r
+156c749 opensm: fix structure definition for trap 257-258\r
+5c09f4a opensm/osm_state_mgr.c: small bug in scanning lid table\r
+72a2fa2 opensm/osm_sa.c: fixing SA MAD dump\r
+539a4d3 opensm/osm_ucast_ftree.c Fixed bad init value for down port index\r
+6690833 opensm/ftree: simplify root guids setup.\r
+90e3291 opensm/ftree: cleanup ftree_sw_tbl_element_t use\r
+c07d245 opensm/qos_config: no invalid option message on default values\r
+b382ad8 opensm: avoid memory leaks on config parameters reloading\r
+45f57ce opensm/osm_ucast_ftree.c: Fixed bug on index port incrementation\r
+3d618aa opensm/osm_subnet.c: break matching when config parameter already found\r
+44d98e3 opensm/osm_subnet.c: clean_val() remove trailing quotation\r
+173010a opensm/doc/perf-manager-arch.txt: Fix some commentary typos\r
+83bf6c5 opensm/osm_subnet.c fix parse functions for big endian machines\r
+6b9a1e9 opensm/PerfMgr: Primarily fix enhanced switch port 0 perf manager\r
+       operation\r
+8406c65 opensm: fix port chooser\r
+4f79a17 opensm/osm_perfmgr.c: In osm_perfmgr_init, eliminate memory leak\r
+       on error\r
+22da81f opensm/osm_ucast_ftree.c: fix full topology dump\r
+aa25fcb opensm/osm_port_info_rcv.c: don't clear sw->need_update if port 0\r
+       is active\r
+003bd4b opensm/osm_subnet.c Fix memory leak for QOS string parameters.\r
+9cbbab2 opensm/opensm.spec: fix event plugin config options\r
+996e8f6 OpenSM: update osmeventplugin example for the new TRAP event.\r
+67f4c07 opensm/lash: simplify some memory allocations\r
+3e6bcdb opensm/lash: fix memory leaks\r
+3ff97b9 opensm/vendor: save some stack memory\r
+fa90512 opensm/osm_vendor_*_sa: fix incompatibility with QLogic SM\r
+ccc7621 opensm/osm_ucast_ftree.c: fixing errors in comments\r
+1a802b3 Corrected incoherency in __osm_ftree_fabric_route_to_non_cns comments\r
+85a7e54 opensm/osm_sm.c: fix MC group creation in race condition\r
+\r
+aad1af2 opensm/osm_trap_rcv.c: Improvements in log_trap_info()\r
+f619d67 opensm/osm_trap_rcv.c: Minor reorganization of trap_rcv_process_request\r
+084335b opensm/link_mgr: verify port's lid\r
+d525931 opensm/osm_vendor_ibumad: Use OSM_UMAD_MAX_AGENTS rather than UMAD_CA_MAX_AGENTS\r
+f342c62 opensm/osm_sa.c: don't ignore failure in osm_mgrp_add_port()\r
+587fda4 osmtest/osmt_multicast.c: fix strict aliasing breakage warning\r
+6931f3e opensm: make subnet's max mlid update implementation independent\r
+30f1acd osm_ucast_ftree.c missing reset of ca_ports\r
+ac04779 opensm: fix LFT allocation size\r
+a7838d0 opensm/osm_ucast_cache: reduce OSM_LOG_INFO debug printouts\r
+c027335 opensm/osm_ucast_updn.c: Further reduction in cas_per_sw allocation\r
+e8ee292 opensm/opensm/osm_subnet.c: adjust buffer to ensure a '\n' is printed\r
+84d9830 opensm/osm_ucast_updn.c: Reduce temporary allocation of cas_per_sw\r
+347ad64 opensm/ib_types.h: Mask off client rereg bit in set_client_rereg\r
+\r
+c2ab189 opensm/osm_state_mgr.c: in cleanup_switch() check only relevant\r
+       LFT part\r
+40c93d3 use transportable constant attributes\r
+c8fa71a osmtest -code cleanup - use strncasecmp()\r
+770704a opensm/osm_mcast_mgr.c: In mcast_mgr_set_mft_block, fix node GUID\r
+       in log message\r
+3d20f82 opensm/osm_sa_path_record.c: separate router guid resolution code\r
+27ea3c8 opensm: fix gcc-4.4.1 warnings\r
+c88bfd3 opensm/osm_lid_mgr.c: Fix typo in OSM_LOG message\r
+a9ea08c opensm/osm_mesh.c: Add dump_mesh routine at OSM_LOG_DEBUG level\r
+bc2a61e C++ style coding does not compile\r
+6647600 opensm: remove meanless 'const' keywords in APIs\r
+323a74f opensm/osm_qos_parser_y.y: fix endless loop\r
+0121a81 opensm: fix endless looping in mcast_mgr\r
+696c022 opensm: fix some obvious -Wsign-compare warnings\r
+b91e3c3 opensm/osm_get_port_by_lid(): don't bother with lmc\r
+ca582df opensm/osm_get_port_by_lid(): speedup a port lookup\r
+fd846ee opensm/osm_mesh.c: simplify compare_switches() function\r
+fe20080 osm_sa.c - void * arithmetic causes problems\r
+220130f osm_helper.c use explicit value for struct init\r
+0168ece use standard varargs syntax in macro OSM_LOG()\r
+180b335 update functions to match .h prototypes\r
+9240ef4 opensm/osm_ucast_lash: fix use after free bug\r
+6f1a21a opensm: osm_get_port_by_lid() helper\r
+7ec9f7c opensm: discard multicast SA PR with wildcard DGID\r
+c9e2818 opensm/osm_sa_path_record.c: validate multicast membership\r
+225dcf5 opensm/osm_mesh.c: Remove edges in lash matrix\r
+4dd928b opensm/osm_sa_mcmember_record.c: clean uninitialized variable use\r
+c48f0bc opensm/osm_perfmgr_db.c: Fix memory leak of db nodes\r
+82d3585 opensm/osm_notice.c: move logging code to separate function\r
+9557f60 opensm/osm_inform.c: For traps 64-67, use GID from DataDetails in\r
+       log message\r
+e2e78d9 opensm/opensm.8.in: Indicate default rule for Default partition\r
+08c5beb opensm/osm_sa_node_record.c: dump NodeInfo with debug verbosity\r
+1fe88f0 opensm/multicast: merge mcm_port and mcm_info\r
+ba75747 opensm/multicast: consolidate port addition/removing code\r
+5e61ab8 opensm: port object reference in mcm ports list\r
+5c5dacf opensm: fix uninitialized return value in osm_sm_mcgrp_leave()\r
+7cfe18d osm_ucast_ftree.c: Removed reverse_hop parameters from\r
+       fabric_route_upgoing_by_going_down\r
+aa7fb47 opensm/multicast: kill mc group to_be_deleted flag\r
+a4910fe opensm/osm_mcast_mgr.c: multicast routing by mlid - renaming\r
+1d14060 opensm/multicast: remove change id tracking\r
+5a84951 opensm: use mgrp pointer as osm_sm_mcgrp_join/leave() parameter\r
+d8e3ff5 opensm: use mgrp pointer in port mcm_info\r
+0631cd3 opensm doc: Indicated limited (rather than partial) partition\r
+       membership\r
+1010535 opensm/osm_ucast_lash.c: In lash_core, return status -1 for all errors\r
+942e20f opensm/osm_helper.c: Add SM priority changed into trap 144 description\r
+2372999 opensm/osm_ucast_mgr: better lft setup\r
+e268b32 opensm/osm_helper.c: Only change method when > rather than >=\r
+9309e8c complib/cl_event.c: change nanosec var type long\r
+d93b126 opensm/complib: account for nsec overflow in timeout values\r
+ef4c8ac opensm/osm_qos_policy.c: matching PR query to QoS level with pkey\r
+c93b58b opensm: fixing some data types in osm_req_get/set\r
+2b89177 opensm/libvendor/osm_vendor_ibumad.c: Handle umad_alloc failure in\r
+       osm_vendor_get\r
+2cba163 opensm/osm_helper.c: In osm_dump_dr_smp, fix endian of status\r
+47397e3 opensm/osm_sm_mad_ctrl.c: Fix endian of status in error message\r
+e83b7ca opensm/osm_mesh.c: Reorder switches for lash\r
+9256239 opensm/osm_trap_rcv.c: Validate trap is 144 before checking for\r
+       NodeDescription changed\r
+011d9ca opensm/osm_ucast_lash.c: Handle calloc failure in generate_cdg_for_sp\r
+59964d7 opensm: fixing handling of opt.max_wire_smps\r
+f4e3cd0 opensm/osm_ucast_lash.c: Directly call calloc/free rather than\r
+       create/delete_cdg\r
+5a208bd opensm/osm_ucast_lash.c: Added error numbers to some error log messages\r
+3b80d10 opensm/osm_helper.c: fix printing trap 258 details\r
+f682fe0 opensm: do not configure MFTs when mcast support is disabled\r
+cc42095 opensm/osm_sm_mad_ctrl.c: In sm_mad_ctrl_send_err_cb, indicate\r
+       failed attribute\r
+aebf215 opensm/osm_ucast_lash.c: Remove osm_mesh_node_delete call from\r
+       switch_delete\r
+1ef4694 opensm/osm_path.h: In osm_dr_path_init, only copy needed part of path\r
+c594a2d opensm: osm_dr_path_extend can fail due to invalid hop count\r
+46e5668 opensm/osm_lash: Fix use after free problem in osm_mesh_node_delete\r
+81841dc opensm/osm_ucast_lash.c: Handle malloc failures better\r
+2801203 opensm: remove extra "0x" from debug message.\r
+88821d2 opensm/main.c: Display SMSL when specified\r
+f814dcd opensm/osm_subnet.c: Format lash_start_vl consistent with other\r
+       uint8 items\r
+66669c9 opensm/main.c: Display LASH start VL when specified\r
+31bb0a7 opensm/osm_mcst_mgr.c: check number of switches only once\r
+75e672c opensm: find MC group by MGID using fleximap\r
+2b7260d Clarify the syntax of the hop_weights_file\r
+e6f0070 opensm/osm_mesh.c: Improve VL utilization\r
+27497a0 opensm/osm_ucast_ftree.c Fix assert comparing number of CAs to CN ports\r
+3b98131 opensm/osm_qos_policy.c: Use proper size in malloc in\r
+       osm_qos_policy_vlarb_scope_create\r
+e6f367d opensm/osm_ucast_ftree.c: Made error numbers unique in some log\r
+       messages\r
+83261a8 osm_ucast_ftree.c Count number of hops instead of calculating it\r
+7bdf4ff opensm/osm_sa_(path multipath)_record.c: Fix typo in a couple of\r
+       log messages\r
+0f8ed87 opensm/osm_ucast_mgr.c: Add error numbers to some error log messages\r
+0b5ccb4 complib/Makefile.am: prevent file duplications\r
+e0b8ec9 opensm/osm_sminfo_rcv.c: clean type of smi_rcv_process_get_sm()\r
+4d01005 opensm: sweep component processors return status value\r
+6ad8d78 opensm/libvendor/osm_vendor_(ibumad mlx)_sa.c: Handle malloc\r
+       failure in __osmv_send_sa_req\r
+cf97ebf opensm/osm_ucast_lash.(h c): Replace memory allocation by array\r
+5cdb53f opensm/osm_sa_node_record.c use comp mask to match by LID or GUID\r
+957461c opensm/osm_sa.c add attribute and component mask to error message\r
+5d339a1 osm_dump.c dump port if lft is set up\r
+518083d osm_port.c: check if op_vls = 0 before max_op_vls comparison\r
+b6964cb opensm/osm_port.c: Change log level of Invalid OP_VLS 0 message\r
+       to VERBOSE\r
+b27568c opensm/PerfMgr: Reduce host name length\r
+bc495c0 opensm/osm_lid_mgr.c bug in opensm LID assignment\r
+5a466fd opensm/osm_perfmgr_db.c: Remove unneeded initialization in\r
+       perfmgr_db_print_by_name\r
+57cf328 opensm/osm_ucast_ftree.c Increase the size of the hop table\r
+8323cf1 opensm/PerfMgr: Remove some underbars from internal names\r
+65b1c15 opensm: Changes to spec and make files for updated release notes\r
+cd226c7 OpenSM: include/vendor/osm_vendor.h - Replaced #elif with no\r
+       condition by #else\r
+9f8bd4a management: Fixed custom_release in SPEC files\r
+c0b8207 opensm/PerfMgr: Change redir_tbl_size to num_ports for better clarity\r
+\r
+* Other less critical or visible bugs were also fixed.\r
+\r
+5 Main Verification Flows\r
+-------------------------\r
+\r
+OpenSM verification is run using the following activities:\r
+* osmtest - a stand-alone program\r
+* ibmgtsim (IB management simulator) based - a set of flows that\r
+  simulate clusters, inject errors and verify OpenSM capability to\r
+  respond and bring up the network correctly.\r
+* small cluster regression testing - where the SM is used on back to\r
+  back or single switch configurations. The regression includes\r
+  multiple OpenSM dedicated tests.\r
+* cluster testing - when we run OpenSM to setup a large cluster, perform\r
+  hand-off, reboots and reconnects, verify routing correctness and SA\r
+  responsiveness at the ULP level (IPoIB and SDP).\r
+\r
+5.1 osmtest\r
+\r
+osmtest is an automated verification tool used for OpenSM\r
+testing. Its verification flows are described by list below.\r
+\r
+* Inventory File: Obtain and verify all port info, node info, link and path\r
+  records parameters.\r
+\r
+* Service Record:\r
+   - Register new service\r
+   - Register another service (with a lease period)\r
+   - Register another service (with service p_key set to zero)\r
+   - Get all services by name\r
+   - Delete the first service\r
+   - Delete the third service\r
+   - Added bad flows of get/delete  non valid service\r
+   - Add / Get same service with different data\r
+   - Add / Get / Delete by different component  mask values (services\r
+     by Name & Key / Name & Data / Name & Id / Id only )\r
+\r
+* Multicast Member Record:\r
+   - Query of existing Groups (IPoIB)\r
+   - BAD Join with insufficient comp mask (o15.0.1.3)\r
+   - Create given MGID=0 (o15.0.1.4)\r
+   - Create given MGID=0xFF12A01C,FE800000,00000000,12345678 (o15.0.1.4)\r
+   - Create BAD MGID=0xFA. (o15.0.1.6)\r
+   - Create BAD MGID=0xFF12A01B w/ link-local not set (o15.0.1.6)\r
+   - New MGID with invalid join state (o15.0.1.9)\r
+   - Retry of existing MGID - See JoinState update (o15.0.1.11)\r
+   - BAD RATE when connecting to existing MGID (o15.0.1.13)\r
+   - Partial JoinState delete request - removing FullMember (o15.0.1.14)\r
+   - Full Delete of a group (o15.0.1.14)\r
+   - Verify Delete by trying to Join deleted group (o15.0.1.14)\r
+   - BAD Delete of IPoIB membership (no prev join) (o15.0.1.15)\r
+\r
+* GUIDInfo Record:\r
+   - All GUIDInfoRecords in subnet are obtained\r
+\r
+* MultiPathRecord:\r
+   - Perform some compliant and noncompliant MultiPathRecord requests\r
+   - Validation is via status in responses and IB analyzer\r
+\r
+* PKeyTableRecord:\r
+  - Perform some compliant and noncompliant PKeyTableRecord queries\r
+  - Validation is via status in responses and IB analyzer\r
+\r
+* LinearForwardingTableRecord:\r
+  - Perform some compliant and noncompliant LinearForwardingTableRecord queries\r
+  - Validation is via status in responses and IB analyzer\r
+\r
+* Event Forwarding: Register for trap forwarding using reports\r
+   - Send a trap and wait for report\r
+   - Unregister non-existing\r
+\r
+* Trap 64/65 Flow: Register to Trap 64-65, create traps (by\r
+  disconnecting/connecting ports) and wait for report, then unregister.\r
+\r
+* Stress Test: send PortInfoRecord queries, both single and RMPP and\r
+  check for the rate of responses as well as their validity.\r
+\r
+\r
+5.2 IB Management Simulator OpenSM Test Flows:\r
+\r
+The simulator provides ability to simulate the SM handling of virtual\r
+topologies that are not limited to actual lab equipment availability.\r
+OpenSM was simulated to bring up clusters of up to 10,000 nodes. Daily\r
+regressions use smaller (16 and 128 nodes clusters).\r
+\r
+The following test flows are run on the IB management simulator:\r
+\r
+* Stability:\r
+  Up to 12 links from the fabric are randomly selected to drop packets\r
+  at drop rates up to 90%. The SM is required to succeed in bringing the\r
+  fabric up. The resulting routing is verified to be correct as well.\r
+\r
+* LID Manager:\r
+  Using LMC = 2 the fabric is initialized with LIDs. Faults such as\r
+  zero LID, Duplicated LID, non-aligned (to LMC) LIDs are\r
+  randomly assigned to various nodes and other errors are randomly\r
+  output to the guid2lid cache file. The SM sweep is run 5 times and\r
+  after each iteration a complete verification is made to ensure that all\r
+  LIDs that could possibly be maintained are kept, as well as that all nodes\r
+  were assigned a legal LID range.\r
+\r
+* Multicast Routing:\r
+  Nodes randomly join the 0xc000 group and eventually the\r
+  resulting routing is verified for completeness and adherence to\r
+  Up/Down routing rules.\r
+\r
+* osmtest:\r
+  The complete osmtest flow as described in the previous table is run on\r
+  the simulated fabrics.\r
+\r
+* Stress Test:\r
+  This flow merges fabric, LID and stability issues with continuous\r
+  PathRecord, ServiceRecord and Multicast Join/Leave activity to\r
+  stress the SM/SA during continuous sweeps. InformInfo Set/Delete/Get\r
+  were added to the test such both existing and non existing nodes\r
+  perform them in random order.\r
+\r
+5.3 OpenSM Regression\r
+\r
+Using a back-to-back or single switch connection, the following set of\r
+tests is run nightly on the stacks described in table 2. The included\r
+tests are:\r
+\r
+* Stress Testing: Flood the SA with queries from multiple channel\r
+  adapters to check the robustness of the entire stack up to the SA.\r
+\r
+* Dynamic Changes: Dynamic Topology changes, through randomly\r
+  dropping SMP packets, used to test OpenSM adaptation to an unstable\r
+  network & verify DB correctness.\r
+\r
+* Trap Injection: This flow injects traps to the SM and verifies that it\r
+  handles them gracefully.\r
+\r
+* SA Query Test: This test exhaustively checks the SA responses to all\r
+  possible single component mask. To do that the test examines the\r
+  entire set of records the SA can provide, classifies them by their\r
+  field values and then selects every field (using component mask and a\r
+  value) and verifies that the response matches the expected set of records.\r
+  A random selection using multiple component mask bits is also performed.\r
+\r
+5.4 Cluster testing:\r
+\r
+Cluster testing is usually run before a distribution release. It\r
+involves real hardware setups of 16 to 32 nodes (or more if a beta site\r
+is available). Each test is validated by running all-to-all ping through the IB\r
+interface. The test procedure includes:\r
+\r
+* Cluster bringup\r
+\r
+* Hand-off between 2 or 3 SM's while performing:\r
+  - Node reboots\r
+  - Switch power cycles (disconnecting the SM's)\r
+\r
+* Unresponsive port detection and recovery\r
+\r
+* osmtest from multiple nodes\r
+\r
+* Trap injection and recovery\r
+\r
+\r
+6 Qualified Software Stacks and Devices\r
+---------------------------------------\r
+\r
+OpenSM Compatibility\r
+--------------------\r
+Note that OpenSM version 3.2.1 and earlier used a value of 1 in host\r
+byte order for the default SM_Key, so there is a compatibility issue\r
+with these earlier versions of OpenSM when the 3.2.2 or later version\r
+is running on a little endian machine. This affects SM handover as well\r
+as SA queries (saquery tool in infiniband-diags).\r
+\r
+\r
+Table 2 - Qualified IB Stacks\r
+=============================\r
+\r
+Stack                                    | Version\r
+-----------------------------------------|--------------------------\r
+The main stream Linux kernel             |   2.6.x\r
+OFED                                     |   1.4\r
+OFED                                     |   1.3\r
+OFED                                     |   1.2\r
+OFED                                     |   1.1\r
+OFED                                     |   1.0\r
+\r
+Table 3 - Qualified Devices and Corresponding Firmware\r
+======================================================\r
+\r
+Mellanox\r
+Device                              |   FW versions\r
+------------------------------------|-------------------------------\r
+InfiniScale                         | fw-43132  5.2.000 (and later)\r
+InfiniScale III                     | fw-47396  0.5.000 (and later)\r
+InfiniScale IV                      | fw-48436  7.1.000 (and later)\r
+InfiniHost                          | fw-23108  3.5.000 (and later)\r
+InfiniHost III Lx                   | fw-25204  1.2.000 (and later)\r
+InfiniHost III Ex (InfiniHost Mode) | fw-25208  4.8.200 (and later)\r
+InfiniHost III Ex (MemFree Mode)    | fw-25218  5.3.000 (and later)\r
+ConnectX IB                         | fw-25408  2.3.000 (and later)\r
+\r
+QLogic/PathScale\r
+Device  |   Note\r
+--------|-----------------------------------------------------------\r
+iPath   | QHT6040 (PathScale InfiniPath HT-460)\r
+iPath   | QHT6140 (PathScale InfiniPath HT-465)\r
+iPath   | QLE6140 (PathScale InfiniPath PE-880)\r
+iPath   | QLE7240\r
+iPath   | QLE7280\r
+\r
+Note 1: OpenSM does not run on an IBM Galaxy (eHCA) as it does not expose\r
+QP0 and QP1. However, it does support it as a device on the subnet.\r
+\r
+Note 2: QoS firmware and Mellanox devices\r
+\r
+HCAs: QoS supported by ConnectX. QoS-enabled FW release is 2_5_000 and\r
+later.\r
+\r
+Switches: QoS supported by InfiniScale III\r
+Any InfiniScale III FW that is supported by OpenSM supports QoS.\r
diff --git a/ulp/opensm/user/doc/partition-config.txt b/ulp/opensm/user/doc/partition-config.txt
new file mode 100644 (file)
index 0000000..50e40de
--- /dev/null
@@ -0,0 +1,131 @@
+OpenSM Partition configuration\r
+===============================\r
+\r
+The default name of OpenSM partitions configuration file is\r
+'/etc/opensm/partitions.conf'. The default may be changed by\r
+using the --Pconfig (-P) option with OpenSM.\r
+\r
+The default partition will be created by OpenSM unconditionally even\r
+when partition configuration file does not exist or cannot be accessed.\r
+\r
+The default partition has P_Key value 0x7fff. OpenSM's port will always\r
+have full membership in default partition. All other end ports will have\r
+full membership if the partition configuration file is not found or cannot\r
+be accessed, or limited membership if the file exists and can be accessed\r
+but there is no rule for the Default partition.\r
+\r
+Effectively, this amounts to the same as if one of the following rules\r
+below appear in the partition configuration file:\r
+In the case of no rule for the Default partition:\r
+Default=0x7fff : ALL=limited, SELF=full ;\r
+In the case of no partition configuration file or file cannot be accessed:\r
+Default=0x7fff : ALL=full ;\r
+\r
+\r
+File Format\r
+===========\r
+\r
+Comments:\r
+--------\r
+\r
+Line content followed after '#' character is comment and ignored by\r
+parser.\r
+\r
+\r
+General file format:\r
+-------------------\r
+\r
+<Partition Definition>:<PortGUIDs list> ;\r
+\r
+\r
+Partition Definition:\r
+--------------------\r
+\r
+[PartitionName][=PKey][,flag[=value]][,defmember=full|limited]\r
+\r
+PartitionName - string, to be used with logging. When omitted\r
+                empty string will be used.\r
+PKey          - P_Key value for this partition. Only low 15 bits will\r
+                be used. When omitted will be autogenerated.\r
+flag          - used to indicate IPoIB capability of this partition.\r
+defmember=full|limited - specifies default membership for port guid\r
+                list. Default is limited.\r
+\r
+Currently recognized flags are:\r
+\r
+ipoib       - indicates that this partition may be used for IPoIB, as\r
+              result IPoIB capable MC group will be created.\r
+rate=<val>  - specifies rate for this IPoIB MC group (default is 3 (10GBps))\r
+mtu=<val>   - specifies MTU for this IPoIB MC group (default is 4 (2048))\r
+sl=<val>    - specifies SL for this IPoIB MC group (default is 0)\r
+scope=<val> - specifies scope for this IPoIB MC group (default is 2 (link\r
+local))\r
+\r
+Note that values for 'rate', 'mtu'. and 'scope' should be specified as defined\r
+in the IBTA specification (for example mtu=4 for 2048).\r
+\r
+\r
+PortGUIDs list:\r
+--------------\r
+\r
+[PortGUID[=full|=limited]] [,PortGUID[=full|=limited]] [,PortGUID] ...\r
+\r
+PortGUID     - GUID of partition member EndPort. Hexadecimal numbers\r
+               should start from 0x, decimal numbers are accepted too.\r
+full or      - indicates full or limited membership for this port. When\r
+  limited      omitted (or unrecognized) limited membership is assumed.\r
+\r
+There are two useful keywords for PortGUID definition:\r
+\r
+- 'ALL' means all end ports in this subnet.\r
+- 'ALL_CAS' means all Channel Adapter end ports in this subnet.\r
+- 'ALL_SWITCHES' means all Switch end ports in this subnet.\r
+- 'ALL_ROUTERS' means all Router end ports in this subnet.\r
+- 'SELF' means subnet manager's port.\r
+\r
+Empty list means no ports in this partition.\r
+\r
+\r
+Notes:\r
+-----\r
+\r
+White spaces are permitted between delimiters ('=', ',',':',';').\r
+\r
+The Line can be wrapped after ':' followed after Partition Definition and\r
+between.\r
+\r
+PartitionName does not need to be unique, PKey does need to be unique.\r
+If PKey is repeated then those partition configurations will be merged\r
+and first PartitionName will be used (see also next note).\r
+\r
+It is possible to split partition configuration in more than one\r
+definition, but then PKey should be explicitly specified (otherwise\r
+different PKey values will be generated for those definitions).\r
+\r
+\r
+Examples:\r
+--------\r
+\r
+Default=0x7fff : ALL, SELF=full ;\r
+Default=0x7fff : ALL, ALL_SWITCHES=full, SELF=full ;\r
+\r
+NewPartition , ipoib : 0x123456=full, 0x3456789034=limi, 0x2134af2306 ;\r
+\r
+YetAnotherOne = 0x300 : SELF=full ;\r
+YetAnotherOne = 0x300 : ALL=limited ;\r
+\r
+ShareIO = 0x80 , defmember=full : 0x123451, 0x123452; # 0x123453, 0x123454 will be limited\r
+ShareIO = 0x80 : 0x123453, 0x123454, 0x123455=full; # 0x123456, 0x123457 will be limited\r
+ShareIO = 0x80 : defmember=limited : 0x123456, 0x123457, 0x123458=full;\r
+ShareIO = 0x80 , defmember=full : 0x123459, 0x12345a;\r
+ShareIO = 0x80 , defmember=full : 0x12345b, 0x12345c=limited, 0x12345d;\r
+\r
+\r
+Note:\r
+----\r
+\r
+The following rule is equivalent to how OpenSM used to run prior to the\r
+partition manager:\r
+\r
+Default=0x7fff,ipoib:ALL=full;\r
+\r
diff --git a/ulp/opensm/user/doc/perf-manager-arch.txt b/ulp/opensm/user/doc/perf-manager-arch.txt
new file mode 100644 (file)
index 0000000..2fc1fd2
--- /dev/null
@@ -0,0 +1,181 @@
+Performance Manager\r
+2/12/07\r
+\r
+This document will describe an architecture and a phased plan\r
+for an OpenFabrics OpenIB performance manager.\r
+\r
+Currently, there is no open source performance manager, only\r
+a perfquery diagnostic tool which some have scripted into a\r
+"poor man's" performance manager.\r
+\r
+The primary responsibilities of the performance manager are to:\r
+1. Monitor subnet topology\r
+2. Based on subnet topology, monitor performance and error counters.\r
+   Also, possibly monitor counters related to congestion.\r
+3. Perform data reduction (various calculations (rates, histograms, etc.))\r
+   on counters obtained\r
+4. Log performance data and indicate "interesting" related events\r
+\r
+\r
+Performance Manager Components\r
+1. Determine subnet topology\r
+   Performance manager can determine the subnet topology by subscribing\r
+   for GID in and out of service events. Upon receipt of a GID in service\r
+   event, use GID to query SA for corresponding LID by using SubnAdmGet\r
+   NodeRecord with PortGUID specified. It would utilize the LID and NumPorts\r
+   returned and add this to the monitoring list. Note that the monitoring\r
+   list can be extended to be distributed with the manager "balancing" the\r
+   assignments of new GIDs to the set of known monitors. For GID out of\r
+   service events, the GID is removed from the monitoring list.\r
+\r
+2. Monitoring\r
+   Counters to be monitored include performance counters (data octets and\r
+   packets both receive and transmit) and error counters. These are all in\r
+   the mandatory PortCounters attribute. Future support will include the\r
+   optional 64 bit counters, PortExtendedCounters (as this is only known\r
+   to be supported on one IB device currently). Also, one congestion\r
+   counter (PortXmitWait) will also be monitored (on switch ports) initially.\r
+\r
+   Polling rather than sampling will be used as the monitoring technique. The\r
+   polling rate configurable from 1-65535 seconds (default TBD)\r
+   Note that with 32 bit counters, on 4x SDR links, byte counts can max out in\r
+   16 seconds and on 4x DDR links in 8 seconds. The polling rate needs to\r
+   deal with this as accurate byte and packet rates are desired. Since IB\r
+   counters are sticky, the counters need to be reset when they get "close"\r
+   to max'ing out. This will result in some inaccuracy. When counters are\r
+   reset, the time of the reset will be tracked in the monitor and will be\r
+   queryable. Note that when the 64 bit counters are supported more generally,\r
+   the polling rate can be reduced.\r
+\r
+   The performance manager will support parallel queries. The level of\r
+   parallelism is configurable with a default of 64 queries outstanding\r
+   at one time.\r
+\r
+   Configuration and dynamic adjustment of any performance manager "knobs"\r
+   will be supported.\r
+\r
+   Also, there will be a console interface to obtain performance data.\r
+   It will be able to reset counters, report on specific nodes or\r
+   node types of interest (CAs only, switches only, all, ...). The\r
+   specifics are TBD.\r
+\r
+3. Data Reduction\r
+   For errors, rate rather than raw value will be calculated. Error\r
+   event is only indicated when rate exceeds a threshold.\r
+   For packet and byte counters, small changes will be aggregated\r
+   and only significant changes are updated.\r
+   Aggregated histograms (per node, all nodes (this is TBD))) for each\r
+   counter will be provided. Actual counters will also be written to files.\r
+   NodeGUID will be used to identify node. File formats are TBD. One\r
+   format to be supported might be CSV.\r
+\r
+4. Logging\r
+   "Interesting" events determined by the performance manager will be\r
+   logged as well as the performance data itself. Significant events\r
+   will be logged to syslog. There are some interesting scalability\r
+   issues relative to logging especially for the distributed model.\r
+\r
+   Events will be based on rates which are configured as thresholds.\r
+   There will be configurable thresholds for the error counters with\r
+   reasonable defaults. Correlation of PerfManager and SM events is\r
+   interesting but not a mandatory requirement.\r
+\r
+\r
+Performance Manager Scalability\r
+Clearly as the polling rate goes up, the number of nodes which can be\r
+monitored from a single performance management node decreases. There is\r
+some evidence that a single dedicated management node may not be able to\r
+monitor the largest clusters at a rapid rate.\r
+\r
+There are numerous PerfManager models which can be supported:\r
+1. Integrated as thread(s) with OpenSM (run only when SM is master)\r
+2. Standby SM\r
+3. Standalone PerfManager (not running with master or standby SM)\r
+4. Distributed PerfManager (most scalable approach)\r
+\r
+Note that these models are in order of implementation complexity and\r
+hence "schedule".\r
+\r
+The simplest model is to run the PerfManager with the master SM. This has\r
+the least scalability but is the simplest model. Note that in this model\r
+the topology can be obtained without the GID in and out of service events\r
+but this is needed for any of the other models to be supported.\r
+\r
+The next model is to run the PerfManager with a standby SM. Standbys are not\r
+doing much currently (polling the master) so there is much idle CPU.\r
+The downside of this approach is that if the standby takes over as master,\r
+the PerfManager would need to be moved (or is becomes model 1).\r
+\r
+A totally separate standlone PerfManager would allow for a deployment\r
+model which eliminates the downside of model 2 (standby SM). It could\r
+still be built in a similar manner with model 2 with unneeded functions\r
+(SM and SA) not included. The advantage of this model is that it could\r
+be more readily usable with a vendor specific SM (switch based or otherwise).\r
+Vendor specific SMs usually come with a built-in performance manager and\r
+this assumes that there would be a way to disable that performance manager.\r
+Model 2 can act like model 3 if a disable SM feature is supported in OpenSM\r
+(command line/console). This will take the SM to not active.\r
+\r
+The most scalable model is a distributed PerfManager. One approach to\r
+distribution is a hierarchial model where there is a PerfManager at the\r
+top level with a number of PerfMonitors which are responsible for some\r
+portion of the subnet.\r
+\r
+The separation of PerfManager from OpenSM brings up the following additional\r
+issues:\r
+1. What communication is needed between OpenSM and the PerfManager ?\r
+2. Integration of interesting events with OpenSM log\r
+(Does performance manager assume OpenSM ? Does it need to work with vendor\r
+SMs ?)\r
+\r
+Hierarchial distribution brings up some additional issues:\r
+1. How is the hierarchy determined ?\r
+2. How do the PerfManager and PerfMonitors find each other ?\r
+3. How is the subnet divided amongst the PerfMonitors\r
+4. Communication amongst the PerfManager and the PerfMonitors\r
+(including communication failures)\r
+\r
+In terms of inter manager communication, there seem to be several\r
+choices:\r
+1. Use vendor specific MADs (which can be RMPP'd) and build on top of\r
+this\r
+2. Use RC QP communication and build on top of this\r
+3. Use IPoIB which is much more powerful as sockets can then be utilized\r
+\r
+RC QP communication improves on the lower performance of the vendor\r
+specific MAD approach but is not as powerful as the socket based approach.\r
+\r
+The only downside of IPoIB is that it requires multicast to be functioning.\r
+It seems reasonable to require IPoIB across the management nodes. This\r
+can either be a separate IPoIB subnet or a shared one with other endnodes\r
+on the subnet. (If this communication is built on top of sockets, it\r
+can be any IP subnet amongst the manager nodes).\r
+\r
+The first implementation phase will address models 1-3. Model 3 is optional\r
+as it is similar to models 1 and 2 and may be not be needed.\r
+\r
+Model 4 will be addressed in a subsequent implementation phase (and a future\r
+version of this document). Model 4 can be built on the basis of models 1 and\r
+2 where some SM, not necessarily master, is the PerfManager and the rest are\r
+PerfMonitors.\r
+\r
+\r
+Performance Manager Partition Membership\r
+Note that as the performance manager needs to talk via GSI to the PMAs\r
+in all the end nodes and GSI utilizes PKey sharing, partition membership\r
+if invoked must account for this.\r
+\r
+The most straightforward deployment of the performance manager is\r
+to have it be a member of the full default partition (P_Key 0xFFFF).\r
+\r
+\r
+Performance Manager Redundancy\r
+TBD (future version of this document)\r
+\r
+\r
+Congestion Management\r
+TBD (future version of this document)\r
+\r
+\r
+QoS Management\r
+TBD (future version of this document)\r
diff --git a/ulp/opensm/user/doc/performance-manager-HOWTO.txt b/ulp/opensm/user/doc/performance-manager-HOWTO.txt
new file mode 100644 (file)
index 0000000..078e8b4
--- /dev/null
@@ -0,0 +1,154 @@
+OpenSM Performance manager HOWTO\r
+================================\r
+\r
+Introduction\r
+============\r
+\r
+OpenSM now includes a performance manager which collects Port counters from\r
+the subnet and stores them internally in OpenSM.\r
+\r
+Some of the features of the performance manager are:\r
+\r
+       1) Collect port data and error counters per v1.2 spec and store in\r
+          64 bit internal counts.\r
+       2) Automatic reset of counters when they reach approximatly 3/4 full.\r
+          (While not guarenteeing that counts will not be missed this does\r
+          keep counts incrementing as best as possible given the current\r
+          hardware limitations.)\r
+       3) Basic warnings in the OpenSM log on "critical" errors like symbol\r
+          errors.\r
+       4) Automatically detects "outside" resets of counters and adjusts to\r
+          continue collecting data.\r
+       5) Can be run when OpenSM is in standby or inactive states in\r
+          addition to master state.\r
+\r
+Known issues are:\r
+\r
+       1) Data counters will be lost on high data rate links.  Sweeping the\r
+          fabric fast enough for even a DDR link is not practical.\r
+       2) Default partition support only.\r
+\r
+\r
+Setup and Usage\r
+===============\r
+\r
+Using the Performance Manager consists of 3 steps:\r
+\r
+       1) compiling in support for the perfmgr (Optionally: the console\r
+          socket as well)\r
+       2) enabling the perfmgr and console in opensm.conf\r
+       3) retrieving data which has been collected.\r
+          3a) using console to "dump data"\r
+          3b) using a plugin module to store the data to your own\r
+              "database"\r
+\r
+Step 1: Compile in support for the Performance Manager\r
+------------------------------------------------------\r
+\r
+Because of the performance manager's experimental status, it is not enabled at\r
+compile time by default.  (This will hopefully soon change as more people use\r
+it and confirm that it does not break things...  ;-)  The configure option is\r
+"--enable-perf-mgr".\r
+\r
+At this time it is really best to enable the console socket option as well.\r
+OpenSM can be run in an "interactive" mode.  But with the console socket option\r
+turned on one can also make a connection to a running OpenSM.  The console\r
+option is "--enable-console-socket".  This option requires the use of\r
+tcp_wrappers to ensure security.  Please be aware of your configuration for\r
+tcp_wrappers as the commands presented in the console can affect the operation\r
+of your subnet.\r
+\r
+The following configure line includes turning on the performance manager as\r
+well as the console:\r
+\r
+       ./configure --enable-perf-mgr --enable-console-socket\r
+\r
+\r
+Step 2: Enable the perfmgr and console in opensm.conf\r
+-----------------------------------------------------\r
+\r
+Turning the Perfmorance Manager on is pretty easy, set the following options in\r
+the opensm.conf config file.  (Default location is\r
+/usr/local/etc/opensm/opensm.conf)\r
+\r
+       # Turn it all on.\r
+       perfmgr TRUE\r
+\r
+       # sweep time in seconds\r
+       perfmgr_sweep_time_s 180\r
+\r
+       # Dump file to dump the events to\r
+       event_db_dump_file /var/log/opensm_port_counters.log\r
+\r
+Also enable the console socket and configure the port for it to listen to if\r
+desired.\r
+\r
+       # console [off|local|socket]\r
+       console socket\r
+\r
+       # Telnet port for console (default 10000)\r
+       console_port 10000\r
+\r
+As noted above you also need to set up tcp_wrappers to prevent unauthorized\r
+users from connecting to the console.[*]\r
+\r
+       [*] As an alternate you can use the loopback mode but I noticed when\r
+       writing this (OpenSM v3.1.10; OFED 1.3) that there are some bugs in\r
+       specifying the loopback mode in the opensm.conf file.  Look for this to\r
+       be fixed in newer versions.\r
+\r
+       [**] Also you could use "local" but this is only useful if you run\r
+       OpenSM in the foreground of a terminal.  As OpenSM is usually started\r
+       as a daemon I left this out as an option.\r
+\r
+Step 3: retrieve data which has been collected\r
+----------------------------------------------\r
+\r
+Step 3a: Using console dump function\r
+------------------------------------\r
+\r
+The console command "perfmgr dump_counters" will dump counters to the file\r
+specified in the opensm.conf file.  In the example above\r
+"/var/log/opensm_port_counters.log"\r
+\r
+Example output is below:\r
+\r
+<snip>\r
+"SW1 wopr ISR9024D (MLX4 FW)" 0x8f10400411f56 port 1 (Since Mon May 12 13:27:14 2008)\r
+     symbol_err_cnt       : 0\r
+     link_err_recover     : 0\r
+     link_downed          : 0\r
+     rcv_err              : 0\r
+     rcv_rem_phys_err     : 0\r
+     rcv_switch_relay_err : 2\r
+     xmit_discards        : 0\r
+     xmit_constraint_err  : 0\r
+     rcv_constraint_err   : 0\r
+     link_integrity_err   : 0\r
+     buf_overrun_err      : 0\r
+     vl15_dropped         : 0\r
+     xmit_data            : 470435\r
+     rcv_data             : 405956\r
+     xmit_pkts            : 8954\r
+     rcv_pkts             : 6900\r
+     unicast_xmit_pkts    : 0\r
+     unicast_rcv_pkts     : 0\r
+     multicast_xmit_pkts  : 0\r
+     multicast_rcv_pkts   : 0\r
+</snip>\r
+\r
+\r
+Step 3b: Using a plugin module\r
+------------------------------\r
+\r
+If you want a more automated method of retrieving the data OpenSM provides a\r
+plugin interface to extend OpenSM.  The header file is osm_event_plugin.h.\r
+The functions you register with this interface will be called when data is\r
+collected.  You can then use that data as appropriate.\r
+\r
+An example plugin can be configured at compile time using the\r
+"--enable-default-event-plugin" option on the configure line.  This plugin is\r
+very simple.  It logs "events" received from the performance manager to a log\r
+file.  I don't recommend using this directly but rather use it as a template to\r
+create your own plugin.\r
+\r
index c90e6f7..b71bf1d 100644 (file)
@@ -1,45 +1,44 @@
-Trivial low level QoS configuration proposition
-===============================================
-
-Basically there is a set of QoS related low-level configuration parameters.
-All these parameter names are prefixed by "qos_" string. Here is a full
-list of these parameters:
-
-  qos_max_vls    - The maximum number of VLs that will be on the subnet
-  qos_high_limit - The limit of High Priority component of VL Arbitration
-                   table (IBA 7.6.9)
-  qos_vlarb_low  - High priority VL Arbitration table (IBA 7.6.9) template
-  qos_vlarb_high - Low priority VL Arbitration table (IBA 7.6.9) template
-                   Both VL arbitration templates are pairs of VL and weight
-  qos_sl2vl      - SL2VL Mapping table (IBA 7.6.6) template. It is a list
-                   of VLs corresponding to SLs 0-15 (Note the VL15 used
-                   here means drop this SL)
-
-Typical default values (hard-coded in OpenSM initialization) are:
-
-  qos_max_vls=15
-  qos_high_limit=0
-  qos_vlarb_low=0:0,1:4,2:4,3:4,4:4,5:4,6:4,7:4,8:4,9:4,10:4,11:4,12:4,13:4,14:4
-  qos_vlarb_high=0:4,1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0
-  qos_sl2vl=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7
-
-The syntax is compatible with rest of OpenSM configuration options and
-values may be stored in OpenSM config file (cached options file).
-
-In addition to the above, we may define separate QoS configuration
-parameters sets for various target types. As targets, we currently support
-CAs, routers, switch external ports, and switch's enhanced port 0. The
-names of such specialized parameters are prefixed by "qos_<type>_"
-string. Here is a full list of the currently supported sets:
-
-  qos_ca_  - QoS configuration parameters set for CAs.
-  qos_rtr_ - parameters set for routers.
-  qos_sw0_ - parameters set for switches' port 0.
-  qos_swe_ - parameters set for switches' external ports.
-
-Examples:
-
-  qos_sw0_max_vls=2
-  qos_ca_sl2vl=0,1,2,3,5,5,5,12,12,0,
-  qos_swe_high_limit=0
-
+Trivial low level QoS configuration proposition\r
+===============================================\r
+\r
+Basically there is a set of QoS related low-level configuration parameters.\r
+All these parameter names are prefixed by "qos_" string. Here is a full\r
+list of these parameters:\r
+\r
+  qos_max_vls    - The maximum number of VLs that will be on the subnet\r
+  qos_high_limit - The limit of High Priority component of VL Arbitration\r
+                   table (IBA 7.6.9)\r
+  qos_vlarb_low  - Low priority VL Arbitration table (IBA 7.6.9) template\r
+  qos_vlarb_high - High priority VL Arbitration table (IBA 7.6.9) template\r
+                   Both VL arbitration templates are pairs of VL and weight\r
+  qos_sl2vl      - SL2VL Mapping table (IBA 7.6.6) template. It is a list\r
+                   of VLs corresponding to SLs 0-15 (Note the VL15 used\r
+                   here means drop this SL)\r
+\r
+Typical default values (hard-coded in OpenSM initialization) are:\r
+\r
+  qos_max_vls 15\r
+  qos_high_limit 0\r
+  qos_vlarb_low 0:0,1:4,2:4,3:4,4:4,5:4,6:4,7:4,8:4,9:4,10:4,11:4,12:4,13:4,14:4\r
+  qos_vlarb_high 0:4,1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0,11:0,12:0,13:0,14:0\r
+  qos_sl2vl 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7\r
+\r
+The syntax is compatible with rest of OpenSM configuration options and\r
+values may be stored in OpenSM config file (cached options file).\r
+\r
+In addition to the above, we may define separate QoS configuration\r
+parameters sets for various target types. As targets, we currently support\r
+CAs, routers, switch external ports, and switch's enhanced port 0. The\r
+names of such specialized parameters are prefixed by "qos_<type>_"\r
+string. Here is a full list of the currently supported sets:\r
+\r
+  qos_ca_  - QoS configuration parameters set for CAs.\r
+  qos_rtr_ - parameters set for routers.\r
+  qos_sw0_ - parameters set for switches' port 0.\r
+  qos_swe_ - parameters set for switches' external ports.\r
+\r
+Examples:\r
+\r
+  qos_sw0_max_vls 2\r
+  qos_ca_sl2vl 0,1,2,3,5,5,5,12,12,0,\r
+  qos_swe_high_limit 0\r
index 9c985f5..a0c0627 100644 (file)
@@ -1,7 +1,7 @@
 #\r
 # DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source\r
 # file to this component.  This file merely indirects to the real make file\r
-# that is shared by all the driver components of the Windows NT DDK\r
+# that is shared by all the driver components of the OpenIB Windows project.\r
 #\r
 \r
-!INCLUDE $(NTMAKEENV)\makefile.def\r
+!INCLUDE ..\..\..\..\inc\openib.def\r
index c58e0c7..850a113 100644 (file)
@@ -16,6 +16,11 @@ TARGETPATH=$(OSM_TARGET)\bin\user\obj$(BUILD_ALT_DIR)
 TARGETPATH=$(WINIBHOME)\bin\user\obj$(BUILD_ALT_DIR)\r
 !endif\r
 \r
+# include only one vendor definition\r
+\r
+!include ..\opensm\vendor-ibal.inc\r
+#!include ..\opensm\vendor-umad.inc\r
+\r
 TARGETTYPE=PROGRAM\r
 UMTYPE=console\r
 USE_MSVCRT=1\r
@@ -24,41 +29,44 @@ OVR_DIR=..\addon
 \r
 SOURCES=\\r
        main.c \\r
-       ibtrapgen.c\r
-\r
+       ibtrapgen.c \\r
+       osm_files.c\r
 \r
 \r
 OSM_HOME=..\r
 \r
 TARGETLIBS=\\r
+       $(SDK_LIB_PATH)\kernel32.lib \\r
+       $(SDK_LIB_PATH)\ws2_32.lib \\r
 !if $(FREEBUILD)\r
-                       $(LIBPATH)\*\ibal.lib \\r
-                       $(LIBPATH)\*\complib.lib \\r
-                       $(TARGETPATH)\*\osmv_ibal.lib \\r
-                       $(TARGETPATH)\*\opensm_ibal.lib\r
+       $(VENDOR_LIBS) \\r
+       $(LIBPATH)\*\ibal.lib \\r
+       $(LIBPATH)\*\complib.lib\r
 !else\r
-                       $(LIBPATH)\*\ibald.lib \\r
-                       $(LIBPATH)\*\complibd.lib \\r
-                       $(TARGETPATH)\*\osmv_ibald.lib \\r
-                       $(TARGETPATH)\*\opensm_ibald.lib\r
+       $(VENDOR_LIBSD) \\r
+       $(LIBPATH)\*\ibald.lib \\r
+       $(LIBPATH)\*\complibd.lib\r
 !endif\r
 \r
-#DO NOT TOUCH the order of search path , until ib_types.h merging process will be done\r
 INCLUDES= \\r
-       $(OSM_HOME)\include; \\r
-       $(OSM_HOME); \\r
        $(WINIBHOME)\inc; \\r
-       $(WINIBHOME)\inc\user;\r
+       $(WINIBHOME)\inc\user; \\r
+       $(WINIBHOME)\inc\user\linux; \\r
+       $(OSM_HOME); \\r
+       $(OSM_HOME)\include; \\r
 \r
 # Could be any special flag needed for this project \r
 USER_C_FLAGS=$(USER_C_FLAGS) /MD\r
+\r
 #Add preproccessor definitions\r
-C_DEFINES=$(C_DEFINES) -DWIN32 -D__WIN__ -D__i386__ -Dinline=__inline -DMT_LITTLE_ENDIAN -DOSM_VENDOR_INTF_AL\r
+C_DEFINES=$(C_DEFINES) -D__WIN__ -D$(VENDOR_IF) -DHAVE_CONFIG_H\r
+\r
 !if !$(FREEBUILD)\r
 #C_DEFINES=$(C_DEFINES) -D_DEBUG -DDEBUG -DDBG\r
 C_DEFINES=$(C_DEFINES) \r
 !endif\r
 \r
 LINKER_FLAGS= $(LINKER_FLAGS)\r
+\r
 MSC_WARNING_LEVEL= /W3\r
 \r
index bd37882..e124474 100644 (file)
@@ -141,8 +141,7 @@ ibtrapgen_init( IN ibtrapgen_t * const p_ibtrapgen,
 
   /* all mads (actually wrappers) are taken and returned to a pool */
   osm_mad_pool_construct( &p_ibtrapgen->mad_pool );
-  status = osm_mad_pool_init(
-    &p_ibtrapgen->mad_pool, p_ibtrapgen->p_log );
+  status = osm_mad_pool_init( &p_ibtrapgen->mad_pool );
   if( status != IB_SUCCESS )
     goto Exit;
 
@@ -169,12 +168,12 @@ __ibtrapgen_rcv_callback(
 {
   ibtrapgen_t* p_ibtrapgen = (ibtrapgen_t*)bind_context;
 
-  OSM_LOG_ENTER( p_ibtrapgen->p_log, __ibtrapgen_rcv_callback );
+  OSM_LOG_ENTER( p_ibtrapgen->p_log );
 
   CL_ASSERT( p_madw );
 
-  osm_log( p_ibtrapgen->p_log, OSM_LOG_VERBOSE,
-           "__ibtrapgen_rcv_callback: Got callback\n",
+  OSM_LOG( p_ibtrapgen->p_log, OSM_LOG_VERBOSE,
+           "Got callback trans_id %64I\n",
            cl_ntoh64(p_madw->p_mad->trans_id) );
 
   OSM_LOG_EXIT( p_ibtrapgen->p_log );
@@ -196,7 +195,7 @@ __ibtrapgen_send_err_cb(
 {
   ibtrapgen_t* p_ibtrapgen = (ibtrapgen_t*)bind_context;
 
-  OSM_LOG_ENTER( p_ibtrapgen->p_log, __ibtrapgen_send_err_callback );
+  OSM_LOG_ENTER( p_ibtrapgen->p_log );
 
   osm_log( p_ibtrapgen->p_log, OSM_LOG_ERROR,
            "__ibtrapgen_send_err_cb: ERR 0011: "
@@ -223,7 +222,7 @@ ibtrapgen_bind( IN ibtrapgen_t * p_ibtrapgen )
   osm_bind_info_t bind_info;
   uint8_t i;
 
-  OSM_LOG_ENTER( p_ibtrapgen->p_log, ibtrapgen_bind );
+  OSM_LOG_ENTER( p_ibtrapgen->p_log );
 
   /*
    * Call the transport layer for a list of local port
@@ -347,7 +346,7 @@ ibtrapgen_run( IN ibtrapgen_t * const p_ibtrapgen )
   osm_log_t *p_log =      p_ibtrapgen->p_log;
   uint16_t                i;
 
-  OSM_LOG_ENTER( p_log, ibtrapgen_run );
+  OSM_LOG_ENTER( p_log );
 
   osm_log( p_log, OSM_LOG_INFO,
            "ibtrapgen_run: "
diff --git a/ulp/opensm/user/ibtrapgen/osm_files.c b/ulp/opensm/user/ibtrapgen/osm_files.c
new file mode 100644 (file)
index 0000000..c4fbcdf
--- /dev/null
@@ -0,0 +1,7 @@
+\r
+/* Supply required OpenSM src files - easier to maintain/diff these files\r
+ * against OFE/openSM source.\r
+ */\r
+\r
+#include <..\opensm\osm_mad_pool.c>\r
+#include <..\opensm\osm_log.c>\r
index 123bd09..0840f62 100644 (file)
-/*
- * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2006 Mellanox Technologies LTD. All rights reserved.
- * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
- *
- * This software is available to you under the OpenIB.org BSD license
- * below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * $Id$
- */
-
-
-/*
- * Abstract:
- *     Declaration of dispatcher abstraction.
- * 
- * Environment:
- *     All
- *
- * $Revision: 1.4 $
- */
-
-#ifndef _CL_DISPATCHER_H_
-#define _CL_DISPATCHER_H_
-
-#include <complib/cl_atomic.h>
-#include <complib/cl_threadpool.h>
-#include <complib/cl_qlist.h>
-#include <complib/cl_qpool.h>
-#include <complib/cl_spinlock.h>
-#include <complib/cl_ptr_vector.h>
-
-#ifdef __cplusplus
-#  define BEGIN_C_DECLS extern "C" {
-#  define END_C_DECLS   }
-#else /* !__cplusplus */
-#  define BEGIN_C_DECLS
-#  define END_C_DECLS
-#endif /* __cplusplus */
-
-BEGIN_C_DECLS
-
-/****h* Component Library/Dispatcher
-* NAME
-*      Dispatcher
-*
-* DESCRIPTION
-*      The Dispatcher provides a facility for message routing to
-*      asynchronous worker threads.
-*
-*      The Dispatcher functions operate on a cl_dispatcher_t structure
-*      which should be treated as opaque and should be manipulated
-*      only through the provided functions.
-*
-* SEE ALSO
-*      Structures:
-*              cl_dispatcher_t
-*
-*      Initialization/Destruction:
-*              cl_disp_construct, cl_disp_init, cl_disp_shutdown, cl_disp_destroy
-*
-*      Manipulation:
-*              cl_disp_post, cl_disp_reset, cl_disp_wait_on
-*********/
-
-/****s* Component Library: Dispatcher/cl_disp_msgid_t
-* NAME
-*      cl_disp_msgid_t
-*
-* DESCRIPTION
-*      Defines the type of dispatcher messages.
-*
-* SYNOPSIS
-*/
-typedef uint32_t cl_disp_msgid_t;
-/**********/
-
-/****s* Component Library: Dispatcher/CL_DISP_MSGID_NONE
-* NAME
-*      CL_DISP_MSGID_NONE
-*
-* DESCRIPTION
-*      Defines a message value that means "no message".
-*      This value is used during registration by Dispatcher clients
-*      that do not wish to receive messages.
-*
-*      No Dispatcher message is allowed to have this value.
-*
-* SYNOPSIS
-*/
-#define CL_DISP_MSGID_NONE     0xFFFFFFFF
-/**********/
-
-/****s* Component Library: Dispatcher/CL_DISP_INVALID_HANDLE
-* NAME
-*      CL_DISP_INVALID_HANDLE
-*
-* DESCRIPTION
-*      Defines the value of an invalid Dispatcher registration handle.
-*
-* SYNOPSIS
-*/
-#define CL_DISP_INVALID_HANDLE ((cl_disp_reg_handle_t)0)
-/*********/
-
-/****f* Component Library: Dispatcher/cl_pfn_msgrcv_cb_t
-* NAME
-*      cl_pfn_msgrcv_cb_t
-*
-* DESCRIPTION
-*      This typedef defines the prototype for client functions invoked
-*      by the Dispatcher.  The Dispatcher calls the corresponding
-*      client function when delivering a message to the client.
-*
-*      The client function must be reentrant if the user creates a
-*      Dispatcher with more than one worker thread.
-*
-* SYNOPSIS
-*/
-typedef void 
-(*cl_pfn_msgrcv_cb_t)(
-       IN      void*                           context,
-       IN      void*                           p_data );
-/*
-* PARAMETERS
-*      context
-*              [in] Client specific context specified in a call to
-*              cl_disp_register
-*
-*      p_data
-*              [in] Pointer to the client specific data payload
-*              of this message.
-*
-* RETURN VALUE
-*      This function does not return a value.
-*
-* NOTES
-*      This typedef provides a function prototype reference for
-*      the function provided by Dispatcher clients as a parameter
-*      to the cl_disp_register function.
-*
-* SEE ALSO
-*      Dispatcher, cl_disp_register
-*********/
-
-/****f* Component Library: Dispatcher/cl_pfn_msgdone_cb_t
-* NAME
-*      cl_pfn_msgdone_cb_t
-*
-* DESCRIPTION
-*      This typedef defines the prototype for client functions invoked
-*      by the Dispatcher.  The Dispatcher calls the corresponding
-*      client function after completing delivery of a message.
-*
-*      The client function must be reentrant if the user creates a
-*      Dispatcher with more than one worker thread.
-*
-* SYNOPSIS
-*/
-typedef void 
-(*cl_pfn_msgdone_cb_t)(
-       IN      void*                           context,
-       IN      void*                           p_data );
-/*
-* PARAMETERS
-*      context
-*              [in] Client specific context specified in a call to
-*              cl_disp_post
-*
-*      p_data
-*              [in] Pointer to the client specific data payload
-*              of this message.
-*
-* RETURN VALUE
-*      This function does not return a value.
-*
-* NOTES
-*      This typedef provides a function prototype reference for
-*      the function provided by Dispatcher clients as a parameter
-*      to the cl_disp_post function.
-*
-* SEE ALSO
-*      Dispatcher, cl_disp_post
-*********/
-
-/****s* Component Library: Dispatcher/cl_dispatcher_t
-* NAME
-*      cl_dispatcher_t
-*
-* DESCRIPTION
-*      Dispatcher structure.
-*
-*      The Dispatcher is thread safe.
-*
-*      The cl_dispatcher_t structure should be treated as opaque and should
-*      be manipulated only through the provided functions.
-*
-* SYNOPSIS
-*/
-typedef struct _cl_dispatcher
-{
-  cl_spinlock_t      lock;
-  cl_ptr_vector_t    reg_vec;
-  cl_qlist_t         reg_list;
-  cl_thread_pool_t   worker_threads;
-  cl_qlist_t         msg_fifo;
-  cl_qpool_t         msg_pool;
-  uint64_t           last_msg_queue_time_us;
-} cl_dispatcher_t;
-/*
-* FIELDS
-*      reg_vec
-*              Vector of registration info objects.  Indexed by message msg_id.
-*
-*      lock
-*              Spinlock to guard internal structures.
-*
-*      msg_fifo
-*              FIFO of messages being processed by the Dispatcher.  New
-*              messages are posted to the tail of the FIFO.  Worker threads
-*              pull messages from the front.
-*
-*      worker_threads
-*              Thread pool of worker threads to dispose of posted messages.
-*
-*      msg_pool
-*              Pool of message objects to be processed through the FIFO.
-*
-*      reg_count
-*              Count of the number of registrants.
-*
-*      state
-*              Indicates the state of the object.
-* 
-*       last_msg_queue_time_us
-*               The time that the last message spent in the Q in usec
-*      
-* SEE ALSO
-*      Dispatcher
-*********/
-
-/****s* Component Library: Dispatcher/cl_disp_reg_info_t
-* NAME
-*      cl_disp_reg_info_t
-*
-* DESCRIPTION
-*      Defines the dispatcher registration object structure.
-*
-*      The cl_disp_reg_info_t structure is for internal use by the
-*      Dispatcher only.
-*
-* SYNOPSIS
-*/
-typedef struct _cl_disp_reg_info
-{
-       cl_list_item_t                  list_item;
-       cl_pfn_msgrcv_cb_t              pfn_rcv_callback;
-       const void                              *context;
-       atomic32_t                              ref_cnt;
-       cl_disp_msgid_t                 msg_id;
-       cl_dispatcher_t                 *p_disp;
-
-} cl_disp_reg_info_t;
-/*
-* FIELDS
-*      pfn_rcv_callback
-*              Client's message receive callback.
-*
-*      context
-*              Client's context for message receive callback.
-*
-*      rcv_thread_count
-*              Number of threads currently in the receive callback.
-*
-*      msg_done_thread_count
-*              Number of threads currently in the message done callback.
-*
-*      state
-*              State of this registration object.
-*                      DISP_REGSTATE_INIT: initialized and inactive
-*                      DISP_REGSTATE_ACTIVE: in active use
-*                      DISP_REGSTATE_UNREGPEND: unregistration is pending
-*
-*      msg_id
-*              Dispatcher message msg_id value for this registration object.
-*
-*      p_disp
-*              Pointer to parent Dispatcher.
-*
-* SEE ALSO
-*********/
-
-/****s* Component Library: Dispatcher/cl_disp_msg_t
-* NAME
-*      cl_disp_msg_t
-*
-* DESCRIPTION
-*      Defines the dispatcher message structure.
-*
-*      The cl_disp_msg_t structure is for internal use by the
-*      Dispatcher only.
-*
-* SYNOPSIS
-*/
-typedef struct _cl_disp_msg
-{
-  cl_pool_item_t         item;
-  const void            *p_data;
-  cl_disp_reg_info_t    *p_src_reg;
-  cl_disp_reg_info_t    *p_dest_reg;
-  cl_pfn_msgdone_cb_t    pfn_xmt_callback;
-  uint64_t               in_time;
-  const void            *context;
-} cl_disp_msg_t;
-/*
-* FIELDS
-*      item
-*              List & Pool linkage.  Must be first element in the structure!!
-*
-*      msg_id
-*              The message's numberic ID value.
-*
-*      p_data
-*              Pointer to the data payload for this message.  The payload
-*              is opaque to the Dispatcher.
-*
-*      p_reg_info
-*              Pointer to the registration info of the sender.
-*
-*      pfn_xmt_callback
-*              Client's message done callback.
-*
-*       in_time 
-*               The absolute time the message was inserted into the queue
-*
-*      context
-*              Client's message done callback context.
-*              
-* SEE ALSO
-*********/
-
-/****s* Component Library: Dispatcher/cl_disp_reg_info_t
-* NAME
-*      cl_disp_reg_info_t
-*
-* DESCRIPTION
-*      Defines the Dispatcher registration handle.  This handle
-*      should be treated as opaque by the client.
-*
-* SYNOPSIS
-*/
-typedef const struct _cl_disp_reg_info *cl_disp_reg_handle_t;
-/**********/
-
-/****f* Component Library: Dispatcher/cl_disp_construct
-* NAME
-*      cl_disp_construct
-*
-* DESCRIPTION
-*      This function constructs a Dispatcher object.
-*
-* SYNOPSIS
-*/
-void
-cl_disp_construct(
-       IN      cl_dispatcher_t* const p_disp );
-/*
-* PARAMETERS
-*      p_disp
-*              [in] Pointer to a Dispatcher.
-*
-* RETURN VALUE
-*      This function does not return a value.
-*
-* NOTES
-*      Allows calling cl_disp_init and cl_disp_destroy.
-*
-* SEE ALSO
-*      Dispatcher, cl_disp_init, cl_disp_destroy
-*********/
-
-/****f* Component Library: Dispatcher/cl_disp_init
-* NAME
-*      cl_disp_init
-*
-* DESCRIPTION
-*      This function initializes a Dispatcher object.
-*
-* SYNOPSIS
-*/
-cl_status_t
-cl_disp_init(
-       IN      cl_dispatcher_t* const  p_disp,
-       IN      const uint32_t                  thread_count,
-    IN const char* const               name );
-/*
-* PARAMETERS
-*      p_disp
-*              [in] Pointer to a Dispatcher.
-*
-*      thread_count
-*              [in] The number of worker threads to create in this Dispatcher.
-*              A value of 0 causes the Dispatcher to create one worker thread
-*              per CPU in the system.  When the Dispatcher is created with
-*              only one thread, the Dispatcher guarantees to deliver posted
-*              messages in order.  When the Dispatcher is created with more
-*              than one thread, messages may be delivered out of order.
-*
-*      name
-*              [in] Name to associate with the threads.  The name may be up to 16
-*              characters, including a terminating null character.  All threads
-*              created in the Dispatcher have the same name.
-*
-* RETURN VALUE
-*      CL_SUCCESS if the operation is successful.
-*
-* SEE ALSO
-*      Dispatcher, cl_disp_destoy, cl_disp_register, cl_disp_unregister, 
-*      cl_disp_post
-*********/
-
-/****f* Component Library: Dispatcher/cl_disp_shutdown
-* NAME
-*      cl_disp_shutdown
-*
-* DESCRIPTION
-*      This function shutdown a Dispatcher object. So it unreg all messages and
-*  clears the fifo and waits for the threads to exit
-*
-* SYNOPSIS
-*/
-void
-cl_disp_shutdown(
-       IN cl_dispatcher_t* const p_disp );
-/*
-* PARAMETERS
-*      p_disp
-*              [in] Pointer to a Dispatcher.
-*
-* RETURN VALUE
-*      This function does not return a value.
-*
-* NOTES
-*      This function does not returns until all worker threads
-*      have exited client callback functions and been successfully
-*      shutdowned.
-*
-* SEE ALSO
-*      Dispatcher, cl_disp_construct, cl_disp_init
-*********/
-
-/****f* Component Library: Dispatcher/cl_disp_destroy
-* NAME
-*      cl_disp_destroy
-*
-* DESCRIPTION
-*      This function destroys a Dispatcher object.
-*
-* SYNOPSIS
-*/
-void
-cl_disp_destroy(
-       IN cl_dispatcher_t* const p_disp );
-/*
-* PARAMETERS
-*      p_disp
-*              [in] Pointer to a Dispatcher.
-*
-* RETURN VALUE
-*      This function does not return a value.
-*
-* SEE ALSO
-*      Dispatcher, cl_disp_construct, cl_disp_init
-*********/
-
-/****f* Component Library: Dispatcher/cl_disp_register
-* NAME
-*      cl_disp_register
-*
-* DESCRIPTION
-*      This function registers a client with a Dispatcher object.
-*
-* SYNOPSIS
-*/
-cl_disp_reg_handle_t
-cl_disp_register(
-       IN cl_dispatcher_t* const p_disp,
-       IN const cl_disp_msgid_t msg_id,
-       IN cl_pfn_msgrcv_cb_t pfn_callback OPTIONAL,
-       IN const void* const context );
-/*
-* PARAMETERS
-*      p_disp
-*              [in] Pointer to a Dispatcher.
-*
-*      msg_id
-*              [in] Numberic message ID for which the client is registering.
-*              If the client does not wish to receive any messages,
-*              (a send-only client) then the caller should set this value
-*              to CL_DISP_MSGID_NONE.  For efficiency, numeric message msg_id
-*              values should start with 0 and should be contiguous, or nearly so.
-*
-*      pfn_callback
-*              [in] Message receive callback.  The Dispatcher calls this
-*              function after receiving a posted message with the
-*              appropriate message msg_id value.  Send-only clients may specify
-*              NULL for this value.
-*
-*      context
-*              [in] Client context value passed to the cl_pfn_msgrcv_cb_t
-*              function.
-*
-* RETURN VALUE
-*      On success a Dispatcher registration handle.
-*      CL_CL_DISP_INVALID_HANDLE otherwise.
-*
-* SEE ALSO
-*      Dispatcher, cl_disp_unregister, cl_disp_post
-*********/
-
-/****f* Component Library: Dispatcher/cl_disp_unregister
-* NAME
-*      cl_disp_unregister
-*
-* DESCRIPTION
-*      This function unregisters a client from a Dispatcher.
-*
-* SYNOPSIS
-*/
-void
-cl_disp_unregister(
-       IN const cl_disp_reg_handle_t handle );
-/*
-* PARAMETERS
-*      handle
-*              [in] cl_disp_reg_handle_t value return by cl_disp_register.
-*
-* RETURN VALUE
-*      This function does not return a value.
-*
-* NOTES
-*      This function will not return until worker threads have exited
-*      the callback functions for this client.  Do not invoke this
-*      function from a callback.
-*
-* SEE ALSO
-*      Dispatcher, cl_disp_register
-*********/
-
-/****f* Component Library: Dispatcher/cl_disp_post
-* NAME
-*      cl_disp_post
-*
-* DESCRIPTION
-*      This function posts a message to a Dispatcher object.
-*
-* SYNOPSIS
-*/
-cl_status_t
-cl_disp_post(
-       IN const cl_disp_reg_handle_t handle,
-       IN const cl_disp_msgid_t msg_id,
-       IN const void* const p_data,
-       IN cl_pfn_msgdone_cb_t pfn_callback OPTIONAL,
-       IN const void* const context );
-/*
-* PARAMETERS
-*      handle
-*              [in] cl_disp_reg_handle_t value return by cl_disp_register.
-*
-*      msg_id
-*              [in] Numeric message msg_id value associated with this message.
-*
-*      p_data
-*              [in] Data payload for this message.
-*
-*      pfn_callback
-*              [in] Pointer to a cl_pfn_msgdone_cb_t function.
-*              The Dispatcher calls this function after the message has been
-*              processed by the recipient.
-*              The caller may pass NULL for this value, which indicates no
-*              message done callback is necessary.
-*
-*      context
-*              [in] Client context value passed to the cl_pfn_msgdone_cb_t
-*              function.
-*      
-* RETURN VALUE
-*      CL_SUCCESS if the message was successfully queued in the Dispatcher.
-*
-* NOTES
-*      The caller must not modify the memory pointed to by p_data until
-*      the Dispatcher call the pfn_callback function.
-*
-* SEE ALSO
-*      Dispatcher
-*********/
-
-/****f* Component Library: Dispatcher/cl_disp_get_queue_status
-* NAME
-*      cl_disp_get_queue_status
-*
-* DESCRIPTION
-*      This function posts a message to a Dispatcher object.
-*
-* SYNOPSIS
-*/
-void
-cl_disp_get_queue_status(
-  IN const cl_disp_reg_handle_t handle,
-  OUT uint32_t *p_num_queued_msgs,
-  OUT uint64_t *p_last_msg_queue_time_ms);
-/*
-* PARAMETERS
-*   handle
-*     [in] cl_disp_reg_handle_t value return by cl_disp_register.
-*
-*   p_last_msg_queue_time_ms
-*     [out] pointer to a variable to hold the time the last popped up message 
-*           spent in the queue 
-*
-*   p_num_queued_msgs
-*     [out] number of messages in the queue
-*
-* RETURN VALUE
-*      Thr time the last popped up message stayed in the queue, in msec
-*
-* NOTES
-*      Extarnel Locking is not required.
-*
-* SEE ALSO
-*      Dispatcher
-*********/
-
-END_C_DECLS
-
-#endif /* !defined(_CL_DISPATCHER_H_) */
-
+/*\r
+ * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.\r
+ * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.\r
+ * Copyright (c) 1996-2003 Intel Corporation. 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
+ * Abstract:\r
+ *     Declaration of dispatcher abstraction.\r
+ */\r
+\r
+#ifndef _CL_DISPATCHER_H_\r
+#define _CL_DISPATCHER_H_\r
+\r
+#include <complib/cl_atomic.h>\r
+#include <complib/cl_threadpool.h>\r
+#include <complib/cl_qlist.h>\r
+#include <complib/cl_qpool.h>\r
+#include <complib/cl_spinlock.h>\r
+#include <complib/cl_ptr_vector.h>\r
+\r
+#ifdef __cplusplus\r
+#  define BEGIN_C_DECLS extern "C" {\r
+#  define END_C_DECLS   }\r
+#else                          /* !__cplusplus */\r
+#  define BEGIN_C_DECLS\r
+#  define END_C_DECLS\r
+#endif                         /* __cplusplus */\r
+\r
+BEGIN_C_DECLS\r
+/****h* Component Library/Dispatcher\r
+* NAME\r
+*      Dispatcher\r
+*\r
+* DESCRIPTION\r
+*      The Dispatcher provides a facility for message routing to\r
+*      asynchronous worker threads.\r
+*\r
+*      The Dispatcher functions operate on a cl_dispatcher_t structure\r
+*      which should be treated as opaque and should be manipulated\r
+*      only through the provided functions.\r
+*\r
+* SEE ALSO\r
+*      Structures:\r
+*              cl_dispatcher_t\r
+*\r
+*      Initialization/Destruction:\r
+*              cl_disp_construct, cl_disp_init, cl_disp_shutdown, cl_disp_destroy\r
+*\r
+*      Manipulation:\r
+*              cl_disp_post, cl_disp_reset, cl_disp_wait_on\r
+*********/\r
+/****s* Component Library: Dispatcher/cl_disp_msgid_t\r
+* NAME\r
+*      cl_disp_msgid_t\r
+*\r
+* DESCRIPTION\r
+*      Defines the type of dispatcher messages.\r
+*\r
+* SYNOPSIS\r
+*/\r
+typedef uint32_t cl_disp_msgid_t;\r
+/**********/\r
+\r
+/****s* Component Library: Dispatcher/CL_DISP_MSGID_NONE\r
+* NAME\r
+*      CL_DISP_MSGID_NONE\r
+*\r
+* DESCRIPTION\r
+*      Defines a message value that means "no message".\r
+*      This value is used during registration by Dispatcher clients\r
+*      that do not wish to receive messages.\r
+*\r
+*      No Dispatcher message is allowed to have this value.\r
+*\r
+* SYNOPSIS\r
+*/\r
+#define CL_DISP_MSGID_NONE     0xFFFFFFFF\r
+/**********/\r
+\r
+/****s* Component Library: Dispatcher/CL_DISP_INVALID_HANDLE\r
+* NAME\r
+*      CL_DISP_INVALID_HANDLE\r
+*\r
+* DESCRIPTION\r
+*      Defines the value of an invalid Dispatcher registration handle.\r
+*\r
+* SYNOPSIS\r
+*/\r
+#define CL_DISP_INVALID_HANDLE ((cl_disp_reg_handle_t)0)\r
+/*********/\r
+\r
+/****f* Component Library: Dispatcher/cl_pfn_msgrcv_cb_t\r
+* NAME\r
+*      cl_pfn_msgrcv_cb_t\r
+*\r
+* DESCRIPTION\r
+*      This typedef defines the prototype for client functions invoked\r
+*      by the Dispatcher.  The Dispatcher calls the corresponding\r
+*      client function when delivering a message to the client.\r
+*\r
+*      The client function must be reentrant if the user creates a\r
+*      Dispatcher with more than one worker thread.\r
+*\r
+* SYNOPSIS\r
+*/\r
+typedef void\r
+ (*cl_pfn_msgrcv_cb_t) (IN void *context, IN void *p_data);\r
+/*\r
+* PARAMETERS\r
+*      context\r
+*              [in] Client specific context specified in a call to\r
+*              cl_disp_register\r
+*\r
+*      p_data\r
+*              [in] Pointer to the client specific data payload\r
+*              of this message.\r
+*\r
+* RETURN VALUE\r
+*      This function does not return a value.\r
+*\r
+* NOTES\r
+*      This typedef provides a function prototype reference for\r
+*      the function provided by Dispatcher clients as a parameter\r
+*      to the cl_disp_register function.\r
+*\r
+* SEE ALSO\r
+*      Dispatcher, cl_disp_register\r
+*********/\r
+\r
+/****f* Component Library: Dispatcher/cl_pfn_msgdone_cb_t\r
+* NAME\r
+*      cl_pfn_msgdone_cb_t\r
+*\r
+* DESCRIPTION\r
+*      This typedef defines the prototype for client functions invoked\r
+*      by the Dispatcher.  The Dispatcher calls the corresponding\r
+*      client function after completing delivery of a message.\r
+*\r
+*      The client function must be reentrant if the user creates a\r
+*      Dispatcher with more than one worker thread.\r
+*\r
+* SYNOPSIS\r
+*/\r
+typedef void\r
+ (*cl_pfn_msgdone_cb_t) (IN void *context, IN void *p_data);\r
+/*\r
+* PARAMETERS\r
+*      context\r
+*              [in] Client specific context specified in a call to\r
+*              cl_disp_post\r
+*\r
+*      p_data\r
+*              [in] Pointer to the client specific data payload\r
+*              of this message.\r
+*\r
+* RETURN VALUE\r
+*      This function does not return a value.\r
+*\r
+* NOTES\r
+*      This typedef provides a function prototype reference for\r
+*      the function provided by Dispatcher clients as a parameter\r
+*      to the cl_disp_post function.\r
+*\r
+* SEE ALSO\r
+*      Dispatcher, cl_disp_post\r
+*********/\r
+\r
+/****s* Component Library: Dispatcher/cl_dispatcher_t\r
+* NAME\r
+*      cl_dispatcher_t\r
+*\r
+* DESCRIPTION\r
+*      Dispatcher structure.\r
+*\r
+*      The Dispatcher is thread safe.\r
+*\r
+*      The cl_dispatcher_t structure should be treated as opaque and should\r
+*      be manipulated only through the provided functions.\r
+*\r
+* SYNOPSIS\r
+*/\r
+typedef struct _cl_dispatcher {\r
+       cl_spinlock_t lock;\r
+       cl_ptr_vector_t reg_vec;\r
+       cl_qlist_t reg_list;\r
+       cl_thread_pool_t worker_threads;\r
+       cl_qlist_t msg_fifo;\r
+       cl_qpool_t msg_pool;\r
+       uint64_t last_msg_queue_time_us;\r
+} cl_dispatcher_t;\r
+/*\r
+* FIELDS\r
+*      reg_vec\r
+*              Vector of registration info objects.  Indexed by message msg_id.\r
+*\r
+*      lock\r
+*              Spinlock to guard internal structures.\r
+*\r
+*      msg_fifo\r
+*              FIFO of messages being processed by the Dispatcher.  New\r
+*              messages are posted to the tail of the FIFO.  Worker threads\r
+*              pull messages from the front.\r
+*\r
+*      worker_threads\r
+*              Thread pool of worker threads to dispose of posted messages.\r
+*\r
+*      msg_pool\r
+*              Pool of message objects to be processed through the FIFO.\r
+*\r
+*      reg_count\r
+*              Count of the number of registrants.\r
+*\r
+*      state\r
+*              Indicates the state of the object.\r
+*\r
+*       last_msg_queue_time_us\r
+*               The time that the last message spent in the Q in usec\r
+*\r
+* SEE ALSO\r
+*      Dispatcher\r
+*********/\r
+\r
+/****s* Component Library: Dispatcher/cl_disp_reg_info_t\r
+* NAME\r
+*      cl_disp_reg_info_t\r
+*\r
+* DESCRIPTION\r
+*      Defines the dispatcher registration object structure.\r
+*\r
+*      The cl_disp_reg_info_t structure is for internal use by the\r
+*      Dispatcher only.\r
+*\r
+* SYNOPSIS\r
+*/\r
+typedef struct _cl_disp_reg_info {\r
+       cl_list_item_t list_item;\r
+       cl_pfn_msgrcv_cb_t pfn_rcv_callback;\r
+       const void *context;\r
+       atomic32_t ref_cnt;\r
+       cl_disp_msgid_t msg_id;\r
+       cl_dispatcher_t *p_disp;\r
+} cl_disp_reg_info_t;\r
+/*\r
+* FIELDS\r
+*      pfn_rcv_callback\r
+*              Client's message receive callback.\r
+*\r
+*      context\r
+*              Client's context for message receive callback.\r
+*\r
+*      rcv_thread_count\r
+*              Number of threads currently in the receive callback.\r
+*\r
+*      msg_done_thread_count\r
+*              Number of threads currently in the message done callback.\r
+*\r
+*      state\r
+*              State of this registration object.\r
+*                      DISP_REGSTATE_INIT: initialized and inactive\r
+*                      DISP_REGSTATE_ACTIVE: in active use\r
+*                      DISP_REGSTATE_UNREGPEND: unregistration is pending\r
+*\r
+*      msg_id\r
+*              Dispatcher message msg_id value for this registration object.\r
+*\r
+*      p_disp\r
+*              Pointer to parent Dispatcher.\r
+*\r
+* SEE ALSO\r
+*********/\r
+\r
+/****s* Component Library: Dispatcher/cl_disp_msg_t\r
+* NAME\r
+*      cl_disp_msg_t\r
+*\r
+* DESCRIPTION\r
+*      Defines the dispatcher message structure.\r
+*\r
+*      The cl_disp_msg_t structure is for internal use by the\r
+*      Dispatcher only.\r
+*\r
+* SYNOPSIS\r
+*/\r
+typedef struct _cl_disp_msg {\r
+       cl_pool_item_t item;\r
+       const void *p_data;\r
+       cl_disp_reg_info_t *p_src_reg;\r
+       cl_disp_reg_info_t *p_dest_reg;\r
+       cl_pfn_msgdone_cb_t pfn_xmt_callback;\r
+       uint64_t in_time;\r
+       const void *context;\r
+} cl_disp_msg_t;\r
+/*\r
+* FIELDS\r
+*      item\r
+*              List & Pool linkage.  Must be first element in the structure!!\r
+*\r
+*      msg_id\r
+*              The message's numberic ID value.\r
+*\r
+*      p_data\r
+*              Pointer to the data payload for this message.  The payload\r
+*              is opaque to the Dispatcher.\r
+*\r
+*      p_reg_info\r
+*              Pointer to the registration info of the sender.\r
+*\r
+*      pfn_xmt_callback\r
+*              Client's message done callback.\r
+*\r
+*       in_time\r
+*               The absolute time the message was inserted into the queue\r
+*\r
+*      context\r
+*              Client's message done callback context.\r
+*\r
+* SEE ALSO\r
+*********/\r
+\r
+/****s* Component Library: Dispatcher/cl_disp_reg_info_t\r
+* NAME\r
+*      cl_disp_reg_info_t\r
+*\r
+* DESCRIPTION\r
+*      Defines the Dispatcher registration handle.  This handle\r
+*      should be treated as opaque by the client.\r
+*\r
+* SYNOPSIS\r
+*/\r
+typedef const struct _cl_disp_reg_info *cl_disp_reg_handle_t;\r
+/**********/\r
+\r
+/****f* Component Library: Dispatcher/cl_disp_construct\r
+* NAME\r
+*      cl_disp_construct\r
+*\r
+* DESCRIPTION\r
+*      This function constructs a Dispatcher object.\r
+*\r
+* SYNOPSIS\r
+*/\r
+void cl_disp_construct(IN cl_dispatcher_t * const p_disp);\r
+/*\r
+* PARAMETERS\r
+*      p_disp\r
+*              [in] Pointer to a Dispatcher.\r
+*\r
+* RETURN VALUE\r
+*      This function does not return a value.\r
+*\r
+* NOTES\r
+*      Allows calling cl_disp_init and cl_disp_destroy.\r
+*\r
+* SEE ALSO\r
+*      Dispatcher, cl_disp_init, cl_disp_destroy\r
+*********/\r
+\r
+/****f* Component Library: Dispatcher/cl_disp_init\r
+* NAME\r
+*      cl_disp_init\r
+*\r
+* DESCRIPTION\r
+*      This function initializes a Dispatcher object.\r
+*\r
+* SYNOPSIS\r
+*/\r
+cl_status_t\r
+cl_disp_init(IN cl_dispatcher_t * const p_disp,\r
+            IN const uint32_t thread_count, IN const char *const name);\r
+/*\r
+* PARAMETERS\r
+*      p_disp\r
+*              [in] Pointer to a Dispatcher.\r
+*\r
+*      thread_count\r
+*              [in] The number of worker threads to create in this Dispatcher.\r
+*              A value of 0 causes the Dispatcher to create one worker thread\r
+*              per CPU in the system.  When the Dispatcher is created with\r
+*              only one thread, the Dispatcher guarantees to deliver posted\r
+*              messages in order.  When the Dispatcher is created with more\r
+*              than one thread, messages may be delivered out of order.\r
+*\r
+*      name\r
+*              [in] Name to associate with the threads.  The name may be up to 16\r
+*              characters, including a terminating null character.  All threads\r
+*              created in the Dispatcher have the same name.\r
+*\r
+* RETURN VALUE\r
+*      CL_SUCCESS if the operation is successful.\r
+*\r
+* SEE ALSO\r
+*      Dispatcher, cl_disp_destoy, cl_disp_register, cl_disp_unregister,\r
+*      cl_disp_post\r
+*********/\r
+\r
+/****f* Component Library: Dispatcher/cl_disp_shutdown\r
+* NAME\r
+*      cl_disp_shutdown\r
+*\r
+* DESCRIPTION\r
+*      This function shutdown a Dispatcher object. So it unreg all messages and\r
+*  clears the fifo and waits for the threads to exit\r
+*\r
+* SYNOPSIS\r
+*/\r
+void cl_disp_shutdown(IN cl_dispatcher_t * const p_disp);\r
+/*\r
+* PARAMETERS\r
+*      p_disp\r
+*              [in] Pointer to a Dispatcher.\r
+*\r
+* RETURN VALUE\r
+*      This function does not return a value.\r
+*\r
+* NOTES\r
+*      This function does not returns until all worker threads\r
+*      have exited client callback functions and been successfully\r
+*      shutdowned.\r
+*\r
+* SEE ALSO\r
+*      Dispatcher, cl_disp_construct, cl_disp_init\r
+*********/\r
+\r
+/****f* Component Library: Dispatcher/cl_disp_destroy\r
+* NAME\r
+*      cl_disp_destroy\r
+*\r
+* DESCRIPTION\r
+*      This function destroys a Dispatcher object.\r
+*\r
+* SYNOPSIS\r
+*/\r
+void cl_disp_destroy(IN cl_dispatcher_t * const p_disp);\r
+/*\r
+* PARAMETERS\r
+*      p_disp\r
+*              [in] Pointer to a Dispatcher.\r
+*\r
+* RETURN VALUE\r
+*      This function does not return a value.\r
+*\r
+* SEE ALSO\r
+*      Dispatcher, cl_disp_construct, cl_disp_init\r
+*********/\r
+\r
+/****f* Component Library: Dispatcher/cl_disp_register\r
+* NAME\r
+*      cl_disp_register\r
+*\r
+* DESCRIPTION\r
+*      This function registers a client with a Dispatcher object.\r
+*\r
+* SYNOPSIS\r
+*/\r
+cl_disp_reg_handle_t\r
+cl_disp_register(IN cl_dispatcher_t * const p_disp,\r
+                IN const cl_disp_msgid_t msg_id,\r
+                IN cl_pfn_msgrcv_cb_t pfn_callback OPTIONAL,\r
+                IN const void *const context);\r
+/*\r
+* PARAMETERS\r
+*      p_disp\r
+*              [in] Pointer to a Dispatcher.\r
+*\r
+*      msg_id\r
+*              [in] Numberic message ID for which the client is registering.\r
+*              If the client does not wish to receive any messages,\r
+*              (a send-only client) then the caller should set this value\r
+*              to CL_DISP_MSGID_NONE.  For efficiency, numeric message msg_id\r
+*              values should start with 0 and should be contiguous, or nearly so.\r
+*\r
+*      pfn_callback\r
+*              [in] Message receive callback.  The Dispatcher calls this\r
+*              function after receiving a posted message with the\r
+*              appropriate message msg_id value.  Send-only clients may specify\r
+*              NULL for this value.\r
+*\r
+*      context\r
+*              [in] Client context value passed to the cl_pfn_msgrcv_cb_t\r
+*              function.\r
+*\r
+* RETURN VALUE\r
+*      On success a Dispatcher registration handle.\r
+*      CL_CL_DISP_INVALID_HANDLE otherwise.\r
+*\r
+* SEE ALSO\r
+*      Dispatcher, cl_disp_unregister, cl_disp_post\r
+*********/\r
+\r
+/****f* Component Library: Dispatcher/cl_disp_unregister\r
+* NAME\r
+*      cl_disp_unregister\r
+*\r
+* DESCRIPTION\r
+*      This function unregisters a client from a Dispatcher.\r
+*\r
+* SYNOPSIS\r
+*/\r
+void cl_disp_unregister(IN const cl_disp_reg_handle_t handle);\r
+/*\r
+* PARAMETERS\r
+*      handle\r
+*              [in] cl_disp_reg_handle_t value return by cl_disp_register.\r
+*\r
+* RETURN VALUE\r
+*      This function does not return a value.\r
+*\r
+* NOTES\r
+*      This function will not return until worker threads have exited\r
+*      the callback functions for this client.  Do not invoke this\r
+*      function from a callback.\r
+*\r
+* SEE ALSO\r
+*      Dispatcher, cl_disp_register\r
+*********/\r
+\r
+/****f* Component Library: Dispatcher/cl_disp_post\r
+* NAME\r
+*      cl_disp_post\r
+*\r
+* DESCRIPTION\r
+*      This function posts a message to a Dispatcher object.\r
+*\r
+* SYNOPSIS\r
+*/\r
+cl_status_t\r
+cl_disp_post(IN const cl_disp_reg_handle_t handle,\r
+            IN const cl_disp_msgid_t msg_id,\r
+            IN const void *const p_data,\r
+            IN cl_pfn_msgdone_cb_t pfn_callback OPTIONAL,\r
+            IN const void *const context);\r
+/*\r
+* PARAMETERS\r
+*      handle\r
+*              [in] cl_disp_reg_handle_t value return by cl_disp_register.\r
+*\r
+*      msg_id\r
+*              [in] Numeric message msg_id value associated with this message.\r
+*\r
+*      p_data\r
+*              [in] Data payload for this message.\r
+*\r
+*      pfn_callback\r
+*              [in] Pointer to a cl_pfn_msgdone_cb_t function.\r
+*              The Dispatcher calls this function after the message has been\r
+*              processed by the recipient.\r
+*              The caller may pass NULL for this value, which indicates no\r
+*              message done callback is necessary.\r
+*\r
+*      context\r
+*              [in] Client context value passed to the cl_pfn_msgdone_cb_t\r
+*              function.\r
+*\r
+* RETURN VALUE\r
+*      CL_SUCCESS if the message was successfully queued in the Dispatcher.\r
+*\r
+* NOTES\r
+*      The caller must not modify the memory pointed to by p_data until\r
+*      the Dispatcher call the pfn_callback function.\r
+*\r
+* SEE ALSO\r
+*      Dispatcher\r
+*********/\r
+\r
+/****f* Component Library: Dispatcher/cl_disp_get_queue_status\r
+* NAME\r
+*      cl_disp_get_queue_status\r
+*\r
+* DESCRIPTION\r
+*      This function posts a message to a Dispatcher object.\r
+*\r
+* SYNOPSIS\r
+*/\r
+void\r
+cl_disp_get_queue_status(IN const cl_disp_reg_handle_t handle,\r
+                        OUT uint32_t * p_num_queued_msgs,\r
+                        OUT uint64_t * p_last_msg_queue_time_ms);\r
+/*\r
+* PARAMETERS\r
+*   handle\r
+*     [in] cl_disp_reg_handle_t value return by cl_disp_register.\r
+*\r
+*   p_last_msg_queue_time_ms\r
+*     [out] pointer to a variable to hold the time the last popped up message\r
+*           spent in the queue\r
+*\r
+*   p_num_queued_msgs\r
+*     [out] number of messages in the queue\r
+*\r
+* RETURN VALUE\r
+*      Thr time the last popped up message stayed in the queue, in msec\r
+*\r
+* NOTES\r
+*      Extarnel Locking is not required.\r
+*\r
+* SEE ALSO\r
+*      Dispatcher\r
+*********/\r
+\r
+END_C_DECLS\r
+#endif                         /* !defined(_CL_DISPATCHER_H_) */\r
index 129eadd..abc5ed0 100644 (file)
-/*
- * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2006 Mellanox Technologies LTD. All rights reserved.
- * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
- *
- * This software is available to you under the OpenIB.org BSD license
- * below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * $Id$
- */
-
-
-/*
- * Abstract:
- *     Declaration of event wheel abstraction.
- * 
- * Environment:
- *     All
- *
- * $Revision: 1.4 $
- */
-
-#ifndef _CL_EVENT_WHEEL_H_
-#define _CL_EVENT_WHEEL_H_
-
-#include <complib/cl_atomic.h>
-#include <complib/cl_qlist.h>
-#include <complib/cl_qmap.h>
-#include <complib/cl_timer.h>
-#include <complib/cl_spinlock.h>
-#include <opensm/osm_log.h>
-
-#ifdef __cplusplus
-#  define BEGIN_C_DECLS extern "C" {
-#  define END_C_DECLS   }
-#else /* !__cplusplus */
-#  define BEGIN_C_DECLS
-#  define END_C_DECLS
-#endif /* __cplusplus */
-
-BEGIN_C_DECLS
-
-/****h* Component Library/Event_Wheel
-* NAME
-*      Event_Wheel
-*
-* DESCRIPTION
-*      The Event_Wheel provides a facility for registering delayed events
-*      and getting called once they timeout.
-*
-*      The Event_Wheel functions operate on a cl_event_wheel_t structure
-*      which should be treated as opaque and should be manipulated
-*      only through the provided functions.
-*
-* SEE ALSO
-*      Structures:
-*              cl_event_wheel_t
-*
-*      Initialization/Destruction:
-*              cl_event_wheel_construct, cl_event_wheel_init, cl_event_wheel_destroy
-*
-*      Manipulation:
-*              cl_event_wheel_reg, cl_event_wheel_unreg
-*
-*********/
-
-/****f* Component Library: Event_Wheel/cl_pfn_event_aged_cb_t
-* NAME
-*      cl_pfn_event_aged_cb_t
-*
-* DESCRIPTION
-*      This typedef defines the prototype for client functions invoked
-*      by the Event_Wheel.  The Event_Wheel calls the corresponding
-*      client function when the specific item has aged.
-*
-* SYNOPSIS
-*/
-typedef uint64_t
-(*cl_pfn_event_aged_cb_t)(
-  IN  uint64_t       key,
-  IN  uint32_t       num_regs,
-  IN   void*                           context);
-/*
-* PARAMETERS
-*  key
-*     [in] The key used for registering the item in the call to
-*     cl_event_wheel_reg
-*
-*  num_regs
-*     [in] The number of times this event was registered (pushed in time).
-*
-*      context
-*              [in] Client specific context specified in a call to
-*              cl_event_wheel_reg
-*
-* RETURN VALUE
-*      This function returns the abosolute time the event should fire in [usec].
-*  If lower then current time means the event should be unregistered
-*  immediatly.
-*
-* NOTES
-*      This typedef provides a function prototype reference for
-*      the function provided by Event_Wheel clients as a parameter
-*      to the cl_event_wheel_reg function.
-*
-* SEE ALSO
-*      Event_Wheel, cl_event_wheel_reg
-*********/
-
-/****s* Component Library: Event_Wheel/cl_event_wheel_t
-* NAME
-*      cl_event_wheel_t
-*
-* DESCRIPTION
-*      Event_Wheel structure.
-*
-*      The Event_Wheel is thread safe.
-*
-*      The cl_event_wheel_t structure should be treated as opaque and should
-*      be manipulated only through the provided functions.
-*
-* SYNOPSIS
-*/
-typedef struct _cl_event_wheel
-{
-  cl_spinlock_t                   lock;
-  cl_spinlock_t           *p_external_lock;
-    
-  cl_qmap_t                events_map;
-  boolean_t                closing;
-  cl_qlist_t               events_wheel;
-  cl_timer_t               timer;
-  osm_log_t                *p_log;
-} cl_event_wheel_t;
-/*
-* FIELDS
-*      lock
-*              Spinlock to guard internal structures.
-*
-*       p_external_lock
-*               Reference to external spinlock to guard internal structures
-*               if the event wheel is part of a larger object protected by its own lock
-*
-*      events_map
-*              A Map holding all registered event items by their key.
-*
-*  closing 
-*     A flag indicating the event wheel is closing. This means that
-*     callbacks that are called when closing == TRUE should just be ignored.
-*
-*      events_wheel
-*              A list of the events sorted by expiration time.
-*
-*      timer
-*              The timer scheduling event time propagation.
-*
-*  p_log
-*     Pointer to opensm log object.
-*
-* SEE ALSO
-*      Event_Wheel
-*********/
-
-/****s* Component Library: Event_Wheel/cl_event_wheel_reg_info_t
-* NAME
-*      cl_event_wheel_reg_info_t
-*
-* DESCRIPTION
-*      Defines the event_wheel registration object structure.
-*
-*      The cl_event_wheel_reg_info_t structure is for internal use by the
-*      Event_Wheel only.
-*
-* SYNOPSIS
-*/
-typedef struct _cl_event_wheel_reg_info
-{
-  cl_map_item_t          map_item;
-  cl_list_item_t                        list_item;
-  uint64_t               key;
-  cl_pfn_event_aged_cb_t pfn_aged_callback;
-  uint64_t               aging_time;
-  uint32_t               num_regs;
-  void                                *context;
-  cl_event_wheel_t              *p_event_wheel;
-} cl_event_wheel_reg_info_t;
-/*
-* FIELDS
-*  map_item 
-*     The map item of this event 
-*
-*  list_item
-*     The sorted by aging time list item
-*
-*  key
-*     The key by which one can find the event
-*
-*      pfn_aged_callback
-*              The clients Event-Aged callback
-*
-*  aging_time
-*     The delta time [msec] for which the event should age.
-*
-*  num_regs
-*     The number of times the same event (key) was registered
-*
-*      context
-*              Client's context for event-aged callback.
-*
-*      p_event_wheel
-*              Pointer to this event wheel object
-*
-* SEE ALSO
-*********/
-
-/****f* Component Library: Event_Wheel/cl_event_wheel_construct
-* NAME
-*      cl_event_wheel_construct
-*
-* DESCRIPTION
-*      This function constructs a Event_Wheel object.
-*
-* SYNOPSIS
-*/
-void
-cl_event_wheel_construct(
-       IN      cl_event_wheel_t* const p_event_wheel );
-/*
-* PARAMETERS
-*      p_event_wheel
-*              [in] Pointer to a Event_Wheel.
-*
-* RETURN VALUE
-*      This function does not return a value.
-*
-* NOTES
-*      Allows calling cl_event_wheel_init and cl_event_wheel_destroy.
-*
-* SEE ALSO
-*      Event_Wheel, cl_event_wheel_init, cl_event_wheel_destroy
-*********/
-
-/****f* Component Library: Event_Wheel/cl_event_wheel_init
-* NAME
-*      cl_event_wheel_init
-*
-* DESCRIPTION
-*      This function initializes a Event_Wheel object.
-*
-* SYNOPSIS
-*/
-cl_status_t
-cl_event_wheel_init(
-  IN   cl_event_wheel_t* const p_event_wheel,
-  IN    osm_log_t               *p_log);
-
-/*
-* PARAMETERS
-*      p_event_wheel
-*              [in] Pointer to a Event_Wheel.
-*
-*  p_log
-*     [in] Pointer to opensm log object to be used for logging
-*
-* RETURN VALUE
-*      CL_SUCCESS if the operation is successful.
-*
-* SEE ALSO
-*      Event_Wheel, cl_event_wheel_destoy, cl_event_wheel_reg, cl_event_wheel_unreg
-*      
-*********/
-
-/****f* Component Library: Event_Wheel/cl_event_wheel_init
-* NAME
-*      cl_event_wheel_init
-*
-* DESCRIPTION
-*      This function initializes a Event_Wheel object.
-*
-* SYNOPSIS
-*/
-cl_status_t
-cl_event_wheel_init_ex(
-  IN   cl_event_wheel_t* const p_event_wheel,
-  IN    osm_log_t               *p_log,
-  IN    cl_spinlock_t           *p_external_lock);
-
-/*
-* PARAMETERS
-*  p_event_wheel
-*     [in] Pointer to a Event_Wheel.
-*
-*  p_log
-*     [in] Pointer to opensm log object to be used for logging
-*
-*  p_external_lock
-*     [in] Reference to external spinlock to guard internal structures
-*          if the event wheel is part of a larger object protected by its own lock
-*
-* RETURN VALUE
-*      CL_SUCCESS if the operation is successful.
-*
-* SEE ALSO
-*      Event_Wheel, cl_event_wheel_destoy, cl_event_wheel_reg, cl_event_wheel_unreg
-*      
-*********/
-
-/****f* Component Library: Event_Wheel/cl_event_wheel_destroy
-* NAME
-*      cl_event_wheel_destroy
-*
-* DESCRIPTION
-*      This function destroys a Event_Wheel object.
-*
-* SYNOPSIS
-*/
-void
-cl_event_wheel_destroy(
-       IN cl_event_wheel_t* const p_event_wheel );
-/*
-* PARAMETERS
-*      p_event_wheel
-*              [in] Pointer to a Event_Wheel.
-*
-* RETURN VALUE
-*      This function does not return a value.
-*
-* NOTES
-*      This function does not returns until all client callback functions
-*  been successfully finished.
-*
-* SEE ALSO
-*      Event_Wheel, cl_event_wheel_construct, cl_event_wheel_init
-*********/
-
-/****f* Component Library: Event_Wheel/cl_event_wheel_dump
-* NAME
-*      cl_event_wheel_dump
-*
-* DESCRIPTION
-*      This function dumps the details of an Event_Whell object.
-*
-* SYNOPSIS
-*/
-void
-cl_event_wheel_dump(
-       IN cl_event_wheel_t* const p_event_wheel );
-/*
-* PARAMETERS
-*      p_event_wheel
-*              [in] Pointer to a Event_Wheel.
-*
-* RETURN VALUE
-*      This function does not return a value.
-*
-* NOTES
-*      Note that this function should be called inside a lock of the event wheel!
-*  It doesn't aquire the lock by itself. 
-*
-* SEE ALSO
-*      Event_Wheel, cl_event_wheel_construct, cl_event_wheel_init
-*********/
-
-/****f* Component Library: Event_Wheel/cl_event_wheel_reg
-* NAME
-*      cl_event_wheel_reg
-*
-* DESCRIPTION
-*      This function registers a client with a Event_Wheel object.
-*
-* SYNOPSIS
-*/
-cl_status_t
-cl_event_wheel_reg(
-       IN cl_event_wheel_t* const p_event_wheel,
-       IN const uint64_t          key,
-       IN const uint64_t          aging_time_usec,
-       IN cl_pfn_event_aged_cb_t  pfn_callback,
-       IN void* const context );
-/*
-* PARAMETERS
-*      p_event_wheel
-*              [in] Pointer to a Event_Wheel.
-*
-*      key
-*              [in] The specifc Key by which events are registered.
-*
-*  aging_time_usec
-*     [in] The absolute time this event should age in usec
-*
-*      pfn_callback
-*              [in] Event Aging callback.  The Event_Wheel calls this
-*              function after the time the event has registed for has come.
-*
-*      context
-*              [in] Client context value passed to the cl_pfn_event_aged_cb_t
-*              function.
-*
-* RETURN VALUE
-*      On success a Event_Wheel CL_SUCCESS or CL_ERROR otherwise.
-*
-* SEE ALSO
-*      Event_Wheel, cl_event_wheel_unreg
-*********/
-
-/****f* Component Library: Event_Wheel/cl_event_wheel_unreg
-* NAME
-*      cl_event_wheel_unreg
-*
-* DESCRIPTION
-*      This function unregisters a client event from a Event_Wheel.
-*
-* SYNOPSIS
-*/
-void
-cl_event_wheel_unreg(
-  IN cl_event_wheel_t* const p_event_wheel,
-  IN uint64_t key );
-/*
-* PARAMETERS
-*      p_event_wheel
-*              [in] Pointer to a Event_Wheel.
-*
-*      key
-*              [in] The key used for registering the event
-*
-* RETURN VALUE
-*      This function does not return a value.
-*
-* NOTES
-*  After the event has aged it is automatically removed from 
-*  the event wheel. So it should only be invoked when the need arises
-*  to remove existing events before they age.
-*
-* SEE ALSO
-*      Event_Wheel, cl_event_wheel_reg
-*********/
-
-/****f* Component Library: Event_Wheel/cl_event_wheel_num_regs
-* NAME
-*      cl_event_wheel_num_regs
-*
-* DESCRIPTION
-*      This function returns the number of times an event was registered.
-*
-* SYNOPSIS
-*/
-uint32_t 
-cl_event_wheel_num_regs(
-  IN cl_event_wheel_t* const p_event_wheel,
-  IN uint64_t key );
-/*
-* PARAMETERS
-*      p_event_wheel
-*              [in] Pointer to a Event_Wheel.
-*
-*      key
-*              [in] The key used for registering the event
-*
-* RETURN VALUE
-*      The number of times the event was registered.
-*  0 if never registered or eventually aged.
-*
-* SEE ALSO
-*      Event_Wheel, cl_event_wheel_reg, cl_event_wheel_unreg
-*********/
-
-END_C_DECLS
-
-#endif /* !defined(_CL_EVENT_WHEEL_H_) */
-
+/*\r
+ * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.\r
+ * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.\r
+ * Copyright (c) 1996-2003 Intel Corporation. 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
+ * Abstract:\r
+ *     Declaration of event wheel abstraction.\r
+ */\r
+\r
+#ifndef _CL_EVENT_WHEEL_H_\r
+#define _CL_EVENT_WHEEL_H_\r
+\r
+#include <complib/cl_atomic.h>\r
+#include <complib/cl_qlist.h>\r
+#include <complib/cl_qmap.h>\r
+#include <complib/cl_timer.h>\r
+#include <complib/cl_spinlock.h>\r
+\r
+#ifdef __cplusplus\r
+#  define BEGIN_C_DECLS extern "C" {\r
+#  define END_C_DECLS   }\r
+#else                          /* !__cplusplus */\r
+#  define BEGIN_C_DECLS\r
+#  define END_C_DECLS\r
+#endif                         /* __cplusplus */\r
+\r
+BEGIN_C_DECLS\r
+/****h* Component Library/Event_Wheel\r
+* NAME\r
+*      Event_Wheel\r
+*\r
+* DESCRIPTION\r
+*      The Event_Wheel provides a facility for registering delayed events\r
+*      and getting called once they timeout.\r
+*\r
+*      The Event_Wheel functions operate on a cl_event_wheel_t structure\r
+*      which should be treated as opaque and should be manipulated\r
+*      only through the provided functions.\r
+*\r
+* SEE ALSO\r
+*      Structures:\r
+*              cl_event_wheel_t\r
+*\r
+*      Initialization/Destruction:\r
+*              cl_event_wheel_construct, cl_event_wheel_init, cl_event_wheel_destroy\r
+*\r
+*      Manipulation:\r
+*              cl_event_wheel_reg, cl_event_wheel_unreg\r
+*\r
+*********/\r
+/****f* Component Library: Event_Wheel/cl_pfn_event_aged_cb_t\r
+* NAME\r
+*      cl_pfn_event_aged_cb_t\r
+*\r
+* DESCRIPTION\r
+*      This typedef defines the prototype for client functions invoked\r
+*      by the Event_Wheel.  The Event_Wheel calls the corresponding\r
+*      client function when the specific item has aged.\r
+*\r
+* SYNOPSIS\r
+*/\r
+typedef uint64_t\r
+    (*cl_pfn_event_aged_cb_t) (IN uint64_t key,\r
+                              IN uint32_t num_regs, IN void *context);\r
+/*\r
+* PARAMETERS\r
+*  key\r
+*     [in] The key used for registering the item in the call to\r
+*     cl_event_wheel_reg\r
+*\r
+*  num_regs\r
+*     [in] The number of times this event was registered (pushed in time).\r
+*\r
+*      context\r
+*              [in] Client specific context specified in a call to\r
+*              cl_event_wheel_reg\r
+*\r
+* RETURN VALUE\r
+*      This function returns the abosolute time the event should fire in [usec].\r
+*  If lower then current time means the event should be unregistered\r
+*  immediatly.\r
+*\r
+* NOTES\r
+*      This typedef provides a function prototype reference for\r
+*      the function provided by Event_Wheel clients as a parameter\r
+*      to the cl_event_wheel_reg function.\r
+*\r
+* SEE ALSO\r
+*      Event_Wheel, cl_event_wheel_reg\r
+*********/\r
+\r
+/****s* Component Library: Event_Wheel/cl_event_wheel_t\r
+* NAME\r
+*      cl_event_wheel_t\r
+*\r
+* DESCRIPTION\r
+*      Event_Wheel structure.\r
+*\r
+*      The Event_Wheel is thread safe.\r
+*\r
+*      The cl_event_wheel_t structure should be treated as opaque and should\r
+*      be manipulated only through the provided functions.\r
+*\r
+* SYNOPSIS\r
+*/\r
+typedef struct _cl_event_wheel {\r
+       cl_spinlock_t lock;\r
+       cl_spinlock_t *p_external_lock;\r
+\r
+       cl_qmap_t events_map;\r
+       boolean_t closing;\r
+       cl_qlist_t events_wheel;\r
+       cl_timer_t timer;\r
+} cl_event_wheel_t;\r
+/*\r
+* FIELDS\r
+*      lock\r
+*              Spinlock to guard internal structures.\r
+*\r
+*       p_external_lock\r
+*               Reference to external spinlock to guard internal structures\r
+*               if the event wheel is part of a larger object protected by its own lock\r
+*\r
+*      events_map\r
+*              A Map holding all registered event items by their key.\r
+*\r
+*  closing\r
+*     A flag indicating the event wheel is closing. This means that\r
+*     callbacks that are called when closing == TRUE should just be ignored.\r
+*\r
+*      events_wheel\r
+*              A list of the events sorted by expiration time.\r
+*\r
+*      timer\r
+*              The timer scheduling event time propagation.\r
+*\r
+* SEE ALSO\r
+*      Event_Wheel\r
+*********/\r
+\r
+/****s* Component Library: Event_Wheel/cl_event_wheel_reg_info_t\r
+* NAME\r
+*      cl_event_wheel_reg_info_t\r
+*\r
+* DESCRIPTION\r
+*      Defines the event_wheel registration object structure.\r
+*\r
+*      The cl_event_wheel_reg_info_t structure is for internal use by the\r
+*      Event_Wheel only.\r
+*\r
+* SYNOPSIS\r
+*/\r
+typedef struct _cl_event_wheel_reg_info {\r
+       cl_map_item_t map_item;\r
+       cl_list_item_t list_item;\r
+       uint64_t key;\r
+       cl_pfn_event_aged_cb_t pfn_aged_callback;\r
+       uint64_t aging_time;\r
+       uint32_t num_regs;\r
+       void *context;\r
+       cl_event_wheel_t *p_event_wheel;\r
+} cl_event_wheel_reg_info_t;\r
+/*\r
+* FIELDS\r
+*  map_item\r
+*     The map item of this event\r
+*\r
+*  list_item\r
+*     The sorted by aging time list item\r
+*\r
+*  key\r
+*     The key by which one can find the event\r
+*\r
+*      pfn_aged_callback\r
+*              The clients Event-Aged callback\r
+*\r
+*  aging_time\r
+*     The delta time [msec] for which the event should age.\r
+*\r
+*  num_regs\r
+*     The number of times the same event (key) was registered\r
+*\r
+*      context\r
+*              Client's context for event-aged callback.\r
+*\r
+*      p_event_wheel\r
+*              Pointer to this event wheel object\r
+*\r
+* SEE ALSO\r
+*********/\r
+\r
+/****f* Component Library: Event_Wheel/cl_event_wheel_construct\r
+* NAME\r
+*      cl_event_wheel_construct\r
+*\r
+* DESCRIPTION\r
+*      This function constructs a Event_Wheel object.\r
+*\r
+* SYNOPSIS\r
+*/\r
+void cl_event_wheel_construct(IN cl_event_wheel_t * const p_event_wheel);\r
+/*\r
+* PARAMETERS\r
+*      p_event_wheel\r
+*              [in] Pointer to a Event_Wheel.\r
+*\r
+* RETURN VALUE\r
+*      This function does not return a value.\r
+*\r
+* NOTES\r
+*      Allows calling cl_event_wheel_init and cl_event_wheel_destroy.\r
+*\r
+* SEE ALSO\r
+*      Event_Wheel, cl_event_wheel_init, cl_event_wheel_destroy\r
+*********/\r
+\r
+/****f* Component Library: Event_Wheel/cl_event_wheel_init\r
+* NAME\r
+*      cl_event_wheel_init\r
+*\r
+* DESCRIPTION\r
+*      This function initializes a Event_Wheel object.\r
+*\r
+* SYNOPSIS\r
+*/\r
+cl_status_t\r
+cl_event_wheel_init(IN cl_event_wheel_t * const p_event_wheel);\r
+\r
+/*\r
+* PARAMETERS\r
+*      p_event_wheel\r
+*              [in] Pointer to a Event_Wheel.\r
+*\r
+* RETURN VALUE\r
+*      CL_SUCCESS if the operation is successful.\r
+*\r
+* SEE ALSO\r
+*      Event_Wheel, cl_event_wheel_destoy, cl_event_wheel_reg, cl_event_wheel_unreg\r
+*\r
+*********/\r
+\r
+/****f* Component Library: Event_Wheel/cl_event_wheel_init\r
+* NAME\r
+*      cl_event_wheel_init\r
+*\r
+* DESCRIPTION\r
+*      This function initializes a Event_Wheel object.\r
+*\r
+* SYNOPSIS\r
+*/\r
+cl_status_t\r
+cl_event_wheel_init_ex(IN cl_event_wheel_t * const p_event_wheel,\r
+                      IN cl_spinlock_t * p_external_lock);\r
+\r
+/*\r
+* PARAMETERS\r
+*  p_event_wheel\r
+*     [in] Pointer to a Event_Wheel.\r
+*\r
+*  p_external_lock\r
+*     [in] Reference to external spinlock to guard internal structures\r
+*          if the event wheel is part of a larger object protected by its own lock\r
+*\r
+* RETURN VALUE\r
+*      CL_SUCCESS if the operation is successful.\r
+*\r
+* SEE ALSO\r
+*      Event_Wheel, cl_event_wheel_destoy, cl_event_wheel_reg, cl_event_wheel_unreg\r
+*\r
+*********/\r
+\r
+/****f* Component Library: Event_Wheel/cl_event_wheel_destroy\r
+* NAME\r
+*      cl_event_wheel_destroy\r
+*\r
+* DESCRIPTION\r
+*      This function destroys a Event_Wheel object.\r
+*\r
+* SYNOPSIS\r
+*/\r
+void cl_event_wheel_destroy(IN cl_event_wheel_t * const p_event_wheel);\r
+/*\r
+* PARAMETERS\r
+*      p_event_wheel\r
+*              [in] Pointer to a Event_Wheel.\r
+*\r
+* RETURN VALUE\r
+*      This function does not return a value.\r
+*\r
+* NOTES\r
+*      This function does not returns until all client callback functions\r
+*  been successfully finished.\r
+*\r
+* SEE ALSO\r
+*      Event_Wheel, cl_event_wheel_construct, cl_event_wheel_init\r
+*********/\r
+\r
+/****f* Component Library: Event_Wheel/cl_event_wheel_dump\r
+* NAME\r
+*      cl_event_wheel_dump\r
+*\r
+* DESCRIPTION\r
+*      This function dumps the details of an Event_Whell object.\r
+*\r
+* SYNOPSIS\r
+*/\r
+void cl_event_wheel_dump(IN cl_event_wheel_t * const p_event_wheel);\r
+/*\r
+* PARAMETERS\r
+*      p_event_wheel\r
+*              [in] Pointer to a Event_Wheel.\r
+*\r
+* RETURN VALUE\r
+*      This function does not return a value.\r
+*\r
+* NOTES\r
+*      Note that this function should be called inside a lock of the event wheel!\r
+*  It doesn't aquire the lock by itself.\r
+*\r
+* SEE ALSO\r
+*      Event_Wheel, cl_event_wheel_construct, cl_event_wheel_init\r
+*********/\r
+\r
+/****f* Component Library: Event_Wheel/cl_event_wheel_reg\r
+* NAME\r
+*      cl_event_wheel_reg\r
+*\r
+* DESCRIPTION\r
+*      This function registers a client with a Event_Wheel object.\r
+*\r
+* SYNOPSIS\r
+*/\r
+cl_status_t\r
+cl_event_wheel_reg(IN cl_event_wheel_t * const p_event_wheel,\r
+                  IN const uint64_t key,\r
+                  IN const uint64_t aging_time_usec,\r
+                  IN cl_pfn_event_aged_cb_t pfn_callback,\r
+                  IN void *const context);\r
+/*\r
+* PARAMETERS\r
+*      p_event_wheel\r
+*              [in] Pointer to a Event_Wheel.\r
+*\r
+*      key\r
+*              [in] The specifc Key by which events are registered.\r
+*\r
+*  aging_time_usec\r
+*     [in] The absolute time this event should age in usec\r
+*\r
+*      pfn_callback\r
+*              [in] Event Aging callback.  The Event_Wheel calls this\r
+*              function after the time the event has registed for has come.\r
+*\r
+*      context\r
+*              [in] Client context value passed to the cl_pfn_event_aged_cb_t\r
+*              function.\r
+*\r
+* RETURN VALUE\r
+*      On success a Event_Wheel CL_SUCCESS or CL_ERROR otherwise.\r
+*\r
+* SEE ALSO\r
+*      Event_Wheel, cl_event_wheel_unreg\r
+*********/\r
+\r
+/****f* Component Library: Event_Wheel/cl_event_wheel_unreg\r
+* NAME\r
+*      cl_event_wheel_unreg\r
+*\r
+* DESCRIPTION\r
+*      This function unregisters a client event from a Event_Wheel.\r
+*\r
+* SYNOPSIS\r
+*/\r
+void\r
+cl_event_wheel_unreg(IN cl_event_wheel_t * const p_event_wheel,\r
+                    IN uint64_t key);\r
+/*\r
+* PARAMETERS\r
+*      p_event_wheel\r
+*              [in] Pointer to a Event_Wheel.\r
+*\r
+*      key\r
+*              [in] The key used for registering the event\r
+*\r
+* RETURN VALUE\r
+*      This function does not return a value.\r
+*\r
+* NOTES\r
+*  After the event has aged it is automatically removed from\r
+*  the event wheel. So it should only be invoked when the need arises\r
+*  to remove existing events before they age.\r
+*\r
+* SEE ALSO\r
+*      Event_Wheel, cl_event_wheel_reg\r
+*********/\r
+\r
+/****f* Component Library: Event_Wheel/cl_event_wheel_num_regs\r
+* NAME\r
+*      cl_event_wheel_num_regs\r
+*\r
+* DESCRIPTION\r
+*      This function returns the number of times an event was registered.\r
+*\r
+* SYNOPSIS\r
+*/\r
+uint32_t\r
+cl_event_wheel_num_regs(IN cl_event_wheel_t * const p_event_wheel,\r
+                       IN uint64_t key);\r
+/*\r
+* PARAMETERS\r
+*      p_event_wheel\r
+*              [in] Pointer to a Event_Wheel.\r
+*\r
+*      key\r
+*              [in] The key used for registering the event\r
+*\r
+* RETURN VALUE\r
+*      The number of times the event was registered.\r
+*  0 if never registered or eventually aged.\r
+*\r
+* SEE ALSO\r
+*      Event_Wheel, cl_event_wheel_reg, cl_event_wheel_unreg\r
+*********/\r
+\r
+END_C_DECLS\r
+#endif                         /* !defined(_CL_EVENT_WHEEL_H_) */\r
diff --git a/ulp/opensm/user/include/iba/ib_cm_types.h b/ulp/opensm/user/include/iba/ib_cm_types.h
new file mode 100644 (file)
index 0000000..29fa2bc
--- /dev/null
@@ -0,0 +1,203 @@
+/*\r
+ * Copyright (c) 2004-2007 Voltaire, Inc. All rights reserved.\r
+ * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.\r
+ * Copyright (c) 1996-2003 Intel Corporation. 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 !defined(__IB_CM_TYPES_H__)\r
+#define __IB_CM_TYPES_H__\r
+\r
+#ifndef __WIN__\r
+\r
+#include <iba/ib_types.h>\r
+\r
+#ifdef __cplusplus\r
+#  define BEGIN_C_DECLS extern "C" {\r
+#  define END_C_DECLS   }\r
+#else                          /* !__cplusplus */\r
+#  define BEGIN_C_DECLS\r
+#  define END_C_DECLS\r
+#endif                         /* __cplusplus */\r
+\r
+BEGIN_C_DECLS\r
+/*\r
+ * Defines known Communication management class versions\r
+ */\r
+#define IB_MCLASS_CM_VER_2                             2\r
+#define IB_MCLASS_CM_VER_1                             1\r
+/*\r
+ *     Defines the size of user available data in communication management MADs\r
+ */\r
+#define IB_REQ_PDATA_SIZE_VER2                         92\r
+#define IB_MRA_PDATA_SIZE_VER2                         222\r
+#define IB_REJ_PDATA_SIZE_VER2                         148\r
+#define IB_REP_PDATA_SIZE_VER2                         196\r
+#define IB_RTU_PDATA_SIZE_VER2                         224\r
+#define IB_LAP_PDATA_SIZE_VER2                         168\r
+#define IB_APR_PDATA_SIZE_VER2                         148\r
+#define IB_DREQ_PDATA_SIZE_VER2                                220\r
+#define IB_DREP_PDATA_SIZE_VER2                                224\r
+#define IB_SIDR_REQ_PDATA_SIZE_VER2                    216\r
+#define IB_SIDR_REP_PDATA_SIZE_VER2                    136\r
+#define IB_REQ_PDATA_SIZE_VER1                         92\r
+#define IB_MRA_PDATA_SIZE_VER1                         222\r
+#define IB_REJ_PDATA_SIZE_VER1                         148\r
+#define IB_REP_PDATA_SIZE_VER1                         204\r
+#define IB_RTU_PDATA_SIZE_VER1                         224\r
+#define IB_LAP_PDATA_SIZE_VER1                         168\r
+#define IB_APR_PDATA_SIZE_VER1                         151\r
+#define IB_DREQ_PDATA_SIZE_VER1                                220\r
+#define IB_DREP_PDATA_SIZE_VER1                                224\r
+#define IB_SIDR_REQ_PDATA_SIZE_VER1                    216\r
+#define IB_SIDR_REP_PDATA_SIZE_VER1                    140\r
+#define IB_ARI_SIZE                                    72      // redefine\r
+#define IB_APR_INFO_SIZE                               72\r
+/****d* Access Layer/ib_rej_status_t\r
+* NAME\r
+*      ib_rej_status_t\r
+*\r
+* DESCRIPTION\r
+*      Rejection reasons.\r
+*\r
+* SYNOPSIS\r
+*/\r
+typedef ib_net16_t ib_rej_status_t;\r
+/*\r
+* SEE ALSO\r
+*      ib_cm_rej, ib_cm_rej_rec_t\r
+*\r
+* SOURCE\r
+*/\r
+#define IB_REJ_INSUF_QP                                        CL_HTON16(1)\r
+#define IB_REJ_INSUF_EEC                               CL_HTON16(2)\r
+#define IB_REJ_INSUF_RESOURCES                         CL_HTON16(3)\r
+#define IB_REJ_TIMEOUT                                 CL_HTON16(4)\r
+#define IB_REJ_UNSUPPORTED                             CL_HTON16(5)\r
+#define IB_REJ_INVALID_COMM_ID                         CL_HTON16(6)\r
+#define IB_REJ_INVALID_COMM_INSTANCE                   CL_HTON16(7)\r
+#define IB_REJ_INVALID_SID                             CL_HTON16(8)\r
+#define IB_REJ_INVALID_XPORT                           CL_HTON16(9)\r
+#define IB_REJ_STALE_CONN                              CL_HTON16(10)\r
+#define IB_REJ_RDC_NOT_EXIST                           CL_HTON16(11)\r
+#define IB_REJ_INVALID_GID                             CL_HTON16(12)\r
+#define IB_REJ_INVALID_LID                             CL_HTON16(13)\r
+#define IB_REJ_INVALID_SL                              CL_HTON16(14)\r
+#define IB_REJ_INVALID_TRAFFIC_CLASS                   CL_HTON16(15)\r
+#define IB_REJ_INVALID_HOP_LIMIT                       CL_HTON16(16)\r
+#define IB_REJ_INVALID_PKT_RATE                                CL_HTON16(17)\r
+#define IB_REJ_INVALID_ALT_GID                         CL_HTON16(18)\r
+#define IB_REJ_INVALID_ALT_LID                         CL_HTON16(19)\r
+#define IB_REJ_INVALID_ALT_SL                          CL_HTON16(20)\r
+#define IB_REJ_INVALID_ALT_TRAFFIC_CLASS               CL_HTON16(21)\r
+#define IB_REJ_INVALID_ALT_HOP_LIMIT                   CL_HTON16(22)\r
+#define IB_REJ_INVALID_ALT_PKT_RATE                    CL_HTON16(23)\r
+#define IB_REJ_PORT_REDIRECT                           CL_HTON16(24)\r
+#define IB_REJ_INVALID_MTU                             CL_HTON16(26)\r
+#define IB_REJ_INSUFFICIENT_RESP_RES                   CL_HTON16(27)\r
+#define IB_REJ_USER_DEFINED                            CL_HTON16(28)\r
+#define IB_REJ_INVALID_RNR_RETRY                       CL_HTON16(29)\r
+#define IB_REJ_DUPLICATE_LOCAL_COMM_ID                 CL_HTON16(30)\r
+#define IB_REJ_INVALID_CLASS_VER                       CL_HTON16(31)\r
+#define IB_REJ_INVALID_FLOW_LBL                                CL_HTON16(32)\r
+#define IB_REJ_INVALID_ALT_FLOW_LBL                    CL_HTON16(33)\r
+\r
+#define IB_REJ_SERVICE_HANDOFF                         CL_HTON16(65535)\r
+/******/\r
+\r
+/****d* Access Layer/ib_apr_status_t\r
+* NAME\r
+*      ib_apr_status_t\r
+*\r
+* DESCRIPTION\r
+*      Automatic path migration status information.\r
+*\r
+* SYNOPSIS\r
+*/\r
+typedef uint8_t ib_apr_status_t;\r
+/*\r
+* SEE ALSO\r
+*      ib_cm_apr, ib_cm_apr_rec_t\r
+*\r
+* SOURCE\r
+ */\r
+#define IB_AP_SUCCESS                                  0\r
+#define IB_AP_INVALID_COMM_ID                          1\r
+#define IB_AP_UNSUPPORTED                              2\r
+#define IB_AP_REJECT                                   3\r
+#define IB_AP_REDIRECT                                 4\r
+#define IB_AP_IS_CURRENT                               5\r
+#define IB_AP_INVALID_QPN_EECN                         6\r
+#define IB_AP_INVALID_LID                              7\r
+#define IB_AP_INVALID_GID                              8\r
+#define IB_AP_INVALID_FLOW_LBL                         9\r
+#define IB_AP_INVALID_TCLASS                           10\r
+#define IB_AP_INVALID_HOP_LIMIT                                11\r
+#define IB_AP_INVALID_PKT_RATE                         12\r
+#define IB_AP_INVALID_SL                               13\r
+/******/\r
+\r
+/****d* Access Layer/ib_cm_cap_mask_t\r
+* NAME\r
+*      ib_cm_cap_mask_t\r
+*\r
+* DESCRIPTION\r
+*      Capability mask values in ClassPortInfo.\r
+*\r
+* SYNOPSIS\r
+*/\r
+#define IB_CM_RELIABLE_CONN_CAPABLE                    CL_HTON16(9)\r
+#define IB_CM_RELIABLE_DGRM_CAPABLE                    CL_HTON16(10)\r
+#define IB_CM_RDGRM_CAPABLE                            CL_HTON16(11)\r
+#define IB_CM_UNRELIABLE_CONN_CAPABLE                  CL_HTON16(12)\r
+#define IB_CM_SIDR_CAPABLE                             CL_HTON16(13)\r
+/*\r
+* SEE ALSO\r
+*      ib_cm_rep, ib_class_port_info_t\r
+*\r
+* SOURCE\r
+*\r
+*******/\r
+\r
+/*\r
+ *     Service ID resolution status\r
+ */\r
+typedef uint16_t ib_sidr_status_t;\r
+#define IB_SIDR_SUCCESS                                        0\r
+#define IB_SIDR_UNSUPPORTED                            1\r
+#define IB_SIDR_REJECT                                 2\r
+#define IB_SIDR_NO_QP                                  3\r
+#define IB_SIDR_REDIRECT                               4\r
+#define IB_SIDR_UNSUPPORTED_VER                                5\r
+\r
+END_C_DECLS\r
+#endif                         /* ndef __WIN__ */\r
+#endif                         /* __IB_CM_TYPES_H__ */\r
index 92d018b..1b0f1f4 100644 (file)
@@ -1,11 +1,14 @@
 /*\r
- * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.\r
- * Copyright (c) 2002-2006 Mellanox Technologies LTD. All rights reserved.\r
+ * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.\r
+ * Copyright (c) 2002-2009 Mellanox Technologies LTD. All rights reserved.\r
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.\r
- * Portions Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ * Copyright (c) 2009 HNR Consulting. All rights reserved.\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
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
  * SOFTWARE.\r
  *\r
- * $Id$\r
  */\r
 \r
-\r
-\r
 #if !defined(__IB_TYPES_H__)\r
 #define __IB_TYPES_H__\r
 \r
 #ifdef __cplusplus\r
 #  define BEGIN_C_DECLS extern "C" {\r
 #  define END_C_DECLS   }\r
-#else /* !__cplusplus */\r
+#else                          /* !__cplusplus */\r
 #  define BEGIN_C_DECLS\r
 #  define END_C_DECLS\r
-#endif /* __cplusplus */\r
+#endif                         /* __cplusplus */\r
 \r
 BEGIN_C_DECLS\r
-\r
-#if defined( WIN32 ) || defined( _WIN64 )\r
-    #if defined( EXPORT_AL_SYMBOLS )\r
-         #define OSM_EXPORT    __declspec(dllexport)\r
-    #else\r
-         #define OSM_EXPORT    __declspec(dllimport)\r
-    #endif\r
-    #define OSM_API __stdcall\r
-    #define OSM_CDECL __cdecl\r
+#if defined( __WIN__ )\r
+#if defined( EXPORT_AL_SYMBOLS )\r
+#define OSM_EXPORT     __declspec(dllexport)\r
 #else\r
-    #define OSM_EXPORT extern\r
-    #define OSM_API\r
-    #define OSM_CDECL\r
-    #define __ptr64\r
+#define OSM_EXPORT     __declspec(dllimport)\r
+#endif\r
+#define OSM_API __stdcall\r
+#define OSM_CDECL __cdecl\r
+#else\r
+#define OSM_EXPORT     extern\r
+#define OSM_API\r
+#define OSM_CDECL\r
+#define __ptr64\r
 #endif\r
-\r
-\r
-#define IB_CONCAT(str1, str2) str1##str2\r
-\r
-#define TO_LONG_PTR(type,member_name) \\r
-    union { type member_name;  uint64_t IB_CONCAT(member_name,_padding) ; }\r
-\r
-\r
-\r
 /****h* IBA Base/Constants\r
 * NAME\r
 *      Constants\r
@@ -84,7 +74,6 @@ BEGIN_C_DECLS
 *      Definitions are from the InfiniBand Architecture Specification v1.2\r
 *\r
 *********/\r
-\r
 /****d* IBA Base: Constants/MAD_BLOCK_SIZE\r
 * NAME\r
 *      MAD_BLOCK_SIZE\r
@@ -96,7 +85,6 @@ BEGIN_C_DECLS
 */\r
 #define MAD_BLOCK_SIZE                                         256\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/MAD_RMPP_HDR_SIZE\r
 * NAME\r
 *      MAD_RMPP_HDR_SIZE\r
@@ -108,7 +96,6 @@ BEGIN_C_DECLS
 */\r
 #define MAD_RMPP_HDR_SIZE                                      36\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/MAD_RMPP_DATA_SIZE\r
 * NAME\r
 *      MAD_RMPP_DATA_SIZE\r
@@ -120,7 +107,6 @@ BEGIN_C_DECLS
 */\r
 #define MAD_RMPP_DATA_SIZE             (MAD_BLOCK_SIZE - MAD_RMPP_HDR_SIZE)\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/MAD_BLOCK_GRH_SIZE\r
 * NAME\r
 *      MAD_BLOCK_GRH_SIZE\r
@@ -132,7 +118,6 @@ BEGIN_C_DECLS
 */\r
 #define MAD_BLOCK_GRH_SIZE                                     296\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_LID_PERMISSIVE\r
 * NAME\r
 *      IB_LID_PERMISSIVE\r
@@ -144,7 +129,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_LID_PERMISSIVE                                      0xFFFF\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_DEFAULT_PKEY\r
 * NAME\r
 *      IB_DEFAULT_PKEY\r
@@ -156,7 +140,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_DEFAULT_PKEY                                                0xFFFF\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_QP1_WELL_KNOWN_Q_KEY\r
 * NAME\r
 *      IB_QP1_WELL_KNOWN_Q_KEY\r
@@ -166,14 +149,11 @@ BEGIN_C_DECLS
 *\r
 * SOURCE\r
 */\r
-#define IB_QP1_WELL_KNOWN_Q_KEY                                CL_NTOH32(0x80010000)\r
+#define IB_QP1_WELL_KNOWN_Q_KEY                                CL_HTON32(0x80010000)\r
 /*********/\r
-\r
 #define IB_QP0                                                         0\r
-#define IB_QP1                                                         CL_NTOH32(1)\r
-\r
-#define IB_QP_PRIVILEGED_Q_KEY                         CL_NTOH32(0x80000000)\r
-\r
+#define IB_QP1                                                         CL_HTON32(1)\r
+#define IB_QP_PRIVILEGED_Q_KEY                         CL_HTON32(0x80000000)\r
 /****d* IBA Base: Constants/IB_LID_UCAST_START\r
 * NAME\r
 *      IB_LID_UCAST_START\r
@@ -186,7 +166,6 @@ BEGIN_C_DECLS
 #define IB_LID_UCAST_START_HO                          0x0001\r
 #define IB_LID_UCAST_START                                     (CL_HTON16(IB_LID_UCAST_START_HO))\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_LID_UCAST_END\r
 * NAME\r
 *      IB_LID_UCAST_END\r
@@ -199,7 +178,6 @@ BEGIN_C_DECLS
 #define IB_LID_UCAST_END_HO                                    0xBFFF\r
 #define IB_LID_UCAST_END                                       (CL_HTON16(IB_LID_UCAST_END_HO))\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_LID_MCAST_START\r
 * NAME\r
 *      IB_LID_MCAST_START\r
@@ -212,7 +190,6 @@ BEGIN_C_DECLS
 #define IB_LID_MCAST_START_HO                          0xC000\r
 #define IB_LID_MCAST_START                                     (CL_HTON16(IB_LID_MCAST_START_HO))\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_LID_MCAST_END\r
 * NAME\r
 *      IB_LID_MCAST_END\r
@@ -225,7 +202,6 @@ BEGIN_C_DECLS
 #define IB_LID_MCAST_END_HO                                    0xFFFE\r
 #define IB_LID_MCAST_END                                       (CL_HTON16(IB_LID_MCAST_END_HO))\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_DEFAULT_SUBNET_PREFIX\r
 * NAME\r
 *      IB_DEFAULT_SUBNET_PREFIX\r
@@ -237,7 +213,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_DEFAULT_SUBNET_PREFIX                       (CL_HTON64(0xFE80000000000000ULL))\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_NODE_NUM_PORTS_MAX\r
 * NAME\r
 *      IB_NODE_NUM_PORTS_MAX\r
@@ -248,7 +223,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_NODE_NUM_PORTS_MAX                          0xFE\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_INVALID_PORT_NUM\r
 * NAME\r
 *      IB_INVALID_PORT_NUM\r
@@ -260,7 +234,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_INVALID_PORT_NUM                                    0xFF\r
 /*********/\r
-\r
 /****d* IBA Base: Constants/IB_SUBNET_PATH_HOPS_MAX\r
 * NAME\r
 *      IB_SUBNET_PATH_HOPS_MAX\r
@@ -272,7 +245,29 @@ BEGIN_C_DECLS
 */\r
 #define IB_SUBNET_PATH_HOPS_MAX                                64\r
 /*********/\r
-\r
+/****d* IBA Base: Constants/IB_HOPLIMIT_MAX\r
+* NAME\r
+*      IB_HOPLIMIT_MAX\r
+*\r
+* DESCRIPTION\r
+*       Maximum number of router hops allowed.\r
+*\r
+* SOURCE\r
+*/\r
+#define IB_HOPLIMIT_MAX                                        255\r
+/*********/\r
+/****d* IBA Base: Constants/IB_MC_SCOPE_*\r
+* NAME\r
+*      IB_MC_SCOPE_*\r
+*\r
+* DESCRIPTION\r
+*      Scope component definitions from IBA 1.2.1 (Table 3 p. 148)\r
+*/\r
+#define IB_MC_SCOPE_LINK_LOCAL         0x2\r
+#define IB_MC_SCOPE_SITE_LOCAL         0x5\r
+#define IB_MC_SCOPE_ORG_LOCAL          0x8\r
+#define IB_MC_SCOPE_GLOBAL             0xE\r
+/*********/\r
 /****d* IBA Base: Constants/IB_PKEY_MAX_BLOCKS\r
 * NAME\r
 *      IB_PKEY_MAX_BLOCKS\r
@@ -284,7 +279,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_PKEY_MAX_BLOCKS                                     2048\r
 /*********/\r
-\r
 /****d* IBA Base: Constants/IB_MCAST_MAX_BLOCK_ID\r
 * NAME\r
 *      IB_MCAST_MAX_BLOCK_ID\r
@@ -296,7 +290,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_MCAST_MAX_BLOCK_ID                          511\r
 /*********/\r
-\r
 /****d* IBA Base: Constants/IB_MCAST_BLOCK_ID_MASK_HO\r
 * NAME\r
 *      IB_MCAST_BLOCK_ID_MASK_HO\r
@@ -308,7 +301,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_MCAST_BLOCK_ID_MASK_HO                      0x000001FF\r
 /*********/\r
-\r
 /****d* IBA Base: Constants/IB_MCAST_BLOCK_SIZE\r
 * NAME\r
 *      IB_MCAST_BLOCK_SIZE\r
@@ -320,7 +312,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_MCAST_BLOCK_SIZE                                    32\r
 /*********/\r
-\r
 /****d* IBA Base: Constants/IB_MCAST_MASK_SIZE\r
 * NAME\r
 *      IB_MCAST_MASK_SIZE\r
@@ -332,7 +323,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_MCAST_MASK_SIZE                                     16\r
 /*********/\r
-\r
 /****d* IBA Base: Constants/IB_MCAST_POSITION_MASK_HO\r
 * NAME\r
 *      IB_MCAST_POSITION_MASK_HO\r
@@ -344,7 +334,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_MCAST_POSITION_MASK_HO                              0xF0000000\r
 /*********/\r
-\r
 /****d* IBA Base: Constants/IB_MCAST_POSITION_MAX\r
 * NAME\r
 *      IB_MCAST_POSITION_MAX\r
@@ -356,7 +345,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_MCAST_POSITION_MAX                          0xF\r
 /*********/\r
-\r
 /****d* IBA Base: Constants/IB_MCAST_POSITION_SHIFT\r
 * NAME\r
 *      IB_MCAST_POSITION_SHIFT\r
@@ -368,7 +356,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_MCAST_POSITION_SHIFT                                28\r
 /*********/\r
-\r
 /****d* IBA Base: Constants/IB_PKEY_ENTRIES_MAX\r
 * NAME\r
 *      IB_PKEY_ENTRIES_MAX\r
@@ -380,7 +367,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_PKEY_ENTRIES_MAX (IB_PKEY_MAX_BLOCKS * IB_NUM_PKEY_ELEMENTS_IN_BLOCK)\r
 /*********/\r
-\r
 /****d* IBA Base: Constants/IB_PKEY_BASE_MASK\r
 * NAME\r
 *      IB_PKEY_BASE_MASK\r
@@ -392,7 +378,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_PKEY_BASE_MASK                                      (CL_HTON16(0x7FFF))\r
 /*********/\r
-\r
 /****d* IBA Base: Constants/IB_PKEY_TYPE_MASK\r
 * NAME\r
 *      IB_PKEY_TYPE_MASK\r
@@ -402,12 +387,11 @@ BEGIN_C_DECLS
 *\r
 * SOURCE\r
 */\r
-#define IB_PKEY_TYPE_MASK                                      (CL_NTOH16(0x8000))\r
+#define IB_PKEY_TYPE_MASK                                      (CL_HTON16(0x8000))\r
 /*********/\r
-\r
 /****d* IBA Base: Constants/IB_DEFAULT_PARTIAL_PKEY\r
 * NAME\r
-*      IB_DEFAULT_PARTIAL_PKEY \r
+*      IB_DEFAULT_PARTIAL_PKEY\r
 *\r
 * DESCRIPTION\r
 *      0x7FFF in network order\r
@@ -416,7 +400,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_DEFAULT_PARTIAL_PKEY                                       (CL_HTON16(0x7FFF))\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_MCLASS_SUBN_LID\r
 * NAME\r
 *      IB_MCLASS_SUBN_LID\r
@@ -428,7 +411,6 @@ BEGIN_C_DECLS
 */\r
 #define IB_MCLASS_SUBN_LID                                     0x01\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_MCLASS_SUBN_DIR\r
 * NAME\r
 *      IB_MCLASS_SUBN_DIR\r
@@ -440,175 +422,162 @@ BEGIN_C_DECLS
 */\r
 #define IB_MCLASS_SUBN_DIR                                     0x81\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_MCLASS_SUBN_ADM\r
 * NAME\r
 *      IB_MCLASS_SUBN_ADM\r
 *\r
 * DESCRIPTION\r
-*      Subnet Management Class, Subnet Administration (13.4.4)\r
+*      Management Class, Subnet Administration (13.4.4)\r
 *\r
 * SOURCE\r
 */\r
 #define IB_MCLASS_SUBN_ADM                                     0x03\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_MCLASS_PERF\r
 * NAME\r
 *      IB_MCLASS_PERF\r
 *\r
 * DESCRIPTION\r
-*      Subnet Management Class, Performance Manager (13.4.4)\r
+*      Management Class, Performance Management (13.4.4)\r
 *\r
 * SOURCE\r
 */\r
 #define IB_MCLASS_PERF                                         0x04\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_MCLASS_BM\r
 * NAME\r
 *      IB_MCLASS_BM\r
 *\r
 * DESCRIPTION\r
-*      Subnet Management Class, Baseboard Manager (13.4.4)\r
+*      Management Class, Baseboard Management (13.4.4)\r
 *\r
 * SOURCE\r
 */\r
 #define IB_MCLASS_BM                                           0x05\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_MCLASS_DEV_MGMT\r
 * NAME\r
 *      IB_MCLASS_DEV_MGMT\r
 *\r
 * DESCRIPTION\r
-*      Subnet Management Class, Device Management (13.4.4)\r
+*      Management Class, Device Management (13.4.4)\r
 *\r
 * SOURCE\r
 */\r
 #define IB_MCLASS_DEV_MGMT                                     0x06\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_MCLASS_COMM_MGMT\r
 * NAME\r
 *      IB_MCLASS_COMM_MGMT\r
 *\r
 * DESCRIPTION\r
-*      Subnet Management Class, Communication Management (13.4.4)\r
+*      Management Class, Communication Management (13.4.4)\r
 *\r
 * SOURCE\r
 */\r
 #define IB_MCLASS_COMM_MGMT                                    0x07\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_MCLASS_SNMP\r
 * NAME\r
 *      IB_MCLASS_SNMP\r
 *\r
 * DESCRIPTION\r
-*      Subnet Management Class, SNMP Tunneling (13.4.4)\r
+*      Management Class, SNMP Tunneling (13.4.4)\r
 *\r
 * SOURCE\r
 */\r
 #define IB_MCLASS_SNMP                                         0x08\r
 /**********/\r
-\r
 /****d* IBA Base: Constants/IB_MCLASS_VENDOR_LOW_RANGE_MIN\r
 * NAME\r
 *      IB_MCLASS_VENDOR_LOW_RANGE_MIN\r
 *\r
 * DESCRIPTION\r
-*      Subnet Management Class, Vendor Specific Low Range Start\r
+*      Management Class, Vendor Specific Low Range Start\r
 *\r
 * SOURCE\r
 */\r
 #define IB_MCLASS_VENDOR_LOW_RANGE_MIN 0x09