[Pkg-ofed-commits] [opensm] 01/06: Imported Upstream version 3.3.18

Ana Beatriz Guerrero López ana at moszumanska.debian.org
Fri Aug 1 13:48:51 UTC 2014


This is an automated email from the git hooks/post-receive script.

ana pushed a commit to branch master
in repository opensm.

commit 80eb2c4a53124e35517079edcdd3dee78c5217b1
Author: Ana Guerrero López <ana at ekaia.org>
Date:   Fri Aug 1 14:36:56 2014 +0200

    Imported Upstream version 3.3.18
---
 ChangeLog                           | 547 ++++++++++++++++++++++
 Makefile.am                         |   2 +-
 Makefile.in                         |   8 +-
 config/compile                      | 142 ++++++
 config/config.guess                 | 866 +++++++++++++++-------------------
 config/config.sub                   | 351 +++-----------
 configure                           |  20 +-
 configure.in                        |   2 +-
 doc/current-routing.txt             | 907 ++++++++++++++++++++++++++++++++++++
 doc/opensm_release_notes-3.3.txt    | 137 +++++-
 doc/performance-manager-HOWTO.txt   |   2 +-
 include/iba/ib_types.h              |  63 ++-
 include/opensm/osm_base.h           |   2 +
 include/opensm/osm_event_plugin.h   |   1 +
 include/opensm/osm_lid_mgr.h        |  12 +-
 include/opensm/osm_perfmgr.h        |  10 +-
 include/opensm/osm_perfmgr_db.h     |   4 +-
 include/opensm/osm_sm.h             |   2 +-
 include/opensm/osm_subnet.h         |  25 +-
 include/opensm/osm_version.h        |   2 +-
 include/opensm/osm_vl15intf.h       |  11 +-
 include/vendor/osm_vendor_sa_api.h  |   8 +
 libvendor/libosmvendor.ver          |   2 +-
 libvendor/osm_vendor_ibumad.c       | 108 ++++-
 libvendor/osm_vendor_ibumad_sa.c    |  14 +
 man/opensm.8                        |  18 +-
 man/opensm.8.in                     |  18 +-
 opensm.spec                         |   6 +-
 opensm.spec.in                      |   2 +-
 opensm/libopensm.ver                |   2 +-
 opensm/main.c                       |   4 +-
 opensm/osm_congestion_control.c     |  16 +-
 opensm/osm_console.c                |   2 -
 opensm/osm_console_io.c             |  11 +-
 opensm/osm_drop_mgr.c               |   8 +-
 opensm/osm_guid_info_rcv.c          |  10 +-
 opensm/osm_helper.c                 |   4 +-
 opensm/osm_lid_mgr.c                |  12 +-
 opensm/osm_lin_fwd_rcv.c            |   8 +
 opensm/osm_link_mgr.c               |   1 +
 opensm/osm_log.c                    |   5 +-
 opensm/osm_mcast_fwd_rcv.c          |   8 +
 opensm/osm_mcast_mgr.c              |   6 +-
 opensm/osm_node_desc_rcv.c          |   8 +
 opensm/osm_node_info_rcv.c          |  68 ++-
 opensm/osm_opensm.c                 |   2 +-
 opensm/osm_perfmgr.c                | 116 +++--
 opensm/osm_perfmgr_db.c             |  27 +-
 opensm/osm_pkey_rcv.c               |   8 +
 opensm/osm_port.c                   |   6 +-
 opensm/osm_port_info_rcv.c          | 202 ++++++--
 opensm/osm_qos.c                    |  18 +-
 opensm/osm_qos_parser_y.c           | 338 +++++++-------
 opensm/osm_qos_parser_y.y           |  18 +
 opensm/osm_sa.c                     |  67 ++-
 opensm/osm_sa_guidinfo_record.c     |  71 ++-
 opensm/osm_sa_informinfo.c          |   9 +-
 opensm/osm_sa_lft_record.c          |   5 +-
 opensm/osm_sa_link_record.c         |   5 +-
 opensm/osm_sa_mad_ctrl.c            |  14 +-
 opensm/osm_sa_mcmember_record.c     |  35 +-
 opensm/osm_sa_mft_record.c          |   5 +-
 opensm/osm_sa_multipath_record.c    |  67 ++-
 opensm/osm_sa_node_record.c         |   5 +-
 opensm/osm_sa_path_record.c         |  83 ++--
 opensm/osm_sa_pkey_record.c         |   5 +-
 opensm/osm_sa_portinfo_record.c     |   5 +-
 opensm/osm_sa_service_record.c      |  19 +-
 opensm/osm_sa_slvl_record.c         |   5 +-
 opensm/osm_sa_sminfo_record.c       |   5 +-
 opensm/osm_sa_sw_info_record.c      |   5 +-
 opensm/osm_sa_vlarb_record.c        |   5 +-
 opensm/osm_slvl_map_rcv.c           |   9 +
 opensm/osm_sm.c                     |   2 +-
 opensm/osm_sm_mad_ctrl.c            |  20 +-
 opensm/osm_sm_state_mgr.c           |  40 +-
 opensm/osm_sminfo_rcv.c             |  15 +-
 opensm/osm_state_mgr.c              | 100 +++-
 opensm/osm_subnet.c                 | 135 +++++-
 opensm/osm_sw_info_rcv.c            |  60 ++-
 opensm/osm_torus.c                  |  15 +-
 opensm/osm_trap_rcv.c               |  12 +-
 opensm/osm_ucast_dfsssp.c           |  46 +-
 opensm/osm_ucast_ftree.c            |   5 +-
 opensm/osm_ucast_mgr.c              |  24 +-
 opensm/osm_ucast_updn.c             |   4 +-
 opensm/osm_vl15intf.c               |  22 +-
 opensm/osm_vl_arb_rcv.c             |   8 +
 osmeventplugin/src/osmeventplugin.c |   4 +-
 osmtest/include/osmtest.h           |   2 +
 osmtest/main.c                      |  17 +-
 osmtest/osmt_multicast.c            |  14 +
 osmtest/osmt_service.c              |  46 ++
 osmtest/osmt_slvl_vl_arb.c          |  10 +
 osmtest/osmtest.c                   | 165 ++++++-
 scripts/opensm.init                 |   2 +
 scripts/opensm.init.in              |   2 +
 97 files changed, 3955 insertions(+), 1439 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 479cf89..e74a8a8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,553 @@
 
 ** Version: HEAD
 
+Wed Jul 16 22:28:15 2014 +0300 Hal Rosenstock
+77f713a8fdb1ce31a24488b370b14dd6f3cf7aaf
+
+	* Update package number for OpenSM to 3.3.18 for release
+
+Wed Jul 16 22:26:35 2014 +0300 Hal Rosenstock
+b2116433f65ebf00d861c875c89aecf88abc05fa
+
+	* Update opensm_release_notes-3.3.txt
+
+Wed Jul 16 21:58:35 2014 +0300 Hal Rosenstock
+7a55d6eafe0800ebf5ef107784417034605e5370
+
+	* Update (internal) shared library versions
+
+Tue Jul 15 16:03:25 2014 +0300 Hal Rosenstock
+179fbacc38a9eefde1cb5c9899e46771d81e6edd
+
+	* Add support for additional Mellanox OUI
+
+Mon Jul 14 13:40:26 2014 +0300 Shlomi Nimrodi
+be3e4f1209e03f1bf8469e85b8fa505cb222985c
+
+	* osm_subnet.c: Remove duplicate strcmp check in osm_subn_rescan_conf_files method
+
+Mon Mar 31 17:52:51 2014 +0300 Ilya Nelkenbaum
+e6fc2f8032d45eeefbe1d6ff12a37ef13354aa0b
+
+	* Add some missing documentation files to installation
+
+Fri Jul 11 23:55:34 2014 +0300 Hal Rosenstock
+ed1571a2c2eaa98357918b494a670f2d0baf5b05
+
+	* osm_subnet.c: Change default for perfmgr_query_cpi option
+
+Fri Jul 11 16:31:25 2014 +0300 Hal Rosenstock
+3a1b458a969a4ebb6eab6257081eee6aac6b470a
+
+	* osm_mcast_mgr.c: Cosmetic change to error log mesage
+
+Mon Jun 2 09:49:56 2014 +0300 Daniel Klein
+56bd96411d84e3818467eeabfd7c556489d0c823
+
+	* opensm.init.in: Fix return value checking in opensm.init script
+
+Wed Jul 2 13:31:47 2014 +0300 Shlomi Nimrodi
+787c16e1dea267ced6be376abb93a5e16342bb94
+
+	* Eliminate redundant calls to ib_port_info_compute_rate
+
+Mon Jun 30 12:35:58 2014 +0300 Shlomi Nimrodi
+6a2d0819e8b4b1468222400baa7a9d4cdeb466df
+
+	* Shorten long lines while calculating SA rate
+
+Fri Jul 4 12:21:03 2014 +0300 Hal Rosenstock
+6ec10d6508127e4ec8ab8a37e26b6e6c338817e8
+
+	* man/opensm.8.in: Update date on man page
+
+Fri Jul 4 12:17:22 2014 +0300 Hal Rosenstock
+1dcf322f2f53c190335403ba46e7006f2d5ad409
+
+	* Improve scatter ports documentation
+
+Fri Jul 4 11:51:47 2014 +0300 Hal Rosenstock
+b1a8fb0612d7bef23456a812087b14021877e417
+
+	* osm_subnet.c: Cosmetic formatting change in subn_validate_neighbor
+
+Tue Jul 1 11:43:39 2014 -0700 Albert Chu
+db69cd8dbbbd76b3a0ce9834d18320c29a8b0a99
+
+	* osm_perfmgr.c: Fix perfmgr sweep_state race
+
+Fri Jun 27 10:55:33 2014 -0700 Albert Chu
+d1b70fccba48f732d3e76caad0207985caa4387a
+
+	* osm_perfmgr.c: Add log message when perfmgr sweep is skipped
+
+Fri Jun 27 10:55:19 2014 -0700 Albert Chu
+8098a4d7eaa00a1994d3290825cb7030a77233c7
+
+	* osm_perfmgr.c: Remove unnecessary log message
+
+Wed Jun 18 16:53:22 2014 +0300 Vladimir Koushnir
+38bc2e449cc171b17c4dc39e79a0c7242dc33d60
+
+	* Skip state_mgr_check_tbl_consistency when no LID is changed by lid or link managers
+
+Thu Jun 26 14:27:53 2014 +0300 Vladimir Koushnir
+ce73c60d761ab33c3edd6c9fd969be6970896e07
+
+	* osm_drop_mgr.c: Add missing CR at end of log message in drop_mgr_check_node
+
+Tue Jun 17 16:08:21 2014 +0300 Vladimir Koushnir
+8255f8f90bf9e383ff8392735d7f96b748f03644
+
+	* osm_state_mgr.c: Improve error flow with wrong LIDs
+
+Tue Jun 24 18:13:01 2014 +0300 Hal Rosenstock
+86f1720d0ec0ee13accfa65a80c5c21b578fe874
+
+	* osm_sa_path_record.c: Fix some commentary typos
+
+Tue Jun 24 18:11:56 2014 +0300 Hal Rosenstock
+2bc6074c23f3d2759a8fdefe300600938229cb7a
+
+	* osmtest/main.c: Output formatting change for case 'x'
+
+Thu Jun 12 17:24:49 2014 +0300 Dan Ben Yosef
+60727f7193823a50849a67dab9c5ebd54e39dc93
+
+	* osmtest: Add GRH tests for SA queries
+
+Tue Aug 28 18:04:04 2012 +0300 Hal Rosenstock
+b42f11f87dc7f4944eab7f883248210402451f5d
+
+	* osm_vendor_ibumad.c: Better match table eviction strategy
+
+Sun Jun 8 13:46:24 2014 +0300 Vladimir Koushnir
+cc0d61b60db5e2b10c38f414a0e713ae423ffe00
+
+	* libvendor/osm_vendor_ibumad.c: Check the next CA if an error is returned for the current one
+
+Thu Jun 5 12:52:40 2014 +0300 Vladimir Koushnir
+a16349de0c5a8ae55407700459a16d7e196667cc
+
+	* osm_trap_rcv.c: Lock released without locking in some cases of trap processing
+
+Sun Jun 1 15:55:34 2014 +0300 Vladimir Koushnir
+6c6e4cced86f56966a2b5eb9f6687858ccba966e
+
+	* osm_sa_guidinfo_record.c: Fix crash when receiving AGUID SET/DELETE with block_num equal to max_block
+
+Sun Jun 1 09:44:26 2014 +0300 Tomer Cohen
+a8b23b7b15f2457d4f2f72d6345224f1bed8a466
+
+	* osm_vl15intf.c: Fix potential NULL dereference in vl15_send_mad
+
+Sun Jun 1 09:13:03 2014 +0300 Tomer Cohen
+d29dcd71eab6f970b3c2be7d0e1c01dd145a85cc
+
+	* osm_sa_path_record.c: Fix misleading error messages during sweep
+
+Thu Nov 8 15:33:32 2012 +0200 Alex Netes
+e91908bd2fc5524017095765b272c2c4e4274a3b
+
+	* Add osm_congestion_control.c to per module logging support
+
+Wed Jan 16 21:57:31 2013 +0200 Hal Rosenstock
+3de10912416a7aba8b95a7f741dc71ed9f3cea1b
+
+	* osm_congestion_control.c: Fix error code
+
+Wed May 28 23:14:52 2014 +0300 Hal Rosenstock
+3ee0a22d7a9765aede09c3ec8aaf1f01183a0c6d
+
+	* osm_sm.c: In sm_sweeper, no need to check for timeout after cl_event_wait_on EVENT_NO_TIMEOUT
+
+Wed May 28 23:13:32 2014 +0300 Hal Rosenstock
+f3e19243b1161964b3522e583ae84b7d8719cfb3
+
+	* osm_trap_rcv.c: In shutup_noisy_port, improve ERR 3811 log message
+
+Wed May 28 23:12:20 2014 +0300 Hal Rosenstock
+f73ff4349349be7443f45c49504563d134370077
+
+	* osm_mcast_mgr.c: In mcast_mgr_process_mlid, cosmetic change to log message
+
+Wed May 28 23:10:32 2014 +0300 Hal Rosenstock
+ab9fec9da0dce24f7534f862019e0b0191cde4a1
+
+	* osm_congestion_control.c: In cc_poller_send, handle cl_event_wait_on return status
+
+Wed Jan 9 19:31:04 2013 +0200 Hal Rosenstock
+af04af757f11f487ff290863299ac46848f2426d
+
+	* osm_[sm sa]_mad_ctrl.c: Improve unsupported attribute error messages
+
+Tue May 27 19:03:14 2014 +0300 Shlomi Nimrodi
+16fee25cecdf47dd357dbbd928f3f346011815b2
+
+	* osm_helper.c: In osm_get_lsa_str, fix printing of wrong FDR10 data if link is down
+
+Wed May 28 22:58:38 2014 +0300 Hal Rosenstock
+6c70bf17da72294d31bab7882fed9fba1ec94d33
+
+	* PerfMgr: Eliminate no longer used sig_sweep variable
+
+Thu May 15 16:23:19 2014 +0300 Hal Rosenstock
+41d0a42ad7c207640f97a653c3ff65c73acfe00c
+
+	* osm_perfmgr.c: In perfmgr_send_mad, handle cl_event_wait_on return status
+
+Thu May 15 16:11:13 2014 +0300 Hal Rosenstock
+d764777305f3bd9065eb2fa5946c375fc1c6e2b5
+
+	* osm_perfmgr.c: Minor code factoring in perfmgr_send_mad
+
+Wed May 14 20:50:50 2014 +0300 Hal Rosenstock
+fa31298650410b2da0201b1d3afe489b458c9bcd
+
+	* doc/opensm_release_notes-3.3.txt: Updated repo location
+
+Tue May 13 15:59:40 2014 +0300 Hal Rosenstock
+8394ef8e066ac058241e0a7134e4c7bccad364a9
+
+	* libvendor/osm_vendor_ibumad.c: Commentary change
+
+Wed May 7 21:21:47 2014 +0300 Hal Rosenstock
+0ab7492e87eed3acaf6afd429ce6966283597758
+
+	* osm_subnet.c: More cosmetic changes to opensm conf file PerfMgr documentation
+
+Wed May 7 21:12:25 2014 +0300 Hal Rosenstock
+cc977bed550ad985ed3e24dfd844d04630904587
+
+	* osm_subnet.c: Enhance opensm conf file documentation for PerfMgr options
+
+Sun Apr 13 15:26:47 2014 +0300 Tomer Cohen
+38273db59e80fb5672d16003b72f8acf59069cef
+
+	* osm_port_info_rcv.c: Fixed calculation of min_data_vls
+
+Wed May 7 08:55:39 2014 +0300 Hal Rosenstock
+dc3259eafdc8eae5be5704d52ad8abb13ef05660
+
+	* Add support for additional Mellanox OUI
+
+Sun May 4 11:38:01 2014 +0300 Tomer Cohen
+99a8e74c976035b3b921635ac42f1aac1917c752
+
+	* osmtest.c: Fixed missing assignment of return value from function osmtest_get_port_rec_by_num
+
+Mon Mar 17 13:10:01 2014 +0200 Daniel Klein
+9ffa520210a805b62067d2600325c57b17d781fb
+
+	* Fix the creation of empty multicast groups from SADB
+
+Sat May 3 08:24:35 2014 +0300 Hal Rosenstock
+1d3aacfc0ff05dd25922a15eaa4e88a0cb6ef145
+
+	* osm_perfmgr_db.c: Add missing clear of new xmit_wait counter in clear_counters
+
+Wed Apr 30 12:21:06 2014 +0300 Vladimir Koushnir
+0f9b15c76369e17fece0960f094705b46df40e79
+
+	* SM should resweep the fabric if vl15_send_mad fails
+
+Thu May 1 11:47:29 2014 +0300 Hal Rosenstock
+ee5f6d567d89ae0e997d9959854c131f91fd4428
+
+	* osm_perfmgr.c: Added Mellanox copyright
+
+Thu May 1 11:45:25 2014 +0300 Hal Rosenstock
+05be6c47089731ad77d12bc493261b2cc42d6188
+
+	* osm_perfmgr.c: Eliminate unneeded initialization in pc_recv_process
+
+Thu May 1 11:43:16 2014 +0300 Hal Rosenstock
+9ac71fd59d90b547766fa86be2c8683f6822b328
+
+	* osm_perfmgr.c: Cosmetic formatting changes
+
+Tue Apr 22 10:14:55 2014 +0300 Tomer Cohen
+54c6c8692068c314cc609cc621849541eea63ff2
+
+	* osm_log.c: Fix wrong hour and date display in log when CL_ASSERT fail
+
+Tue Apr 1 11:46:13 2014 +0300 Tomer Cohen
+5c81051ac07c2db916e86bc40a86fba3a06f5997
+
+	* osm_console_io.c: Handle return value of function setsockopt
+
+Sun Mar 30 15:51:14 2014 +0300 Tomer Cohen
+2e1294a6d5b9ad5890f0c486907207c8079b2498
+
+	* osm_sa_[mcmember path]_record.c: Optimize clearing of SA record items
+
+Mon Apr 28 18:27:33 2014 +0300 Hal Rosenstock
+db9c45056d0a47c7d70325678c1627cda72074ce
+
+	* osm_guid_info_rcv.c: Fix assert placement in osm_gi_rcv_process
+
+Fri Apr 25 05:25:42 2014 +0300 Hal Rosenstock
+44a6358d79594af30f71dad714120e95252f4de4
+
+	* libvendor/osm_vendor_ibumad.c: Support GRH (for GS classes)
+
+Fri Apr 25 04:59:29 2014 +0300 Hal Rosenstock
+bb723ae6f8a68fd702b2242a41b4f0ffa0c46288
+
+	* libvendor/osm_vendor_ibumad.c: Cosmetic change to umad_set_grh calls
+
+Thu Apr 24 20:55:55 2014 +0300 Hal Rosenstock
+5ca6bdc7cea0ce245a8cae3dc3640fb84843afce
+
+	* osm_perfmgr.c: Add current PerfMgr sweep state to 54FF error log message
+
+Fri Apr 4 20:07:04 2014 -0400 Ira Weiny
+672de651baaacb4ca05ff77c3a32d368a4d26c91
+
+	* perfmgr: Add xmit_wait to event plugin error counters data structure
+
+Sat Apr 5 11:41:12 2014 -0400 Ira Weiny
+d86e7e3f7828c9f2240cca8de83e28e4ab6e09d9
+
+	* perfmgr: Add xmit_wait support
+
+Wed Apr 23 22:20:20 2014 +0300 Hal Rosenstock
+753af81f6461a9d8415c501e35c8c8198cc113ea
+
+	* osm_mcast_mgr.c: Add missing new line at end of ERR 0A21 log message
+
+Wed Apr 23 18:29:36 2014 +0300 Hal Rosenstock
+d437d58ec08fb6694d71437969c3299d08152aa5
+
+	* osm_mcast_mgr.c: Fix endian of port GUID in ERR 0A06 log message
+
+Thu Apr 10 11:33:03 2014 +0300 Shlomi Nimrodi
+51fb51db9220c765eebdb5bd013b964b24355590
+
+	* osm_ucast_mgr.c: Fix duplicated error codes
+
+Fri Apr 11 07:23:06 2014 -0400 Hal Rosenstock
+21c2ab7ca44695f0f4f5107f789803f4f5ef2df5
+
+	* osm_sa_mad_ctrl.c: In sa_mad_ctrl_rcv_callback, improve 1A04 error log message
+
+Fri Apr 11 18:12:01 2014 +0300 Hal Rosenstock
+c83bde443b0b843011696f9d46b7f8276aff52b2
+
+	* doc/performance-manager-HOWTO.txt: Fix typo
+
+Thu Mar 27 18:52:49 2014 +0200 Shlomi Nimrodi
+e94d4712772a3c50620a98f7a55fbe0d143496e3
+
+	* osm_torus.c: Fix torus crash when actual topology is not torus
+
+Thu Mar 27 14:38:02 2014 +0200 Hal Rosenstock
+a20cd5f02b9cd7eef99de10c37d3eb01ef096e6c
+
+	* osm_sa_service_record.c: Fix locking issue in osm_sr_rcv_process
+
+Thu Mar 27 12:21:14 2014 +0200 Hal Rosenstock
+127acf187ec9a2cb0f14b24d322e3491a4940e66
+
+	* osm_sa_mcmember_record.c: Fix double locking in mcmr_rcv_join_mgrp
+
+Tue Mar 25 12:01:56 2014 +0200 Alex Netes
+abaf91ba6b4134b1207e88c2af4a687ccb669dcf
+
+	* osm_sa_service_record.c: Improved locking
+
+Thu Feb 27 11:46:22 2014 +0200 Alex Netes
+c86c30abd4c4df59561665077d982e926640ca77
+
+	* All SA queries should validate the requester port under lock
+
+Sun Mar 16 17:35:13 2014 +0200 Tomer Cohen
+1f4de5850d38b3a75bf228650af3c3094da78ace
+
+	* osm_subnet.c: Fix bug in parsing configuration file
+
+Thu Mar 20 10:26:51 2014 +0200 Daniel Klein
+0fa5fc1ceb88226d5a0b03fc895989a7e57b5612
+
+	* osm_sa_mcmember_record.c: Fix removing members from existing mc group due to invalid requests
+
+Sun Mar 23 16:58:40 2014 +0200 Tomer Cohen
+e1566267b103b08350da984b4147137ad4719d74
+
+	* osm_qos_parser_y.y: Added range check for mtu limit parsing
+
+Tue Mar 18 08:27:00 2014 +0200 Tomer Cohen
+cb439b3cc226df279c2a677b243462965395de1e
+
+	* osm_qos_parser_y.y: Added range check for rate limit parsing
+
+Wed Mar 19 02:07:17 2014 +0200 Hal Rosenstock
+a556f82d8f08a41e45130071d5e9179bbfcccde7
+
+	* man/opensm.8.in: Minor fixes to per module logging configuration
+
+Thu Mar 6 16:33:21 2014 +0200 Daniel Klein
+79917450678fcf5aa460ea6eceb93a7e04bc1b7e
+
+	* osm_node_info_rcv.c: Update local copy of node info for known nodes
+
+Tue Aug 7 10:58:16 2012 +0300 Alex Netes
+1c637df9a00d5550a0dc81bbc4021bb130582525
+
+	* osm_node_info_rcv.c: Update NodeInfo.SysImageGUID on heavy sweep
+
+Wed Nov 24 11:18:44 2010 +0200 Eli Dorfman
+275a56a2901bcc9e53dd06980d9ee80da0587731
+
+	* osm_state_mgr.c: Clear first time sweep even after subnet error
+
+Thu Mar 6 20:35:05 2014 +0200 Hal Rosenstock
+09b5ffe4537be4bb63c799c61b66c40b31da1618
+
+	* osm_sa_path_record.c: In osm_pr_rcv_process, release lock before log message
+
+Fri Mar 7 17:05:29 2014 +0200 Hal Rosenstock
+ef7a6511c298a52fdb71bf8acc1f538e572efe46
+
+	* osm_state_mgr.c: Revert commit to "remove redundant unset to first_time_master_sweep"
+
+Thu Mar 6 15:01:01 2014 +0200 Alex Netes
+80e1e59ac329e8fbd50fd434f5acdb1a64b75bab
+
+	* osm_sminfo_rcv.c: Send trap 144 to a newly found MASTER SM when in MASTER state
+
+Thu Jul 18 11:08:14 2013 +0300 Alex Netes
+23dfbf8a5fa3cf601d36511cd1bea1e623d73411
+
+	* osm_state_mgr.c: Remove redundant unset to first_time_master_sweep
+
+Mon Dec 3 14:45:24 2012 +0200 Alex Netes
+e5a87dd459417cc5b84f7c7e6044d0ae3f3151c8
+
+	* Revert "Reset client reregistration when receiving handover"
+
+Mon Apr 8 20:09:23 2013 +0300 Vladimir Koushnir
+0189deaac8025874038b62be52fcfee0da80b675
+
+	* osm_sm_state_mgr.c: Fix opensm crash after handover
+
+Sun Aug 5 11:50:07 2012 +0300 Alex Netes
+52c4a301f1dd7b73132be700fe3f08d86ef0868d
+
+	* osm_sm_state_mgr.c: Reconfigure the fabric when receiving HANDOVER/POLLING_TIMEOUT in MASTER state
+
+Tue Mar 4 13:07:48 2014 +0200 Alex Netes
+26af3a9c0d921a834f3ce2ce3fee2c6168e64537
+
+	* Fix crash during handover
+
+Sun Feb 10 14:34:12 2013 +0200 Ilya Nelkenbaum
+28e5fa7c33121117cbf0378d4a78bd6c96744937
+
+	* osm_sw_info_rcv.c: Add check of switch mcast_cap
+
+Wed Feb 26 12:52:01 2014 +0200 Alex Netes
+f775a1a16afcaf988260508e57fb7c156607b314
+
+	* osm_sa_path_record.c: Search for requester port should be under lock
+
+Sun Mar 17 10:17:00 2013 +0200 Alex Netes
+24d6219cbea9b3d36dd662cf758097a989b5b927
+
+	* osm_sw_info_rcv.c: Fix sending PortInfo during lightsweep
+
+Tue Dec 11 09:37:23 2012 +0200 Dan Ben Yosef
+78b6e8fa47922650404b5a8a888ba48285d0df62
+
+	* osm_subnet.c: Fix resource leak neighbor parser ("subn_validate_neighbor" function)
+
+Tue Dec 11 09:07:22 2012 +0200 Dan Ben Yosef
+46749c088d889bf73e9c82681f93b4febe42cb89
+
+	* osm_subnet.c: Fix resource leak guid2mkey parser (guid validation function)
+
+Sun Feb 23 10:53:54 2014 +0200 Rafi Wiener
+6212e4b2dc24177d4016a5703c34c481ef227116
+
+	* osm_ucast_ftree.c: Fix memory leak in ftree fabric_rank
+
+Wed Feb 12 18:54:25 2014 +0200 Hal Rosenstock
+afb6cb88df55fb8f02282a31d702e53692381002
+
+	* osm_ucast_mgr.c: Use LFT block of all port 0s to indicate resend
+
+Wed Feb 5 14:25:11 2014 +0200 Alex Netes
+319e065aea18d1906ec88d9817c20323d1a3e953
+
+	* ib_types.h: Rename ib_switch_info_set_state_change function
+
+Wed Feb 5 12:08:18 2014 +0200 Alex Netes
+12d2c8ea7c6057f0c7c1a280016b3fa2d0e4921d
+
+	* osm_node_info_rcv.c: Fix multiple switch discovery during a sweep
+
+Tue Aug 13 12:24:53 2013 +0300 Alex Netes
+ef22eb9ad5d88ce7dd4c3cf858ace035240a2785
+
+	* osm_qos.c: Fix possible seg fault
+
+Tue Feb 4 15:54:13 2014 +0200 Jens Domke
+9dd8f45616c0a4489594da4907f26f8bd6f95582
+
+	* dfsssp: avoid crash due to port initialisation errors
+
+Tue Feb 4 21:18:46 2014 +0900 Jens Domke
+f6418cf03b8df1b32e800c42554f06e5b3248926
+
+	* osm_ucast_dfsssp.c: prevent double free error
+
+Mon Feb 3 13:05:16 2014 +0200 Alex Netes
+1633550020087f3296dbc2f7b1dd533cd83a6398
+
+	* Resend LFTs/VLArb/SL2VL MADs in case of error
+
+Mon Feb 3 13:05:15 2014 +0200 Alex Netes
+90d19c2dacb63bb9dd2912fdb1303daced98a5ed
+
+	* osm_port_info_rcv.c: Reread pkeys from SP0 if switch rebooted during a sweep
+
+Mon Feb 3 13:05:14 2014 +0200 Alex Netes
+6e90421fe34190e2fb62c3f9092ef39f6a971ea1
+
+	* Better handling of topology changes in the fabric
+
+Mon Feb 3 13:05:13 2014 +0200 Alex Netes
+b33c3ba29be21f5d3b7912dfcf213bfe180c6d14
+
+	* Change discovery order of switch data
+
+Mon Feb 3 13:05:12 2014 +0200 Alex Netes
+b1c17a8b6d8e66ca73b5912f61b4b4ddd93c44de
+
+	* ib_types.h: Fix shadow declaration warnings
+
+Thu Nov 14 11:07:11 2013 -0600 Mohammad Ismail
+e3f0440183cf246a735bad733a25f0de9319049b
+
+	* osm_ucast_updn.c: Fix the AA0B error number
+
+Wed Nov 14 09:30:50 2012 +0200 Ilya Nelkenbaum
+30d9020ba95c904fb59d3baef765d06093b0dc89
+
+	* osm_ucast_updn.c: Add missing ERR number to log message
+
+Wed Aug 22 10:30:21 2012 +0300 Hal Rosenstock
+395b5f0ef9b224d11acc6fd69e8536d9beee8d98
+
+	* Handle bad SMP status
+
+Sat Feb 1 18:16:23 2014 +0200 Hal Rosenstock
+e8a92759ea44b0af29e6ac970c25993f52a132fb
+
+	* osm_port.c: Improve ERR 4108 log message
+
+** Version: opensm-3.3.17
+
 Thu Jan 30 21:03:46 2014 +0200 Hal Rosenstock
 650b60c0b77bcbd0d8912c4f241ff774705cd564
 
diff --git a/Makefile.am b/Makefile.am
index e6fd74a..63b3410 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,7 +17,7 @@ man_MANS = man/opensm.8 man/osmtest.8 man/torus-2QoS.8 man/torus-2QoS.conf.5
 various_scripts = $(wildcard scripts/*)
 docs = doc/performance-manager-HOWTO.txt doc/QoS_management_in_OpenSM.txt \
 	doc/partition-config.txt doc/opensm-sriov.txt \
-	doc/opensm_release_notes-3.3.txt
+	doc/current-routing.txt doc/opensm_release_notes-3.3.txt
 
 EXTRA_DIST = autogen.sh opensm.spec $(various_scripts) $(man_MANS) $(docs)
 
diff --git a/Makefile.in b/Makefile.in
index 6d9caa7..59a07f9 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -45,9 +45,9 @@ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
 	$(top_srcdir)/scripts/opensm.init.in \
 	$(top_srcdir)/scripts/redhat-opensm.init.in \
 	$(top_srcdir)/scripts/sldd.sh.in AUTHORS COPYING ChangeLog \
-	INSTALL NEWS config/config.guess config/config.sub \
-	config/depcomp config/install-sh config/ltmain.sh \
-	config/missing config/ylwrap
+	INSTALL NEWS config/compile config/config.guess \
+	config/config.sub config/depcomp config/install-sh \
+	config/ltmain.sh config/missing config/ylwrap
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/config/libtool.m4 \
 	$(top_srcdir)/config/ltoptions.m4 \
@@ -289,7 +289,7 @@ man_MANS = man/opensm.8 man/osmtest.8 man/torus-2QoS.8 man/torus-2QoS.conf.5
 various_scripts = $(wildcard scripts/*)
 docs = doc/performance-manager-HOWTO.txt doc/QoS_management_in_OpenSM.txt \
 	doc/partition-config.txt doc/opensm-sriov.txt \
-	doc/opensm_release_notes-3.3.txt
+	doc/current-routing.txt doc/opensm_release_notes-3.3.txt
 
 EXTRA_DIST = autogen.sh opensm.spec $(various_scripts) $(man_MANS) $(docs)
 all: all-recursive
diff --git a/config/compile b/config/compile
new file mode 100755
index 0000000..1b1d232
--- /dev/null
+++ b/config/compile
@@ -0,0 +1,142 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand `-c -o'.
+
+scriptversion=2005-05-14.22
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey at cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake at gnu.org> or send patches to
+# <automake-patches at gnu.org>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand `-c -o'.
+Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file `INSTALL'.
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+esac
+
+ofile=
+cfile=
+eat=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+	# configure might choose to run compile as `compile cc -o foo foo.c'.
+	# So we strip `-o arg' only if arg is an object.
+	eat=1
+	case $2 in
+	  *.o | *.obj)
+	    ofile=$2
+	    ;;
+	  *)
+	    set x "$@" -o "$2"
+	    shift
+	    ;;
+	esac
+	;;
+      *.c)
+	cfile=$1
+	set x "$@" "$1"
+	shift
+	;;
+      *)
+	set x "$@" "$1"
+	shift
+	;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no `-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # `.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/config/config.guess b/config/config.guess
index dc84c68..2fc3acc 100755
--- a/config/config.guess
+++ b/config/config.guess
@@ -1,10 +1,9 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-#   Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
-timestamp='2009-11-20'
+timestamp='2003-06-17'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -18,25 +17,23 @@ timestamp='2009-11-20'
 #
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
 # configuration script generated by Autoconf, you may include it under
 # the same distribution terms that you use for the rest of that program.
 
-
-# Originally written by Per Bothner.  Please send patches (context
-# diff format) to <config-patches at gnu.org> and include a ChangeLog
-# entry.
+# Originally written by Per Bothner <per at bothner.com>.
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
 #
 # This script attempts to guess a canonical system name similar to
 # config.sub.  If it succeeds, it prints the system name on stdout, and
 # exits with 0.  Otherwise, it exits with 1.
 #
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
 
 me=`echo "$0" | sed -e 's,.*/,,'`
 
@@ -56,8 +53,8 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -69,11 +66,11 @@ Try \`$me --help' for more information."
 while test $# -gt 0 ; do
   case $1 in
     --time-stamp | --time* | -t )
-       echo "$timestamp" ; exit ;;
+       echo "$timestamp" ; exit 0 ;;
     --version | -v )
-       echo "$version" ; exit ;;
+       echo "$version" ; exit 0 ;;
     --help | --h* | -h )
-       echo "$usage"; exit ;;
+       echo "$usage"; exit 0 ;;
     -- )     # Stop option processing
        shift; break ;;
     - )	# Use stdin as input.
@@ -107,7 +104,7 @@ set_cc_for_build='
 trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
 trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
 : ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
  { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
  { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
  { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
@@ -126,7 +123,7 @@ case $CC_FOR_BUILD,$HOST_CC,$CC in
 	;;
  ,,*)   CC_FOR_BUILD=$CC ;;
  ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
+esac ;'
 
 # This is needed to find uname on a Pyramid OSx when run in the BSD universe.
 # (ghazi at noc.rutgers.edu 1994-08-24)
@@ -139,6 +136,13 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
 UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
 UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 
+## for Red Hat Linux
+if test -f /etc/redhat-release ; then
+    VENDOR=redhat ;
+else
+    VENDOR= ;
+fi
+
 # Note: order is significant - the case branches are not exclusive.
 
 case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
@@ -161,7 +165,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	    arm*) machine=arm-unknown ;;
 	    sh3el) machine=shl-unknown ;;
 	    sh3eb) machine=sh-unknown ;;
-	    sh5el) machine=sh5le-unknown ;;
 	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
 	esac
 	# The Operating System including object format, if it has switched
@@ -170,7 +173,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
 		eval $set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
-			| grep -q __ELF__
+			| grep __ELF__ >/dev/null
 		then
 		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
 		    # Return netbsd for either.  FIX?
@@ -200,32 +203,50 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	# contains redundant information, the shorter form:
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
 	echo "${machine}-${os}${release}"
-	exit ;;
+	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mipseb-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
     *:OpenBSD:*:*)
-	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
-	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
-	exit ;;
-    *:ekkoBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
-	exit ;;
-    *:SolidBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
-	exit ;;
-    macppc:MirBSD:*:*)
-	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
-	exit ;;
-    *:MirBSD:*:*)
-	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
-	exit ;;
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
     alpha:OSF1:*:*)
-	case $UNAME_RELEASE in
-	*4.0)
+	if test $UNAME_RELEASE = "V4.0"; then
 		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
-		;;
-	*5.*)
-	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
-		;;
-	esac
+	fi
 	# According to Compaq, /usr/sbin/psrinfo has been available on
 	# OSF/1 and Tru64 systems produced since 1995.  I hope that
 	# covers most systems running today.  This code pipes the CPU
@@ -263,49 +284,42 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	    "EV7.9 (21364A)")
 		UNAME_MACHINE="alphaev79" ;;
 	esac
-	# A Pn.n version is a patched version.
 	# A Vn.n version is a released version.
 	# A Tn.n version is a released field test version.
 	# A Xn.n version is an unreleased experimental baselevel.
 	# 1.2 uses "1.2" for uname -r.
-	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-	exit ;;
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha*:OpenVMS:*:*)
+	echo alpha-hp-vms
+	exit 0 ;;
     Alpha\ *:Windows_NT*:*)
 	# How do we know it's Interix rather than the generic POSIX subsystem?
 	# Should we change UNAME_MACHINE based on the output of uname instead
 	# of the specific Alpha model?
 	echo alpha-pc-interix
-	exit ;;
+	exit 0 ;;
     21064:Windows_NT:50:3)
 	echo alpha-dec-winnt3.5
-	exit ;;
+	exit 0 ;;
     Amiga*:UNIX_System_V:4.0:*)
 	echo m68k-unknown-sysv4
-	exit ;;
+	exit 0;;
     *:[Aa]miga[Oo][Ss]:*:*)
 	echo ${UNAME_MACHINE}-unknown-amigaos
-	exit ;;
+	exit 0 ;;
     *:[Mm]orph[Oo][Ss]:*:*)
 	echo ${UNAME_MACHINE}-unknown-morphos
-	exit ;;
+	exit 0 ;;
     *:OS/390:*:*)
 	echo i370-ibm-openedition
-	exit ;;
-    *:z/VM:*:*)
-	echo s390-ibm-zvmoe
-	exit ;;
-    *:OS400:*:*)
-        echo powerpc-ibm-os400
-	exit ;;
+	exit 0 ;;
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
 	echo arm-acorn-riscix${UNAME_RELEASE}
-	exit ;;
-    arm:riscos:*:*|arm:RISCOS:*:*)
-	echo arm-unknown-riscos
-	exit ;;
+	exit 0;;
     SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
 	echo hppa1.1-hitachi-hiuxmpp
-	exit ;;
+	exit 0;;
     Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
 	# akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
 	if test "`(/bin/universe) 2>/dev/null`" = att ; then
@@ -313,51 +327,32 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	else
 		echo pyramid-pyramid-bsd
 	fi
-	exit ;;
+	exit 0 ;;
     NILE*:*:*:dcosx)
 	echo pyramid-pyramid-svr4
-	exit ;;
+	exit 0 ;;
     DRS?6000:unix:4.0:6*)
 	echo sparc-icl-nx6
-	exit ;;
-    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7*)
 	case `/usr/bin/uname -p` in
-	    sparc) echo sparc-icl-nx7; exit ;;
+	    sparc) echo sparc-icl-nx7 && exit 0 ;;
 	esac ;;
-    s390x:SunOS:*:*)
-	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit ;;
     sun4H:SunOS:5.*:*)
 	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit ;;
+	exit 0 ;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
 	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit ;;
-    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
-	echo i386-pc-auroraux${UNAME_RELEASE}
-	exit ;;
-    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
-	eval $set_cc_for_build
-	SUN_ARCH="i386"
-	# If there is a compiler, see if it is configured for 64-bit objects.
-	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
-	# This test works for both compilers.
-	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
-	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
-		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-		grep IS_64BIT_ARCH >/dev/null
-	    then
-		SUN_ARCH="x86_64"
-	    fi
-	fi
-	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit ;;
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
     sun4*:SunOS:6*:*)
 	# According to config.sub, this is the proper way to canonicalize
 	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
 	# it's likely to be more like Solaris than SunOS4.
 	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit ;;
+	exit 0 ;;
     sun4*:SunOS:*:*)
 	case "`/usr/bin/arch -k`" in
 	    Series*|S4*)
@@ -366,10 +361,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	esac
 	# Japanese Language versions have a version number like `4.1.3-JL'.
 	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
-	exit ;;
+	exit 0 ;;
     sun3*:SunOS:*:*)
 	echo m68k-sun-sunos${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     sun*:*:4.2BSD:*)
 	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
 	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
@@ -381,10 +376,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 		echo sparc-sun-sunos${UNAME_RELEASE}
 		;;
 	esac
-	exit ;;
+	exit 0 ;;
     aushp:SunOS:*:*)
 	echo sparc-auspex-sunos${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     # The situation for MiNT is a little confusing.  The machine name
     # can be virtually everything (everything which is not
     # "atarist" or "atariste" at least should have a processor
@@ -395,40 +390,37 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     # be no problem.
     atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
         echo m68k-atari-mint${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
 	echo m68k-atari-mint${UNAME_RELEASE}
-        exit ;;
+        exit 0 ;;
     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
         echo m68k-atari-mint${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
         echo m68k-milan-mint${UNAME_RELEASE}
-        exit ;;
+        exit 0 ;;
     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
         echo m68k-hades-mint${UNAME_RELEASE}
-        exit ;;
+        exit 0 ;;
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
         echo m68k-unknown-mint${UNAME_RELEASE}
-        exit ;;
-    m68k:machten:*:*)
-	echo m68k-apple-machten${UNAME_RELEASE}
-	exit ;;
+        exit 0 ;;
     powerpc:machten:*:*)
 	echo powerpc-apple-machten${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     RISC*:Mach:*:*)
 	echo mips-dec-mach_bsd4.3
-	exit ;;
+	exit 0 ;;
     RISC*:ULTRIX:*:*)
 	echo mips-dec-ultrix${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     VAX*:ULTRIX*:*:*)
 	echo vax-dec-ultrix${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     2020:CLIX:*:* | 2430:CLIX:*:*)
 	echo clipper-intergraph-clix${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     mips:*:*:UMIPS | mips:*:*:RISCos)
 	eval $set_cc_for_build
 	sed 's/^	//' << EOF >$dummy.c
@@ -452,33 +444,32 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	  exit (-1);
 	}
 EOF
-	$CC_FOR_BUILD -o $dummy $dummy.c &&
-	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
-	  SYSTEM_NAME=`$dummy $dummyarg` &&
-	    { echo "$SYSTEM_NAME"; exit; }
+	$CC_FOR_BUILD -o $dummy $dummy.c \
+	  && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && exit 0
 	echo mips-mips-riscos${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     Motorola:PowerMAX_OS:*:*)
 	echo powerpc-motorola-powermax
-	exit ;;
+	exit 0 ;;
     Motorola:*:4.3:PL8-*)
 	echo powerpc-harris-powermax
-	exit ;;
+	exit 0 ;;
     Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
 	echo powerpc-harris-powermax
-	exit ;;
+	exit 0 ;;
     Night_Hawk:Power_UNIX:*:*)
 	echo powerpc-harris-powerunix
-	exit ;;
+	exit 0 ;;
     m88k:CX/UX:7*:*)
 	echo m88k-harris-cxux7
-	exit ;;
+	exit 0 ;;
     m88k:*:4*:R4*)
 	echo m88k-motorola-sysv4
-	exit ;;
+	exit 0 ;;
     m88k:*:3*:R3*)
 	echo m88k-motorola-sysv3
-	exit ;;
+	exit 0 ;;
     AViiON:dgux:*:*)
         # DG/UX returns AViiON for all architectures
         UNAME_PROCESSOR=`/usr/bin/uname -p`
@@ -494,29 +485,29 @@ EOF
 	else
 	    echo i586-dg-dgux${UNAME_RELEASE}
 	fi
- 	exit ;;
+ 	exit 0 ;;
     M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
 	echo m88k-dolphin-sysv3
-	exit ;;
+	exit 0 ;;
     M88*:*:R3*:*)
 	# Delta 88k system running SVR3
 	echo m88k-motorola-sysv3
-	exit ;;
+	exit 0 ;;
     XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
 	echo m88k-tektronix-sysv3
-	exit ;;
+	exit 0 ;;
     Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
 	echo m68k-tektronix-bsd
-	exit ;;
+	exit 0 ;;
     *:IRIX*:*:*)
 	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
-	exit ;;
+	exit 0 ;;
     ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
-	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
-	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
     i*86:AIX:*:*)
 	echo i386-ibm-aix
-	exit ;;
+	exit 0 ;;
     ia64:AIX:*:*)
 	if [ -x /usr/bin/oslevel ] ; then
 		IBM_REV=`/usr/bin/oslevel`
@@ -524,7 +515,7 @@ EOF
 		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
 	fi
 	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
-	exit ;;
+	exit 0 ;;
     *:AIX:2:3)
 	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
 		eval $set_cc_for_build
@@ -539,19 +530,15 @@ EOF
 			exit(0);
 			}
 EOF
-		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
-		then
-			echo "$SYSTEM_NAME"
-		else
-			echo rs6000-ibm-aix3.2.5
-		fi
+		$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+		echo rs6000-ibm-aix3.2.5
 	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
 		echo rs6000-ibm-aix3.2.4
 	else
 		echo rs6000-ibm-aix3.2
 	fi
-	exit ;;
-    *:AIX:*:[456])
+	exit 0 ;;
+    *:AIX:*:[45])
 	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
 	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
 		IBM_ARCH=rs6000
@@ -564,28 +551,28 @@ EOF
 		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
 	fi
 	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
-	exit ;;
+	exit 0 ;;
     *:AIX:*:*)
 	echo rs6000-ibm-aix
-	exit ;;
+	exit 0 ;;
     ibmrt:4.4BSD:*|romp-ibm:BSD:*)
 	echo romp-ibm-bsd4.4
-	exit ;;
+	exit 0 ;;
     ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
 	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
-	exit ;;                             # report: romp-ibm BSD 4.3
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
     *:BOSX:*:*)
 	echo rs6000-bull-bosx
-	exit ;;
+	exit 0 ;;
     DPX/2?00:B.O.S.:*:*)
 	echo m68k-bull-sysv3
-	exit ;;
+	exit 0 ;;
     9000/[34]??:4.3bsd:1.*:*)
 	echo m68k-hp-bsd
-	exit ;;
+	exit 0 ;;
     hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
 	echo m68k-hp-bsd4.4
-	exit ;;
+	exit 0 ;;
     9000/[34678]??:HP-UX:*:*)
 	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
 	case "${UNAME_MACHINE}" in
@@ -647,19 +634,9 @@ EOF
 	esac
 	if [ ${HP_ARCH} = "hppa2.0w" ]
 	then
-	    eval $set_cc_for_build
-
-	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
-	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
-	    # generating 64-bit code.  GNU and HP use different nomenclature:
-	    #
-	    # $ CC_FOR_BUILD=cc ./config.guess
-	    # => hppa2.0w-hp-hpux11.23
-	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
-	    # => hppa64-hp-hpux11.23
-
-	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
-		grep -q __LP64__
+	    # avoid double evaluation of $set_cc_for_build
+	    test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
 	    then
 		HP_ARCH="hppa2.0w"
 	    else
@@ -667,11 +644,11 @@ EOF
 	    fi
 	fi
 	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
-	exit ;;
+	exit 0 ;;
     ia64:HP-UX:*:*)
 	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
 	echo ia64-hp-hpux${HPUX_REV}
-	exit ;;
+	exit 0 ;;
     3050*:HI-UX:*:*)
 	eval $set_cc_for_build
 	sed 's/^	//' << EOF >$dummy.c
@@ -699,248 +676,208 @@ EOF
 	  exit (0);
 	}
 EOF
-	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
-		{ echo "$SYSTEM_NAME"; exit; }
+	$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
 	echo unknown-hitachi-hiuxwe2
-	exit ;;
+	exit 0 ;;
     9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
 	echo hppa1.1-hp-bsd
-	exit ;;
+	exit 0 ;;
     9000/8??:4.3bsd:*:*)
 	echo hppa1.0-hp-bsd
-	exit ;;
+	exit 0 ;;
     *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
 	echo hppa1.0-hp-mpeix
-	exit ;;
+	exit 0 ;;
     hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
 	echo hppa1.1-hp-osf
-	exit ;;
+	exit 0 ;;
     hp8??:OSF1:*:*)
 	echo hppa1.0-hp-osf
-	exit ;;
+	exit 0 ;;
     i*86:OSF1:*:*)
 	if [ -x /usr/sbin/sysversion ] ; then
 	    echo ${UNAME_MACHINE}-unknown-osf1mk
 	else
 	    echo ${UNAME_MACHINE}-unknown-osf1
 	fi
-	exit ;;
+	exit 0 ;;
     parisc*:Lites*:*:*)
 	echo hppa1.1-hp-lites
-	exit ;;
+	exit 0 ;;
     C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
 	echo c1-convex-bsd
-        exit ;;
+        exit 0 ;;
     C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
 	if getsysinfo -f scalar_acc
 	then echo c32-convex-bsd
 	else echo c2-convex-bsd
 	fi
-        exit ;;
+        exit 0 ;;
     C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
 	echo c34-convex-bsd
-        exit ;;
+        exit 0 ;;
     C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
 	echo c38-convex-bsd
-        exit ;;
+        exit 0 ;;
     C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
 	echo c4-convex-bsd
-        exit ;;
+        exit 0 ;;
     CRAY*Y-MP:*:*:*)
 	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
+	exit 0 ;;
     CRAY*[A-Z]90:*:*:*)
 	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
 	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
 	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
 	      -e 's/\.[^.]*$/.X/'
-	exit ;;
+	exit 0 ;;
     CRAY*TS:*:*:*)
 	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
+	exit 0 ;;
     CRAY*T3E:*:*:*)
 	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
+	exit 0 ;;
     CRAY*SV1:*:*:*)
 	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
+	exit 0 ;;
     *:UNICOS/mp:*:*)
-	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
+	echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 
+	exit 0 ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
 	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
         FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
         FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
         echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-        exit ;;
-    5000:UNIX_System_V:4.*:*)
-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
-        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-	exit ;;
+        exit 0 ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
 	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     sparc*:BSD/OS:*:*)
 	echo sparc-unknown-bsdi${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     *:BSD/OS:*:*)
 	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
-	exit ;;
-    *:FreeBSD:*:*)
-	case ${UNAME_MACHINE} in
-	    pc98)
-		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
-	    amd64)
-		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
-	    *)
-		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
-	esac
-	exit ;;
+	exit 0 ;;
+    *:FreeBSD:*:*|*:GNU/FreeBSD:*:*)
+	# Determine whether the default compiler uses glibc.
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#if __GLIBC__ >= 2
+	LIBC=gnu
+	#else
+	LIBC=
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+	exit 0 ;;
     i*:CYGWIN*:*)
 	echo ${UNAME_MACHINE}-pc-cygwin
-	exit ;;
-    *:MINGW*:*)
+	exit 0 ;;
+    i*:MINGW*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
-	exit ;;
-    i*:windows32*:*)
-    	# uname -m includes "-pc" on this system.
-    	echo ${UNAME_MACHINE}-mingw32
-	exit ;;
+	exit 0 ;;
     i*:PW*:*)
 	echo ${UNAME_MACHINE}-pc-pw32
-	exit ;;
-    *:Interix*:*)
-    	case ${UNAME_MACHINE} in
-	    x86)
-		echo i586-pc-interix${UNAME_RELEASE}
-		exit ;;
-	    authenticamd | genuineintel | EM64T)
-		echo x86_64-unknown-interix${UNAME_RELEASE}
-		exit ;;
-	    IA64)
-		echo ia64-unknown-interix${UNAME_RELEASE}
-		exit ;;
-	esac ;;
+	exit 0 ;;
+    x86:Interix*:[34]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit 0 ;;
     [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
 	echo i${UNAME_MACHINE}-pc-mks
-	exit ;;
-    8664:Windows_NT:*)
-	echo x86_64-pc-mks
-	exit ;;
+	exit 0 ;;
     i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
 	# How do we know it's Interix rather than the generic POSIX subsystem?
 	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
 	# UNAME_MACHINE based on the output of uname instead of i386?
 	echo i586-pc-interix
-	exit ;;
+	exit 0 ;;
     i*:UWIN*:*)
 	echo ${UNAME_MACHINE}-pc-uwin
-	exit ;;
-    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
-	echo x86_64-unknown-cygwin
-	exit ;;
+	exit 0 ;;
     p*:CYGWIN*:*)
 	echo powerpcle-unknown-cygwin
-	exit ;;
+	exit 0 ;;
     prep*:SunOS:5.*:*)
 	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
-	exit ;;
+	exit 0 ;;
     *:GNU:*:*)
-	# the GNU system
 	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
-	exit ;;
-    *:GNU/*:*:*)
-	# other systems with GNU libc and userland
-	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
-	exit ;;
+	exit 0 ;;
     i*86:Minix:*:*)
 	echo ${UNAME_MACHINE}-pc-minix
-	exit ;;
-    alpha:Linux:*:*)
-	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
-	  EV5)   UNAME_MACHINE=alphaev5 ;;
-	  EV56)  UNAME_MACHINE=alphaev56 ;;
-	  PCA56) UNAME_MACHINE=alphapca56 ;;
-	  PCA57) UNAME_MACHINE=alphapca56 ;;
-	  EV6)   UNAME_MACHINE=alphaev6 ;;
-	  EV67)  UNAME_MACHINE=alphaev67 ;;
-	  EV68*) UNAME_MACHINE=alphaev68 ;;
-        esac
-	objdump --private-headers /bin/sh | grep -q ld.so.1
-	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
-	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
-	exit ;;
+	exit 0 ;;
     arm*:Linux:*:*)
-	eval $set_cc_for_build
-	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
-	    | grep -q __ARM_EABI__
-	then
-	    echo ${UNAME_MACHINE}-unknown-linux-gnu
-	else
-	    echo ${UNAME_MACHINE}-unknown-linux-gnueabi
-	fi
-	exit ;;
-    avr32*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
-	exit ;;
+	exit 0 ;;
     cris:Linux:*:*)
 	echo cris-axis-linux-gnu
-	exit ;;
-    crisv32:Linux:*:*)
-	echo crisv32-axis-linux-gnu
-	exit ;;
-    frv:Linux:*:*)
-    	echo frv-unknown-linux-gnu
-	exit ;;
-    i*86:Linux:*:*)
-	LIBC=gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR:-unknown}-linux-gnu
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
 	eval $set_cc_for_build
 	sed 's/^	//' << EOF >$dummy.c
-	#ifdef __dietlibc__
-	LIBC=dietlibc
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
 	#endif
 EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
-	echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
-	exit ;;
-    ia64:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-gnu
-	exit ;;
-    m32r*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-gnu
-	exit ;;
-    m68*:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-gnu
-	exit ;;
-    mips:Linux:*:* | mips64:Linux:*:*)
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    mips64:Linux:*:*)
 	eval $set_cc_for_build
 	sed 's/^	//' << EOF >$dummy.c
 	#undef CPU
-	#undef ${UNAME_MACHINE}
-	#undef ${UNAME_MACHINE}el
+	#undef mips64
+	#undef mips64el
 	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-	CPU=${UNAME_MACHINE}el
+	CPU=mips64el
 	#else
 	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-	CPU=${UNAME_MACHINE}
+	CPU=mips64
 	#else
 	CPU=
 	#endif
 	#endif
 EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
-	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
 	;;
-    or32:Linux:*:*)
-	echo or32-unknown-linux-gnu
-	exit ;;
-    padre:Linux:*:*)
-	echo sparc-unknown-linux-gnu
-	exit ;;
-    parisc64:Linux:*:* | hppa64:Linux:*:*)
-	echo hppa64-unknown-linux-gnu
-	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-${VENDOR:-unknown}-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-${VENDOR:-unknown}-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
 	# Look for CPU level
 	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
@@ -948,40 +885,84 @@ EOF
 	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
 	  *)    echo hppa-unknown-linux-gnu ;;
 	esac
-	exit ;;
-    ppc64:Linux:*:*)
-	echo powerpc64-unknown-linux-gnu
-	exit ;;
-    ppc:Linux:*:*)
-	echo powerpc-unknown-linux-gnu
-	exit ;;
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
     s390:Linux:*:* | s390x:Linux:*:*)
-	echo ${UNAME_MACHINE}-ibm-linux
-	exit ;;
+	echo ${UNAME_MACHINE}-${VENDOR:-ibm}-linux-gnu
+	exit 0 ;;
     sh64*:Linux:*:*)
     	echo ${UNAME_MACHINE}-unknown-linux-gnu
-	exit ;;
+	exit 0 ;;
     sh*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
-	exit ;;
+	exit 0 ;;
     sparc:Linux:*:* | sparc64:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-gnu
-	exit ;;
-    vax:Linux:*:*)
-	echo ${UNAME_MACHINE}-dec-linux-gnu
-	exit ;;
+	exit 0 ;;
     x86_64:Linux:*:*)
-	echo x86_64-unknown-linux-gnu
-	exit ;;
-    xtensa*:Linux:*:*)
-    	echo ${UNAME_MACHINE}-unknown-linux-gnu
-	exit ;;
+	echo x86_64-${VENDOR:-unknown}-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-${VENDOR:-pc}-linux-${LIBC}" && exit 0
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
     i*86:DYNIX/ptx:4*:*)
 	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
 	# earlier versions are messed up and put the nodename in both
 	# sysname and nodename.
 	echo i386-sequent-sysv4
-	exit ;;
+	exit 0 ;;
     i*86:UNIX_SV:4.2MP:2.*)
         # Unixware is an offshoot of SVR4, but it has its own version
         # number series starting with 2...
@@ -989,27 +970,24 @@ EOF
 	# I just have to hope.  -- rms.
         # Use sysv4.2uw... so that sysv4* matches it.
 	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
-	exit ;;
+	exit 0 ;;
     i*86:OS/2:*:*)
 	# If we were able to find `uname', then EMX Unix compatibility
 	# is probably installed.
 	echo ${UNAME_MACHINE}-pc-os2-emx
-	exit ;;
+	exit 0 ;;
     i*86:XTS-300:*:STOP)
 	echo ${UNAME_MACHINE}-unknown-stop
-	exit ;;
+	exit 0 ;;
     i*86:atheos:*:*)
 	echo ${UNAME_MACHINE}-unknown-atheos
-	exit ;;
-    i*86:syllable:*:*)
-	echo ${UNAME_MACHINE}-pc-syllable
-	exit ;;
-    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
 	echo i386-unknown-lynxos${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     i*86:*DOS:*:*)
 	echo ${UNAME_MACHINE}-pc-msdosdjgpp
-	exit ;;
+	exit 0 ;;
     i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
 	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
 	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
@@ -1017,16 +995,15 @@ EOF
 	else
 		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
 	fi
-	exit ;;
-    i*86:*:5:[678]*)
-    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	exit 0 ;;
+    i*86:*:5:[78]*)
 	case `/bin/uname -X | grep "^Machine"` in
 	    *486*)	     UNAME_MACHINE=i486 ;;
 	    *Pentium)	     UNAME_MACHINE=i586 ;;
 	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
 	esac
 	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
-	exit ;;
+	exit 0 ;;
     i*86:*:3.2:*)
 	if test -f /usr/options/cb.name; then
 		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
@@ -1044,86 +1021,73 @@ EOF
 	else
 		echo ${UNAME_MACHINE}-pc-sysv32
 	fi
-	exit ;;
+	exit 0 ;;
     pc:*:*:*)
 	# Left here for compatibility:
         # uname -m prints for DJGPP always 'pc', but it prints nothing about
-        # the processor, so we play safe by assuming i586.
-	# Note: whatever this is, it MUST be the same as what config.sub
-	# prints for the "djgpp" host, or else GDB configury will decide that
-	# this is a cross-build.
-	echo i586-pc-msdosdjgpp
-        exit ;;
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
     Intel:Mach:3*:*)
 	echo i386-pc-mach3
-	exit ;;
+	exit 0 ;;
     paragon:*:*:*)
 	echo i860-intel-osf1
-	exit ;;
+	exit 0 ;;
     i860:*:4.*:*) # i860-SVR4
 	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
 	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
 	else # Add other i860-SVR4 vendors below as they are discovered.
 	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
 	fi
-	exit ;;
+	exit 0 ;;
     mini*:CTIX:SYS*5:*)
 	# "miniframe"
 	echo m68010-convergent-sysv
-	exit ;;
+	exit 0 ;;
     mc68k:UNIX:SYSTEM5:3.51m)
 	echo m68k-convergent-sysv
-	exit ;;
+	exit 0 ;;
     M680?0:D-NIX:5.3:*)
 	echo m68k-diab-dnix
-	exit ;;
-    M68*:*:R3V[5678]*:*)
-	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
-    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	exit 0 ;;
+    M68*:*:R3V[567]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
 	OS_REL=''
 	test -r /etc/.relid \
 	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
 	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
 	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
         /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-          && { echo i486-ncr-sysv4; exit; } ;;
-    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
-	OS_REL='.3'
-	test -r /etc/.relid \
-	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
-	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
-	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
-	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
-	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+          && echo i486-ncr-sysv4 && exit 0 ;;
     m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
 	echo m68k-unknown-lynxos${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     mc68030:UNIX_System_V:4.*:*)
 	echo m68k-atari-sysv4
-	exit ;;
+	exit 0 ;;
     TSUNAMI:LynxOS:2.*:*)
 	echo sparc-unknown-lynxos${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     rs6000:LynxOS:2.*:*)
 	echo rs6000-unknown-lynxos${UNAME_RELEASE}
-	exit ;;
-    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
 	echo powerpc-unknown-lynxos${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     SM[BE]S:UNIX_SV:*:*)
 	echo mips-dde-sysv${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     RM*:ReliantUNIX-*:*:*)
 	echo mips-sni-sysv4
-	exit ;;
+	exit 0 ;;
     RM*:SINIX-*:*:*)
 	echo mips-sni-sysv4
-	exit ;;
+	exit 0 ;;
     *:SINIX-*:*:*)
 	if uname -p 2>/dev/null >/dev/null ; then
 		UNAME_MACHINE=`(uname -p) 2>/dev/null`
@@ -1131,94 +1095,68 @@ EOF
 	else
 		echo ns32k-sni-sysv
 	fi
-	exit ;;
+	exit 0 ;;
     PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
                       # says <Richard.M.Bartel at ccMail.Census.GOV>
         echo i586-unisys-sysv4
-        exit ;;
+        exit 0 ;;
     *:UNIX_System_V:4*:FTX*)
 	# From Gerald Hewes <hewes at openmarket.com>.
 	# How about differentiating between stratus architectures? -djm
 	echo hppa1.1-stratus-sysv4
-	exit ;;
+	exit 0 ;;
     *:*:*:FTX*)
 	# From seanf at swdc.stratus.com.
 	echo i860-stratus-sysv4
-	exit ;;
-    i*86:VOS:*:*)
-	# From Paul.Green at stratus.com.
-	echo ${UNAME_MACHINE}-stratus-vos
-	exit ;;
+	exit 0 ;;
     *:VOS:*:*)
 	# From Paul.Green at stratus.com.
 	echo hppa1.1-stratus-vos
-	exit ;;
+	exit 0 ;;
     mc68*:A/UX:*:*)
 	echo m68k-apple-aux${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     news*:NEWS-OS:6*:*)
 	echo mips-sony-newsos6
-	exit ;;
+	exit 0 ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
 	if [ -d /usr/nec ]; then
 	        echo mips-nec-sysv${UNAME_RELEASE}
 	else
 	        echo mips-unknown-sysv${UNAME_RELEASE}
 	fi
-        exit ;;
+        exit 0 ;;
     BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
 	echo powerpc-be-beos
-	exit ;;
+	exit 0 ;;
     BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
 	echo powerpc-apple-beos
-	exit ;;
+	exit 0 ;;
     BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
 	echo i586-pc-beos
-	exit ;;
-    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
-	echo i586-pc-haiku
-	exit ;;
+	exit 0 ;;
     SX-4:SUPER-UX:*:*)
 	echo sx4-nec-superux${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     SX-5:SUPER-UX:*:*)
 	echo sx5-nec-superux${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     SX-6:SUPER-UX:*:*)
 	echo sx6-nec-superux${UNAME_RELEASE}
-	exit ;;
-    SX-7:SUPER-UX:*:*)
-	echo sx7-nec-superux${UNAME_RELEASE}
-	exit ;;
-    SX-8:SUPER-UX:*:*)
-	echo sx8-nec-superux${UNAME_RELEASE}
-	exit ;;
-    SX-8R:SUPER-UX:*:*)
-	echo sx8r-nec-superux${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     Power*:Rhapsody:*:*)
 	echo powerpc-apple-rhapsody${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     *:Rhapsody:*:*)
 	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     *:Darwin:*:*)
-	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
-	case $UNAME_PROCESSOR in
-	    i386)
-		eval $set_cc_for_build
-		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
-		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-		      grep IS_64BIT_ARCH >/dev/null
-		  then
-		      UNAME_PROCESSOR="x86_64"
-		  fi
-		fi ;;
-	    unknown) UNAME_PROCESSOR=powerpc ;;
+	case `uname -p` in
+	    *86) UNAME_PROCESSOR=i686 ;;
+	    powerpc) UNAME_PROCESSOR=powerpc ;;
 	esac
 	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
 	UNAME_PROCESSOR=`uname -p`
 	if test "$UNAME_PROCESSOR" = "x86"; then
@@ -1226,25 +1164,22 @@ EOF
 		UNAME_MACHINE=pc
 	fi
 	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     *:QNX:*:4*)
 	echo i386-pc-qnx
-	exit ;;
-    NSE-?:NONSTOP_KERNEL:*:*)
-	echo nse-tandem-nsk${UNAME_RELEASE}
-	exit ;;
-    NSR-?:NONSTOP_KERNEL:*:*)
+	exit 0 ;;
+    NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
 	echo nsr-tandem-nsk${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     *:NonStop-UX:*:*)
 	echo mips-compaq-nonstopux
-	exit ;;
+	exit 0 ;;
     BS2000:POSIX*:*:*)
 	echo bs2000-siemens-sysv
-	exit ;;
+	exit 0 ;;
     DS/*:UNIX_System_V:*:*)
 	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
-	exit ;;
+	exit 0 ;;
     *:Plan9:*:*)
 	# "uname -m" is not consistent, so use $cputype instead. 386
 	# is converted to i386 for consistency with other x86
@@ -1255,50 +1190,28 @@ EOF
 	    UNAME_MACHINE="$cputype"
 	fi
 	echo ${UNAME_MACHINE}-unknown-plan9
-	exit ;;
+	exit 0 ;;
     *:TOPS-10:*:*)
 	echo pdp10-unknown-tops10
-	exit ;;
+	exit 0 ;;
     *:TENEX:*:*)
 	echo pdp10-unknown-tenex
-	exit ;;
+	exit 0 ;;
     KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
 	echo pdp10-dec-tops20
-	exit ;;
+	exit 0 ;;
     XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
 	echo pdp10-xkl-tops20
-	exit ;;
+	exit 0 ;;
     *:TOPS-20:*:*)
 	echo pdp10-unknown-tops20
-	exit ;;
+	exit 0 ;;
     *:ITS:*:*)
 	echo pdp10-unknown-its
-	exit ;;
+	exit 0 ;;
     SEI:*:*:SEIUX)
         echo mips-sei-seiux${UNAME_RELEASE}
-	exit ;;
-    *:DragonFly:*:*)
-	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
-	exit ;;
-    *:*VMS:*:*)
-    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
-	case "${UNAME_MACHINE}" in
-	    A*) echo alpha-dec-vms ; exit ;;
-	    I*) echo ia64-dec-vms ; exit ;;
-	    V*) echo vax-dec-vms ; exit ;;
-	esac ;;
-    *:XENIX:*:SysV)
-	echo i386-pc-xenix
-	exit ;;
-    i*86:skyos:*:*)
-	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
-	exit ;;
-    i*86:rdos:*:*)
-	echo ${UNAME_MACHINE}-pc-rdos
-	exit ;;
-    i*86:AROS:*:*)
-	echo ${UNAME_MACHINE}-pc-aros
-	exit ;;
+	exit 0 ;;
 esac
 
 #echo '(No uname command or uname output not recognized.)' 1>&2
@@ -1330,7 +1243,7 @@ main ()
 #endif
 
 #if defined (__arm) && defined (__acorn) && defined (__unix)
-  printf ("arm-acorn-riscix\n"); exit (0);
+  printf ("arm-acorn-riscix"); exit (0);
 #endif
 
 #if defined (hp300) && !defined (hpux)
@@ -1419,12 +1332,11 @@ main ()
 }
 EOF
 
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
-	{ echo "$SYSTEM_NAME"; exit; }
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
 
 # Apollos put the system type in the environment.
 
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
 
 # Convex versions that predate uname can use getsysinfo(1)
 
@@ -1433,22 +1345,22 @@ then
     case `getsysinfo -f cpu_type` in
     c1*)
 	echo c1-convex-bsd
-	exit ;;
+	exit 0 ;;
     c2*)
 	if getsysinfo -f scalar_acc
 	then echo c32-convex-bsd
 	else echo c2-convex-bsd
 	fi
-	exit ;;
+	exit 0 ;;
     c34*)
 	echo c34-convex-bsd
-	exit ;;
+	exit 0 ;;
     c38*)
 	echo c38-convex-bsd
-	exit ;;
+	exit 0 ;;
     c4*)
 	echo c4-convex-bsd
-	exit ;;
+	exit 0 ;;
     esac
 fi
 
@@ -1459,9 +1371,7 @@ This script, last modified $timestamp, has failed to recognize
 the operating system you are using. It is advised that you
 download the most up to date version of the config scripts from
 
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-and
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+    ftp://ftp.gnu.org/pub/gnu/config/
 
 If the version you run ($0) is already up to date, please
 send the following data and any information you think might be
diff --git a/config/config.sub b/config/config.sub
index 2a55a50..6b2ff9f 100755
--- a/config/config.sub
+++ b/config/config.sub
@@ -1,10 +1,9 @@
 #! /bin/sh
 # Configuration validation subroutine script.
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-#   Free Software Foundation, Inc.
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
-timestamp='2009-11-20'
+timestamp='2003-06-18'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -22,26 +21,22 @@ timestamp='2009-11-20'
 #
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
 # configuration script generated by Autoconf, you may include it under
 # the same distribution terms that you use for the rest of that program.
 
-
 # Please send patches to <config-patches at gnu.org>.  Submit a context
-# diff and a properly formatted GNU ChangeLog entry.
+# diff and a properly formatted ChangeLog entry.
 #
 # Configuration subroutine to validate and canonicalize a configuration type.
 # Supply the specified configuration type as an argument.
 # If it is invalid, we print an error message on stderr and exit with code 1.
 # Otherwise, we print the canonical config type on stdout and succeed.
 
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
 # This file is supposed to be the same for all GNU packages
 # and recognize all the CPU types, system types and aliases
 # that are meaningful with *any* GNU software.
@@ -75,8 +70,8 @@ Report bugs and patches to <config-patches at gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -88,11 +83,11 @@ Try \`$me --help' for more information."
 while test $# -gt 0 ; do
   case $1 in
     --time-stamp | --time* | -t )
-       echo "$timestamp" ; exit ;;
+       echo "$timestamp" ; exit 0 ;;
     --version | -v )
-       echo "$version" ; exit ;;
+       echo "$version" ; exit 0 ;;
     --help | --h* | -h )
-       echo "$usage"; exit ;;
+       echo "$usage"; exit 0 ;;
     -- )     # Stop option processing
        shift; break ;;
     - )	# Use stdin as input.
@@ -104,7 +99,7 @@ while test $# -gt 0 ; do
     *local*)
        # First pass through any local machine types.
        echo $1
-       exit ;;
+       exit 0;;
 
     * )
        break ;;
@@ -123,10 +118,7 @@ esac
 # Here we must recognize all the valid KERNEL-OS combinations.
 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
-  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
-  kopensolaris*-gnu* | \
-  storm-chaos* | os2-emx* | rtmk-nova*)
+  nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
     ;;
@@ -152,13 +144,10 @@ case $os in
 	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
 	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
 	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-	-apple | -axis | -knuth | -cray | -microblaze)
+	-apple | -axis)
 		os=
 		basic_machine=$1
 		;;
-        -bluegene*)
-	        os=-cnk
-		;;
 	-sim | -cisco | -oki | -wec | -winbond)
 		os=
 		basic_machine=$1
@@ -180,10 +169,6 @@ case $os in
 	-hiux*)
 		os=-hiuxwe2
 		;;
-	-sco6)
-		os=-sco5v6
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
 	-sco5)
 		os=-sco3.2v5
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -200,10 +185,6 @@ case $os in
 		# Don't forget version if it is 3.2v4 or newer.
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 		;;
-	-sco5v6*)
-		# Don't forget version if it is 3.2v4 or newer.
-		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
-		;;
 	-sco*)
 		os=-sco3.2v2
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -247,71 +228,54 @@ case $basic_machine in
 	| a29k \
 	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
 	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-	| am33_2.0 \
-	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
-	| bfin \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
 	| c4x | clipper \
 	| d10v | d30v | dlx | dsp16xx \
-	| fido | fr30 | frv \
+	| fr30 | frv \
 	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 	| i370 | i860 | i960 | ia64 \
-	| ip2k | iq2000 \
-	| lm32 \
-	| m32c | m32r | m32rle | m68000 | m68k | m88k \
-	| maxq | mb | microblaze | mcore | mep | metag \
+	| ip2k \
+	| m32r | m68000 | m68k | m88k | mcore \
 	| mips | mipsbe | mipseb | mipsel | mipsle \
 	| mips16 \
 	| mips64 | mips64el \
-	| mips64octeon | mips64octeonel \
-	| mips64orion | mips64orionel \
-	| mips64r5900 | mips64r5900el \
 	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
 	| mips64vr4100 | mips64vr4100el \
 	| mips64vr4300 | mips64vr4300el \
 	| mips64vr5000 | mips64vr5000el \
-	| mips64vr5900 | mips64vr5900el \
 	| mipsisa32 | mipsisa32el \
 	| mipsisa32r2 | mipsisa32r2el \
 	| mipsisa64 | mipsisa64el \
-	| mipsisa64r2 | mipsisa64r2el \
 	| mipsisa64sb1 | mipsisa64sb1el \
 	| mipsisa64sr71k | mipsisa64sr71kel \
 	| mipstx39 | mipstx39el \
 	| mn10200 | mn10300 \
-	| moxie \
-	| mt \
 	| msp430 \
-	| nios | nios2 \
 	| ns16k | ns32k \
-	| or32 \
+	| openrisc | or32 \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
 	| pyramid \
-	| rx \
-	| score \
-	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| s390 | s390x \
+	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
 	| sh64 | sh64le \
-	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
-	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-	| spu | strongarm \
+	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \
+	| strongarm \
 	| tahoe | thumb | tic4x | tic80 | tron \
-	| ubicom32 \
 	| v850 | v850e \
 	| we32k \
-	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
-	| z8k | z80)
+	| x86 | xscale | xstormy16 | xtensa \
+	| z8k)
 		basic_machine=$basic_machine-unknown
 		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+	m6811 | m68hc11 | m6812 | m68hc12)
 		# Motorola 68HC11/12.
 		basic_machine=$basic_machine-unknown
 		os=-none
 		;;
 	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
 		;;
-	ms1)
-		basic_machine=mt-unknown
-		;;
 
 	# We use `pc' rather than `unknown'
 	# because (1) that's what they normally are, and
@@ -331,68 +295,55 @@ case $basic_machine in
 	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
 	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
 	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-	| avr-* | avr32-* \
-	| bfin-* | bs2000-* \
+	| avr-* \
+	| bs2000-* \
 	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
-	| clipper-* | craynv-* | cydra-* \
+	| clipper-* | cydra-* \
 	| d10v-* | d30v-* | dlx-* \
 	| elxsi-* \
-	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
 	| h8300-* | h8500-* \
 	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
 	| i*86-* | i860-* | i960-* | ia64-* \
-	| ip2k-* | iq2000-* \
-	| lm32-* \
-	| m32c-* | m32r-* | m32rle-* \
+	| ip2k-* \
+	| m32r-* \
 	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+	| m88110-* | m88k-* | mcore-* \
 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
 	| mips16-* \
 	| mips64-* | mips64el-* \
-	| mips64octeon-* | mips64octeonel-* \
-	| mips64orion-* | mips64orionel-* \
-	| mips64r5900-* | mips64r5900el-* \
 	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
 	| mips64vr4100-* | mips64vr4100el-* \
 	| mips64vr4300-* | mips64vr4300el-* \
 	| mips64vr5000-* | mips64vr5000el-* \
-	| mips64vr5900-* | mips64vr5900el-* \
 	| mipsisa32-* | mipsisa32el-* \
 	| mipsisa32r2-* | mipsisa32r2el-* \
 	| mipsisa64-* | mipsisa64el-* \
-	| mipsisa64r2-* | mipsisa64r2el-* \
 	| mipsisa64sb1-* | mipsisa64sb1el-* \
 	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
 	| mipstx39-* | mipstx39el-* \
-	| mmix-* \
-	| mt-* \
 	| msp430-* \
-	| nios-* | nios2-* \
-	| none-* | np1-* | ns16k-* | ns32k-* \
+	| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
 	| pyramid-* \
-	| romp-* | rs6000-* | rx-* \
-	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| romp-* | rs6000-* \
+	| s390-* | s390x-* \
+	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
 	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
-	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
 	| tahoe-* | thumb-* \
-	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
 	| tron-* \
-	| ubicom32-* \
 	| v850-* | v850e-* | vax-* \
 	| we32k-* \
-	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
-	| xstormy16-* | xtensa*-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+	| xtensa-* \
 	| ymp-* \
-	| z8k-* | z80-*)
-		;;
-	# Recognize the basic CPU types without company name, with glob match.
-	xtensa*)
-		basic_machine=$basic_machine-unknown
+	| z8k-*)
 		;;
 	# Recognize the various machine names and aliases which stand
 	# for a CPU type and a company and sometimes even an OS.
@@ -410,9 +361,6 @@ case $basic_machine in
 		basic_machine=a29k-amd
 		os=-udi
 		;;
-    	abacus)
-		basic_machine=abacus-unknown
-		;;
 	adobe68k)
 		basic_machine=m68010-adobe
 		os=-scout
@@ -430,9 +378,6 @@ case $basic_machine in
 	amd64)
 		basic_machine=x86_64-pc
 		;;
-	amd64-*)
-		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
 	amdahl)
 		basic_machine=580-amdahl
 		os=-sysv
@@ -456,10 +401,6 @@ case $basic_machine in
 		basic_machine=m68k-apollo
 		os=-bsd
 		;;
-	aros)
-		basic_machine=i386-pc
-		os=-aros
-		;;
 	aux)
 		basic_machine=m68k-apple
 		os=-aux
@@ -468,26 +409,10 @@ case $basic_machine in
 		basic_machine=ns32k-sequent
 		os=-dynix
 		;;
-	blackfin)
-		basic_machine=bfin-unknown
-		os=-linux
-		;;
-	blackfin-*)
-		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	bluegene*)
-		basic_machine=powerpc-ibm
-		os=-cnk
-		;;
 	c90)
 		basic_machine=c90-cray
 		os=-unicos
 		;;
-        cegcc)
-		basic_machine=arm-unknown
-		os=-cegcc
-		;;
 	convex-c1)
 		basic_machine=c1-convex
 		os=-bsd
@@ -512,27 +437,12 @@ case $basic_machine in
 		basic_machine=j90-cray
 		os=-unicos
 		;;
-	craynv)
-		basic_machine=craynv-cray
-		os=-unicosmp
-		;;
-	cr16)
-		basic_machine=cr16-unknown
-		os=-elf
-		;;
 	crds | unos)
 		basic_machine=m68k-crds
 		;;
-	crisv32 | crisv32-* | etraxfs*)
-		basic_machine=crisv32-axis
-		;;
 	cris | cris-* | etrax*)
 		basic_machine=cris-axis
 		;;
-	crx)
-		basic_machine=crx-unknown
-		os=-elf
-		;;
 	da30 | da30-*)
 		basic_machine=m68k-da30
 		;;
@@ -555,14 +465,6 @@ case $basic_machine in
 		basic_machine=m88k-motorola
 		os=-sysv3
 		;;
-	dicos)
-		basic_machine=i686-pc
-		os=-dicos
-		;;
-	djgpp)
-		basic_machine=i586-pc
-		os=-msdosdjgpp
-		;;
 	dpx20 | dpx20-*)
 		basic_machine=rs6000-bull
 		os=-bosx
@@ -713,14 +615,6 @@ case $basic_machine in
 		basic_machine=m68k-isi
 		os=-sysv
 		;;
-	m68knommu)
-		basic_machine=m68k-unknown
-		os=-linux
-		;;
-	m68knommu-*)
-		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
 	m88k-omron*)
 		basic_machine=m88k-omron
 		;;
@@ -732,17 +626,10 @@ case $basic_machine in
 		basic_machine=ns32k-utek
 		os=-sysv
 		;;
-        microblaze)
-		basic_machine=microblaze-xilinx
-		;;
 	mingw32)
 		basic_machine=i386-pc
 		os=-mingw32
 		;;
-	mingw32ce)
-		basic_machine=arm-unknown
-		os=-mingw32ce
-		;;
 	miniframe)
 		basic_machine=m68000-convergent
 		;;
@@ -756,6 +643,10 @@ case $basic_machine in
 	mips3*)
 		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
 		;;
+	mmix*)
+		basic_machine=mmix-knuth
+		os=-mmixware
+		;;
 	monitor)
 		basic_machine=m68k-rom68k
 		os=-coff
@@ -768,9 +659,6 @@ case $basic_machine in
 		basic_machine=i386-pc
 		os=-msdos
 		;;
-	ms1-*)
-		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
-		;;
 	mvs)
 		basic_machine=i370-ibm
 		os=-mvs
@@ -839,6 +727,10 @@ case $basic_machine in
 	np1)
 		basic_machine=np1-gould
 		;;
+	nv1)
+		basic_machine=nv1-cray
+		os=-unicosmp
+		;;
 	nsr-tandem)
 		basic_machine=nsr-tandem
 		;;
@@ -846,12 +738,9 @@ case $basic_machine in
 		basic_machine=hppa1.1-oki
 		os=-proelf
 		;;
-	openrisc | openrisc-*)
+	or32 | or32-*)
 		basic_machine=or32-unknown
-		;;
-	os400)
-		basic_machine=powerpc-ibm
-		os=-os400
+		os=-coff
 		;;
 	OSE68000 | ose68000)
 		basic_machine=m68000-ericsson
@@ -869,14 +758,6 @@ case $basic_machine in
 		basic_machine=i860-intel
 		os=-osf
 		;;
-	parisc)
-		basic_machine=hppa-unknown
-		os=-linux
-		;;
-	parisc-*)
-		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
 	pbd)
 		basic_machine=sparc-tti
 		;;
@@ -886,12 +767,6 @@ case $basic_machine in
 	pc532 | pc532-*)
 		basic_machine=ns32k-pc532
 		;;
-	pc98)
-		basic_machine=i386-pc
-		;;
-	pc98-*)
-		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
-		;;
 	pentium | p5 | k5 | k6 | nexgen | viac3)
 		basic_machine=i586-pc
 		;;
@@ -948,10 +823,6 @@ case $basic_machine in
 		basic_machine=i586-unknown
 		os=-pw32
 		;;
-	rdos)
-		basic_machine=i386-pc
-		os=-rdos
-		;;
 	rom68k)
 		basic_machine=m68k-rom68k
 		os=-coff
@@ -962,12 +833,6 @@ case $basic_machine in
 	rtpc | rtpc-*)
 		basic_machine=romp-ibm
 		;;
-	s390 | s390-*)
-		basic_machine=s390-ibm
-		;;
-	s390x | s390x-*)
-		basic_machine=s390x-ibm
-		;;
 	sa29200)
 		basic_machine=a29k-amd
 		os=-udi
@@ -978,10 +843,6 @@ case $basic_machine in
 	sb1el)
 		basic_machine=mipsisa64sb1el-unknown
 		;;
-	sde)
-		basic_machine=mipsisa32-sde
-		os=-elf
-		;;
 	sei)
 		basic_machine=mips-sei
 		os=-seiux
@@ -993,9 +854,6 @@ case $basic_machine in
 		basic_machine=sh-hitachi
 		os=-hms
 		;;
-	sh5el)
-		basic_machine=sh5le-unknown
-		;;
 	sh64)
 		basic_machine=sh64-unknown
 		;;
@@ -1085,10 +943,6 @@ case $basic_machine in
 		basic_machine=tic6x-unknown
 		os=-coff
 		;;
-	tile*)
-		basic_machine=tile-unknown
-		os=-linux-gnu
-		;;
 	tx39)
 		basic_machine=mipstx39-unknown
 		;;
@@ -1102,10 +956,6 @@ case $basic_machine in
 	tower | tower-32)
 		basic_machine=m68k-ncr
 		;;
-	tpf)
-		basic_machine=s390x-ibm
-		os=-tpf
-		;;
 	udi29k)
 		basic_machine=a29k-amd
 		os=-udi
@@ -1149,10 +999,6 @@ case $basic_machine in
 		basic_machine=hppa1.1-winbond
 		os=-proelf
 		;;
-	xbox)
-		basic_machine=i686-pc
-		os=-mingw32
-		;;
 	xps | xps100)
 		basic_machine=xps100-honeywell
 		;;
@@ -1164,10 +1010,6 @@ case $basic_machine in
 		basic_machine=z8k-unknown
 		os=-sim
 		;;
-	z80-*-coff)
-		basic_machine=z80-unknown
-		os=-sim
-		;;
 	none)
 		basic_machine=none-none
 		os=-none
@@ -1187,9 +1029,6 @@ case $basic_machine in
 	romp)
 		basic_machine=romp-ibm
 		;;
-	mmix)
-		basic_machine=mmix-knuth
-		;;
 	rs6000)
 		basic_machine=rs6000-ibm
 		;;
@@ -1206,10 +1045,13 @@ case $basic_machine in
 	we32k)
 		basic_machine=we32k-att
 		;;
-	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
 		basic_machine=sh-unknown
 		;;
-	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b)
 		basic_machine=sparc-sun
 		;;
 	cydra)
@@ -1256,9 +1098,6 @@ case $os in
         # First match some system type aliases
         # that might get confused with valid system types.
 	# -solaris* is a basic system type, with this one exception.
-        -auroraux)
-	        os=-auroraux
-		;;
 	-solaris1 | -solaris1.*)
 		os=`echo $os | sed -e 's|solaris1|sunos4|'`
 		;;
@@ -1279,30 +1118,25 @@ case $os in
 	# Each alternative MUST END IN A *, to match a version number.
 	# -sysv* is not here because it comes later, after sysvr4.
 	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
-	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
-	      | -sym* | -kopensolaris* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
 	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* | -aros* \
+	      | -aos* \
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-	      | -openbsd* | -solidbsd* \
-	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -chorusos* | -chorusrdb* \
 	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
-	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
-	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1320,15 +1154,12 @@ case $os in
 		os=`echo $os | sed -e 's|nto|nto-qnx|'`
 		;;
 	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
-	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
 	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
 		;;
 	-mac*)
 		os=`echo $os | sed -e 's|mac|macos|'`
 		;;
-	-linux-dietlibc)
-		os=-linux-dietlibc
-		;;
 	-linux*)
 		os=`echo $os | sed -e 's|linux|linux-gnu|'`
 		;;
@@ -1341,9 +1172,6 @@ case $os in
 	-opened*)
 		os=-openedition
 		;;
-        -os400*)
-		os=-os400
-		;;
 	-wince*)
 		os=-wince
 		;;
@@ -1365,9 +1193,6 @@ case $os in
 	-atheos*)
 		os=-atheos
 		;;
-	-syllable*)
-		os=-syllable
-		;;
 	-386bsd)
 		os=-bsd
 		;;
@@ -1390,9 +1215,6 @@ case $os in
 	-sinix*)
 		os=-sysv4
 		;;
-        -tpf*)
-		os=-tpf
-		;;
 	-triton*)
 		os=-sysv3
 		;;
@@ -1429,12 +1251,6 @@ case $os in
 	-kaos*)
 		os=-kaos
 		;;
-	-zvmoe)
-		os=-zvmoe
-		;;
-	-dicos*)
-		os=-dicos
-		;;
 	-none)
 		;;
 	*)
@@ -1457,12 +1273,6 @@ else
 # system, and we'll never get to this point.
 
 case $basic_machine in
-        score-*)
-		os=-elf
-		;;
-        spu-*)
-		os=-elf
-		;;
 	*-acorn)
 		os=-riscix1.2
 		;;
@@ -1472,8 +1282,8 @@ case $basic_machine in
 	arm*-semi)
 		os=-aout
 		;;
-        c4x-* | tic4x-*)
-        	os=-coff
+	c4x-* | tic4x-*)
+		os=-coff
 		;;
 	# This must come before the *-dec entry.
 	pdp10-*)
@@ -1500,9 +1310,6 @@ case $basic_machine in
 	m68*-cisco)
 		os=-aout
 		;;
-        mep-*)
-		os=-elf
-		;;
 	mips*-cisco)
 		os=-elf
 		;;
@@ -1521,15 +1328,9 @@ case $basic_machine in
 	*-be)
 		os=-beos
 		;;
-	*-haiku)
-		os=-haiku
-		;;
 	*-ibm)
 		os=-aix
 		;;
-    	*-knuth)
-		os=-mmixware
-		;;
 	*-wec)
 		os=-proelf
 		;;
@@ -1632,7 +1433,7 @@ case $basic_machine in
 			-sunos*)
 				vendor=sun
 				;;
-			-cnk*|-aix*)
+			-aix*)
 				vendor=ibm
 				;;
 			-beos*)
@@ -1662,15 +1463,9 @@ case $basic_machine in
 			-mvs* | -opened*)
 				vendor=ibm
 				;;
-			-os400*)
-				vendor=ibm
-				;;
 			-ptx*)
 				vendor=sequent
 				;;
-			-tpf*)
-				vendor=ibm
-				;;
 			-vxsim* | -vxworks* | -windiss*)
 				vendor=wrs
 				;;
@@ -1695,7 +1490,7 @@ case $basic_machine in
 esac
 
 echo $basic_machine$os
-exit
+exit 0
 
 # Local variables:
 # eval: (add-hook 'write-file-hooks 'time-stamp)
diff --git a/configure b/configure
index 7be8a3b..1b6d413 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for opensm 3.3.17.
+# Generated by GNU Autoconf 2.69 for opensm 3.3.18.
 #
 # Report bugs to <linux-rdma at vger.kernel.org>.
 #
@@ -729,8 +729,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='opensm'
 PACKAGE_TARNAME='opensm'
-PACKAGE_VERSION='3.3.17'
-PACKAGE_STRING='opensm 3.3.17'
+PACKAGE_VERSION='3.3.18'
+PACKAGE_STRING='opensm 3.3.18'
 PACKAGE_BUGREPORT='linux-rdma at vger.kernel.org'
 PACKAGE_URL=''
 
@@ -1498,7 +1498,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures opensm 3.3.17 to adapt to many kinds of systems.
+\`configure' configures opensm 3.3.18 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1568,7 +1568,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of opensm 3.3.17:";;
+     short | recursive ) echo "Configuration of opensm 3.3.18:";;
    esac
   cat <<\_ACEOF
 
@@ -1715,7 +1715,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-opensm configure 3.3.17
+opensm configure 3.3.18
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2138,7 +2138,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by opensm $as_me 3.3.17, which was
+It was created by opensm $as_me 3.3.18, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2957,7 +2957,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='opensm'
- VERSION='3.3.17'
+ VERSION='3.3.18'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -12686,7 +12686,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by opensm $as_me 3.3.17, which was
+This file was extended by opensm $as_me 3.3.18, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -12752,7 +12752,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-opensm config.status 3.3.17
+opensm config.status 3.3.18
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.in b/configure.in
index 9158aec..8d8f05b 100644
--- a/configure.in
+++ b/configure.in
@@ -1,7 +1,7 @@
 dnl Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.57)
-AC_INIT(opensm, 3.3.17, linux-rdma at vger.kernel.org)
+AC_INIT(opensm, 3.3.18, linux-rdma at vger.kernel.org)
 AC_CONFIG_SRCDIR([opensm/osm_opensm.c])
 AC_CONFIG_AUX_DIR(config)
 AC_CONFIG_MACRO_DIR(config)
diff --git a/doc/current-routing.txt b/doc/current-routing.txt
new file mode 100644
index 0000000..d23ae0d
--- /dev/null
+++ b/doc/current-routing.txt
@@ -0,0 +1,907 @@
+Current OpenSM Routing
+11/14/12
+
+OpenSM offers nine 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. DNUP Unicast routing algorithm - similar to UPDN but allows routing in
+fabrics which have some CA nodes attached closer to the roots than some switch
+nodes.
+
+4.  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.
+
+5. LASH unicast routing algorithm - uses Infiniband virtual layers
+(SL) to provide deadlock-free shortest-path routing while also
+distributing the paths between layers. LASH is an alternative
+deadlock-free topology-agnostic routing algorithm to the non-minimal
+UPDN algorithm avoiding the use of a potentially congested root node.
+
+6. DOR Unicast routing algorithm - based on the Min Hop algorithm, but
+avoids port equalization except for redundant links between the same
+two switches.  This provides deadlock free routes for hypercubes when
+the fabric is cabled as a hypercube and for meshes when cabled as a
+mesh (see details below).
+
+7. Torus-2QoS unicast routing algorithm - a DOR-based routing algorithm
+specialized for 2D/3D torus topologies.  Torus-2QoS provides deadlock-free
+routing while supporting two quality of service (QoS) levels.  In addition
+it is able to route around multiple failed fabric links or a single failed
+fabric switch without introducing deadlocks, and without changing path SL
+values granted before the failure.
+
+8. DFSSSP unicast routing algorithm - a deadlock-free single-source-
+shortest-path routing, which uses the SSSP algorithm (see algorithm 9.)
+as the base to optimize link utilization and uses Infiniband virtual lanes
+(SL) to provide deadlock-freedom.
+
+9. SSSP unicast routing algorithm - a single-source-shortest-path routing
+algorithm, which globally balances the number of routes per link to
+optimize link utilization. This routing algorithm has no restrictions
+in terms of the underlying topology.
+
+OpenSM provides an optional unicast routing cache (enabled by -A or
+--ucast_cache options). When enabled, unicast routing cache prevents
+routing recalculation (which is a heavy task in a large cluster) when
+there was no topology change detected during the heavy sweep, or when
+the topology change does not require new routing calculation, e.g. when
+one or more CAs/RTRs/leaf switches going down, or one or more of these
+nodes coming back after being down.
+A very common case that is handled by the unicast routing cache is host
+reboot, which otherwise would cause two full routing recalculations: one
+when the host goes down, and the other when the host comes back online.
+
+OpenSM also supports 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 LIDs 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 by default if no routing algorithm is
+specified.  It can also be invoked by specifying '-R minhop'.
+
+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.
+
+Note: Up/Down routing does not allow LID routing communication between
+switches that are located inside spine "switch systems".
+The reason is that there is no way to allow a LID route between them
+that does not break the Up/Down rule.
+One ramification of this is that you cannot run SM on switches other
+than the leaf switches of the fabric.
+
+
+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).
+
+
+DNUP Routing Algorithm
+----------------------
+
+Purpose:
+
+The DNUP algorithm is designed to serve a similar purpose to UPDN. However
+it is intended to work in network topologies which are unsuited to
+UPDN due to nodes being connected closer to the roots than some of
+the switches.  An example would be a fabric which contains nodes and
+uplinks connected to the same switch. The operation of DNUP is the
+same as UPDN with the exception of the ranking process.  In DNUP all
+switch nodes are ranked based solely on their distance from CA Nodes,
+all switch nodes directly connected to at least one CA are assigned a
+value of 1 all other switch nodes are assigned a value of one more than
+the minimum rank of all neighbor switch nodes.
+
+
+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 or almost 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 Constant
+Bisectional Ratio (CBB) ratio.  As in UPDN, fat-tree also prevents
+credit-loop-deadlocks.
+
+If the root guid file is not provided ('-a' or '--root_guid_file' options),
+the topology has to be pure fat-tree that complies 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.
+  - All the CAs have to be at the same tree level (rank).
+
+If the root guid file is provided, the topology doesn't have to be pure
+fat-tree, and it should only comply with the following rules:
+  - Tree rank should be between two and eight (inclusively)
+  - All the Compute Nodes** have to be at the same tree level (rank).
+    Note that non-compute node CAs are allowed here to be at different
+    tree ranks.
+
+* ports that are connected to the same remote switch are referenced as
+'port group'.
+** list of compute nodes (CNs) can be specified by '-u' or '--cn_guid_file'
+OpenSM options.
+
+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.
+In general, even if the root list is provided, the closer the topology to a
+pure and symmetrical fat-tree, the more optimal the routing will be.
+
+The algorithm also dumps compute node ordering file (opensm-ftree-ca-order.dump)
+in the same directory where the OpenSM log resides. This ordering file provides
+the CN order that may be used to create efficient communication pattern, that
+will match the routing tables.
+
+Routing between non-CN nodes
+
+
+The use of the cn_guid_file option allows non-CN nodes to be located on different levels in the fat tree.
+In such case, it is not guaranteed that the Fat Tree algorithm will route between two non-CN nodes.
+In the scheme below, N1, N2 and N3 are non-CN nodes. Although all the CN have routes to and from them,
+there will not necessarily be a route between N1,N2 and N3.
+Such routes would require to use at least one of the Switch the wrong way around
+(In fact, go out of one of the top Switch through a downgoing port while we are supposed to go up).
+
+  Spine1   Spine2    Spine 3
+   / \     /  |  \    /   \
+  /   \   /   |   \  /     \
+ N1  Switch   N2  Switch    N3
+      /|\          /|\
+     / | \        / | \
+    Going down to compute nodes
+
+To solve this problem, a list of non-CN nodes can be specified by \'-G\' or \'--io_guid_file\' option.
+Theses nodes will be allowed to use switches the wrong way around a specific number of times (specified by \'-H\' or \'--max_reverse_hops\'.
+With the proper max_reverse_hops and io_guid_file values, you can ensure full connectivity in the Fat Tree.
+
+In the scheme above, with a max_reverse_hop of 1, routes will be instanciated between N1<->N2 and N2<->N3.
+With a max_reverse_hops value of 2, N1,N2 and N3 will all have routes between them.
+
+Please note that using max_reverse_hops creates routes that use the switch in a counter-stream way.
+This option should never be used to connect nodes with high bandwidth traffic between them ! It should only be used
+to allow connectivity for HA purposes or similar.
+Also having routes the other way around can in theory cause credit loops.
+
+Use these options with extreme care !
+
+
+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.
+
+
+LASH Routing Algorithm
+----------------------
+
+LASH is an acronym for LAyered SHortest Path Routing. It is a
+deterministic shortest path routing algorithm that enables topology
+agnostic deadlock-free routing within communication networks.
+
+When computing the routing function, LASH analyzes the network
+topology for the shortest-path routes between all pairs of sources /
+destinations and groups these paths into virtual layers in such a way
+as to avoid deadlock.
+
+Note LASH analyzes routes and ensures deadlock freedom between switch
+pairs. The link from HCA between and switch does not need virtual
+layers as deadlock will not arise between switch and HCA.
+
+In more detail, the algorithm works as follows:
+
+1) LASH determines the shortest-path between all pairs of source /
+destination switches. Note, LASH ensures the same SL is used for all
+SRC/DST - DST/SRC pairs and there is no guarantee that the return
+path for a given DST/SRC will be the reverse of the route SRC/DST.
+
+2) LASH then begins an SL assignment process where a route is assigned
+to a layer (SL) if the addition of that route does not cause deadlock
+within that layer. This is achieved by maintaining and analysing a
+channel dependency graph for each layer. Once the potential addition
+of a path could lead to deadlock, LASH opens a new layer and continues
+the process.
+
+3) Once this stage has been completed, it is highly likely that the
+first layers processed will contain more paths than the latter ones.
+To better balance the use of layers, LASH moves paths from one layer
+to another so that the number of paths in each layer averages out.
+
+Note, the implementation of LASH in opensm attempts to use as few layers
+as possible. This number can be less than the number of actual layers
+available.
+
+In general LASH is a very flexible algorithm. It can, for example,
+reduce to Dimension Order Routing in certain topologies, it is topology
+agnostic and fares well in the face of faults.
+
+It has been shown that for both regular and irregular topologies, LASH
+outperforms Up/Down. The reason for this is that LASH distributes the
+traffic more evenly through a network, avoiding the bottleneck issues
+related to a root node and always routes shortest-path.
+
+The algorithm was developed by Simula Research Laboratory.
+
+To learn more about LASH and the flexibility behind it, the requirement
+for layers, performance comparisons to other algorithms, see the
+following articles:
+
+"Layered Routing in Irregular Networks", Lysne et al, IEEE
+Transactions on Parallel and Distributed Systems, VOL.16, No12,
+December 2005.
+
+"Routing for the ASI Fabric Manager", Solheim et al. IEEE
+Communications Magazine, Vol.44, No.7, July 2006.
+
+"Layered Shortest Path (LASH) Routing in Irregular System Area
+Networks", Skeie et al. IEEE Computer Society Communication
+Architecture for Clusters 2002.
+
+
+Use '-R lash -Q ' option to activate the LASH algorithm.
+
+Note: QoS support has to be turned on in order that SL/VL mappings are
+used.
+
+Note: LMC > 0 is not supported by the LASH routing. If this is
+specified, the default routing algorithm is invoked instead.
+
+For open regular cartesian meshes the DOR algorithm is the ideal
+routing algorithm. For toroidal meshes on the other hand there
+are routing loops that can cause deadlocks. LASH can be used to
+route these cases. The performance of LASH can be improved by
+preconditioning the mesh in cases where there are multiple links
+connecting switches and also in cases where the switches are not
+cabled consistently. An option exists for LASH to do this. To
+invoke this use '-R lash -Q --do_mesh_analysis'. This will
+add an additional phase that analyses the mesh to try to determine
+the dimension and size of a mesh. If it determines that the mesh
+looks like an open or closed cartesian mesh it reorders the ports
+in dimension order before the rest of the LASH algorithm runs.
+
+DOR Routing Algorithm
+---------------------
+
+The Dimension Order Routing algorithm is based on the Min Hop
+algorithm and so uses shortest paths.  Instead of spreading traffic
+out across different paths with the same shortest distance, it chooses
+among the available shortest paths based on an ordering of dimensions.
+Each port must be consistently cabled to represent a hypercube
+dimension or a mesh dimension.  Paths are grown from a destination
+back to a source using the lowest dimension (port) of available paths
+at each step.  This provides the ordering necessary to avoid deadlock.
+When there are multiple links between any two switches, they still
+represent only one dimension and traffic is balanced across them
+unless port equalization is turned off.  In the case of hypercubes,
+the same port must be used throughout the fabric to represent the
+hypercube dimension and match on both ends of the cable.  In the case
+of meshes, the dimension should consistently use the same pair of
+ports, one port on one end of the cable, and the other port on the
+other end, continuing along the mesh dimension.
+
+Use '-R dor' option to activate the DOR algorithm.
+
+Torus-2QoS Routing Algorithm
+----------------------------
+
+Torus-2QoS is a routing algorithm designed for large-scale 2D/3D torus fabrics.
+The torus-2QoS routing engine can provide the following functionality on
+a 2D/3D torus:
+- routing that is free of credit loops
+- two levels of QoS, assuming switches support 8 data VLs
+- ability to route around a single failed switch, and/or multiple failed
+    links, without
+    - introducing credit loops
+    - changing path SL values
+- very short run times, with good scaling properties as fabric size
+    increases
+
+Unicast Routing:
+
+Torus-2QoS is a DOR-based algorithm that avoids deadlocks that would otherwise
+occur in a torus using the concept of a dateline for each torus dimension.
+It encodes into a path SL which datelines the path crosses as follows:
+
+  sl = 0;
+  for (d = 0; d < torus_dimensions; d++)
+    /* path_crosses_dateline(d) returns 0 or 1 */
+    sl |= path_crosses_dateline(d) << d;
+
+For a 3D torus, that leaves one SL bit free, which torus-2QoS uses to
+implement two QoS levels.
+
+Torus-2QoS also makes use of the output port dependence of switch SL2VL
+maps to encode into one VL bit the information encoded in three SL bits.
+It computes in which torus coordinate direction each inter-switch link
+"points", and writes SL2VL maps for such ports as follows:
+
+  for (sl = 0; sl < 16; sl ++)
+    /* cdir(port) reports which torus coordinate direction a switch port
+     * "points" in, and returns 0, 1, or 2 */
+    sl2vl(iport,oport,sl) = 0x1 & (sl >> cdir(oport));
+
+Thus, on a pristine 3D torus, i.e., in the absence of failed fabric switches,
+torus-2QoS consumes 8 SL values (SL bits 0-2) and 2 VL values (VL bit 0)
+per QoS level to provide deadlock-free routing on a 3D torus.
+
+Torus-2QoS routes around link failure by "taking the long way around" any
+1D ring interrupted by a link failure.  For example, consider the 2D 6x5
+torus below, where switches are denoted by [+a-zA-Z]:
+
+	|    |    |    |    |    |
+   4  --+----+----+----+----+----+--
+	|    |    |    |    |    |
+   3  --+----+----+----D----+----+--
+	|    |    |    |    |    |
+   2  --+----+----I----r----+----+--
+	|    |    |    |    |    |
+   1  --m----S----n----T----o----p--
+	|    |    |    |    |    |
+ y=0  --+----+----+----+----+----+--
+	|    |    |    |    |    |
+
+      x=0    1    2    3    4    5
+
+For a pristine fabric the path from S to D would be S-n-T-r-D.  In the
+event that either link S-n or n-T has failed, torus-2QoS would use the path
+S-m-p-o-T-r-D.  Note that it can do this without changing the path SL
+value; once the 1D ring m-S-n-T-o-p-m has been broken by failure, path
+segments using it cannot contribute to deadlock, and the x-direction
+dateline (between, say, x=5 and x=0) can be ignored for path segments on
+that ring.
+
+One result of this is that torus-2QoS can route around many simultaneous
+link failures, as long as no 1D ring is broken into disjoint segments.  For
+example, if links n-T and T-o have both failed, that ring has been broken
+into two disjoint segments, T and o-p-m-S-n.  Torus-2QoS checks for such
+issues, reports if they are found, and refuses to route such fabrics.
+
+Note that in the case where there are multiple parallel links between a pair
+of switches, torus-2QoS will allocate routes across such links in a round-
+robin fashion, based on ports at the path destination switch that are active
+and not used for inter-switch links.  Should a link that is one of several
+such parallel links fail, routes are redistributed across the remaining
+links.   When the last of such a set of parallel links fails, traffic is
+rerouted as described above.
+
+Handling a failed switch under DOR requires introducing into a path at
+least one turn that would be otherwise "illegal", i.e. not allowed by DOR
+rules.  Torus-2QoS will introduce such a turn as close as possible to the
+failed switch in order to route around it.
+
+In the above example, suppose switch T has failed, and consider the path
+from S to D.  Torus-2QoS will produce the path S-n-I-r-D, rather than the
+S-n-T-r-D path for a pristine torus, by introducing an early turn at n.
+Normal DOR rules will cause traffic arriving at switch I to be forwarded
+to switch r; for traffic arriving from I due to the "early" turn at n,
+this will generate an "illegal" turn at I.
+
+Torus-2QoS will also use the input port dependence of SL2VL maps to set VL
+bit 1 (which would be otherwise unused) for y-x, z-x, and z-y turns, i.e.,
+those turns that are illegal under DOR.  This causes the first hop after
+any such turn to use a separate set of VL values, and prevents deadlock in
+the presence of a single failed switch.
+
+For any given path, only the hops after a turn that is illegal under DOR
+can contribute to a credit loop that leads to deadlock.  So in the example
+above with failed switch T, the location of the illegal turn at I in the
+path from S to D requires that any credit loop caused by that turn must
+encircle the failed switch at T.  Thus the second and later hops after the
+illegal turn at I (i.e., hop r-D) cannot contribute to a credit loop
+because they cannot be used to construct a loop encircling T.  The hop I-r
+uses a separate VL, so it cannot contribute to a credit loop encircling T.
+
+Extending this argument shows that in addition to being capable of routing
+around a single switch failure without introducing deadlock, torus-2QoS can
+also route around multiple failed switches on the condition they are
+adjacent in the last dimension routed by DOR.  For example, consider the
+following case on a 6x6 2D torus:
+
+
+	|    |    |    |    |    |
+   5  --+----+----+----+----+----+--
+	|    |    |    |    |    |
+   4  --+----+----+----D----+----+--
+	|    |    |    |    |    |
+   3  --+----+----I----u----+----+--
+	|    |    |    |    |    |
+   2  --+----+----q----R----+----+--
+	|    |    |    |    |    |
+   1  --m----S----n----T----o----p--
+	|    |    |    |    |    |
+ y=0  --+----+----+----+----+----+--
+	|    |    |    |    |    |
+
+      x=0    1    2    3    4    5
+
+
+Suppose switches T and R have failed, and consider the path from S to D.
+Torus-2QoS will generate the path S-n-q-I-u-D, with an illegal turn at
+switch I, and with hop I-u using a VL with bit 1 set.
+
+As a further example, consider a case that torus-2QoS cannot route without
+deadlock: two failed switches adjacent in a dimension that is not the last
+dimension routed by DOR; here the failed switches are O and T:
+
+	|    |    |    |    |    |
+   5  --+----+----+----+----+----+--
+	|    |    |    |    |    |
+   4  --+----+----+----+----+----+--
+	|    |    |    |    |    |
+   3  --+----+----+----+----D----+--
+	|    |    |    |    |    |
+   2  --+----+----I----q----r----+--
+	|    |    |    |    |    |
+   1  --m----S----n----O----T----p--
+	|    |    |    |    |    |
+ y=0  --+----+----+----+----+----+--
+	|    |    |    |    |    |
+
+      x=0    1    2    3    4    5
+
+In a pristine fabric, torus-2QoS would generate the path from S to D as
+S-n-O-T-r-D.  With failed switches O and T, torus-2QoS will generate the
+path S-n-I-q-r-D, with illegal turn at switch I, and with hop I-q using a
+VL with bit 1 set.  In contrast to the earlier examples, the second hop
+after the illegal turn, q-r, can be used to construct a credit loop
+encircling the failed switches.
+
+Multicast Routing:
+
+Since torus-2QoS uses all four available SL bits, and the three data VL
+bits that are typically available in current switches, there is no way
+to use SL/VL values to separate multicast traffic from unicast traffic.
+Thus, torus-2QoS must generate multicast routing such that credit loops
+cannot arise from a combination of multicast and unicast path segments.
+
+It turns out that it is possible to construct spanning trees for multicast
+routing that have that property.  For the 2D 6x5 torus example above, here
+is the full-fabric spanning tree that torus-2QoS will construct, where "x"
+is the root switch and each "+" is a non-root switch:
+
+   4    +    +    +    +    +    +
+	|    |    |    |    |    |
+   3    +    +    +    +    +    +
+	|    |    |    |    |    |
+   2    +----+----+----x----+----+
+	|    |    |    |    |    |
+   1    +    +    +    +    +    +
+	|    |    |    |    |    |
+ y=0    +    +    +    +    +    +
+
+      x=0    1    2    3    4    5
+
+For multicast traffic routed from root to tip, every turn in the above
+spanning tree is a legal DOR turn.
+
+For traffic routed from tip to root, and some traffic routed through the
+root, turns are not legal DOR turns.  However, to construct a credit loop,
+the union of multicast routing on this spanning tree with DOR unicast
+routing can only provide 3 of the 4 turns needed for the loop.
+
+In addition, if none of the above spanning tree branches crosses a dateline
+used for unicast credit loop avoidance on a torus, and if multicast traffic
+is confined to SL 0 or SL 8 (recall that torus-2QoS uses SL bit 3 to
+differentiate QoS level), then multicast traffic also cannot contribute to
+the "ring" credit loops that are otherwise possible in a torus.
+
+Torus-2QoS uses these ideas to create a master spanning tree.  Every
+multicast group spanning tree will be constructed as a subset of the master
+tree, with the same root as the master tree.
+
+Such multicast group spanning trees will in general not be optimal for
+groups which are a subset of the full fabric. However, this compromise must
+be made to enable support for two QoS levels on a torus while preventing
+credit loops.
+
+In the presence of link or switch failures that result in a fabric for
+which torus-2QoS can generate credit-loop-free unicast routes, it is also
+possible to generate a master spanning tree for multicast that retains the
+required properties.  For example, consider that same 2D 6x5 torus, with
+the link from (2,2) to (3,2) failed.  Torus-2QoS will generate the following
+master spanning tree:
+
+   4    +    +    +    +    +    +
+	|    |    |    |    |    |
+   3    +    +    +    +    +    +
+	|    |    |    |    |    |
+   2  --+----+----+    x----+----+--
+	|    |    |    |    |    |
+   1    +    +    +    +    +    +
+	|    |    |    |    |    |
+ y=0    +    +    +    +    +    +
+
+      x=0    1    2    3    4    5
+
+Two things are notable about this master spanning tree.  First, assuming
+the x dateline was between x=5 and x=0, this spanning tree has a branch
+that crosses the dateline.  However, just as for unicast, crossing a
+dateline on a 1D ring (here, the ring for y=2) that is broken by a failure
+cannot contribute to a torus credit loop.
+
+Second, this spanning tree is no longer optimal even for multicast groups
+that encompass the entire fabric.  That, unfortunately, is a compromise that
+must be made to retain the other desirable properties of torus-2QoS routing.
+
+In the event that a single switch fails, torus-2QoS will generate a master
+spanning tree that has no "extra" turns by appropriately selecting a root
+switch.  In the 2D 6x5 torus example, assume now that the switch at (3,2),
+i.e. the root for a pristine fabric, fails.  Torus-2QoS will generate the
+following master spanning tree for that case:
+
+		       |
+   4    +    +    +    +    +    +
+	|    |    |    |    |    |
+   3    +    +    +    +    +    +
+	|    |    |         |    |
+   2    +    +    +         +    +
+	|    |    |         |    |
+   1    +----+----x----+----+----+
+	|    |    |    |    |    |
+ y=0    +    +    +    +    +    +
+		       |
+
+      x=0    1    2    3    4    5
+
+Assuming the y dateline was between y=4 and y=0, this spanning tree has
+a branch that crosses a dateline.  However, again this cannot contribute
+to credit loops as it occurs on a 1D ring (the ring for x=3) that is
+broken by a failure, as in the above example.
+
+Torus Topolgy Discovery:
+
+The algorithm used by torus-2QoS to construct the torus topology from the
+undirected graph representing the fabric requires that the radix of each
+dimension be configured via torus-2QoS.conf. It also requires that the
+torus topology be "seeded"; for a 3D torus this requires configuring four
+switches that define the three coordinate directions of the torus.
+
+Given this starting information, the algorithm is to examine the cube
+formed by the eight switch locations bounded by the corners (x,y,z) and
+(x+1,y+1,z+1).  Based on switches already placed into the torus topology at
+some of these locations, the algorithm examines 4-loops of interswitch
+links to find the one that is consistent with a face of the cube of switch
+locations, and adds its swiches to the discovered topology in the correct
+locations.
+
+Because the algorithm is based on examining the topology of 4-loops of links,
+a torus with one or more radix-4 dimensions requires extra initial seed
+configuration.  See torus-2QoS.conf(5) for details. Torus-2QoS will detect
+and report when it has insufficient configuration for a torus with radix-4
+dimensions.
+
+In the event the torus is significantly degraded, i.e., there are many
+missing switches or links, it may happen that torus-2QoS is unable to place
+into the torus some switches and/or links that were discovered in the
+fabric, and will generate a warning in that case.  A similar condition
+occurs if torus-2QoS is misconfigured, i.e., the radix of a torus dimension
+as configured does not match the radix of that torus dimension as wired,
+and many switches/links in the fabric will not be placed into the torus.
+
+Quality Of Service Configuration:
+
+OpenSM will not program switchs and channel adapters with SL2VL maps or VL
+arbitration configuration unless it is invoked with -Q.  Since torus-2QoS
+depends on such functionality for correct operation, always invoke OpenSM
+with -Q when torus-2QoS is in the list of routing engines.
+
+Any quality of service configuration method supported by OpenSM will work
+with torus-2QoS, subject to the following limitations and considerations.
+
+For all routing engines supported by OpenSM except torus-2QoS, there is a
+one-to-one correspondence between QoS level and SL. Torus-2QoS can only
+support two quality of service levels, so only the high-order bit of any SL
+value used for unicast QoS configuration will be honored by torus-2QoS.
+
+For multicast QoS configuration, only SL values 0 and 8 should be used with
+torus-2QoS.
+
+Since SL to VL map configuration must be under the complete control of
+torus-2QoS, any configuration via qos_sl2vl, qos_swe_sl2vl, etc., must and
+will be ignored, and a warning will be generated.
+
+For inter-switch links, Torus-2QoS uses VL values 0-3 to implement one of
+its supported QoS levels, and VL values 4-7 to implement the other. For
+endport links (CA, router, switch management port), Torus-2QoS uses VL
+value 0 for one of its supported QoS levels and VL value 1 to implement
+the other.  Hard-to-diagnose application issues may arise if traffic is
+not delivered fairly across each of these two VL ranges. For
+inter-switch links, Torus-2QoS will detect and warn if VL arbitration is
+configured unfairly across VLs in the range 0-3, and also in the range
+4-7. Note that the default OpenSM VL arbitration configuration does
+not meet this constraint, so all torus-2QoS users should configure VL
+arbitration via qos_ca_vlarb_high, qos_swe_vlarb_high, qos_ca_vlarb_low,
+qos_swe_vlarb_low, etc.
+
+Note that torus-2QoS maps SL values to VL values differently
+for inter-switch and endport links.  This is why qos_vlarb_high and
+qos_vlarb_low should not be used, as using them may result in
+VL arbitration for a QoS level being different across inter-switch
+links vs. across endport links.
+
+Operational Considerations:
+
+Any routing algorithm for a torus IB fabric must employ path SL values to
+avoid credit loops. As a result, all applications run over such fabrics
+must perform a path record query to obtain the correct path SL for
+connection setup. Applications that use rdma_cm for connection setup will
+automatically meet this requirement.
+
+If a change in fabric topology causes changes in path SL values required to
+route without credit loops, in general all applications would need to
+repath to avoid message deadlock. Since torus-2QoS has the ability to
+reroute after a single switch failure without changing path SL values,
+repathing by running applications is not required when the fabric is routed
+with torus-2QoS.
+
+Torus-2QoS can provide unchanging path SL values in the presence of subnet
+manager failover provided that all OpenSM instances have the same idea of
+dateline location. See torus-2QoS.conf(5) for details.
+
+Torus-2QoS will detect configurations of failed switches and links that
+prevent routing that is free of credit loops, and will log warnings and
+refuse to route. If "no_fallback" was configured in the list of OpenSM
+routing engines, then no other routing engine will attempt to route the
+fabric. In that case all paths that do not transit the failed components
+will continue to work, and the subset of paths that are still operational
+will continue to remain free of credit loops. OpenSM will continue to
+attempt to route the fabric after every sweep interval, and after any
+change (such as a link up) in the fabric topology. When the fabric
+components are repaired, full functionality will be restored.
+
+In the event OpenSM was configured to allow some other engine to route the
+fabric if torus-2QoS fails, then credit loops and message deadlock are
+likely if torus-2QoS had previously routed the fabric successfully. Even if
+the other engine is capable of routing a torus without credit loops,
+applications that built connections with path SL values granted under
+torus-2QoS will likely experience message deadlock under routing generated
+by a different engine, unless they repath.
+
+To verify that a torus fabric is routed free of credit loops, use ibdmchk
+to analyze data collected via ibdiagnet -vlr.
+
+DFSSSP and SSSP Routing Algorithm
+---------------------------------
+
+The (Deadlock-Free) Single-Source-Shortest-Path routing algorithm is
+designed to optimize link utilization thru global balancing of routes,
+while supporting arbitrary topologies. The DFSSSP routing algorithm
+uses Infiniband virtual lanes (SL) to provide deadlock-freedom.
+
+The DFSSSP algorithm consists of five major steps:
+1) It discovers the subnet and models the subnet as a directed
+   multigraph in which each node represents a node of the physical
+   network and each edge represents one direction of the full-duplex
+   links used to connect the nodes.
+2) A loop, which iterates over all CA and switches of the subnet, will
+   perform three steps to generate the linear forwarding tables for
+   each switch:
+2.1) use Dijkstra's algorithm to find the shortest path from all nodes
+     to the current selected destination;
+2.2) update the egde weights in the graph, i.e. add the number of
+     routes, which use a link to reach the destination, to the link/edge;
+2.3) update the LFT of each switch with the outgoing port which was used
+     in the current step to route the traffic to the destination node.
+3) After the number of available virtual lanes or layers in the subnet
+   is detected and a channel dependency graph is initialized for each layer,
+   the algorithm will put each possible route of the subnet into the first
+   layer.
+4) A loop iterates over all channel dependency graphs (CDG) and performs
+   the following substeps:
+4.1) search for a cycle in the current CDG;
+4.2) when a cycle is found, i.e. a possible deadlock is present,
+     one edge is selected and all routes, which induced this egde, are moved
+     to the "next higher" virtual layer (CDG[i+1]);
+4.3) the cycle search is continued until all cycles are broken and
+     routes are moved "up".
+5) When the number of needed layers does not exceeds the number of
+   available SL/VL to remove all cycles in all CDGs, the rounting is
+   deadlock-free and an relation table is generated, which contains
+   the assignment of routes from source to destination to a SL
+
+Note on SSSP:
+This algorithm does not perform the steps 3)-5) and can not be
+considered to be deadlock-free for all topologies. But on the one
+hand, you can choose this algorithm for really large networks
+(5,000+ CAs and deadlock-free by design) to reduce
+the runtime of the algorithm. On the other hand, you might use
+the SSSP routing algorithm as an alternative, when all deadlock-free
+routing algorithms fail to route the network for whatever reason.
+In the last case, SSSP was designed to deliver an equal or higher
+bandwidth due to better congestion avoidance than the Min Hop
+routing algorithm.
+
+Notes for usage:
+  a) running DFSSSP: '-R dfsssp -Q'
+    a.1) QoS has to be configured to equally spread the load on the
+         available SL or virtual lanes
+    a.2) applications must perform a path record query to get path SL for
+         each route, which the application will use to transmite packages
+  b) running SSSP:   '-R sssp'
+  c) both algorithms support LMC > 0
+
+Hints for separate optimization of compute and I/O traffic:
+Having more nodes (I/O and compute) connected to a switch than incoming links
+can result in a 'bad' routing of the I/O traffic as long as (DF)SSSP routing
+is not aware of the dedicated I/O nodes, i.e., in the following network
+configuration CN1-CN3 might send all I/O traffic via Link2 to IO1,IO2:
+
+     CN1         Link1        IO1
+        \       /----\       /
+  CN2 -- Switch1      Switch2 -- CN4
+        /       \----/       \
+     CN3         Link2        IO2
+
+To prevent this from happening (DF)SSSP can use both the compute node guid
+file and the I/O guid file specified by the '-u' or '--cn_guid_file' and
+'-G' or '--io_guid_file' options (similar to the Fat-Tree routing).
+This ensures that traffic towards compute nodes and I/O nodes is balanced
+separately and therefore distributed as much as possible across the available
+links. Port GUIDs, as listed by ibstat, must be specified (not Node GUIDs).
+The priority for the optimization is as follows:
+  compute nodes -> I/O nodes -> other nodes
+Possible use case szenarios:
+  a) neither '-u' nor '-G' are specified: all nodes a treated as 'other nodes'
+     and therefore balanced equally;
+  b) '-G' is specified: traffic towards I/O nodes will be balanced optimally;
+  c) the system has three node types, such as login/admin, compute and I/O,
+     but the balancing focus should be I/O, then one has to use '-u' and '-G'
+     with I/O guids listed in cn_guid_file and compute node guids listed in
+     io_guid_file;
+  d) ...
+
+For more information about the algorithms, i.e. balancing the routes and
+moving the routes to different virtual layers, and about comparison with
+other routing algorithms, please refer to the following articles:
+1. J. Domke, T. Hoefler and W. Nagel: Deadlock-Free Oblivious Routing
+   for Arbitrary Topologies, In Proceedings of the 25th IEEE International
+   Parallel & Distributed Processing Symposium (IPDPS 2011)
+2. T. Hoefler, T. Schneider and A. Lumsdaine: Optimized Routing for
+   Large-Scale InfiniBand Networks, In 17th Annual IEEE Symposium on High
+   Performance Interconnects (HOTI 2009)
diff --git a/doc/opensm_release_notes-3.3.txt b/doc/opensm_release_notes-3.3.txt
index 7172d79..4177b83 100644
--- a/doc/opensm_release_notes-3.3.txt
+++ b/doc/opensm_release_notes-3.3.txt
@@ -2,15 +2,15 @@
                        =============================
 
 Version: OpenSM 3.3.x
-Repo:    git://git.openfabrics.org/~alexnetes/opensm.git
-Date:    Jan 2014
+Repo:    git://git.openfabrics.org/~halr/opensm.git
+Date:    July 2014
 
 1 Overview
 ----------
 This document describes the contents of the OpenSM 3.3 release.
 OpenSM is an InfiniBand compliant Subnet Manager and Administration,
 and runs on top of OpenIB. The OpenSM version for this release
-is opensm-3.3.17.
+is opensm-3.3.18.
 
 This document includes the following sections:
 1 This Overview section (describing new features and software
@@ -95,6 +95,8 @@ This document includes the following sections:
 
 1.2 Minor New Features:
 
+672de65 perfmgr: Add xmit_wait to event plugin error counters data structure
+d86e7e3 perfmgr: Add xmit_wait support
 7e6bdef opensm/man/opensm.8.in: Add section for MKey support
 aebe678 opensm: Add support for multicast service records
 5509234 opensm/scripts/sldd.sh: Update to support guid2mkey/neighbors
@@ -415,6 +417,7 @@ b73c378 opensm/perfmgr; add support for PortCountersExtended NOIETF
 
 1.3 Library API Changes
 
+44a6358 libvendor/osm_vendor_ibumad.c: Support GRH (for GS classes)
 de02954 osm_trap_rcv.c: Log DR path to node when trap 128
 
 1.4 Software Dependencies
@@ -509,6 +512,37 @@ information regarding each compliance statement.
 
 4.1 Major Bug Fixes
 
+db69cd8 osm_perfmgr.c: Fix perfmgr sweep_state race
+b42f11f osm_vendor_ibumad.c: Better match table eviction strategy
+cc0d61b libvendor/osm_vendor_ibumad.c: Check the next CA if an error is
+returned for the current one
+a16349d osm_trap_rcv.c: Lock released without locking in some cases of trap
+processing
+6c6e4cc osm_sa_guidinfo_record.c: Fix crash when receiving AGUID SET/DELETE
+with block_num equal to max_block
+a8b23b7 osm_vl15intf.c: Fix potential NULL dereference in vl15_send_mad
+e94d471 osm_torus.c: Fix torus crash when actual topology is not torus
+a20cd5f osm_sa_service_record.c: Fix locking issue in osm_sr_rcv_process
+127acf1 osm_sa_mcmember_record.c: Fix double locking in mcmr_rcv_join_mgrp
+c86c30a All SA queries should validate the requester port under lock
+80e1e59 osm_sminfo_rcv.c: Send trap 144 to a newly found MASTER SM when in
+MASTER state
+0189dea osm_sm_state_mgr.c: Fix opensm crash after handover
+52c4a30 osm_sm_state_mgr.c: Reconfigure the fabric when receiving
+HANDOVER/POLLING_TIMEOUT in MASTER state
+26af3a9 Fix crash during handover
+f775a1a osm_sa_path_record.c: Search for requester port should be under lock
+24d6219 osm_sw_info_rcv.c: Fix sending PortInfo during lightsweep
+12d2c8e osm_node_info_rcv.c: Fix multiple switch discovery during a sweep
+ef22eb9 osm_qos.c: Fix possible seg fault
+9dd8f45 dfsssp: avoid crash due to port initialisation errors
+f6418cf osm_ucast_dfsssp.c: prevent double free error
+1633550 Resend LFTs/VLArb/SL2VL MADs in case of error
+90d19c2 osm_port_info_rcv.c: Reread pkeys from SP0 if switch rebooted during a
+sweep
+6e90421 Better handling of topology changes in the fabric
+b33c3ba Change discovery order of switch data
+395b5f0 Handle bad SMP status
 a322f51 Skip TID 0 on 32 bit wraparound for SMP, SA and PerfMgt queries
 cded9af Fix transaction id casting
 3585f8b opensm: Fix crash found with ucast cache
@@ -668,6 +702,103 @@ f37bf3c opensm/perfmgr: skip data counters when only printing errors
 
 4.2 Other Bug Fixes
 
+179fbac Add support for additional Mellanox OUI
+be3e4f1 osm_subnet.c: Remove duplicate strcmp check in
+osm_subn_rescan_conf_files method
+e6fc2f8 Add some missing documentation files to installation
+ed1571a osm_subnet.c: Change default for perfmgr_query_cpi option
+3a1b458 osm_mcast_mgr.c: Cosmetic change to error log mesage
+56bd964 opensm.init.in: Fix return value checking in opensm.init script
+787c16e Eliminate redundant calls to ib_port_info_compute_rate
+6a2d081 Shorten long lines while calculating SA rate
+6ec10d6 man/opensm.8.in: Update date on man page
+1dcf322 Improve scatter ports documentation
+b1a8fb0 osm_subnet.c: Cosmetic formatting change in subn_validate_neighbor
+d1b70fc osm_perfmgr.c: Add log message when perfmgr sweep is skipped
+8098a4d osm_perfmgr.c: Remove unnecessary log message
+38bc2e4 Skip state_mgr_check_tbl_consistency when no LID is changed by lid or
+link managers
+ce73c60 osm_drop_mgr.c: Add missing CR at end of log message in
+drop_mgr_check_node
+8255f8f osm_state_mgr.c: Improve error flow with wrong LIDs
+86f1720 osm_sa_path_record.c: Fix some commentary typos
+2bc6074 osmtest/main.c: Output formatting change for case 'x'
+60727f7 osmtest: Add GRH tests for SA queries
+d29dcd7 osm_sa_path_record.c: Fix misleading error messages during sweep
+e91908b Add osm_congestion_control.c to per module logging support
+3de1091 osm_congestion_control.c: Fix error code
+3ee0a22 osm_sm.c: In sm_sweeper, no need to check for timeout after
+cl_event_wait_on EVENT_NO_TIMEOUT
+f3e1924 osm_trap_rcv.c: In shutup_noisy_port, improve ERR 3811 log message
+f73ff43 osm_mcast_mgr.c: In mcast_mgr_process_mlid, cosmetic change to log
+message
+ab9fec9 osm_congestion_control.c: In cc_poller_send, handle cl_event_wait_on
+return status
+af04af7 osm_[sm sa]_mad_ctrl.c: Improve unsupported attribute error messages
+16fee25 osm_helper.c: In osm_get_lsa_str, fix printing of wrong FDR10 data if
+link is down
+6c70bf1 PerfMgr: Eliminate no longer used sig_sweep variable
+41d0a42 osm_perfmgr.c: In perfmgr_send_mad, handle cl_event_wait_on return
+status
+d764777 osm_perfmgr.c: Minor code factoring in perfmgr_send_mad
+fa31298 doc/opensm_release_notes-3.3.txt: Updated repo location
+8394ef8 libvendor/osm_vendor_ibumad.c: Commentary change
+0ab7492 osm_subnet.c: More cosmetic changes to opensm conf file PerfMgr
+documentation
+cc977be osm_subnet.c: Enhance opensm conf file documentation for PerfMgr
+options
+38273db osm_port_info_rcv.c: Fixed calculation of min_data_vls
+dc3259e Add support for additional Mellanox OUI
+99a8e74 osmtest.c: Fixed missing assignment of return value from function
+osmtest_get_port_rec_by_num
+9ffa520 Fix the creation of empty multicast groups from SADB
+1d3aacf osm_perfmgr_db.c: Add missing clear of new xmit_wait counter in
+clear_counters
+0f9b15c SM should resweep the fabric if vl15_send_mad fails
+ee5f6d5 osm_perfmgr.c: Added Mellanox copyright
+05be6c4 osm_perfmgr.c: Eliminate unneeded initialization in pc_recv_process
+9ac71fd osm_perfmgr.c: Cosmetic formatting changes
+54c6c86 osm_log.c: Fix wrong hour and date display in log when CL_ASSERT fail
+5c81051 osm_console_io.c: Handle return value of function setsockopt
+2e1294a osm_sa_[mcmember path]_record.c: Optimize clearing of SA record items
+db9c450 osm_guid_info_rcv.c: Fix assert placement in osm_gi_rcv_process
+bb723ae libvendor/osm_vendor_ibumad.c: Cosmetic change to umad_set_grh calls
+5ca6bdc osm_perfmgr.c: Add current PerfMgr sweep state to 54FF error log
+message
+753af81 osm_mcast_mgr.c: Add missing new line at end of ERR 0A21 log message
+d437d58 osm_mcast_mgr.c: Fix endian of port GUID in ERR 0A06 log message
+51fb51d osm_ucast_mgr.c: Fix duplicated error codes
+21c2ab7 osm_sa_mad_ctrl.c: In sa_mad_ctrl_rcv_callback, improve 1A04 error log
+message
+c83bde4 doc/performance-manager-HOWTO.txt: Fix typo
+abaf91b osm_sa_service_record.c: Improved locking
+1f4de58 osm_subnet.c: Fix bug in parsing configuration file
+0fa5fc1 osm_sa_mcmember_record.c: Fix removing members from existing mc group
+due to invalid requests
+e156626 osm_qos_parser_y.y: Added range check for mtu limit parsing
+cb439b3 osm_qos_parser_y.y: Added range check for rate limit parsing
+a556f82 man/opensm.8.in: Minor fixes to per module logging configuration
+7991745 osm_node_info_rcv.c: Update local copy of node info for known nodes
+1c637df osm_node_info_rcv.c: Update NodeInfo.SysImageGUID on heavy sweep
+275a56a osm_state_mgr.c: Clear first time sweep even after subnet error
+09b5ffe osm_sa_path_record.c: In osm_pr_rcv_process, release lock before log
+message
+ef7a651 osm_state_mgr.c: Revert commit to "remove redundant unset to
+first_time_master_sweep"
+23dfbf8 osm_state_mgr.c: Remove redundant unset to first_time_master_sweep
+e5a87dd Revert "Reset client reregistration when receiving handover"
+28e5fa7 osm_sw_info_rcv.c: Add check of switch mcast_cap
+78b6e8f osm_subnet.c: Fix resource leak neighbor parser
+("subn_validate_neighbor" function)
+46749c0 osm_subnet.c: Fix resource leak guid2mkey parser (guid validation
+function)
+6212e4b osm_ucast_ftree.c: Fix memory leak in ftree fabric_rank
+afb6cb8 osm_ucast_mgr.c: Use LFT block of all port 0s to indicate resend
+319e065 ib_types.h: Rename ib_switch_info_set_state_change function
+b1c17a8 ib_types.h: Fix shadow declaration warnings
+e3f0440 osm_ucast_updn.c: Fix the AA0B error number
+30d9020 osm_ucast_updn.c: Add missing ERR number to log message
+e8a9275 osm_port.c: Improve ERR 4108 log message
 740c22b opensm/include/opensm/osm_log.h: Fix commentary cut 'n paste error
 13ebee4 opensm/osm_subnet.c: Fixed ftree/updn configuration failure when
 	root_guid_file points to non-existing file
diff --git a/doc/performance-manager-HOWTO.txt b/doc/performance-manager-HOWTO.txt
index 7471c6f..bf5f778 100644
--- a/doc/performance-manager-HOWTO.txt
+++ b/doc/performance-manager-HOWTO.txt
@@ -57,7 +57,7 @@ operation of your subnet.
 Step 2: Enable the perfmgr and console in opensm.conf
 -----------------------------------------------------
 
-Turning the Perfmorance Manager on is pretty easy, set the following options in
+Turning the Performance Manager on is pretty easy, set the following options in
 the opensm.conf config file.  (Default location is
 /usr/local/etc/opensm/opensm.conf)
 
diff --git a/include/iba/ib_types.h b/include/iba/ib_types.h
index 86fa07b..a0bb31c 100644
--- a/include/iba/ib_types.h
+++ b/include/iba/ib_types.h
@@ -6507,6 +6507,34 @@ ib_switch_info_clear_state_change(IN ib_switch_info_t * const p_si)
 * SEE ALSO
 *********/
 
+/****f* IBA Base: Types/ib_switch_info_state_change_set
+* NAME
+*	ib_switch_info_state_change_set
+*
+* DESCRIPTION
+*	Clears the switch's state change bit.
+*
+* SYNOPSIS
+*/
+static inline void OSM_API
+ib_switch_info_state_change_set(IN ib_switch_info_t * const p_si)
+{
+	p_si->life_state = (uint8_t) ((p_si->life_state & ~IB_SWITCH_PSC) | IB_SWITCH_PSC);
+}
+
+/*
+* PARAMETERS
+*	p_si
+*		[in] Pointer to a SwitchInfo attribute.
+*
+* RETURN VALUES
+*	None
+*
+* NOTES
+*
+* SEE ALSO
+*********/
+
 /****f* IBA Base: Types/ib_switch_info_get_opt_sl2vlmapping
 * NAME
 *	ib_switch_info_get_state_opt_sl2vlmapping
@@ -6535,6 +6563,38 @@ ib_switch_info_get_opt_sl2vlmapping(IN const ib_switch_info_t * const p_si)
 * SEE ALSO
 *********/
 
+/****f* IBA Base: Types/ib_switch_info_set_life_time
+* NAME
+*	ib_switch_info_set_life_time
+*
+* DESCRIPTION
+*	Sets the value of LifeTimeValue.
+*
+* SYNOPSIS
+*/
+static inline void OSM_API
+ib_switch_info_set_life_time(IN ib_switch_info_t * const p_si,
+			     IN const uint8_t life_time_val)
+{
+	p_si->life_state = (p_si->life_state & 0x1f) |
+			   (life_time_val << 3);
+}
+
+/*
+* PARAMETERS
+*	p_si
+*		[in] Pointer to a SwitchInfo attribute.
+*	life_time_val
+*		[in] LiveTimeValue.
+*
+* RETURN VALUES
+*	None.
+*
+* NOTES
+*
+* SEE ALSO
+*********/
+
 /****f* IBA Base: Types/ib_switch_info_is_enhanced_port0
 * NAME
 *	ib_switch_info_is_enhanced_port0
@@ -8164,9 +8224,10 @@ static inline void OSM_API
 ib_inform_info_set_qpn(IN ib_inform_info_t * p_ii, IN ib_net32_t const qpn)
 {
 	uint32_t tmp = cl_ntoh32(p_ii->g_or_v.generic.qpn_resp_time_val);
+	uint32_t qpn_h = cl_ntoh32(qpn);
 
 	p_ii->g_or_v.generic.qpn_resp_time_val =
-	    cl_hton32((tmp & 0x000000ff) | ((cl_ntoh32(qpn) << 8) & 0xffffff00)
+	    cl_hton32((tmp & 0x000000ff) | ((qpn_h << 8) & 0xffffff00)
 	    );
 }
 
diff --git a/include/opensm/osm_base.h b/include/opensm/osm_base.h
index be2dca3..e2425bf 100644
--- a/include/opensm/osm_base.h
+++ b/include/opensm/osm_base.h
@@ -1008,6 +1008,8 @@ typedef enum _osm_sm_signal {
 #define OSM_VENDOR_ID_OPENIB        0x001405
 #define OSM_VENDOR_ID_IBM2	    0x5CF3FC
 #define OSM_VENDOR_ID_MELLANOX2     0xF45214
+#define OSM_VENDOR_ID_MELLANOX3     0x00258B
+#define OSM_VENDOR_ID_MELLANOX4     0xE41D2D
 
 /* IPoIB Broadcast Defaults */
 #define OSM_IPOIB_BROADCAST_MGRP_QKEY 0x0b1b
diff --git a/include/opensm/osm_event_plugin.h b/include/opensm/osm_event_plugin.h
index ca5a719..db5ebca 100644
--- a/include/opensm/osm_event_plugin.h
+++ b/include/opensm/osm_event_plugin.h
@@ -126,6 +126,7 @@ typedef struct osm_epi_pe_event {
 	uint64_t link_integrity;
 	uint64_t buffer_overrun;
 	uint64_t vl15_dropped;
+	uint64_t xmit_wait;
 	time_t time_diff_s;
 } osm_epi_pe_event_t;
 
diff --git a/include/opensm/osm_lid_mgr.h b/include/opensm/osm_lid_mgr.h
index 40f0d30..f95a2a1 100644
--- a/include/opensm/osm_lid_mgr.h
+++ b/include/opensm/osm_lid_mgr.h
@@ -98,6 +98,7 @@ typedef struct osm_lid_mgr {
 	cl_plock_t *p_lock;
 	osm_db_domain_t *p_g2l;
 	cl_qlist_t free_ranges;
+	boolean_t dirty;
 	uint8_t used_lids[IB_LID_UCAST_END_HO + 1];
 } osm_lid_mgr_t;
 /*
@@ -120,16 +121,19 @@ typedef struct osm_lid_mgr {
 *	p_g2l
 *		Pointer to the database domain storing guid to lid mapping.
 *
-*	used_lids
-*		An array of used lids. keeps track of
-*		existing and non existing mapping of guid->lid
-*
 *	free_ranges
 *		A list of available free lid ranges. The list is initialized
 *		by the code that initializes the lid assignment and is consumed
 *		by the procedure that finds a free range. It holds elements of
 *		type osm_lid_mgr_range_t
 *
+*	dirty
+*		 Indicates that lid table was updated
+*
+*	used_lids
+*		 An array of used lids. keeps track of
+*		 existing and non existing mapping of guid->lid
+*
 * SEE ALSO
 *	LID Manager object
 *********/
diff --git a/include/opensm/osm_perfmgr.h b/include/opensm/osm_perfmgr.h
index 0304d9c..44a278d 100644
--- a/include/opensm/osm_perfmgr.h
+++ b/include/opensm/osm_perfmgr.h
@@ -75,6 +75,7 @@ extern "C" {
 #define OSM_PERFMGR_DEFAULT_SWEEP_TIME_S 180
 #define OSM_PERFMGR_DEFAULT_DUMP_FILE "opensm_port_counters.log"
 #define OSM_PERFMGR_DEFAULT_MAX_OUTSTANDING_QUERIES 500
+#define OSM_PERFMGR_DEFAULT_XMIT_WAIT_THRESHOLD 0x0000FFFF
 
 /****s* OpenSM: PerfMgr/osm_perfmgr_state_t */
 typedef enum {
@@ -87,7 +88,8 @@ typedef enum {
 typedef enum {
 	PERFMGR_SWEEP_SLEEP,
 	PERFMGR_SWEEP_ACTIVE,
-	PERFMGR_SWEEP_SUSPENDED
+	PERFMGR_SWEEP_SUSPENDED,
+	PERFMGR_SWEEP_POST_PROCESSING
 } osm_perfmgr_sweep_state_t;
 
 typedef struct monitored_port {
@@ -124,7 +126,6 @@ struct osm_opensm;
 *  be manipulated only through the provided functions.
 */
 typedef struct osm_perfmgr {
-	cl_event_t sig_sweep;
 	cl_timer_t sweep_timer;
 	struct osm_opensm *osm;
 	osm_subn_t *subn;
@@ -150,6 +151,8 @@ typedef struct osm_perfmgr {
 	int16_t local_port;
 	int rm_nodes;
 	boolean_t query_cpi;
+	boolean_t xmit_wait_log;
+	uint32_t xmit_wait_threshold;
 } osm_perfmgr_t;
 /*
 * FIELDS
@@ -237,6 +240,9 @@ inline static const char *osm_perfmgr_get_sweep_state_str(osm_perfmgr_t * perfmg
 	case PERFMGR_SWEEP_SUSPENDED:
 		return "Suspended";
 		break;
+	case PERFMGR_SWEEP_POST_PROCESSING:
+		return "PostProcessing";
+		break;
 	}
 	return "UNKNOWN";
 }
diff --git a/include/opensm/osm_perfmgr_db.h b/include/opensm/osm_perfmgr_db.h
index ed14f76..25d9c58 100644
--- a/include/opensm/osm_perfmgr_db.h
+++ b/include/opensm/osm_perfmgr_db.h
@@ -90,6 +90,7 @@ typedef struct {
 	uint64_t link_integrity;
 	uint64_t buffer_overrun;
 	uint64_t vl15_dropped;
+	uint64_t xmit_wait;
 	time_t time;
 } perfmgr_db_err_reading_t;
 
@@ -205,7 +206,8 @@ void perfmgr_db_print_by_guid(perfmgr_db_t * db, uint64_t guid, FILE *fp,
  */
 
 void perfmgr_db_fill_err_read(ib_port_counters_t * wire_read,
-			      perfmgr_db_err_reading_t * reading);
+			      perfmgr_db_err_reading_t * reading,
+			      boolean_t xmit_wait_sup);
 void perfmgr_db_fill_data_cnt_read_pc(ib_port_counters_t * wire_read,
 				      perfmgr_db_data_cnt_reading_t * reading);
 void perfmgr_db_fill_data_cnt_read_pce(ib_port_counters_ext_t * wire_read,
diff --git a/include/opensm/osm_sm.h b/include/opensm/osm_sm.h
index e48c549..94d1831 100644
--- a/include/opensm/osm_sm.h
+++ b/include/opensm/osm_sm.h
@@ -116,7 +116,7 @@ typedef struct osm_sm {
 	unsigned master_sm_found;
 	uint32_t retry_number;
 	ib_net64_t master_sm_guid;
-	osm_remote_sm_t *p_polling_sm;
+	ib_net64_t polling_sm_guid;
 	osm_subn_t *p_subn;
 	osm_db_t *p_db;
 	osm_vendor_t *p_vendor;
diff --git a/include/opensm/osm_subnet.h b/include/opensm/osm_subnet.h
index 03f116e..a4ce2ed 100644
--- a/include/opensm/osm_subnet.h
+++ b/include/opensm/osm_subnet.h
@@ -296,6 +296,7 @@ typedef struct osm_subn_opt {
 	uint8_t sm_assigned_guid;
 	boolean_t qos;
 	char *qos_policy_file;
+	boolean_t suppress_sl2vl_mad_status_errors;
 	boolean_t accum_log_file;
 	char *console;
 	uint16_t console_port;
@@ -362,6 +363,8 @@ typedef struct osm_subn_opt {
 	int perfmgr_rm_nodes;
 	boolean_t perfmgr_log_errors;
 	boolean_t perfmgr_query_cpi;
+	boolean_t perfmgr_xmit_wait_log;
+	uint32_t perfmgr_xmit_wait_threshold;
 #endif				/* ENABLE_OSM_PERF_MGR */
 	char *event_plugin_name;
 	char *event_plugin_options;
@@ -762,7 +765,6 @@ typedef struct osm_subn {
 	boolean_t force_reroute;
 	boolean_t in_sweep_hop_0;
 	boolean_t first_time_master_sweep;
-	boolean_t set_client_rereg_on_sweep;
 	boolean_t coming_out_of_standby;
 	boolean_t sweeping_enabled;
 	unsigned need_update;
@@ -871,20 +873,13 @@ typedef struct osm_subn {
 *		the sweeping.
 *
 *	first_time_master_sweep
-*		This flag is to indicate the first sweep as master (meaning
-*		after moving from Standby|Discovering state).  The flag is
-*		used to notify some alternate actions that must be done on
-*		the first master sweep.  It may perform some actions indicated
-*		by flags below, such as set_client_rereg_on_sweep.
-*
-*	set_client_rereg_on_sweep
-*		This flag is used for the PortInfo setting client rereg.
-*		When configuring the subnet for the first time, and several
-*		other circumstances, SM must send a PortInfoSet to all ports.
-*		After that - we want to minimize the number of PortInfoSet
-*		requests sent, and to send only requests that change the value
-*		from what is updated in the port (or send a first request if
-*		this is a new port). We will set this flag to TRUE when entering
+*		This flag is used for the PortInfo setting. On the first
+*		sweep as master (meaning after moving from Standby|Discovering
+*		state), the SM must send a PortInfoSet to all ports. After
+*		that - we want to minimize the number of PortInfoSet requests
+*		sent, and to send only requests that change the value from
+*		what is updated in the port (or send a first request if this
+*		is a new port). We will set this flag to TRUE when entering
 *		the master state, and set it back to FALSE at the end of the
 *		drop manager. This is done since at the end of the drop manager
 *		we have updated all the ports that are reachable, and from now
diff --git a/include/opensm/osm_version.h b/include/opensm/osm_version.h
index e4251ac..f70ea07 100644
--- a/include/opensm/osm_version.h
+++ b/include/opensm/osm_version.h
@@ -45,7 +45,7 @@
 *
 * SYNOPSIS
 */
-#define OSM_VERSION "OpenSM 3.3.17"
+#define OSM_VERSION "OpenSM 3.3.18"
 /********/
 
 #endif				/* _OSM_VERSION_H_ */
diff --git a/include/opensm/osm_vl15intf.h b/include/opensm/osm_vl15intf.h
index e621c68..b024b23 100644
--- a/include/opensm/osm_vl15intf.h
+++ b/include/opensm/osm_vl15intf.h
@@ -53,6 +53,7 @@
 #include <opensm/osm_madw.h>
 #include <opensm/osm_mad_pool.h>
 #include <vendor/osm_vendor_api.h>
+#include <opensm/osm_subnet.h>
 
 #ifdef __cplusplus
 #  define BEGIN_C_DECLS extern "C" {
@@ -127,6 +128,7 @@ typedef struct osm_vl15 {
 	osm_vendor_t *p_vend;
 	osm_log_t *p_log;
 	osm_stats_t *p_stats;
+	osm_subn_t *p_subn;
 } osm_vl15_t;
 /*
 * FIELDS
@@ -171,6 +173,9 @@ typedef struct osm_vl15 {
 *	p_stats
 *		Pointer to the OpenSM statistics block.
 *
+*	p_subn
+*		Pointer to the OpenSM subnet object.
+*
 * SEE ALSO
 *	VL15 object
 *********/
@@ -251,6 +256,7 @@ void osm_vl15_destroy(IN osm_vl15_t * p_vl15, IN struct osm_mad_pool *p_pool);
 */
 ib_api_status_t osm_vl15_init(IN osm_vl15_t * p_vl15, IN osm_vendor_t * p_vend,
 			      IN osm_log_t * p_log, IN osm_stats_t * p_stats,
+			      IN osm_subn_t * p_subn,
 			      IN int32_t max_wire_smps,
 			      IN int32_t max_wire_smps2,
 			      IN uint32_t max_smps_timeout);
@@ -266,7 +272,10 @@ ib_api_status_t osm_vl15_init(IN osm_vl15_t * p_vl15, IN osm_vendor_t * p_vend,
 *		[in] Pointer to the log object.
 *
 *	p_stats
-*		[in] Pointer to the OpenSM stastics block.
+*		[in] Pointer to the OpenSM statistics block.
+*
+*	p_subn
+*		[in] Pointer to the OpenSM subnet object.
 *
 *	max_wire_smps
 *		[in] Maximum number of SMPs allowed on the wire at one time.
diff --git a/include/vendor/osm_vendor_sa_api.h b/include/vendor/osm_vendor_sa_api.h
index 653d847..d5f9376 100644
--- a/include/vendor/osm_vendor_sa_api.h
+++ b/include/vendor/osm_vendor_sa_api.h
@@ -740,6 +740,8 @@ typedef struct _osmv_query_req {
 
 	const void *query_context;
 	osmv_pfn_query_cb_t pfn_query_cb;
+	int with_grh;
+	ib_gid_t gid;
 } osmv_query_req_t;
 /*
 * FIELDS
@@ -777,6 +779,12 @@ typedef struct _osmv_query_req {
 *		A user-defined callback that is invoked upon completion of the
 *		query.
 *
+*	with_grh
+*		Indicates that SA queries should be sent with GRH.
+*
+*	gid
+*		Used to store the SM/SA GID.
+*
 * NOTES
 *	This structure is used when requesting an osm vendor provided query
 *	of subnet administration.  Clients specify the type of query through
diff --git a/libvendor/libosmvendor.ver b/libvendor/libosmvendor.ver
index d2b5c37..a2b6766 100644
--- a/libvendor/libosmvendor.ver
+++ b/libvendor/libosmvendor.ver
@@ -6,4 +6,4 @@
 # API_REV - advance on any added API
 # RUNNING_REV - advance any change to the vendor files
 # AGE - number of backward versions the API still supports
-LIBVERSION=3:9:0
+LIBVERSION=4:0:0
diff --git a/libvendor/osm_vendor_ibumad.c b/libvendor/osm_vendor_ibumad.c
index aa9396c..e05db8d 100644
--- a/libvendor/osm_vendor_ibumad.c
+++ b/libvendor/osm_vendor_ibumad.c
@@ -190,15 +190,21 @@ static osm_madw_t *get_madw(osm_vendor_t * p_vend, ib_net64_t * tid,
 	return 0;
 }
 
+/*
+ * If match table full, evict LRU (least recently used) transaction.
+ * Maintain 2 LRUs: one for SMPs, and one for others (GS).
+ * Evict LRU GS transaction if one is available and only evict LRU SMP
+ * transaction if no other choice.
+ */
 static void
 put_madw(osm_vendor_t * p_vend, osm_madw_t * p_madw, ib_net64_t tid,
 	 uint8_t mgmt_class)
 {
-	umad_match_t *m, *e, *old_lru, *lru = 0;
+	umad_match_t *m, *e, *old_lru, *lru = 0, *lru_smp = 0;
 	osm_madw_t *p_req_madw;
 	osm_umad_bind_info_t *p_bind;
 	ib_net64_t old_tid;
-	uint32_t oldest = ~0;
+	uint32_t oldest = ~0, oldest_smp = ~0;
 	uint8_t old_mgmt_class;
 
 	pthread_mutex_lock(&p_vend->match_tbl_mutex);
@@ -213,15 +219,30 @@ put_madw(osm_vendor_t * p_vend, osm_madw_t * p_madw, ib_net64_t tid,
 			pthread_mutex_unlock(&p_vend->match_tbl_mutex);
 			return;
 		}
-		if (oldest >= m->version) {
-			oldest = m->version;
-			lru = m;
+		if (m->mgmt_class == IB_MCLASS_SUBN_DIR ||
+		    m->mgmt_class == IB_MCLASS_SUBN_LID) {
+			if (oldest_smp >= m->version) {
+				oldest_smp = m->version;
+				lru_smp = m;
+			}
+		} else {
+			if (oldest >= m->version) {
+				oldest = m->version;
+				lru = m;
+			}
 		}
 	}
 
-	old_lru = lru;
-	old_tid = lru->tid;
-	old_mgmt_class = lru->mgmt_class;
+	if (oldest != ~0) {
+		old_lru = lru;
+		old_tid = lru->tid;
+		old_mgmt_class = lru->mgmt_class;
+	} else {
+		CL_ASSERT(oldest_smp != ~0);
+		old_lru = lru_smp;
+		old_tid = lru_smp->tid;
+		old_mgmt_class = lru_smp->mgmt_class;
+	}
 	p_req_madw = old_lru->v;
 	p_bind = p_req_madw->h_bind;
 	p_req_madw->status = IB_CANCELED;
@@ -229,11 +250,20 @@ put_madw(osm_vendor_t * p_vend, osm_madw_t * p_madw, ib_net64_t tid,
 	pthread_mutex_lock(&p_vend->cb_mutex);
 	(*p_bind->send_err_callback) (p_bind->client_context, p_req_madw);
 	pthread_mutex_unlock(&p_vend->cb_mutex);
-	lru->tid = tid;
-	lru->mgmt_class = mgmt_class;
-	lru->v = p_madw;
-	lru->version =
-	    cl_atomic_inc((atomic32_t *) & p_vend->mtbl.last_version);
+	if (mgmt_class == IB_MCLASS_SUBN_DIR ||
+	    mgmt_class == IB_MCLASS_SUBN_LID) {
+		lru_smp->tid = tid;
+		lru_smp->mgmt_class = mgmt_class;
+		lru_smp->v = p_madw;
+		lru_smp->version =
+		    cl_atomic_inc((atomic32_t *) & p_vend->mtbl.last_version);
+	} else {
+		lru->tid = tid;
+		lru->mgmt_class = mgmt_class;
+		lru->v = p_madw;
+		lru->version =
+		    cl_atomic_inc((atomic32_t *) & p_vend->mtbl.last_version);
+	}
 	pthread_mutex_unlock(&p_vend->match_tbl_mutex);
 	OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5402: "
 		"evicting entry %p (tid was 0x%" PRIx64
@@ -246,6 +276,7 @@ ib_mad_addr_conv(ib_user_mad_t * umad, osm_mad_addr_t * osm_mad_addr,
 		 int is_smi)
 {
 	ib_mad_addr_t *ib_mad_addr = umad_get_mad_addr(umad);
+
 	osm_mad_addr->dest_lid = ib_mad_addr->lid;
 	osm_mad_addr->path_bits = ib_mad_addr->path_bits;
 	osm_mad_addr->static_rate = 0;
@@ -260,9 +291,20 @@ ib_mad_addr_conv(ib_user_mad_t * umad, osm_mad_addr_t * osm_mad_addr,
 	osm_mad_addr->addr_type.gsi.remote_qkey = ib_mad_addr->qkey;
 	osm_mad_addr->addr_type.gsi.pkey_ix = umad_get_pkey(umad);
 	osm_mad_addr->addr_type.gsi.service_level = ib_mad_addr->sl;
-	osm_mad_addr->addr_type.gsi.global_route = 0;	/* FIXME: handle GRH */
-	memset(&osm_mad_addr->addr_type.gsi.grh_info, 0,
-	       sizeof osm_mad_addr->addr_type.gsi.grh_info);
+	if (ib_mad_addr->grh_present) {
+		osm_mad_addr->addr_type.gsi.global_route = 1;
+		osm_mad_addr->addr_type.gsi.grh_info.hop_limit = ib_mad_addr->hop_limit;
+		osm_mad_addr->addr_type.gsi.grh_info.ver_class_flow =
+			ib_grh_set_ver_class_flow(6,	/* GRH version */
+						  ib_mad_addr->traffic_class,
+						  ib_mad_addr->flow_label);
+		memcpy(&osm_mad_addr->addr_type.gsi.grh_info.dest_gid,
+		       &ib_mad_addr->gid, 16);
+	} else {
+		osm_mad_addr->addr_type.gsi.global_route = 0;
+		memset(&osm_mad_addr->addr_type.gsi.grh_info, 0,
+		       sizeof osm_mad_addr->addr_type.gsi.grh_info);
+	}
 }
 
 static void *swap_mad_bufs(osm_madw_t * p_madw, void *umad)
@@ -289,6 +331,7 @@ static void *umad_receiver(void *p_ptr)
 	osm_mad_addr_t osm_addr;
 	osm_madw_t *p_madw, *p_req_madw;
 	ib_mad_t *p_mad, *p_req_mad;
+	ib_mad_addr_t *p_mad_addr;
 	void *umad = 0;
 	int mad_agent, length;
 
@@ -341,6 +384,14 @@ static void *umad_receiver(void *p_ptr)
 		}
 
 		p_mad = (ib_mad_t *) umad_get_mad(umad);
+		p_mad_addr = umad_get_mad_addr(umad);
+		/* Only support GID index 0 currently */
+		if (p_mad_addr->grh_present && p_mad_addr->gid_index) {
+			OSM_LOG(p_ur->p_log, OSM_LOG_ERROR, "ERR 5409: "
+				"GRH received on GID index %d for mgmt class 0x%x\n",
+				p_mad_addr->gid_index, p_mad->mgmt_class);
+			continue;
+		}
 
 		ib_mad_addr_conv(umad, &osm_addr,
 				 p_mad->mgmt_class == IB_MCLASS_SUBN_LID ||
@@ -706,10 +757,14 @@ osm_vendor_open_port(IN osm_vendor_t * const p_vend,
 	for (ca = 0; ca < p_vend->ca_count; ca++) {
 		if ((r = umad_get_ca_portguids(p_vend->ca_names[ca], portguids,
 					       OSM_UMAD_MAX_PORTS_PER_CA + 1)) < 0) {
+#ifdef __WIN__
+			OSM_LOG(p_vend->p_log, OSM_LOG_VERBOSE,
+#else
 			OSM_LOG(p_vend->p_log, OSM_LOG_ERROR, "ERR 5421: "
+#endif
 				"Unable to get CA %s port guids (%s)\n",
 				p_vend->ca_names[ca], strerror(r));
-			goto Exit;
+			continue;
 		}
 		for (i = 0; i < r; i++)
 			if (port_guid == portguids[i]) {
@@ -1069,6 +1124,7 @@ osm_vendor_send(IN osm_bind_handle_t h_bind,
 	osm_mad_addr_t *const p_mad_addr = osm_madw_get_mad_addr_ptr(p_madw);
 	ib_mad_t *const p_mad = osm_madw_get_mad_ptr(p_madw);
 	ib_sa_mad_t *const p_sa = (ib_sa_mad_t *) p_mad;
+	ib_mad_addr_t mad_addr;
 	int ret = -1;
 	int __attribute__((__unused__)) is_rmpp = 0;
 	uint32_t sent_mad_size;
@@ -1084,12 +1140,12 @@ osm_vendor_send(IN osm_bind_handle_t h_bind,
 
 	if (p_mad->mgmt_class == IB_MCLASS_SUBN_DIR) {
 		umad_set_addr_net(p_vw->umad, 0xffff, 0, 0, 0);
-		umad_set_grh(p_vw->umad, 0);
+		umad_set_grh(p_vw->umad, NULL);
 		goto Resp;
 	}
 	if (p_mad->mgmt_class == IB_MCLASS_SUBN_LID) {
 		umad_set_addr_net(p_vw->umad, p_mad_addr->dest_lid, 0, 0, 0);
-		umad_set_grh(p_vw->umad, 0);
+		umad_set_grh(p_vw->umad, NULL);
 		goto Resp;
 	}
 	/* GS classes */
@@ -1097,9 +1153,19 @@ osm_vendor_send(IN osm_bind_handle_t h_bind,
 			  p_mad_addr->addr_type.gsi.remote_qp,
 			  p_mad_addr->addr_type.gsi.service_level,
 			  IB_QP1_WELL_KNOWN_Q_KEY);
-	umad_set_grh(p_vw->umad, 0);	/* FIXME: GRH support */
+	if (p_mad_addr->addr_type.gsi.global_route) {
+		mad_addr.grh_present = 1;
+		mad_addr.gid_index = 0;
+		mad_addr.hop_limit = p_mad_addr->addr_type.gsi.grh_info.hop_limit;
+		ib_grh_get_ver_class_flow(p_mad_addr->addr_type.gsi.grh_info.ver_class_flow,
+					  NULL, &mad_addr.traffic_class,
+					  &mad_addr.flow_label);
+		memcpy(&mad_addr.gid, &p_mad_addr->addr_type.gsi.grh_info.dest_gid, 16);
+		umad_set_grh(p_vw->umad, &mad_addr);
+	} else
+		umad_set_grh(p_vw->umad, NULL);
 	umad_set_pkey(p_vw->umad, p_mad_addr->addr_type.gsi.pkey_ix);
-	if (ib_class_is_rmpp(p_mad->mgmt_class)) {	/* RMPP GS classes     FIXME: no GRH */
+	if (ib_class_is_rmpp(p_mad->mgmt_class)) {	/* RMPP GS classes */
 		if (!ib_rmpp_is_flag_set((ib_rmpp_mad_t *) p_sa,
 					 IB_RMPP_FLAG_ACTIVE)) {
 			/* Clear RMPP header when RMPP not ACTIVE */
diff --git a/libvendor/osm_vendor_ibumad_sa.c b/libvendor/osm_vendor_ibumad_sa.c
index f715cf6..32e0d9e 100644
--- a/libvendor/osm_vendor_ibumad_sa.c
+++ b/libvendor/osm_vendor_ibumad_sa.c
@@ -415,6 +415,20 @@ __osmv_send_sa_req(IN osmv_sa_bind_info_t * p_bind,
 	p_madw->fail_msg = CL_DISP_MSGID_NONE;
 
 	/*
+	   add grh
+	 */
+	if (p_query_req->with_grh) {
+		OSM_LOG(p_log, OSM_LOG_DEBUG, "sending sa query with GRH "
+			"GID : 0x%016" PRIx64 " 0x%016" PRIx64 "\n",
+			p_query_req->gid.unicast.prefix,
+			p_query_req->gid.unicast.interface_id);
+		p_madw->mad_addr.addr_type.gsi.global_route = 1;
+		memset(&p_madw->mad_addr.addr_type.gsi.grh_info, 0,
+		       sizeof(p_madw->mad_addr.addr_type.gsi.grh_info));
+		memcpy(&p_madw->mad_addr.addr_type.gsi.grh_info.dest_gid, &(p_query_req->gid), 16);
+	}
+
+	/*
 	   Provide MAD context such that the call back will know what to do.
 	   We have to keep the entire request structure so we know the CB.
 	   Since we can not rely on the client to keep it around until
diff --git a/man/opensm.8 b/man/opensm.8
index 82d3ae5..e598c7e 100644
--- a/man/opensm.8
+++ b/man/opensm.8
@@ -1,4 +1,4 @@
-.TH OPENSM 8 "March 8, 2012" "OpenIB" "OpenIB Management"
+.TH OPENSM 8 "July 4, 2014" "OpenIB" "OpenIB Management"
 
 .SH NAME
 opensm \- InfiniBand subnet manager and administration (SM/SA)
@@ -26,7 +26,7 @@ opensm \- InfiniBand subnet manager and administration (SM/SA)
 [\-u | \-\-cn_guid_file <path to file>]
 [\-G | \-\-io_guid_file <path to file>]
 [\-\-port\-shifting]
-[\-\-scatter\-ports]
+[\-\-scatter\-ports <random seed>]
 [\-H | \-\-max_reverse_hops <max reverse hops allowed>]
 [\-X | \-\-guid_routing_order_file <path to file>]
 [\-m | \-\-ids_guid_file <path to file>]
@@ -234,8 +234,11 @@ congest with other routes due to algorithmically unchanging traffic
 patterns.  This routing option will "shift" routing around in an
 attempt to alleviate this problem.
 .TP
-\fB\-\-scatter\-ports\fR
-This option will randomize port selecting in routing.
+\fB\-\-scatter\-ports\fR <random seed>
+This option is used to randomize port selection in routing rather than
+using a round-robin algorithm (which is the default). Value supplied
+with option is used as a random seed.  If value is 0,
+which is the default, the scatter ports option is disabled.
 .TP
 \fB\-H\fR, \fB\-\-max_reverse_hops\fR <max reverse hops allowed>
 Set the maximum number of reverse hops an I/O node is allowed
@@ -1467,9 +1470,10 @@ Both or one of options -U and -M can be specified together with \'-R file\'.
 
 .SH PER MODULE LOGGING CONFIGURATION
 .PP
-To enabled per module logging, set per_module_logging to TRUE in
-the opensm options file and configure per_module_logging_file there
-appropriately.
+To enable per module logging, configure per_module_logging_file to
+the per module logging config file name in the opensm options
+file. To disable, configure per_module_logging_file to (null)
+there.
 
 The per module logging config file format is a set of lines with module
 name and logging level as follows:
diff --git a/man/opensm.8.in b/man/opensm.8.in
index 4d4facd..2be2690 100644
--- a/man/opensm.8.in
+++ b/man/opensm.8.in
@@ -1,4 +1,4 @@
-.TH OPENSM 8 "March 8, 2012" "OpenIB" "OpenIB Management"
+.TH OPENSM 8 "July 4, 2014" "OpenIB" "OpenIB Management"
 
 .SH NAME
 opensm \- InfiniBand subnet manager and administration (SM/SA)
@@ -26,7 +26,7 @@ opensm \- InfiniBand subnet manager and administration (SM/SA)
 [\-u | \-\-cn_guid_file <path to file>]
 [\-G | \-\-io_guid_file <path to file>]
 [\-\-port\-shifting]
-[\-\-scatter\-ports]
+[\-\-scatter\-ports <random seed>]
 [\-H | \-\-max_reverse_hops <max reverse hops allowed>]
 [\-X | \-\-guid_routing_order_file <path to file>]
 [\-m | \-\-ids_guid_file <path to file>]
@@ -234,8 +234,11 @@ congest with other routes due to algorithmically unchanging traffic
 patterns.  This routing option will "shift" routing around in an
 attempt to alleviate this problem.
 .TP
-\fB\-\-scatter\-ports\fR
-This option will randomize port selecting in routing.
+\fB\-\-scatter\-ports\fR <random seed>
+This option is used to randomize port selection in routing rather than
+using a round-robin algorithm (which is the default). Value supplied
+with option is used as a random seed.  If value is 0,
+which is the default, the scatter ports option is disabled.
 .TP
 \fB\-H\fR, \fB\-\-max_reverse_hops\fR <max reverse hops allowed>
 Set the maximum number of reverse hops an I/O node is allowed
@@ -1467,9 +1470,10 @@ Both or one of options -U and -M can be specified together with \'-R file\'.
 
 .SH PER MODULE LOGGING CONFIGURATION
 .PP
-To enabled per module logging, set per_module_logging to TRUE in
-the opensm options file and configure per_module_logging_file there
-appropriately.
+To enable per module logging, configure per_module_logging_file to
+the per module logging config file name in the opensm options
+file. To disable, configure per_module_logging_file to (null)
+there.
 
 The per module logging config file format is a set of lines with module
 name and logging level as follows:
diff --git a/opensm.spec b/opensm.spec
index 7e83a04..8bdee43 100644
--- a/opensm.spec
+++ b/opensm.spec
@@ -27,12 +27,12 @@
 
 Summary: InfiniBand subnet manager and administration
 Name: opensm
-Version: 3.3.17
+Version: 3.3.18
 Release: %rel%{?dist}
 License: GPLv2 or BSD
 Group: System Environment/Daemons
 URL: http://openfabrics.org/
-Source: http://www.openfabrics.org/downloads/management/opensm-3.3.17.tar.gz
+Source: http://www.openfabrics.org/downloads/management/opensm-3.3.18.tar.gz
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: libibumad-devel, libtool
 Requires: %{name}-libs = %{version}-%{release}, logrotate
@@ -143,7 +143,7 @@ fi
 %{_sbindir}/osmtest
 %{_mandir}/man8/*
 %{_mandir}/man5/*
-%doc AUTHORS COPYING README doc/performance-manager-HOWTO.txt doc/QoS_management_in_OpenSM.txt doc/opensm_release_notes-3.3.txt
+%doc AUTHORS COPYING README doc/performance-manager-HOWTO.txt doc/QoS_management_in_OpenSM.txt doc/partition-config.txt doc/opensm-sriov.txt doc/current-routing.txt doc/opensm_release_notes-3.3.txt
 %{_sysconfdir}/init.d/opensmd
 %{_sbindir}/sldd.sh
 %config(noreplace) %{_sysconfdir}/logrotate.d/opensm
diff --git a/opensm.spec.in b/opensm.spec.in
index 0187069..29dc481 100644
--- a/opensm.spec.in
+++ b/opensm.spec.in
@@ -143,7 +143,7 @@ fi
 %{_sbindir}/osmtest
 %{_mandir}/man8/*
 %{_mandir}/man5/*
-%doc AUTHORS COPYING README doc/performance-manager-HOWTO.txt doc/QoS_management_in_OpenSM.txt doc/opensm_release_notes-3.3.txt
+%doc AUTHORS COPYING README doc/performance-manager-HOWTO.txt doc/QoS_management_in_OpenSM.txt doc/partition-config.txt doc/opensm-sriov.txt doc/current-routing.txt doc/opensm_release_notes-3.3.txt
 %{_sysconfdir}/init.d/opensmd
 %{_sbindir}/sldd.sh
 %config(noreplace) %{_sysconfdir}/logrotate.d/opensm
diff --git a/opensm/libopensm.ver b/opensm/libopensm.ver
index db08fc3..59322e3 100644
--- a/opensm/libopensm.ver
+++ b/opensm/libopensm.ver
@@ -6,4 +6,4 @@
 # API_REV - advance on any added API
 # RUNNING_REV - advance any change to the vendor files
 # AGE - number of backward versions the API still supports
-LIBVERSION=7:0:2
+LIBVERSION=7:1:2
diff --git a/opensm/main.c b/opensm/main.c
index 27c1b35..a053b05 100644
--- a/opensm/main.c
+++ b/opensm/main.c
@@ -232,7 +232,9 @@ static void show_usage(void)
 	       "          Attempt to shift port routes around to remove alignment problems\n"
 	       "          in routing tables\n\n");
 	printf("--scatter-ports <random seed>\n"
-	       "          Randomize best port chosen for a route\n\n");
+	       "          Randomize best port chosen for a route\n"
+	       "          Assign ports in a random order instead of round-robin\n"
+	       "          If zero disable (default), otherwise use the value as a random seed\n\n");
 	printf("--max_reverse_hops, -H <hop_count>\n"
 	       "          Set the max number of hops the wrong way around\n"
 	       "          an I/O node is allowed to do (connectivity for I/O nodes on top swithces)\n\n");
diff --git a/opensm/osm_congestion_control.c b/opensm/osm_congestion_control.c
index ce8b696..9337af8 100644
--- a/opensm/osm_congestion_control.c
+++ b/opensm/osm_congestion_control.c
@@ -50,6 +50,8 @@
 
 #include <iba/ib_types.h>
 #include <complib/cl_debug.h>
+#include <opensm/osm_file_ids.h>
+#define FILE_ID OSM_FILE_CONGESTION_CONTROL_C
 #include <opensm/osm_subnet.h>
 #include <opensm/osm_opensm.h>
 #include <opensm/osm_log.h>
@@ -521,16 +523,20 @@ static void cc_poller_send(osm_congestion_control_t *p_cc,
 {
 	osm_subn_opt_t *p_opt = &p_cc->subn->opt;
 	ib_api_status_t status;
+	cl_status_t sts;
 	osm_madw_context_t mad_context = p_madw->context;
 
 	status = osm_vendor_send(p_cc->bind_handle, p_madw, TRUE);
 	if (status == IB_SUCCESS) {
 		cl_atomic_inc(&p_cc->outstanding_mads_on_wire);
 		while (p_cc->outstanding_mads_on_wire >
-		       (int32_t)p_opt->cc_max_outstanding_mads)
-			cl_event_wait_on(&p_cc->sig_mads_on_wire_continue,
-					 EVENT_NO_TIMEOUT,
-					 TRUE);
+		       (int32_t)p_opt->cc_max_outstanding_mads) {
+wait:
+			sts = cl_event_wait_on(&p_cc->sig_mads_on_wire_continue,
+					       EVENT_NO_TIMEOUT, TRUE);
+			if (sts != CL_SUCCESS)
+				goto wait;
+		}
 	} else
 		OSM_LOG(p_cc->log, OSM_LOG_ERROR, "ERR C104: "
 			"send failed to node 0x%" PRIx64 "port %u\n",
@@ -667,7 +673,7 @@ static void cc_mad_send_err_callback(void *bind_context,
 
 	p_port = osm_get_port_by_guid(p_cc->subn, port_guid);
 	if (!p_port) {
-		OSM_LOG(p_cc->log, OSM_LOG_ERROR, "ERR C106A: "
+		OSM_LOG(p_cc->log, OSM_LOG_ERROR, "ERR C10B: "
 			"Port guid not in table 0x%" PRIx64 "\n",
 			port_guid);
 		cl_plock_release(&p_osm->lock);
diff --git a/opensm/osm_console.c b/opensm/osm_console.c
index 665b8a5..1a05902 100644
--- a/opensm/osm_console.c
+++ b/opensm/osm_console.c
@@ -512,7 +512,6 @@ static void print_status(osm_opensm_t * p_osm, FILE * out)
 			"   Subnet Init errors             : %d\n"
 			"   In sweep hop 0                 : %d\n"
 			"   First time master sweep        : %d\n"
-			"   Set client rereg on sweep      : %d\n"
 			"   Coming out of standby          : %d\n",
 			p_osm->subn.sweeping_enabled,
 			p_osm->subn.opt.sweep_interval,
@@ -520,7 +519,6 @@ static void print_status(osm_opensm_t * p_osm, FILE * out)
 			p_osm->subn.subnet_initialization_error,
 			p_osm->subn.in_sweep_hop_0,
 			p_osm->subn.first_time_master_sweep,
-			p_osm->subn.set_client_rereg_on_sweep,
 			p_osm->subn.coming_out_of_standby);
 		dump_sms(p_osm, out);
 		fprintf(out, "\n");
diff --git a/opensm/osm_console_io.c b/opensm/osm_console_io.c
index dfc903f..2426b84 100644
--- a/opensm/osm_console_io.c
+++ b/opensm/osm_console_io.c
@@ -208,8 +208,15 @@ int osm_console_init(osm_subn_opt_t * opt, osm_console_t * p_oct, osm_log_t * p_
 				strerror(errno));
 			return -1;
 		}
-		setsockopt(p_oct->socket, SOL_SOCKET, SO_REUSEADDR,
-			   &optval, sizeof(optval));
+
+		if (setsockopt(p_oct->socket, SOL_SOCKET, SO_REUSEADDR,
+			       &optval, sizeof(optval))) {
+			OSM_LOG(p_log, OSM_LOG_ERROR,
+		                "ERR 4B06: Failed to set socket option: %s\n",
+		                strerror(errno));
+		        return -1;
+		}
+
 		sin.sin_family = AF_INET;
 		sin.sin_port = htons(opt->console_port);
 #ifdef ENABLE_OSM_CONSOLE_SOCKET
diff --git a/opensm/osm_drop_mgr.c b/opensm/osm_drop_mgr.c
index ff6a81b..ab06bf8 100644
--- a/opensm/osm_drop_mgr.c
+++ b/opensm/osm_drop_mgr.c
@@ -257,9 +257,9 @@ static void drop_mgr_remove_port(osm_sm_t * sm, IN osm_port_t * p_port)
 		OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
 			"Cleaned SM for port guid 0x%016" PRIx64 "\n",
 			cl_ntoh64(port_guid));
-		/* clean up the polling_sm pointer */
-		if (sm->p_polling_sm == p_sm)
-			sm->p_polling_sm = NULL;
+		/* clean up the polling_sm_guid */
+		if (sm->polling_sm_guid == p_sm->smi.guid)
+			sm->polling_sm_guid = 0;
 		free(p_sm);
 	}
 
@@ -472,7 +472,7 @@ static void drop_mgr_check_node(osm_sm_t * sm, IN osm_node_t * p_node)
 					"Unlinking local node 0x%" PRIx64
 					", port %u"
 					"\n\t\t\t\tand remote node 0x%" PRIx64
-					", port %u\n due to missing PortInfo",
+					", port %u due to missing PortInfo\n",
 					cl_ntoh64(osm_node_get_node_guid
 						  (p_node)), port_num,
 					cl_ntoh64(osm_node_get_node_guid
diff --git a/opensm/osm_guid_info_rcv.c b/opensm/osm_guid_info_rcv.c
index 141bcb1..f4d0592 100644
--- a/opensm/osm_guid_info_rcv.c
+++ b/opensm/osm_guid_info_rcv.c
@@ -74,9 +74,10 @@ void osm_gi_rcv_process(IN void *context, IN void *data)
 	ib_net64_t port_guid, node_guid;
 	uint8_t block_num;
 
+	CL_ASSERT(sm);
+
 	OSM_LOG_ENTER(sm->p_log);
 
-	CL_ASSERT(sm);
 	CL_ASSERT(p_madw);
 
 	p_smp = osm_madw_get_smp_ptr(p_madw);
@@ -93,6 +94,13 @@ void osm_gi_rcv_process(IN void *context, IN void *data)
 	osm_dump_guid_info_v2(sm->p_log, node_guid, port_guid, block_num, p_gi,
 			      FILE_ID, OSM_LOG_DEBUG);
 
+	if (ib_smp_get_status(p_smp)) {
+		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+			"MAD status 0x%x received\n",
+			cl_ntoh16(ib_smp_get_status(p_smp)));
+		goto Exit;
+	}
+
 	CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
 	p_port = osm_get_port_by_guid(sm->p_subn, port_guid);
 	if (!p_port) {
diff --git a/opensm/osm_helper.c b/opensm/osm_helper.c
index e3ea3a7..8e6f525 100644
--- a/opensm/osm_helper.c
+++ b/opensm/osm_helper.c
@@ -3011,6 +3011,8 @@ const char *osm_get_manufacturer_str(IN uint64_t guid_ho)
 		return intel_str;
 	case OSM_VENDOR_ID_MELLANOX:
 	case OSM_VENDOR_ID_MELLANOX2:
+	case OSM_VENDOR_ID_MELLANOX3:
+	case OSM_VENDOR_ID_MELLANOX4:
 		return mellanox_str;
 	case OSM_VENDOR_ID_REDSWITCH:
 		return redswitch_str;
@@ -3125,7 +3127,7 @@ static const char *lsea_str_fixed_width[] = {
 const char *osm_get_lsa_str(IN uint8_t lsa, IN uint8_t lsea, IN uint8_t state,
 			    IN uint8_t fdr10)
 {
-	if (lsa > IB_LINK_SPEED_ACTIVE_10)
+	if (lsa > IB_LINK_SPEED_ACTIVE_10 || state == IB_LINK_DOWN)
 		return lsa_str_fixed_width[3];
 	if (lsea == IB_LINK_SPEED_EXT_ACTIVE_NONE) {
 		if (fdr10)
diff --git a/opensm/osm_lid_mgr.c b/opensm/osm_lid_mgr.c
index 757a9e3..f52c770 100644
--- a/opensm/osm_lid_mgr.c
+++ b/opensm/osm_lid_mgr.c
@@ -889,6 +889,7 @@ static int lid_mgr_set_physp_pi(IN osm_lid_mgr_t * p_mgr,
 		 */
 		osm_physp_set_base_lid(p_physp, 0);
 		send_set = TRUE;
+		p_mgr->dirty = TRUE;
 	}
 
 	/* we are updating the ports with our local sm_base_lid */
@@ -1034,9 +1035,7 @@ static int lid_mgr_set_physp_pi(IN osm_lid_mgr_t * p_mgr,
 	   the cli_rereg bit. We know that the port was just discovered if its
 	   is_new field is set.
 	 */
-	if ((p_mgr->p_subn->first_time_master_sweep == TRUE
-	     || p_mgr->p_subn->set_client_rereg_on_sweep == TRUE
-	     || p_port->is_new)
+	if ((p_mgr->p_subn->first_time_master_sweep == TRUE || p_port->is_new)
 	    && !p_mgr->p_subn->opt.no_clients_rereg
 	    && (p_old_pi->capability_mask & IB_PORT_CAP_HAS_CLIENT_REREG)) {
 		OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
@@ -1056,13 +1055,8 @@ static int lid_mgr_set_physp_pi(IN osm_lid_mgr_t * p_mgr,
 	   2. first_time_master_sweep flag on the subnet is TRUE. This means the
 	   SM just became master, and it then needs to send a PortInfo Set to
 	   every port.
-	   3. set_client_rereg_on_sweep is TRUE.  The one situation in which this
-	   is true but first_time_master_sweep is FALSE is when the SM receives
-	   a HANDOVER while in master.  We don't want to re-setup everything by
-	   setting first_time_master_sweep, but we do want to reset up this.
 	 */
-	if (p_mgr->p_subn->first_time_master_sweep == TRUE
-	    || p_mgr->p_subn->set_client_rereg_on_sweep == TRUE)
+	if (p_mgr->p_subn->first_time_master_sweep == TRUE)
 		send_set = TRUE;
 
 	if (!send_set)
diff --git a/opensm/osm_lin_fwd_rcv.c b/opensm/osm_lin_fwd_rcv.c
index 5b9422b..b798ce5 100644
--- a/opensm/osm_lin_fwd_rcv.c
+++ b/opensm/osm_lin_fwd_rcv.c
@@ -84,6 +84,13 @@ void osm_lft_rcv_process(IN void *context, IN void *data)
 	p_lft_context = osm_madw_get_lft_context_ptr(p_madw);
 	node_guid = p_lft_context->node_guid;
 
+	if (ib_smp_get_status(p_smp)) {
+		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+			"MAD status 0x%x received\n",
+			cl_ntoh16(ib_smp_get_status(p_smp)));
+		goto Exit;
+	}
+
 	CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
 	p_sw = osm_get_switch_by_guid(sm->p_subn, node_guid);
 
@@ -113,5 +120,6 @@ void osm_lft_rcv_process(IN void *context, IN void *data)
 	}
 
 	CL_PLOCK_RELEASE(sm->p_lock);
+Exit:
 	OSM_LOG_EXIT(sm->p_log);
 }
diff --git a/opensm/osm_link_mgr.c b/opensm/osm_link_mgr.c
index ed19d75..d5c7dde 100644
--- a/opensm/osm_link_mgr.c
+++ b/opensm/osm_link_mgr.c
@@ -126,6 +126,7 @@ static int link_mgr_set_physp_pi(osm_sm_t * sm, IN osm_physp_t * p_physp,
 			p_port = osm_get_port_by_guid(sm->p_subn,
 						      osm_physp_get_port_guid(p_physp));
 			p_pi->base_lid = p_port->lid;
+			sm->lid_mgr.dirty = TRUE;
 			send_set = TRUE;
 		}
 
diff --git a/opensm/osm_log.c b/opensm/osm_log.c
index 3460cc5..29e80e4 100644
--- a/opensm/osm_log.c
+++ b/opensm/osm_log.c
@@ -230,6 +230,7 @@ void osm_log_v2(IN osm_log_t * p_log, IN osm_log_level_t verbosity,
 	SYSTEMTIME st;
 	uint32_t pid = GetCurrentThreadId();
 #else
+	struct timeval tv;
 	pid_t pid = 0;
 	time_t tim;
 	struct tm result;
@@ -294,7 +295,9 @@ _retry:
 		    st.wHour, st.wMinute, st.wSecond, st.wMilliseconds,
 		    pid, verbosity, buffer);
 #else
-	time_usecs = cl_get_time_stamp();
+	gettimeofday(&tv, NULL);
+	/* Convert the time of day into a microsecond timestamp */
+	time_usecs = ((uint64_t) tv.tv_sec * 1000000) + (uint64_t) tv.tv_usec;
 	tim = time_usecs / 1000000;
 	usecs = time_usecs % 1000000;
 	localtime_r(&tim, &result);
diff --git a/opensm/osm_mcast_fwd_rcv.c b/opensm/osm_mcast_fwd_rcv.c
index d855cbb..6404f8c 100644
--- a/opensm/osm_mcast_fwd_rcv.c
+++ b/opensm/osm_mcast_fwd_rcv.c
@@ -96,6 +96,13 @@ void osm_mft_rcv_process(IN void *context, IN void *data)
 		block_num, position, cl_ntoh64(node_guid),
 		cl_ntoh64(p_smp->trans_id));
 
+	if (ib_smp_get_status(p_smp)) {
+		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+			"MAD status 0x%x received\n",
+			cl_ntoh16(ib_smp_get_status(p_smp)));
+		goto Exit;
+	}
+
 	CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
 	p_sw = osm_get_switch_by_guid(sm->p_subn, node_guid);
 
@@ -118,5 +125,6 @@ void osm_mft_rcv_process(IN void *context, IN void *data)
 	}
 
 	CL_PLOCK_RELEASE(sm->p_lock);
+Exit:
 	OSM_LOG_EXIT(sm->p_log);
 }
diff --git a/opensm/osm_mcast_mgr.c b/opensm/osm_mcast_mgr.c
index ad67d48..ee5a145 100644
--- a/opensm/osm_mcast_mgr.c
+++ b/opensm/osm_mcast_mgr.c
@@ -472,7 +472,7 @@ static void mcast_mgr_purge_list(osm_sm_t * sm, cl_qlist_t * list)
 			wobj = cl_item_obj(i, wobj, list_item);
 			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A06: "
 				"Unable to route for port 0x%" PRIx64 "\n",
-				osm_port_get_guid(wobj->p_port));
+				cl_ntoh64(osm_port_get_guid(wobj->p_port)));
 		}
 	}
 	osm_mcast_drop_port_list(list);
@@ -522,7 +522,7 @@ static osm_mtree_node_t *mcast_mgr_branch(osm_sm_t * sm, uint16_t mlid_ho,
 	if (depth >= 64) {
 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0A21: "
 			"Maximal hops number is reached for MLID 0x%x."
-			" Break processing.", mlid_ho);
+			" Break processing\n", mlid_ho);
 		mcast_mgr_purge_list(sm, p_list);
 		goto Exit;
 	}
@@ -978,7 +978,7 @@ static ib_api_status_t mcast_mgr_process_mlid(osm_sm_t * sm, uint16_t mlid)
 	OSM_LOG_ENTER(sm->p_log);
 
 	OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
-		"Processing multicast group with lid 0x%X\n", mlid);
+		"Processing multicast group with mlid 0x%X\n", mlid);
 
 	/* Clear the multicast tables to start clean, then build
 	   the spanning tree which sets the mcast table bits for each
diff --git a/opensm/osm_node_desc_rcv.c b/opensm/osm_node_desc_rcv.c
index 546ffed..858ac45 100644
--- a/opensm/osm_node_desc_rcv.c
+++ b/opensm/osm_node_desc_rcv.c
@@ -110,6 +110,13 @@ void osm_nd_rcv_process(IN void *context, IN void *data)
 	CL_ASSERT(p_madw);
 
 	p_smp = osm_madw_get_smp_ptr(p_madw);
+	if (ib_smp_get_status(p_smp)) {
+		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+			"MAD status 0x%x received\n",
+			cl_ntoh16(ib_smp_get_status(p_smp)));
+		goto Exit;
+	}
+
 	p_nd = ib_smp_get_payload_ptr(p_smp);
 
 	/* Acquire the node object and add the node description. */
@@ -124,5 +131,6 @@ void osm_nd_rcv_process(IN void *context, IN void *data)
 		nd_rcv_process_nd(sm, p_node, p_nd);
 
 	CL_PLOCK_RELEASE(sm->p_lock);
+Exit:
 	OSM_LOG_EXIT(sm->p_log);
 }
diff --git a/opensm/osm_node_info_rcv.c b/opensm/osm_node_info_rcv.c
index 4242924..68f3913 100644
--- a/opensm/osm_node_info_rcv.c
+++ b/opensm/osm_node_info_rcv.c
@@ -283,19 +283,13 @@ static void ni_rcv_get_port_info(IN osm_sm_t * sm, IN osm_node_t * node,
 	osm_madw_context_t context;
 	osm_physp_t *physp;
 	ib_node_info_t *ni;
-	unsigned port, num_ports;
+	unsigned port;
 	ib_api_status_t status;
 	int mlnx_epi_supported = 0;
 
 	ni = ib_smp_get_payload_ptr(osm_madw_get_smp_ptr(madw));
 
-	if (ni->node_type == IB_NODE_TYPE_SWITCH) {
-		port = 0;
-		num_ports = osm_node_get_num_physp(node);
-	} else {
-		port = ib_node_info_get_local_port_num(ni);
-		num_ports = port + 1;
-	}
+	port = ib_node_info_get_local_port_num(ni);
 
 	if (sm->p_subn->opt.fdr10)
 		mlnx_epi_supported = is_mlnx_ext_port_info_supported(ni->device_id);
@@ -309,25 +303,23 @@ static void ni_rcv_get_port_info(IN osm_sm_t * sm, IN osm_node_t * node,
 	context.pi_context.active_transition = FALSE;
 	context.pi_context.client_rereg = FALSE;
 
-	for (; port < num_ports; port++) {
-		status = osm_req_get(sm, osm_physp_get_dr_path_ptr(physp),
-				     IB_MAD_ATTR_PORT_INFO, cl_hton32(port),
+	status = osm_req_get(sm, osm_physp_get_dr_path_ptr(physp),
+			     IB_MAD_ATTR_PORT_INFO, cl_hton32(port),
+			     TRUE, 0, CL_DISP_MSGID_NONE, &context);
+	if (status != IB_SUCCESS)
+		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD02: "
+			"Failure initiating PortInfo request (%s)\n",
+			ib_get_err_str(status));
+	if (mlnx_epi_supported) {
+		status = osm_req_get(sm,
+				     osm_physp_get_dr_path_ptr(physp),
+				     IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO,
+				     cl_hton32(port),
 				     TRUE, 0, CL_DISP_MSGID_NONE, &context);
 		if (status != IB_SUCCESS)
-			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD02: "
-				"Failure initiating PortInfo request (%s)\n",
+			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D0B: "
+				"Failure initiating MLNX ExtPortInfo request (%s)\n",
 				ib_get_err_str(status));
-		if (mlnx_epi_supported) {
-			status = osm_req_get(sm,
-					     osm_physp_get_dr_path_ptr(physp),
-					     IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO,
-					     cl_hton32(port), TRUE, 0,
-					     CL_DISP_MSGID_NONE, &context);
-			if (status != IB_SUCCESS)
-				OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D0B: "
-					"Failure initiating MLNX ExtPortInfo request (%s)\n",
-					ib_get_err_str(status));
-		}
 	}
 }
 
@@ -566,9 +558,6 @@ static void ni_rcv_process_switch(IN osm_sm_t * sm, IN osm_node_t * p_node,
 			"Failure initiating SwitchInfo request (%s)\n",
 			ib_get_err_str(status));
 
-	if (p_node->discovery_count == 1)
-		ni_rcv_get_port_info(sm, p_node, p_madw);
-
 	OSM_LOG_EXIT(sm->p_log);
 }
 
@@ -584,20 +573,9 @@ static void ni_rcv_process_existing_switch(IN osm_sm_t * sm,
 	/*
 	   If this switch has already been probed during this sweep,
 	   then don't bother reprobing it.
-	   There is one exception - if the node has been visited, but
-	   for some reason we don't have the switch object (this can happen
-	   if the SwitchInfo mad didn't reach the SM) then we want
-	   to retry to probe the switch.
 	 */
 	if (p_node->discovery_count == 1)
 		ni_rcv_process_switch(sm, p_node, p_madw);
-	else if (!p_node->sw) {
-		/* we don't have the SwitchInfo - retry to get it */
-		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
-			"Retry to get SwitchInfo on node GUID:0x%" PRIx64 "\n",
-			cl_ntoh64(osm_node_get_node_guid(p_node)));
-		ni_rcv_process_switch(sm, p_node, p_madw);
-	}
 
 	OSM_LOG_EXIT(sm->p_log);
 }
@@ -868,7 +846,14 @@ static void ni_rcv_process_existing(IN osm_sm_t * sm, IN osm_node_t * p_node,
 		break;
 	}
 
+	if ( p_ni->sys_guid != p_node->node_info.sys_guid) {
+		OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Updated SysImageGUID: 0x%"
+			PRIx64 " for node 0x%" PRIx64 "\n",
+			cl_ntoh64(p_ni->sys_guid),
+			cl_ntoh64(p_ni->node_guid));
+	}
 	ni_rcv_set_links(sm, p_node, port_num, p_ni_context);
+	p_node->node_info = *p_ni;
 
 Exit:
 	OSM_LOG_EXIT(sm->p_log);
@@ -907,6 +892,13 @@ void osm_ni_rcv_process(IN void *context, IN void *data)
 		goto Exit;
 	}
 
+	if (ib_smp_get_status(p_smp)) {
+		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+			"MAD status 0x%x received\n",
+			cl_ntoh16(ib_smp_get_status(p_smp)));
+		goto Exit;
+	}
+
 	/*
 	   Determine if this node has already been discovered,
 	   and process accordingly.
diff --git a/opensm/osm_opensm.c b/opensm/osm_opensm.c
index f702c80..69d2ba6 100644
--- a/opensm/osm_opensm.c
+++ b/opensm/osm_opensm.c
@@ -465,7 +465,7 @@ ib_api_status_t osm_opensm_init_finish(IN osm_opensm_t * p_osm,
 		goto Exit;
 
 	status = osm_vl15_init(&p_osm->vl15, p_osm->p_vendor,
-			       &p_osm->log, &p_osm->stats,
+			       &p_osm->log, &p_osm->stats, &p_osm->subn,
 			       p_opt->max_wire_smps, p_opt->max_wire_smps2,
 			       p_opt->max_smps_timeout);
 	if (status != IB_SUCCESS)
diff --git a/opensm/osm_perfmgr.c b/opensm/osm_perfmgr.c
index bf2bfc9..d3fa1f7 100644
--- a/opensm/osm_perfmgr.c
+++ b/opensm/osm_perfmgr.c
@@ -2,7 +2,8 @@
  * Copyright (c) 2007 The Regents of the University of California.
  * Copyright (c) 2007-2009 Voltaire, Inc. All rights reserved.
  * Copyright (c) 2009,2010 HNR Consulting. All rights reserved.
- * Copyright (c) 2013 Lawrence Livermore National Security. All rights * reserved.
+ * Copyright (c) 2013 Lawrence Livermore National Security. All rights reserved.
+ * Copyright (c) 2011-2014 Mellanox Technologies LTD. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -162,6 +163,17 @@ static void remove_marked_nodes(osm_perfmgr_t * pm)
 static inline void decrement_outstanding_queries(osm_perfmgr_t * pm)
 {
 	cl_atomic_dec(&pm->outstanding_queries);
+
+	if (!pm->outstanding_queries) {
+		cl_spinlock_acquire(&pm->lock);
+		if (pm->sweep_state == PERFMGR_SWEEP_POST_PROCESSING) {
+			pm->sweep_state = PERFMGR_SWEEP_SLEEP;
+			OSM_LOG(pm->log, OSM_LOG_INFO,
+				"PM sweep state exiting Post Processing\n");
+		}
+		cl_spinlock_release(&pm->lock);
+	}
+
 	cl_event_signal(&pm->sig_query);
 }
 
@@ -429,6 +441,7 @@ static osm_madw_t *perfmgr_build_mad(osm_perfmgr_t * perfmgr,
 static ib_api_status_t perfmgr_send_mad(osm_perfmgr_t *perfmgr,
 					osm_madw_t * const p_madw)
 {
+	cl_status_t sts;
 	ib_api_status_t status = osm_vendor_send(perfmgr->bind_handle, p_madw,
 						 TRUE);
 	if (status == IB_SUCCESS) {
@@ -437,20 +450,23 @@ static ib_api_status_t perfmgr_send_mad(osm_perfmgr_t *perfmgr,
 		while (perfmgr->outstanding_queries >
 		       (int32_t)perfmgr->max_outstanding_queries) {
 			cl_spinlock_acquire(&perfmgr->lock);
-			perfmgr->sweep_state = PERFMGR_SWEEP_SUSPENDED;
+			if (perfmgr->sweep_state == PERFMGR_SWEEP_SLEEP) {
+				perfmgr->sweep_state = PERFMGR_SWEEP_POST_PROCESSING;
+				OSM_LOG(perfmgr->log, OSM_LOG_INFO,
+					"PM sweep state going into Post Processing\n");
+			} else if (perfmgr->sweep_state == PERFMGR_SWEEP_ACTIVE)
+				perfmgr->sweep_state = PERFMGR_SWEEP_SUSPENDED;
 			cl_spinlock_release(&perfmgr->lock);
-			cl_event_wait_on(&perfmgr->sig_query, EVENT_NO_TIMEOUT,
-					 TRUE);
+wait:
+			sts = cl_event_wait_on(&perfmgr->sig_query,
+					       EVENT_NO_TIMEOUT, TRUE);
+			if (sts != CL_SUCCESS)
+				goto wait;
 
 			cl_spinlock_acquire(&perfmgr->lock);
-			if (perfmgr->sweep_state == PERFMGR_SWEEP_SUSPENDED) {
+			if (perfmgr->sweep_state == PERFMGR_SWEEP_SUSPENDED)
 				perfmgr->sweep_state = PERFMGR_SWEEP_ACTIVE;
-				cl_spinlock_release(&perfmgr->lock);
-			} else {
-				cl_spinlock_release(&perfmgr->lock);
-				OSM_LOG(perfmgr->log, OSM_LOG_ERROR, "ERR 54FF: "
-					"PM was NOT in Suspended state???\n");
-			}
+			cl_spinlock_release(&perfmgr->lock);
 		}
 	}
 	return (status);
@@ -465,6 +481,7 @@ static ib_api_status_t perfmgr_send_pc_mad(osm_perfmgr_t * perfmgr,
 					   ib_net32_t dest_qp, uint16_t pkey_ix,
 					   uint8_t port, uint8_t mad_method,
 					   uint16_t counter_select,
+					   uint8_t counter_select2,
 					   osm_madw_context_t * p_context,
 					   uint8_t sl)
 {
@@ -486,6 +503,7 @@ static ib_api_status_t perfmgr_send_pc_mad(osm_perfmgr_t * perfmgr,
 	memset(port_counter, 0, sizeof(*port_counter));
 	port_counter->port_select = port;
 	port_counter->counter_select = cl_hton16(counter_select);
+	port_counter->counter_select2 = counter_select2;
 
 	status = perfmgr_send_mad(perfmgr, p_madw);
 
@@ -594,6 +612,16 @@ static inline boolean_t pce_supported(monitored_node_t *mon_node, uint8_t port)
 }
 
 /**********************************************************************
+ * return if CapMask.PortCountersXmitWaitSupported is set
+ **********************************************************************/
+static inline boolean_t xmit_wait_supported(monitored_node_t *mon_node, uint8_t port)
+{
+	monitored_port_t *mon_port = &(mon_node->port[port]);
+	return (mon_port->cpi_valid
+		&& (mon_port->cap_mask & IB_PM_PC_XMIT_WAIT_SUP));
+}
+
+/**********************************************************************
  * return if "full" PortCountersExtended (IETF) is indicated
  **********************************************************************/
 static inline boolean_t ietf_supported(monitored_node_t *mon_node, uint8_t port)
@@ -728,12 +756,14 @@ static void perfmgr_query_counters(cl_map_item_t * p_map_item, void *context)
 			gettimeofday(&mad_context.perfmgr_context.query_start, NULL);
 #endif
 			OSM_LOG(pm->log, OSM_LOG_VERBOSE, "Getting stats for node 0x%"
-				PRIx64 " port %d (lid %u) (%s)\n", node_guid, port,
-				cl_ntoh16(lid), node->print_desc);
+				PRIx64 " port %d (lid %u) (%s)\n",
+				node_guid, port, cl_ntoh16(lid),
+				node->print_desc);
 			status = perfmgr_send_pc_mad(pm, lid, remote_qp,
 						     mon_node->port[port].pkey_ix,
 						     port, IB_MAD_METHOD_GET,
 						     0xffff,
+						     1,
 						     &mad_context,
 						     0); /* FIXME SL != 0 */
 			if (status != IB_SUCCESS)
@@ -1001,8 +1031,12 @@ void osm_perfmgr_process(osm_perfmgr_t * pm)
 
 	cl_spinlock_acquire(&pm->lock);
 	if (pm->sweep_state == PERFMGR_SWEEP_ACTIVE ||
-	    pm->sweep_state == PERFMGR_SWEEP_SUSPENDED) {
+	    pm->sweep_state == PERFMGR_SWEEP_SUSPENDED ||
+	    pm->sweep_state == PERFMGR_SWEEP_POST_PROCESSING) {
 		cl_spinlock_release(&pm->lock);
+		OSM_LOG(pm->log, OSM_LOG_INFO,
+			"PM sweep state %d, skipping sweep\n",
+			pm->sweep_state);
 		return;
 	}
 
@@ -1052,10 +1086,6 @@ void osm_perfmgr_process(osm_perfmgr_t * pm)
 	remove_marked_nodes(pm);
 
 #ifdef ENABLE_OSM_PERF_MGR_PROFILE
-	/* spin on outstanding queries */
-	while (pm->outstanding_queries > 0)
-		cl_event_wait_on(&pm->sig_sweep, 1000, TRUE);
-
 	gettimeofday(&after, NULL);
 	diff_time(&before, &after, &after);
 	osm_log_v2(pm->log, OSM_LOG_INFO, FILE_ID,
@@ -1139,6 +1169,7 @@ static void perfmgr_check_oob_clear(osm_perfmgr_t * pm,
 		"LI:   %"PRIu64" ?< %"PRIu64"\n"
 		"BO:   %"PRIu64" ?< %"PRIu64"\n"
 		"VL15: %"PRIu64" ?< %"PRIu64"\n"
+		"XW:   %"PRIu64" ?< %"PRIu64"\n"
 		,
 		mon_node->name, mon_node->guid, port,
 		cr->symbol_err_cnt, prev_err.symbol_err_cnt,
@@ -1152,7 +1183,8 @@ static void perfmgr_check_oob_clear(osm_perfmgr_t * pm,
 		cr->rcv_constraint_err, prev_err.rcv_constraint_err,
 		cr->link_integrity, prev_err.link_integrity,
 		cr->buffer_overrun, prev_err.buffer_overrun,
-		cr->vl15_dropped, prev_err.vl15_dropped);
+		cr->vl15_dropped, prev_err.vl15_dropped,
+		cr->xmit_wait, prev_err.xmit_wait);
 
 	if (cr->symbol_err_cnt < prev_err.symbol_err_cnt ||
 	    cr->link_err_recover < prev_err.link_err_recover ||
@@ -1165,7 +1197,8 @@ static void perfmgr_check_oob_clear(osm_perfmgr_t * pm,
 	    cr->rcv_constraint_err < prev_err.rcv_constraint_err ||
 	    cr->link_integrity < prev_err.link_integrity ||
 	    cr->buffer_overrun < prev_err.buffer_overrun ||
-	    cr->vl15_dropped < prev_err.vl15_dropped) {
+	    cr->vl15_dropped < prev_err.vl15_dropped ||
+	    cr->xmit_wait < prev_err.xmit_wait) {
 		OSM_LOG(pm->log, OSM_LOG_ERROR, "PerfMgr: ERR 540A: "
 			"Detected an out of band error clear "
 			"on %s (0x%" PRIx64 ") port %u\n",
@@ -1209,12 +1242,14 @@ static int counter_overflow_64(ib_net64_t val)
  **********************************************************************/
 static void perfmgr_check_overflow(osm_perfmgr_t * pm,
 				   monitored_node_t * mon_node, int16_t pkey_ix,
-				   uint8_t port, ib_port_counters_t * pc)
+				   uint8_t port, ib_port_counters_t * pc,
+				   boolean_t xmit_wait_sup)
 {
 	osm_madw_context_t mad_context;
 	ib_api_status_t status;
 	ib_net32_t remote_qp;
 	uint16_t counter_select;
+	uint8_t counter_select2;
 
 	OSM_LOG_ENTER(pm->log);
 
@@ -1230,6 +1265,7 @@ static void perfmgr_check_overflow(osm_perfmgr_t * pm,
 	    counter_overflow_4(PC_LINK_INT(pc->link_int_buffer_overrun)) ||
 	    counter_overflow_4(PC_BUF_OVERRUN(pc->link_int_buffer_overrun)) ||
 	    counter_overflow_16(pc->vl15_dropped) ||
+	    (xmit_wait_sup && counter_overflow_32(pc->xmit_wait)) ||
 	    (!pce_supported(mon_node, port) &&
 	    (counter_overflow_32(pc->xmit_data) ||
 	     counter_overflow_32(pc->rcv_data) ||
@@ -1275,9 +1311,15 @@ static void perfmgr_check_overflow(osm_perfmgr_t * pm,
 		else
 			counter_select = 0xffff;
 
+		if (xmit_wait_sup)
+			counter_select2 = 1;
+		else
+			counter_select2 = 0;
+
 		status = perfmgr_send_pc_mad(pm, lid, remote_qp, pkey_ix,
 					     port, IB_MAD_METHOD_SET,
 					     counter_select,
+					     counter_select2,
 					     &mad_context,
 					     0); /* FIXME SL != 0 */
 		if (status != IB_SUCCESS)
@@ -1377,6 +1419,7 @@ static void perfmgr_log_errors(osm_perfmgr_t * pm,
 	perfmgr_db_err_reading_t prev_read;
 	perfmgr_db_err_t err =
 	    perfmgr_db_get_prev_err(pm->db, mon_node->guid, port, &prev_read);
+	uint64_t cur, prev;
 
 	if (err != PERFMGR_EVENT_DB_SUCCESS) {
 		OSM_LOG(pm->log, OSM_LOG_VERBOSE, "Failed to find previous "
@@ -1406,6 +1449,15 @@ static void perfmgr_log_errors(osm_perfmgr_t * pm,
 	LOG_ERR_CNT("LocalLinkIntegrityErrors",     "543A", link_integrity);
 	LOG_ERR_CNT("ExcessiveBufferOverrunErrors", "543B", buffer_overrun);
 	LOG_ERR_CNT("VL15Dropped",                  "543C", vl15_dropped);
+
+	cur = reading->xmit_wait;
+	prev = prev_read.xmit_wait;
+	if (pm->xmit_wait_log && cur > prev &&
+	    (cur - prev) >= pm->xmit_wait_threshold) {
+		OSM_LOG(pm->log, OSM_LOG_ERROR, "ERR 543D: XmitWait : %" PRIu64
+			" : node \"%s\" (NodeGUID: 0x%" PRIx64 ") : port %u\n",
+			cur - prev, mon_node->name, mon_node->guid, port);
+	}
 }
 
 static int16_t validate_redir_pkey(osm_perfmgr_t *pm, ib_net16_t pkey)
@@ -1555,13 +1607,22 @@ static boolean_t handle_redirect(osm_perfmgr_t *pm,
 						0); /* FIXME SL != 0 */
 	} else {
 		/* reissue the original query to the redirected location */
+		uint8_t counter_select2;
+
+		if (xmit_wait_supported(p_mon_node, port))
+			counter_select2 = 1;
+		else
+			counter_select2 = 0;
+
 		mad_method = mad_context->perfmgr_context.mad_method;
 		if (mad_context->perfmgr_context.mad_attr_id
 		    == IB_MAD_ATTR_PORT_CNTRS) {
-			status = perfmgr_send_pc_mad(pm, cpi->redir_lid, cpi->redir_qp,
+			status = perfmgr_send_pc_mad(pm, cpi->redir_lid,
+						     cpi->redir_qp,
 						     pkey_ix, port,
 						     mad_method,
 						     0xffff,
+						     counter_select2,
 						     mad_context,
 						     0); /* FIXME SL != 0 */
 		} else {
@@ -1714,7 +1775,7 @@ static void pc_recv_process(void *context, void *data)
 		if (pm->query_cpi && cpi_valid) {
 			cl_plock_acquire(&pm->osm->lock);
 			if (p_mon_node->node_type == IB_NODE_TYPE_SWITCH) {
-				int i = 0;
+				int i;
 				for (i = p_mon_node->esp0 ? 0 : 1;
 				     i < p_mon_node->num_ports;
 				     i++) {
@@ -1760,11 +1821,12 @@ static void pc_recv_process(void *context, void *data)
 					   port, ext_wire_read);
 	} else {
 		boolean_t pce_sup = pce_supported(p_mon_node, port);
+		boolean_t xmit_wait_sup = xmit_wait_supported(p_mon_node, port);
 		ib_port_counters_t *wire_read =
 				(ib_port_counters_t *)
 				&osm_madw_get_perfmgt_mad_ptr(p_madw)->data;
 
-		perfmgr_db_fill_err_read(wire_read, &err_reading);
+		perfmgr_db_fill_err_read(wire_read, &err_reading, xmit_wait_sup);
 		if (!pce_sup)
 			perfmgr_db_fill_data_cnt_read_pc(wire_read, &data_reading);
 
@@ -1791,7 +1853,7 @@ static void pc_recv_process(void *context, void *data)
 		}
 
 		perfmgr_check_overflow(pm, p_mon_node, p_mon_node->port[port].pkey_ix,
-				       port, wire_read);
+				       port, wire_read, xmit_wait_sup);
 
 	}
 
@@ -1825,8 +1887,6 @@ ib_api_status_t osm_perfmgr_init(osm_perfmgr_t * pm, osm_opensm_t * osm,
 
 	memset(pm, 0, sizeof(*pm));
 
-	cl_event_construct(&pm->sig_sweep);
-	cl_event_init(&pm->sig_sweep, FALSE);
 	pm->subn = &osm->subn;
 	pm->sm = &osm->sm;
 	pm->log = &osm->log;
@@ -1868,6 +1928,8 @@ ib_api_status_t osm_perfmgr_init(osm_perfmgr_t * pm, osm_opensm_t * osm,
 
 	pm->rm_nodes = p_opt->perfmgr_rm_nodes;
 	pm->query_cpi = p_opt->perfmgr_query_cpi;
+	pm->xmit_wait_log = p_opt->perfmgr_xmit_wait_log;
+	pm->xmit_wait_threshold = p_opt->perfmgr_xmit_wait_threshold;
 	status = IB_SUCCESS;
 Exit:
 	OSM_LOG_EXIT(pm->log);
diff --git a/opensm/osm_perfmgr_db.c b/opensm/osm_perfmgr_db.c
index 92e1a39..e57b804 100644
--- a/opensm/osm_perfmgr_db.c
+++ b/opensm/osm_perfmgr_db.c
@@ -341,6 +341,10 @@ debug_dump_err_reading(perfmgr_db_t * db, uint64_t guid, uint8_t port_num,
 		   "vld %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
 		   cur->vl15_dropped, port->err_previous.vl15_dropped,
 		   port->err_total.vl15_dropped);
+	osm_log_v2(log, OSM_LOG_DEBUG, FILE_ID,
+		   "xw %" PRIu64 " <-- %" PRIu64 " (%" PRIu64 ")\n",
+		   cur->xmit_wait, port->err_previous.xmit_wait,
+		   port->err_total.xmit_wait);
 }
 
 /**********************************************************************
@@ -410,6 +414,9 @@ perfmgr_db_add_err_reading(perfmgr_db_t * db, uint64_t guid, uint8_t port,
 	epi_pe_data.vl15_dropped =
 	    (reading->vl15_dropped - previous->vl15_dropped);
 	p_port->err_total.vl15_dropped += epi_pe_data.vl15_dropped;
+	epi_pe_data.xmit_wait =
+	    (reading->xmit_wait - previous->xmit_wait);
+	p_port->err_total.xmit_wait += epi_pe_data.xmit_wait;
 
 	p_port->err_previous = *reading;
 
@@ -620,6 +627,7 @@ static void clear_counters(cl_map_item_t * const p_map_item, void *context)
 		node->ports[i].err_total.link_integrity = 0;
 		node->ports[i].err_total.buffer_overrun = 0;
 		node->ports[i].err_total.vl15_dropped = 0;
+		node->ports[i].err_total.xmit_wait = 0;
 		node->ports[i].err_total.time = ts;
 
 		node->ports[i].dc_total.xmit_data = 0;
@@ -662,7 +670,7 @@ static void dump_node_mr(db_node_t * node, FILE * fp)
 		"%s\t%s\t"
 		"%s\t%s\t%s\t%s\t%s\t%s\t%s\t"
 		"%s\t%s\t%s\t%s\t%s\t%s\t%s\t"
-		"%s\t%s\t%s\t%s\n",
+		"%s\t%s\t%s\t%s\t%s\n",
 		"symbol_err_cnt",
 		"link_err_recover",
 		"link_downed",
@@ -675,6 +683,7 @@ static void dump_node_mr(db_node_t * node, FILE * fp)
 		"link_int_err",
 		"buf_overrun_err",
 		"vl15_dropped",
+		"xmit_wait",
 		"xmit_data",
 		"rcv_data",
 		"xmit_pkts",
@@ -704,7 +713,7 @@ static void dump_node_mr(db_node_t * node, FILE * fp)
 			"%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t" "%" PRIu64
 			"\t%" PRIu64 "\t%" PRIu64 "\t" "%" PRIu64 "\t%" PRIu64
 			"\t%" PRIu64 "\t%" PRIu64 "\t" "%" PRIu64 "\t%" PRIu64
-			"\t%" PRIu64 "\t%" PRIu64 "\n", node->node_name,
+			"\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\n", node->node_name,
 			node->node_guid,
 			node->active ? "TRUE" : "FALSE",
 			i, last_reset, last_err_update, last_data_update,
@@ -720,6 +729,7 @@ static void dump_node_mr(db_node_t * node, FILE * fp)
 			node->ports[i].err_total.link_integrity,
 			node->ports[i].err_total.buffer_overrun,
 			node->ports[i].err_total.vl15_dropped,
+			node->ports[i].err_total.xmit_wait,
 			node->ports[i].dc_total.xmit_data,
 			node->ports[i].dc_total.rcv_data,
 			node->ports[i].dc_total.xmit_pkts,
@@ -827,7 +837,8 @@ static void dump_node_hr(db_node_t * node, FILE * fp, char *port, int err_only)
 		    && err->rcv_constraint_err == 0
 		    && err->link_integrity == 0
 		    && err->buffer_overrun == 0
-		    && err->vl15_dropped == 0)
+		    && err->vl15_dropped == 0
+		    && err->xmit_wait == 0)
 			continue;
 
 		fprintf(fp, "\"%s\" 0x%" PRIx64 " active %s port %d\n"
@@ -873,6 +884,9 @@ static void dump_node_hr(db_node_t * node, FILE * fp, char *port, int err_only)
 		if (!err_only || err->vl15_dropped != 0)
 			fprintf(fp, "     vl15_dropped         : %" PRIu64 "\n",
 				err->vl15_dropped);
+		if (!err_only || err->xmit_wait != 0)
+			fprintf(fp, "     xmit_wait            : %" PRIu64 "\n",
+				err->xmit_wait);
 
 		if (err_only)
 			continue;
@@ -1022,7 +1036,8 @@ perfmgr_db_dump(perfmgr_db_t * db, char *file, perfmgr_db_dump_t dump_type)
  **********************************************************************/
 void
 perfmgr_db_fill_err_read(ib_port_counters_t * wire_read,
-			 perfmgr_db_err_reading_t * reading)
+			 perfmgr_db_err_reading_t * reading,
+			 boolean_t xmit_wait_sup)
 {
 	reading->symbol_err_cnt = cl_ntoh16(wire_read->symbol_err_cnt);
 	reading->link_err_recover = wire_read->link_err_recover;
@@ -1039,6 +1054,10 @@ perfmgr_db_fill_err_read(ib_port_counters_t * wire_read,
 	reading->buffer_overrun =
 	    PC_BUF_OVERRUN(wire_read->link_int_buffer_overrun);
 	reading->vl15_dropped = cl_ntoh16(wire_read->vl15_dropped);
+	if (xmit_wait_sup)
+		reading->xmit_wait = cl_ntoh32(wire_read->xmit_wait);
+	else
+		reading->xmit_wait = 0;
 	reading->time = time(NULL);
 }
 
diff --git a/opensm/osm_pkey_rcv.c b/opensm/osm_pkey_rcv.c
index 20c6cca..b64ed7b 100644
--- a/opensm/osm_pkey_rcv.c
+++ b/opensm/osm_pkey_rcv.c
@@ -84,6 +84,13 @@ void osm_pkey_rcv_process(IN void *context, IN void *data)
 
 	CL_ASSERT(p_smp->attr_id == IB_MAD_ATTR_P_KEY_TABLE);
 
+	if (ib_smp_get_status(p_smp)) {
+		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+			"MAD status 0x%x received\n",
+			cl_ntoh16(ib_smp_get_status(p_smp)));
+		goto Exit2;
+	}
+
 	cl_plock_excl_acquire(sm->p_lock);
 	p_port = osm_get_port_by_guid(sm->p_subn, port_guid);
 	if (!p_port) {
@@ -140,5 +147,6 @@ void osm_pkey_rcv_process(IN void *context, IN void *data)
 Exit:
 	cl_plock_release(sm->p_lock);
 
+Exit2:
 	OSM_LOG_EXIT(sm->p_log);
 }
diff --git a/opensm/osm_port.c b/opensm/osm_port.c
index bcee338..ae74ba6 100644
--- a/opensm/osm_port.c
+++ b/opensm/osm_port.c
@@ -632,9 +632,9 @@ void osm_physp_set_pkey_tbl(IN osm_log_t * p_log, IN const osm_subn_t * p_subn,
 
 	if (block_num >= max_blocks) {
 		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 4108: "
-			"Got illegal set for block number:%u "
-			"For GUID: %" PRIx64 " port number:%u\n",
-			block_num,
+			"Got illegal update for block number:%u max:%u "
+			"for GUID: %" PRIx64 " port number:%u\n",
+			block_num, max_blocks,
 			cl_ntoh64(p_physp->p_node->node_info.node_guid),
 			p_physp->port_num);
 		return;
diff --git a/opensm/osm_port_info_rcv.c b/opensm/osm_port_info_rcv.c
index 5c12989..4d42470 100644
--- a/opensm/osm_port_info_rcv.c
+++ b/opensm/osm_port_info_rcv.c
@@ -85,6 +85,7 @@ static void pi_rcv_process_endport(IN osm_sm_t * sm, IN osm_physp_t * p_physp,
 	osm_madw_context_t context;
 	ib_api_status_t status;
 	ib_net64_t port_guid;
+	int extended;
 	uint8_t rate, mtu, mpb;
 	unsigned data_vls;
 	cl_qmap_t *p_sm_tbl;
@@ -106,8 +107,8 @@ static void pi_rcv_process_endport(IN osm_sm_t * sm, IN osm_physp_t * p_physp,
 			sm->p_subn->min_ca_mtu = mtu;
 		}
 
-		rate = ib_port_info_compute_rate(p_pi,
-						 p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS);
+		extended = p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS;
+		rate = ib_port_info_compute_rate(p_pi, extended);
 		if (rate < sm->p_subn->min_ca_rate) {
 			OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
 				"Setting endport minimal rate to:%u defined by port:0x%"
@@ -115,7 +116,9 @@ static void pi_rcv_process_endport(IN osm_sm_t * sm, IN osm_physp_t * p_physp,
 			sm->p_subn->min_ca_rate = rate;
 		}
 
-		data_vls = 1U << (ib_port_info_get_op_vls(p_pi) - 1);
+		data_vls = 1U << (ib_port_info_get_vl_cap(p_pi) - 1);
+		if (data_vls > sm->p_subn->opt.max_op_vls)
+			data_vls = sm->p_subn->opt.max_op_vls;
 		if (data_vls >= IB_MAX_NUM_VLS)
 			data_vls = IB_MAX_NUM_VLS - 1;
 		if ((uint8_t)data_vls < sm->p_subn->min_data_vls) {
@@ -199,18 +202,75 @@ static void pi_rcv_process_endport(IN osm_sm_t * sm, IN osm_physp_t * p_physp,
 /**********************************************************************
  The plock must be held before calling this function.
 **********************************************************************/
-static void pi_rcv_process_switch_port(IN osm_sm_t * sm, IN osm_node_t * p_node,
-				       IN osm_physp_t * p_physp,
-				       IN ib_port_info_t * p_pi)
+static void pi_rcv_process_switch_port0(IN osm_sm_t * sm,
+					IN osm_node_t * p_node,
+					IN osm_physp_t * p_physp,
+					IN ib_port_info_t * p_pi)
+{
+	ib_api_status_t status;
+	osm_madw_context_t context;
+	uint8_t port, num_ports;
+
+	OSM_LOG_ENTER(sm->p_log);
+
+	num_ports = osm_node_get_num_physp(p_node);
+
+	context.pi_context.node_guid = osm_node_get_node_guid(p_node);
+	context.pi_context.port_guid = osm_physp_get_port_guid(p_physp);
+	context.pi_context.set_method = FALSE;
+	context.pi_context.light_sweep = FALSE;
+	context.pi_context.active_transition = FALSE;
+	context.pi_context.client_rereg = FALSE;
+
+	for (port = 1; port < num_ports; port++) {
+		status = osm_req_get(sm, osm_physp_get_dr_path_ptr(p_physp),
+				     IB_MAD_ATTR_PORT_INFO, cl_hton32(port),
+				     FALSE,
+				     ib_port_info_get_m_key(&p_physp->port_info),
+				     CL_DISP_MSGID_NONE, &context);
+		if (status != IB_SUCCESS)
+			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0F16: "
+				"Failure initiating PortInfo request (%s)\n",
+				ib_get_err_str(status));
+	}
+
+	if (p_physp->need_update)
+		sm->p_subn->ignore_existing_lfts = TRUE;
+
+	pi_rcv_check_and_fix_lid(sm->p_log, p_pi, p_physp);
+
+	/*
+	   Update the PortInfo attribute.
+	 */
+	osm_physp_set_port_info(p_physp, p_pi, sm);
+
+	/* Determine if base switch port 0 */
+	if (p_node->sw &&
+	    !ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info))
+		/* PortState is not used on BSP0 but just in case it is DOWN */
+		p_physp->port_info = *p_pi;
+	pi_rcv_process_endport(sm, p_physp, p_pi);
+	OSM_LOG_EXIT(sm->p_log);
+}
+
+/**********************************************************************
+ The plock must be held before calling this function.
+**********************************************************************/
+static void pi_rcv_process_switch_ext_port(IN osm_sm_t * sm,
+					   IN osm_node_t * p_node,
+					   IN osm_physp_t * p_physp,
+					   IN ib_port_info_t * p_pi)
 {
 	ib_api_status_t status = IB_SUCCESS;
 	osm_madw_context_t context;
-	osm_physp_t *p_remote_physp;
+	osm_physp_t *p_remote_physp, *physp0;
 	osm_node_t *p_remote_node;
+	ib_net64_t m_key;
 	unsigned data_vls;
 	uint8_t port_num;
 	uint8_t remote_port_num;
 	osm_dr_path_t path;
+	int mlnx_epi_supported = 0;
 
 	OSM_LOG_ENTER(sm->p_log);
 
@@ -220,10 +280,14 @@ static void pi_rcv_process_switch_port(IN osm_sm_t * sm, IN osm_node_t * p_node,
 	   then ask for NodeInfo.  Ignore the switch management port.
 	 */
 	port_num = osm_physp_get_port_num(p_physp);
+
+	if (sm->p_subn->opt.fdr10)
+		mlnx_epi_supported = is_mlnx_ext_port_info_supported(p_node->node_info.device_id);
+
 	/* if in_sweep_hop_0 is TRUE, then this means the SM is on the switch,
 	   and we got switchInfo of our local switch. Do not continue
 	   probing through the switch. */
-	if (port_num != 0 && sm->p_subn->in_sweep_hop_0 == FALSE) {
+	if (sm->p_subn->in_sweep_hop_0 == FALSE) {
 		switch (ib_port_info_get_port_state(p_pi)) {
 		case IB_LINK_DOWN:
 			p_remote_physp = osm_physp_get_remote(p_physp);
@@ -259,6 +323,26 @@ static void pi_rcv_process_switch_port(IN osm_sm_t * sm, IN osm_node_t * p_node,
 		case IB_LINK_INIT:
 		case IB_LINK_ARMED:
 		case IB_LINK_ACTIVE:
+			physp0 = osm_node_get_physp_ptr(p_node, 0);
+			if (mlnx_epi_supported) {
+				m_key = ib_port_info_get_m_key(&physp0->port_info);
+
+				context.pi_context.node_guid = osm_node_get_node_guid(p_node);
+				context.pi_context.port_guid = osm_physp_get_port_guid(p_physp);
+				context.pi_context.set_method = FALSE;
+				context.pi_context.light_sweep = FALSE;
+				context.pi_context.active_transition = FALSE;
+				context.pi_context.client_rereg = FALSE;
+				status = osm_req_get(sm,
+						     osm_physp_get_dr_path_ptr(p_physp),
+						     IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO,
+						     cl_hton32(port_num), FALSE, m_key,
+						     CL_DISP_MSGID_NONE, &context);
+				if (status != IB_SUCCESS)
+					OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0F11: "
+						"Failure initiating MLNX ExtPortInfo request (%s)\n",
+						ib_get_err_str(status));
+		        }
 			/*
 			   To avoid looping forever, only probe the port if it
 			   is NOT the port that responded to the SMP.
@@ -316,46 +400,38 @@ static void pi_rcv_process_switch_port(IN osm_sm_t * sm, IN osm_node_t * p_node,
 	}
 
 	if (ib_port_info_get_port_state(p_pi) > IB_LINK_INIT && p_node->sw &&
-	    p_node->sw->need_update == 1 && port_num != 0)
+	    !ib_switch_info_get_state_change(&p_node->sw->switch_info) &&
+	    p_node->sw->need_update == 1)
 		p_node->sw->need_update = 0;
 
 	if (p_physp->need_update)
 		sm->p_subn->ignore_existing_lfts = TRUE;
 
-	if (port_num == 0)
-		pi_rcv_check_and_fix_lid(sm->p_log, p_pi, p_physp);
-
 	/*
 	   Update the PortInfo attribute.
 	 */
 	osm_physp_set_port_info(p_physp, p_pi, sm);
 
-	if (port_num == 0) {
-		/* Determine if base switch port 0 */
-		if (p_node->sw &&
-		    !ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info))
-			/* PortState is not used on BSP0 but just in case it is DOWN */
-			p_physp->port_info = *p_pi;
-		pi_rcv_process_endport(sm, p_physp, p_pi);
-	} else {
-		if (ib_port_info_get_port_state(p_pi) == IB_LINK_DOWN)
-			goto Exit;
+	if (ib_port_info_get_port_state(p_pi) == IB_LINK_DOWN)
+		goto Exit;
 
-		p_remote_physp = osm_physp_get_remote(p_physp);
-		if (p_remote_physp) {
-			p_remote_node = osm_physp_get_node_ptr(p_remote_physp);
-			if (p_remote_node->sw) {
-				data_vls = 1U << (ib_port_info_get_op_vls(p_pi) - 1);
-				if (data_vls >= IB_MAX_NUM_VLS)
-					data_vls = IB_MAX_NUM_VLS - 1;
-				if ((uint8_t)data_vls < sm->p_subn->min_sw_data_vls) {
-					OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
-						"Setting switch port minimal data VLs to:%u defined by node:0x%"
-						PRIx64 ", port:%u\n", data_vls,
-						cl_ntoh64(osm_node_get_node_guid(p_node)),
-						port_num);
-					sm->p_subn->min_sw_data_vls = data_vls;
-				}
+	p_remote_physp = osm_physp_get_remote(p_physp);
+	if (p_remote_physp) {
+		p_remote_node = osm_physp_get_node_ptr(p_remote_physp);
+		if (p_remote_node->sw) {
+			data_vls = 1U << (ib_port_info_get_vl_cap(p_pi) - 1);
+			if (data_vls > sm->p_subn->opt.max_op_vls)
+				data_vls = sm->p_subn->opt.max_op_vls;
+			if (data_vls >= IB_MAX_NUM_VLS)
+				data_vls = IB_MAX_NUM_VLS - 1;
+			if ((uint8_t)data_vls < sm->p_subn->min_sw_data_vls) {
+				OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
+					"Setting switch port minimal data VLs "
+					"to:%u defined by node:0x%"
+					PRIx64 ", port:%u\n", data_vls,
+					cl_ntoh64(osm_node_get_node_guid(p_node)),
+					port_num);
+				sm->p_subn->min_sw_data_vls = data_vls;
 			}
 		}
 	}
@@ -469,6 +545,19 @@ static void pi_rcv_get_pkey_slvl_vla_tables(IN osm_sm_t * sm,
 	OSM_LOG_EXIT(sm->p_log);
 }
 
+static int osm_pi_rcv_update_self(IN osm_sm_t *sm, IN osm_physp_t *p_physp,
+				  IN ib_port_info_t *p_pi)
+{
+	if (ib_port_info_get_port_state(p_pi) == IB_LINK_DOWN)
+		return 0;
+
+	if (sm->p_subn->need_update || p_physp->need_update > 1 ||
+	    ib_port_info_get_port_state(p_pi) == IB_LINK_INIT)
+		return 1;
+
+	return 0;
+}
+
 static void pi_rcv_process_set(IN osm_sm_t * sm, IN osm_node_t * p_node,
 			       IN uint8_t port_num, IN osm_madw_t * p_madw)
 {
@@ -526,6 +615,28 @@ static void pi_rcv_process_set(IN osm_sm_t * sm, IN osm_node_t * p_node,
 	OSM_LOG_EXIT(sm->p_log);
 }
 
+static int osm_pi_rcv_update_neighbor(IN osm_physp_t *p_physp)
+{
+	osm_physp_t *p_rem_physp = p_physp->p_remote_physp;
+	osm_node_t *p_node;
+
+	/*
+	 * Our own port - this is the only case where CA port
+	 * is discovered before its' neighbor port
+	 */
+	if (!p_rem_physp)
+		return p_physp->need_update;
+
+	p_node = osm_physp_get_node_ptr(p_rem_physp);
+	CL_ASSERT(p_node);
+
+	/* CA/RTR to CA/RTR connection */
+	if (!p_node->sw)
+		return p_physp->need_update;
+
+	return (ib_switch_info_get_state_change(&p_node->sw->switch_info) ? 1 : p_physp->need_update);
+}
+
 void osm_pi_rcv_process(IN void *context, IN void *data)
 {
 	osm_sm_t *sm = context;
@@ -654,11 +765,7 @@ void osm_pi_rcv_process(IN void *context, IN void *data)
 		osm_dr_path_init(p_dr_path, p_smp->hop_count,
 				 p_smp->initial_path);
 
-		/* if port just inited or reached INIT state (external reset)
-		   request update for port related tables */
-		p_physp->need_update =
-		    (ib_port_info_get_port_state(p_pi) == IB_LINK_INIT ||
-		     p_physp->need_update > 1) ? 1 : 0;
+		p_physp->need_update = osm_pi_rcv_update_self(sm, p_physp, p_pi);
 
 		switch (osm_node_get_type(p_node)) {
 		case IB_NODE_TYPE_CA:
@@ -667,6 +774,7 @@ void osm_pi_rcv_process(IN void *context, IN void *data)
 				p_port->discovery_count++;
 				p_node->physp_discovered[port_num] = 1;
 			}
+			p_physp->need_update = osm_pi_rcv_update_neighbor(p_physp);
 			pi_rcv_process_ca_or_router_port(sm, p_node, p_physp,
 							 p_pi);
 			break;
@@ -675,7 +783,12 @@ void osm_pi_rcv_process(IN void *context, IN void *data)
 				p_port->discovery_count++;
 				p_node->physp_discovered[port_num] = 1;
 			}
-			pi_rcv_process_switch_port(sm, p_node, p_physp, p_pi);
+			if (port_num == 0)
+				pi_rcv_process_switch_port0(sm, p_node,
+							    p_physp, p_pi);
+			else
+				pi_rcv_process_switch_ext_port(sm, p_node,
+							       p_physp, p_pi);
 			break;
 		default:
 			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0F07: "
@@ -688,7 +801,8 @@ void osm_pi_rcv_process(IN void *context, IN void *data)
 		/*
 		   Get the tables on the physp.
 		 */
-		if (p_physp->need_update || sm->p_subn->need_update)
+		if (p_physp->need_update || (p_node->sw &&
+					     p_node->sw->need_update))
 			pi_rcv_get_pkey_slvl_vla_tables(sm, p_node, p_physp);
 
 	}
diff --git a/opensm/osm_qos.c b/opensm/osm_qos.c
index a301803..da5638a 100644
--- a/opensm/osm_qos.c
+++ b/opensm/osm_qos.c
@@ -183,6 +183,13 @@ static ib_api_status_t vlarb_update_table_block(osm_sm_t * sm,
 	if (!p_mad)
 		return IB_INSUFFICIENT_MEMORY;
 
+	/*
+	 * Zero the stored VL Arbitration block, so in case the MAD will
+	 * end up with error, we will resend it in the next sweep.
+	 */
+	memset(&p->vl_arb[block_num], 0,
+	       block_length * sizeof(block.vl_entry[0]));
+
 	cl_qlist_insert_tail(mad_list, &p_mad->list_item);
 
 	return IB_SUCCESS;
@@ -263,8 +270,9 @@ static ib_api_status_t sl2vl_update_table(osm_sm_t * sm, osm_physp_t * p,
 		tbl.raw_vl_by_sl[i] = (vl1 << 4) | vl2;
 	}
 
-	if (!force_update && (p_tbl = osm_physp_get_slvl_tbl(p, in_port)) &&
-	    !memcmp(p_tbl, &tbl, sizeof(tbl)))
+	p_tbl = osm_physp_get_slvl_tbl(p, in_port);
+
+	if (!force_update && !memcmp(p_tbl, &tbl, sizeof(tbl)))
 		return IB_SUCCESS;
 
 	p_mad = osm_qos_mad_create(sm, p, sizeof(tbl), (uint8_t *) & tbl,
@@ -272,6 +280,12 @@ static ib_api_status_t sl2vl_update_table(osm_sm_t * sm, osm_physp_t * p,
 	if (!p_mad)
 		return IB_INSUFFICIENT_MEMORY;
 
+	/*
+	 * Zero the stored SL2VL block, so in case the MAD will
+	 * end up with error, we will resend it in the next sweep.
+	 */
+	memset(p_tbl, 0, sizeof(tbl));
+
 	cl_qlist_insert_tail(mad_list, &p_mad->list_item);
 	return IB_SUCCESS;
 }
diff --git a/opensm/osm_qos_parser_y.c b/opensm/osm_qos_parser_y.c
index 29749f5..a4aa114 100644
--- a/opensm/osm_qos_parser_y.c
+++ b/opensm/osm_qos_parser_y.c
@@ -132,6 +132,10 @@
 #define OSM_QOS_POLICY_MAX_LINE_LEN         1024*10
 #define OSM_QOS_POLICY_SL2VL_TABLE_LEN      IB_MAX_NUM_VLS
 #define OSM_QOS_POLICY_MAX_VL_NUM           IB_MAX_NUM_VLS
+#define OSM_QOS_POLICY_MAX_RATE             IB_MAX_RATE
+#define OSM_QOS_POLICY_MIN_RATE             IB_MIN_RATE
+#define OSM_QOS_POLICY_MAX_MTU              IB_MAX_MTU
+#define OSM_QOS_POLICY_MIN_MTU              IB_MIN_MTU
 
 typedef struct tmp_parser_struct_t_ {
     char       str[OSM_QOS_POLICY_MAX_LINE_LEN];
@@ -259,7 +263,7 @@ static cl_list_t __ulp_match_rules;
 
 
 /* Line 189 of yacc.c  */
-#line 263 "osm_qos_parser_y.c"
+#line 267 "osm_qos_parser_y.c"
 
 /* Enabling traces.  */
 #ifndef YYDEBUG
@@ -459,7 +463,7 @@ typedef int YYSTYPE;
 
 
 /* Line 264 of yacc.c  */
-#line 463 "osm_qos_parser_y.c"
+#line 467 "osm_qos_parser_y.c"
 
 #ifdef short
 # undef short
@@ -832,31 +836,31 @@ static const yytype_int16 yyrhs[] =
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   281,   281,   284,   285,   288,   289,   290,   291,   292,
-     318,   321,   322,   351,   354,   355,   358,   361,   366,   372,
-     373,   376,   377,   378,   379,   380,   381,   382,   409,   412,
-     413,   414,   419,   422,   423,   426,   429,   434,   440,   441,
-     456,   457,   458,   459,   460,   465,   468,   469,   472,   475,
-     480,   486,   487,   506,   507,   508,   509,   510,   511,   512,
-     536,   539,   540,   543,   546,   551,   557,   558,   561,   562,
-     563,   564,   565,   566,   567,   568,   590,   593,   594,   597,
-     600,   605,   611,   612,   615,   616,   617,   618,   619,   620,
-     621,   645,   663,   663,   684,   684,   705,   705,   740,   740,
-     775,   775,   813,   813,   826,   826,   860,   860,   873,   873,
-     907,   907,   920,   920,   954,   954,   990,   990,  1010,  1010,
-    1043,  1046,  1049,  1052,  1055,  1058,  1061,  1064,  1067,  1070,
-    1073,  1076,  1079,  1082,  1086,  1125,  1148,  1153,  1176,  1181,
-    1247,  1252,  1272,  1277,  1297,  1302,  1310,  1315,  1320,  1325,
-    1326,  1329,  1330,  1331,  1332,  1333,  1336,  1342,  1348,  1354,
-    1362,  1384,  1401,  1406,  1423,  1428,  1446,  1451,  1468,  1473,
-    1490,  1506,  1523,  1528,  1547,  1552,  1569,  1574,  1592,  1597,
-    1602,  1607,  1612,  1617,  1618,  1621,  1628,  1629,  1632,  1639,
-    1670,  1702,  1745,  1762,  1785,  1790,  1813,  1818,  1838,  1843,
-    1863,  1869,  1889,  1895,  1915,  1921,  1956,  1961,  1994,  2011,
-    2034,  2039,  2073,  2078,  2095,  2100,  2117,  2122,  2145,  2150,
-    2183,  2188,  2221,  2232,  2239,  2240,  2243,  2250,  2251,  2256,
-    2259,  2260,  2263,  2271,  2277,  2285,  2291,  2297,  2300,  2306,
-    2318,  2330,  2338,  2345,  2351
+       0,   285,   285,   288,   289,   292,   293,   294,   295,   296,
+     322,   325,   326,   355,   358,   359,   362,   365,   370,   376,
+     377,   380,   381,   382,   383,   384,   385,   386,   413,   416,
+     417,   418,   423,   426,   427,   430,   433,   438,   444,   445,
+     460,   461,   462,   463,   464,   469,   472,   473,   476,   479,
+     484,   490,   491,   510,   511,   512,   513,   514,   515,   516,
+     540,   543,   544,   547,   550,   555,   561,   562,   565,   566,
+     567,   568,   569,   570,   571,   572,   594,   597,   598,   601,
+     604,   609,   615,   616,   619,   620,   621,   622,   623,   624,
+     625,   649,   667,   667,   688,   688,   709,   709,   744,   744,
+     779,   779,   817,   817,   830,   830,   864,   864,   877,   877,
+     911,   911,   924,   924,   958,   958,   994,   994,  1014,  1014,
+    1047,  1050,  1053,  1056,  1059,  1062,  1065,  1068,  1071,  1074,
+    1077,  1080,  1083,  1086,  1090,  1129,  1152,  1157,  1180,  1185,
+    1251,  1256,  1276,  1281,  1301,  1306,  1314,  1319,  1324,  1329,
+    1330,  1333,  1334,  1335,  1336,  1337,  1340,  1346,  1352,  1358,
+    1366,  1388,  1405,  1410,  1427,  1432,  1450,  1455,  1472,  1477,
+    1494,  1510,  1527,  1532,  1551,  1556,  1573,  1578,  1596,  1601,
+    1606,  1611,  1616,  1621,  1622,  1625,  1632,  1633,  1636,  1643,
+    1674,  1706,  1749,  1766,  1789,  1794,  1817,  1822,  1842,  1847,
+    1874,  1880,  1907,  1913,  1933,  1939,  1974,  1979,  2012,  2029,
+    2052,  2057,  2091,  2096,  2113,  2118,  2135,  2140,  2163,  2168,
+    2201,  2206,  2239,  2250,  2257,  2258,  2261,  2268,  2269,  2274,
+    2277,  2278,  2281,  2289,  2295,  2303,  2309,  2315,  2318,  2324,
+    2336,  2348,  2356,  2363,  2369
 };
 #endif
 
@@ -2075,7 +2079,7 @@ yyreduce:
         case 17:
 
 /* Line 1455 of yacc.c  */
-#line 361 "osm_qos_parser_y.y"
+#line 365 "osm_qos_parser_y.y"
     {
                         __parser_port_group_start();
                     }
@@ -2084,7 +2088,7 @@ yyreduce:
   case 18:
 
 /* Line 1455 of yacc.c  */
-#line 366 "osm_qos_parser_y.y"
+#line 370 "osm_qos_parser_y.y"
     {
                         if ( __parser_port_group_end() )
                             return 1;
@@ -2094,7 +2098,7 @@ yyreduce:
   case 36:
 
 /* Line 1455 of yacc.c  */
-#line 429 "osm_qos_parser_y.y"
+#line 433 "osm_qos_parser_y.y"
     {
                         __parser_vlarb_scope_start();
                     }
@@ -2103,7 +2107,7 @@ yyreduce:
   case 37:
 
 /* Line 1455 of yacc.c  */
-#line 434 "osm_qos_parser_y.y"
+#line 438 "osm_qos_parser_y.y"
     {
                         if ( __parser_vlarb_scope_end() )
                             return 1;
@@ -2113,7 +2117,7 @@ yyreduce:
   case 49:
 
 /* Line 1455 of yacc.c  */
-#line 475 "osm_qos_parser_y.y"
+#line 479 "osm_qos_parser_y.y"
     {
                         __parser_sl2vl_scope_start();
                     }
@@ -2122,7 +2126,7 @@ yyreduce:
   case 50:
 
 /* Line 1455 of yacc.c  */
-#line 480 "osm_qos_parser_y.y"
+#line 484 "osm_qos_parser_y.y"
     {
                         if ( __parser_sl2vl_scope_end() )
                             return 1;
@@ -2132,7 +2136,7 @@ yyreduce:
   case 64:
 
 /* Line 1455 of yacc.c  */
-#line 546 "osm_qos_parser_y.y"
+#line 550 "osm_qos_parser_y.y"
     {
                         __parser_qos_level_start();
                     }
@@ -2141,7 +2145,7 @@ yyreduce:
   case 65:
 
 /* Line 1455 of yacc.c  */
-#line 551 "osm_qos_parser_y.y"
+#line 555 "osm_qos_parser_y.y"
     {
                         if ( __parser_qos_level_end() )
                             return 1;
@@ -2151,7 +2155,7 @@ yyreduce:
   case 80:
 
 /* Line 1455 of yacc.c  */
-#line 600 "osm_qos_parser_y.y"
+#line 604 "osm_qos_parser_y.y"
     {
                         __parser_match_rule_start();
                     }
@@ -2160,7 +2164,7 @@ yyreduce:
   case 81:
 
 /* Line 1455 of yacc.c  */
-#line 605 "osm_qos_parser_y.y"
+#line 609 "osm_qos_parser_y.y"
     {
                         if ( __parser_match_rule_end() )
                             return 1;
@@ -2170,7 +2174,7 @@ yyreduce:
   case 91:
 
 /* Line 1455 of yacc.c  */
-#line 645 "osm_qos_parser_y.y"
+#line 649 "osm_qos_parser_y.y"
     {
                         /* parsing default ulp rule: "default: num" */
                         cl_list_iterator_t    list_iterator;
@@ -2193,7 +2197,7 @@ yyreduce:
   case 92:
 
 /* Line 1455 of yacc.c  */
-#line 663 "osm_qos_parser_y.y"
+#line 667 "osm_qos_parser_y.y"
     {
                         /* "any, service-id ... : sl" - one instance of list of ranges */
                         uint64_t ** range_arr;
@@ -2219,7 +2223,7 @@ yyreduce:
   case 94:
 
 /* Line 1455 of yacc.c  */
-#line 684 "osm_qos_parser_y.y"
+#line 688 "osm_qos_parser_y.y"
     {
                         /* "any, pkey ... : sl" - one instance of list of ranges */
                         uint64_t ** range_arr;
@@ -2245,7 +2249,7 @@ yyreduce:
   case 96:
 
 /* Line 1455 of yacc.c  */
-#line 705 "osm_qos_parser_y.y"
+#line 709 "osm_qos_parser_y.y"
     {
                         /* any, target-port-guid ... : sl */
                         uint64_t ** range_arr;
@@ -2285,7 +2289,7 @@ yyreduce:
   case 98:
 
 /* Line 1455 of yacc.c  */
-#line 740 "osm_qos_parser_y.y"
+#line 744 "osm_qos_parser_y.y"
     {
 			/* any, source-port-guid ... : sl */
 			uint64_t ** range_arr;
@@ -2325,7 +2329,7 @@ yyreduce:
   case 100:
 
 /* Line 1455 of yacc.c  */
-#line 775 "osm_qos_parser_y.y"
+#line 779 "osm_qos_parser_y.y"
     {
 			/* any, source-target-port-guid ... : sl */
 			uint64_t ** range_arr;
@@ -2368,7 +2372,7 @@ yyreduce:
   case 102:
 
 /* Line 1455 of yacc.c  */
-#line 813 "osm_qos_parser_y.y"
+#line 817 "osm_qos_parser_y.y"
     {
                         /* "sdp : sl" - default SL for SDP */
                         uint64_t ** range_arr =
@@ -2386,7 +2390,7 @@ yyreduce:
   case 104:
 
 /* Line 1455 of yacc.c  */
-#line 826 "osm_qos_parser_y.y"
+#line 830 "osm_qos_parser_y.y"
     {
                         /* sdp with port numbers */
                         uint64_t ** range_arr;
@@ -2425,7 +2429,7 @@ yyreduce:
   case 106:
 
 /* Line 1455 of yacc.c  */
-#line 860 "osm_qos_parser_y.y"
+#line 864 "osm_qos_parser_y.y"
     {
                         /* "rds : sl" - default SL for RDS */
                         uint64_t ** range_arr =
@@ -2443,7 +2447,7 @@ yyreduce:
   case 108:
 
 /* Line 1455 of yacc.c  */
-#line 873 "osm_qos_parser_y.y"
+#line 877 "osm_qos_parser_y.y"
     {
                         /* rds with port numbers */
                         uint64_t ** range_arr;
@@ -2482,7 +2486,7 @@ yyreduce:
   case 110:
 
 /* Line 1455 of yacc.c  */
-#line 907 "osm_qos_parser_y.y"
+#line 911 "osm_qos_parser_y.y"
     {
                         /* "iSER : sl" - default SL for iSER */
                         uint64_t ** range_arr =
@@ -2500,7 +2504,7 @@ yyreduce:
   case 112:
 
 /* Line 1455 of yacc.c  */
-#line 920 "osm_qos_parser_y.y"
+#line 924 "osm_qos_parser_y.y"
     {
                         /* iser with port numbers */
                         uint64_t ** range_arr;
@@ -2539,7 +2543,7 @@ yyreduce:
   case 114:
 
 /* Line 1455 of yacc.c  */
-#line 954 "osm_qos_parser_y.y"
+#line 958 "osm_qos_parser_y.y"
     {
                         /* srp with target guids - this rule is similar
                            to writing 'any' ulp with target port guids */
@@ -2580,7 +2584,7 @@ yyreduce:
   case 116:
 
 /* Line 1455 of yacc.c  */
-#line 990 "osm_qos_parser_y.y"
+#line 994 "osm_qos_parser_y.y"
     {
                         /* ipoib w/o any pkeys (default pkey) */
                         uint64_t ** range_arr =
@@ -2605,7 +2609,7 @@ yyreduce:
   case 118:
 
 /* Line 1455 of yacc.c  */
-#line 1010 "osm_qos_parser_y.y"
+#line 1014 "osm_qos_parser_y.y"
     {
                         /* ipoib with pkeys */
                         uint64_t ** range_arr;
@@ -2642,105 +2646,105 @@ yyreduce:
   case 120:
 
 /* Line 1455 of yacc.c  */
-#line 1044 "osm_qos_parser_y.y"
+#line 1048 "osm_qos_parser_y.y"
     { __parser_ulp_match_rule_start(); }
     break;
 
   case 121:
 
 /* Line 1455 of yacc.c  */
-#line 1047 "osm_qos_parser_y.y"
+#line 1051 "osm_qos_parser_y.y"
     { __parser_ulp_match_rule_start(); }
     break;
 
   case 122:
 
 /* Line 1455 of yacc.c  */
-#line 1050 "osm_qos_parser_y.y"
+#line 1054 "osm_qos_parser_y.y"
     { __parser_ulp_match_rule_start(); }
     break;
 
   case 123:
 
 /* Line 1455 of yacc.c  */
-#line 1053 "osm_qos_parser_y.y"
+#line 1057 "osm_qos_parser_y.y"
     { __parser_ulp_match_rule_start(); }
     break;
 
   case 124:
 
 /* Line 1455 of yacc.c  */
-#line 1056 "osm_qos_parser_y.y"
+#line 1060 "osm_qos_parser_y.y"
     { __parser_ulp_match_rule_start(); }
     break;
 
   case 125:
 
 /* Line 1455 of yacc.c  */
-#line 1059 "osm_qos_parser_y.y"
+#line 1063 "osm_qos_parser_y.y"
     { __parser_ulp_match_rule_start(); }
     break;
 
   case 126:
 
 /* Line 1455 of yacc.c  */
-#line 1062 "osm_qos_parser_y.y"
+#line 1066 "osm_qos_parser_y.y"
     { __parser_ulp_match_rule_start(); }
     break;
 
   case 127:
 
 /* Line 1455 of yacc.c  */
-#line 1065 "osm_qos_parser_y.y"
+#line 1069 "osm_qos_parser_y.y"
     { __parser_ulp_match_rule_start(); }
     break;
 
   case 128:
 
 /* Line 1455 of yacc.c  */
-#line 1068 "osm_qos_parser_y.y"
+#line 1072 "osm_qos_parser_y.y"
     { __parser_ulp_match_rule_start(); }
     break;
 
   case 129:
 
 /* Line 1455 of yacc.c  */
-#line 1071 "osm_qos_parser_y.y"
+#line 1075 "osm_qos_parser_y.y"
     { __parser_ulp_match_rule_start(); }
     break;
 
   case 130:
 
 /* Line 1455 of yacc.c  */
-#line 1074 "osm_qos_parser_y.y"
+#line 1078 "osm_qos_parser_y.y"
     { __parser_ulp_match_rule_start(); }
     break;
 
   case 131:
 
 /* Line 1455 of yacc.c  */
-#line 1077 "osm_qos_parser_y.y"
+#line 1081 "osm_qos_parser_y.y"
     { __parser_ulp_match_rule_start(); }
     break;
 
   case 132:
 
 /* Line 1455 of yacc.c  */
-#line 1080 "osm_qos_parser_y.y"
+#line 1084 "osm_qos_parser_y.y"
     { __parser_ulp_match_rule_start(); }
     break;
 
   case 133:
 
 /* Line 1455 of yacc.c  */
-#line 1083 "osm_qos_parser_y.y"
+#line 1087 "osm_qos_parser_y.y"
     { __parser_ulp_match_rule_start(); }
     break;
 
   case 134:
 
 /* Line 1455 of yacc.c  */
-#line 1086 "osm_qos_parser_y.y"
+#line 1090 "osm_qos_parser_y.y"
     {
                         /* get the SL for ULP rules */
                         cl_list_iterator_t  list_iterator;
@@ -2772,7 +2776,7 @@ yyreduce:
   case 135:
 
 /* Line 1455 of yacc.c  */
-#line 1125 "osm_qos_parser_y.y"
+#line 1129 "osm_qos_parser_y.y"
     {
                             /* 'name' of 'port-group' - one instance */
                             cl_list_iterator_t    list_iterator;
@@ -2799,7 +2803,7 @@ yyreduce:
   case 136:
 
 /* Line 1455 of yacc.c  */
-#line 1148 "osm_qos_parser_y.y"
+#line 1152 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -2808,7 +2812,7 @@ yyreduce:
   case 137:
 
 /* Line 1455 of yacc.c  */
-#line 1153 "osm_qos_parser_y.y"
+#line 1157 "osm_qos_parser_y.y"
     {
                             /* 'use' of 'port-group' - one instance */
                             cl_list_iterator_t    list_iterator;
@@ -2835,7 +2839,7 @@ yyreduce:
   case 138:
 
 /* Line 1455 of yacc.c  */
-#line 1176 "osm_qos_parser_y.y"
+#line 1180 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -2844,7 +2848,7 @@ yyreduce:
   case 139:
 
 /* Line 1455 of yacc.c  */
-#line 1181 "osm_qos_parser_y.y"
+#line 1185 "osm_qos_parser_y.y"
     {
                             /* 'port-name' in 'port-group' - any num of instances */
                             cl_list_iterator_t list_iterator;
@@ -2914,7 +2918,7 @@ yyreduce:
   case 140:
 
 /* Line 1455 of yacc.c  */
-#line 1247 "osm_qos_parser_y.y"
+#line 1251 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -2923,7 +2927,7 @@ yyreduce:
   case 141:
 
 /* Line 1455 of yacc.c  */
-#line 1252 "osm_qos_parser_y.y"
+#line 1256 "osm_qos_parser_y.y"
     {
                             /* 'port-guid' in 'port-group' - any num of instances */
                             /* list of guid ranges */
@@ -2947,7 +2951,7 @@ yyreduce:
   case 142:
 
 /* Line 1455 of yacc.c  */
-#line 1272 "osm_qos_parser_y.y"
+#line 1276 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -2956,7 +2960,7 @@ yyreduce:
   case 143:
 
 /* Line 1455 of yacc.c  */
-#line 1277 "osm_qos_parser_y.y"
+#line 1281 "osm_qos_parser_y.y"
     {
                             /* 'pkey' in 'port-group' - any num of instances */
                             /* list of pkey ranges */
@@ -2980,7 +2984,7 @@ yyreduce:
   case 144:
 
 /* Line 1455 of yacc.c  */
-#line 1297 "osm_qos_parser_y.y"
+#line 1301 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -2989,7 +2993,7 @@ yyreduce:
   case 145:
 
 /* Line 1455 of yacc.c  */
-#line 1302 "osm_qos_parser_y.y"
+#line 1306 "osm_qos_parser_y.y"
     {
                             /* 'partition' in 'port-group' - any num of instances */
                             __parser_add_partition_list_to_port_map(
@@ -3001,7 +3005,7 @@ yyreduce:
   case 146:
 
 /* Line 1455 of yacc.c  */
-#line 1310 "osm_qos_parser_y.y"
+#line 1314 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3010,7 +3014,7 @@ yyreduce:
   case 147:
 
 /* Line 1455 of yacc.c  */
-#line 1315 "osm_qos_parser_y.y"
+#line 1319 "osm_qos_parser_y.y"
     {
                             /* 'node-type' in 'port-group' - any num of instances */
                         }
@@ -3019,7 +3023,7 @@ yyreduce:
   case 148:
 
 /* Line 1455 of yacc.c  */
-#line 1320 "osm_qos_parser_y.y"
+#line 1324 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3028,7 +3032,7 @@ yyreduce:
   case 156:
 
 /* Line 1455 of yacc.c  */
-#line 1336 "osm_qos_parser_y.y"
+#line 1340 "osm_qos_parser_y.y"
     {
                             p_current_port_group->node_types |=
                                OSM_QOS_POLICY_NODE_TYPE_CA;
@@ -3038,7 +3042,7 @@ yyreduce:
   case 157:
 
 /* Line 1455 of yacc.c  */
-#line 1342 "osm_qos_parser_y.y"
+#line 1346 "osm_qos_parser_y.y"
     {
                             p_current_port_group->node_types |=
                                OSM_QOS_POLICY_NODE_TYPE_SWITCH;
@@ -3048,7 +3052,7 @@ yyreduce:
   case 158:
 
 /* Line 1455 of yacc.c  */
-#line 1348 "osm_qos_parser_y.y"
+#line 1352 "osm_qos_parser_y.y"
     {
                             p_current_port_group->node_types |=
                                OSM_QOS_POLICY_NODE_TYPE_ROUTER;
@@ -3058,7 +3062,7 @@ yyreduce:
   case 159:
 
 /* Line 1455 of yacc.c  */
-#line 1354 "osm_qos_parser_y.y"
+#line 1358 "osm_qos_parser_y.y"
     {
                             p_current_port_group->node_types |=
                                (OSM_QOS_POLICY_NODE_TYPE_CA |
@@ -3070,7 +3074,7 @@ yyreduce:
   case 160:
 
 /* Line 1455 of yacc.c  */
-#line 1362 "osm_qos_parser_y.y"
+#line 1366 "osm_qos_parser_y.y"
     {
                             osm_port_t * p_osm_port =
                                 osm_get_port_by_guid(p_qos_policy->p_subn,
@@ -3085,7 +3089,7 @@ yyreduce:
   case 161:
 
 /* Line 1455 of yacc.c  */
-#line 1384 "osm_qos_parser_y.y"
+#line 1388 "osm_qos_parser_y.y"
     {
                             /* 'group' in 'vlarb-scope' - any num of instances */
                             cl_list_iterator_t    list_iterator;
@@ -3106,7 +3110,7 @@ yyreduce:
   case 162:
 
 /* Line 1455 of yacc.c  */
-#line 1401 "osm_qos_parser_y.y"
+#line 1405 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3115,7 +3119,7 @@ yyreduce:
   case 163:
 
 /* Line 1455 of yacc.c  */
-#line 1406 "osm_qos_parser_y.y"
+#line 1410 "osm_qos_parser_y.y"
     {
                             /* 'across' in 'vlarb-scope' - any num of instances */
                             cl_list_iterator_t    list_iterator;
@@ -3136,7 +3140,7 @@ yyreduce:
   case 164:
 
 /* Line 1455 of yacc.c  */
-#line 1423 "osm_qos_parser_y.y"
+#line 1427 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3145,7 +3149,7 @@ yyreduce:
   case 165:
 
 /* Line 1455 of yacc.c  */
-#line 1428 "osm_qos_parser_y.y"
+#line 1432 "osm_qos_parser_y.y"
     {
                             /* 'vl-high-limit' in 'vlarb-scope' - one instance of one number */
                             cl_list_iterator_t    list_iterator;
@@ -3167,7 +3171,7 @@ yyreduce:
   case 166:
 
 /* Line 1455 of yacc.c  */
-#line 1446 "osm_qos_parser_y.y"
+#line 1450 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3176,7 +3180,7 @@ yyreduce:
   case 167:
 
 /* Line 1455 of yacc.c  */
-#line 1451 "osm_qos_parser_y.y"
+#line 1455 "osm_qos_parser_y.y"
     {
                             /* 'vlarb-high' in 'vlarb-scope' - list of pairs of numbers with ':' and ',' */
                             cl_list_iterator_t    list_iterator;
@@ -3197,7 +3201,7 @@ yyreduce:
   case 168:
 
 /* Line 1455 of yacc.c  */
-#line 1468 "osm_qos_parser_y.y"
+#line 1472 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3206,7 +3210,7 @@ yyreduce:
   case 169:
 
 /* Line 1455 of yacc.c  */
-#line 1473 "osm_qos_parser_y.y"
+#line 1477 "osm_qos_parser_y.y"
     {
                             /* 'vlarb-low' in 'vlarb-scope' - list of pairs of numbers with ':' and ',' */
                             cl_list_iterator_t    list_iterator;
@@ -3227,7 +3231,7 @@ yyreduce:
   case 170:
 
 /* Line 1455 of yacc.c  */
-#line 1490 "osm_qos_parser_y.y"
+#line 1494 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3236,7 +3240,7 @@ yyreduce:
   case 171:
 
 /* Line 1455 of yacc.c  */
-#line 1506 "osm_qos_parser_y.y"
+#line 1510 "osm_qos_parser_y.y"
     {
                             /* 'group' in 'sl2vl-scope' - any num of instances */
                             cl_list_iterator_t    list_iterator;
@@ -3257,7 +3261,7 @@ yyreduce:
   case 172:
 
 /* Line 1455 of yacc.c  */
-#line 1523 "osm_qos_parser_y.y"
+#line 1527 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3266,7 +3270,7 @@ yyreduce:
   case 173:
 
 /* Line 1455 of yacc.c  */
-#line 1528 "osm_qos_parser_y.y"
+#line 1532 "osm_qos_parser_y.y"
     {
                             /* 'across' in 'sl2vl-scope' - any num of instances */
                             cl_list_iterator_t    list_iterator;
@@ -3289,7 +3293,7 @@ yyreduce:
   case 174:
 
 /* Line 1455 of yacc.c  */
-#line 1547 "osm_qos_parser_y.y"
+#line 1551 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3298,7 +3302,7 @@ yyreduce:
   case 175:
 
 /* Line 1455 of yacc.c  */
-#line 1552 "osm_qos_parser_y.y"
+#line 1556 "osm_qos_parser_y.y"
     {
                             /* 'across-from' in 'sl2vl-scope' - any num of instances */
                             cl_list_iterator_t    list_iterator;
@@ -3319,7 +3323,7 @@ yyreduce:
   case 176:
 
 /* Line 1455 of yacc.c  */
-#line 1569 "osm_qos_parser_y.y"
+#line 1573 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3328,7 +3332,7 @@ yyreduce:
   case 177:
 
 /* Line 1455 of yacc.c  */
-#line 1574 "osm_qos_parser_y.y"
+#line 1578 "osm_qos_parser_y.y"
     {
                             /* 'across-to' in 'sl2vl-scope' - any num of instances */
                             cl_list_iterator_t    list_iterator;
@@ -3350,7 +3354,7 @@ yyreduce:
   case 178:
 
 /* Line 1455 of yacc.c  */
-#line 1592 "osm_qos_parser_y.y"
+#line 1596 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3359,7 +3363,7 @@ yyreduce:
   case 179:
 
 /* Line 1455 of yacc.c  */
-#line 1597 "osm_qos_parser_y.y"
+#line 1601 "osm_qos_parser_y.y"
     {
                             /* 'from' in 'sl2vl-scope' - any num of instances */
                         }
@@ -3368,7 +3372,7 @@ yyreduce:
   case 180:
 
 /* Line 1455 of yacc.c  */
-#line 1602 "osm_qos_parser_y.y"
+#line 1606 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3377,7 +3381,7 @@ yyreduce:
   case 181:
 
 /* Line 1455 of yacc.c  */
-#line 1607 "osm_qos_parser_y.y"
+#line 1611 "osm_qos_parser_y.y"
     {
                             /* 'to' in 'sl2vl-scope' - any num of instances */
                         }
@@ -3386,7 +3390,7 @@ yyreduce:
   case 182:
 
 /* Line 1455 of yacc.c  */
-#line 1612 "osm_qos_parser_y.y"
+#line 1616 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3395,7 +3399,7 @@ yyreduce:
   case 185:
 
 /* Line 1455 of yacc.c  */
-#line 1621 "osm_qos_parser_y.y"
+#line 1625 "osm_qos_parser_y.y"
     {
                             int i;
                             for (i = 0; i < OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH; i++)
@@ -3406,7 +3410,7 @@ yyreduce:
   case 188:
 
 /* Line 1455 of yacc.c  */
-#line 1632 "osm_qos_parser_y.y"
+#line 1636 "osm_qos_parser_y.y"
     {
                             int i;
                             for (i = 0; i < OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH; i++)
@@ -3417,7 +3421,7 @@ yyreduce:
   case 189:
 
 /* Line 1455 of yacc.c  */
-#line 1639 "osm_qos_parser_y.y"
+#line 1643 "osm_qos_parser_y.y"
     {
                             int i;
                             cl_list_iterator_t    list_iterator;
@@ -3452,7 +3456,7 @@ yyreduce:
   case 190:
 
 /* Line 1455 of yacc.c  */
-#line 1670 "osm_qos_parser_y.y"
+#line 1674 "osm_qos_parser_y.y"
     {
                             int i;
                             cl_list_iterator_t    list_iterator;
@@ -3487,7 +3491,7 @@ yyreduce:
   case 191:
 
 /* Line 1455 of yacc.c  */
-#line 1702 "osm_qos_parser_y.y"
+#line 1706 "osm_qos_parser_y.y"
     {
                             /* 'sl2vl-table' - one instance of exactly
                                OSM_QOS_POLICY_SL2VL_TABLE_LEN numbers */
@@ -3534,7 +3538,7 @@ yyreduce:
   case 192:
 
 /* Line 1455 of yacc.c  */
-#line 1745 "osm_qos_parser_y.y"
+#line 1749 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3543,7 +3547,7 @@ yyreduce:
   case 193:
 
 /* Line 1455 of yacc.c  */
-#line 1762 "osm_qos_parser_y.y"
+#line 1766 "osm_qos_parser_y.y"
     {
                             /* 'name' of 'qos-level' - one instance */
                             cl_list_iterator_t    list_iterator;
@@ -3570,7 +3574,7 @@ yyreduce:
   case 194:
 
 /* Line 1455 of yacc.c  */
-#line 1785 "osm_qos_parser_y.y"
+#line 1789 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3579,7 +3583,7 @@ yyreduce:
   case 195:
 
 /* Line 1455 of yacc.c  */
-#line 1790 "osm_qos_parser_y.y"
+#line 1794 "osm_qos_parser_y.y"
     {
                             /* 'use' of 'qos-level' - one instance */
                             cl_list_iterator_t    list_iterator;
@@ -3606,7 +3610,7 @@ yyreduce:
   case 196:
 
 /* Line 1455 of yacc.c  */
-#line 1813 "osm_qos_parser_y.y"
+#line 1817 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3615,7 +3619,7 @@ yyreduce:
   case 197:
 
 /* Line 1455 of yacc.c  */
-#line 1818 "osm_qos_parser_y.y"
+#line 1822 "osm_qos_parser_y.y"
     {
                             /* 'sl' in 'qos-level' - one instance */
                             cl_list_iterator_t   list_iterator;
@@ -3639,7 +3643,7 @@ yyreduce:
   case 198:
 
 /* Line 1455 of yacc.c  */
-#line 1838 "osm_qos_parser_y.y"
+#line 1842 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3648,7 +3652,7 @@ yyreduce:
   case 199:
 
 /* Line 1455 of yacc.c  */
-#line 1843 "osm_qos_parser_y.y"
+#line 1847 "osm_qos_parser_y.y"
     {
                             /* 'mtu-limit' in 'qos-level' - one instance */
                             cl_list_iterator_t   list_iterator;
@@ -3662,6 +3666,13 @@ yyreduce:
                             }
                             list_iterator = cl_list_head(&tmp_parser_struct.num_list);
                             p_num = (uint64_t*)cl_list_obj(list_iterator);
+                            if (*p_num > OSM_QOS_POLICY_MAX_MTU || *p_num < OSM_QOS_POLICY_MIN_MTU)
+                            {
+                                yyerror("mtu limit is out of range, value: %d", *p_num);
+                                free(p_num);
+                                cl_list_remove_all(&tmp_parser_struct.num_list);
+                                return 1;
+                            }
                             p_current_qos_level->mtu_limit = (uint8_t)(*p_num);
                             free(p_num);
                             p_current_qos_level->mtu_limit_set = TRUE;
@@ -3672,7 +3683,7 @@ yyreduce:
   case 200:
 
 /* Line 1455 of yacc.c  */
-#line 1863 "osm_qos_parser_y.y"
+#line 1874 "osm_qos_parser_y.y"
     {
                             /* 'mtu-limit' in 'qos-level' - one instance */
                             RESET_BUFFER;
@@ -3682,7 +3693,7 @@ yyreduce:
   case 201:
 
 /* Line 1455 of yacc.c  */
-#line 1869 "osm_qos_parser_y.y"
+#line 1880 "osm_qos_parser_y.y"
     {
                             /* 'rate-limit' in 'qos-level' - one instance */
                             cl_list_iterator_t   list_iterator;
@@ -3696,6 +3707,13 @@ yyreduce:
                             }
                             list_iterator = cl_list_head(&tmp_parser_struct.num_list);
                             p_num = (uint64_t*)cl_list_obj(list_iterator);
+                            if (*p_num > OSM_QOS_POLICY_MAX_RATE || *p_num < OSM_QOS_POLICY_MIN_RATE)
+                            {
+                                yyerror("rate limit is out of range, value: %d", *p_num);
+                                free(p_num);
+                                cl_list_remove_all(&tmp_parser_struct.num_list);
+                                return 1;
+                            }
                             p_current_qos_level->rate_limit = (uint8_t)(*p_num);
                             free(p_num);
                             p_current_qos_level->rate_limit_set = TRUE;
@@ -3706,7 +3724,7 @@ yyreduce:
   case 202:
 
 /* Line 1455 of yacc.c  */
-#line 1889 "osm_qos_parser_y.y"
+#line 1907 "osm_qos_parser_y.y"
     {
                             /* 'rate-limit' in 'qos-level' - one instance */
                             RESET_BUFFER;
@@ -3716,7 +3734,7 @@ yyreduce:
   case 203:
 
 /* Line 1455 of yacc.c  */
-#line 1895 "osm_qos_parser_y.y"
+#line 1913 "osm_qos_parser_y.y"
     {
                             /* 'packet-life' in 'qos-level' - one instance */
                             cl_list_iterator_t   list_iterator;
@@ -3740,7 +3758,7 @@ yyreduce:
   case 204:
 
 /* Line 1455 of yacc.c  */
-#line 1915 "osm_qos_parser_y.y"
+#line 1933 "osm_qos_parser_y.y"
     {
                             /* 'packet-life' in 'qos-level' - one instance */
                             RESET_BUFFER;
@@ -3750,7 +3768,7 @@ yyreduce:
   case 205:
 
 /* Line 1455 of yacc.c  */
-#line 1921 "osm_qos_parser_y.y"
+#line 1939 "osm_qos_parser_y.y"
     {
                             /* 'path-bits' in 'qos-level' - any num of instances */
                             /* list of path bit ranges */
@@ -3789,7 +3807,7 @@ yyreduce:
   case 206:
 
 /* Line 1455 of yacc.c  */
-#line 1956 "osm_qos_parser_y.y"
+#line 1974 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3798,7 +3816,7 @@ yyreduce:
   case 207:
 
 /* Line 1455 of yacc.c  */
-#line 1961 "osm_qos_parser_y.y"
+#line 1979 "osm_qos_parser_y.y"
     {
                             /* 'pkey' in 'qos-level' - num of instances of list of ranges */
                             if (cl_list_count(&tmp_parser_struct.num_pair_list))
@@ -3835,7 +3853,7 @@ yyreduce:
   case 208:
 
 /* Line 1455 of yacc.c  */
-#line 1994 "osm_qos_parser_y.y"
+#line 2012 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3844,7 +3862,7 @@ yyreduce:
   case 209:
 
 /* Line 1455 of yacc.c  */
-#line 2011 "osm_qos_parser_y.y"
+#line 2029 "osm_qos_parser_y.y"
     {
                             /* 'use' of 'qos-match-rule' - one instance */
                             cl_list_iterator_t    list_iterator;
@@ -3871,7 +3889,7 @@ yyreduce:
   case 210:
 
 /* Line 1455 of yacc.c  */
-#line 2034 "osm_qos_parser_y.y"
+#line 2052 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3880,7 +3898,7 @@ yyreduce:
   case 211:
 
 /* Line 1455 of yacc.c  */
-#line 2039 "osm_qos_parser_y.y"
+#line 2057 "osm_qos_parser_y.y"
     {
                             /* 'qos-class' in 'qos-match-rule' - num of instances of list of ranges */
                             /* list of class ranges (QoS Class is 12-bit value) */
@@ -3918,7 +3936,7 @@ yyreduce:
   case 212:
 
 /* Line 1455 of yacc.c  */
-#line 2073 "osm_qos_parser_y.y"
+#line 2091 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3927,7 +3945,7 @@ yyreduce:
   case 213:
 
 /* Line 1455 of yacc.c  */
-#line 2078 "osm_qos_parser_y.y"
+#line 2096 "osm_qos_parser_y.y"
     {
                             /* 'source' in 'qos-match-rule' - text */
                             cl_list_iterator_t    list_iterator;
@@ -3948,7 +3966,7 @@ yyreduce:
   case 214:
 
 /* Line 1455 of yacc.c  */
-#line 2095 "osm_qos_parser_y.y"
+#line 2113 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3957,7 +3975,7 @@ yyreduce:
   case 215:
 
 /* Line 1455 of yacc.c  */
-#line 2100 "osm_qos_parser_y.y"
+#line 2118 "osm_qos_parser_y.y"
     {
                             /* 'destination' in 'qos-match-rule' - text */
                             cl_list_iterator_t    list_iterator;
@@ -3978,7 +3996,7 @@ yyreduce:
   case 216:
 
 /* Line 1455 of yacc.c  */
-#line 2117 "osm_qos_parser_y.y"
+#line 2135 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -3987,7 +4005,7 @@ yyreduce:
   case 217:
 
 /* Line 1455 of yacc.c  */
-#line 2122 "osm_qos_parser_y.y"
+#line 2140 "osm_qos_parser_y.y"
     {
                             /* 'qos-level-name' in 'qos-match-rule' - single string */
                             cl_list_iterator_t   list_iterator;
@@ -4014,7 +4032,7 @@ yyreduce:
   case 218:
 
 /* Line 1455 of yacc.c  */
-#line 2145 "osm_qos_parser_y.y"
+#line 2163 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -4023,7 +4041,7 @@ yyreduce:
   case 219:
 
 /* Line 1455 of yacc.c  */
-#line 2150 "osm_qos_parser_y.y"
+#line 2168 "osm_qos_parser_y.y"
     {
                             /* 'service-id' in 'qos-match-rule' - num of instances of list of ranges */
                             if (cl_list_count(&tmp_parser_struct.num_pair_list))
@@ -4060,7 +4078,7 @@ yyreduce:
   case 220:
 
 /* Line 1455 of yacc.c  */
-#line 2183 "osm_qos_parser_y.y"
+#line 2201 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -4069,7 +4087,7 @@ yyreduce:
   case 221:
 
 /* Line 1455 of yacc.c  */
-#line 2188 "osm_qos_parser_y.y"
+#line 2206 "osm_qos_parser_y.y"
     {
                             /* 'pkey' in 'qos-match-rule' - num of instances of list of ranges */
                             if (cl_list_count(&tmp_parser_struct.num_pair_list))
@@ -4106,7 +4124,7 @@ yyreduce:
   case 222:
 
 /* Line 1455 of yacc.c  */
-#line 2221 "osm_qos_parser_y.y"
+#line 2239 "osm_qos_parser_y.y"
     {
                             RESET_BUFFER;
                         }
@@ -4115,7 +4133,7 @@ yyreduce:
   case 223:
 
 /* Line 1455 of yacc.c  */
-#line 2232 "osm_qos_parser_y.y"
+#line 2250 "osm_qos_parser_y.y"
     {
                         cl_list_insert_tail(&tmp_parser_struct.str_list,
                                             strdup(__parser_strip_white(tmp_parser_struct.str)));
@@ -4126,7 +4144,7 @@ yyreduce:
   case 226:
 
 /* Line 1455 of yacc.c  */
-#line 2243 "osm_qos_parser_y.y"
+#line 2261 "osm_qos_parser_y.y"
     {
                         strcat(tmp_parser_struct.str,(yyvsp[(1) - (1)]));
                         free((yyvsp[(1) - (1)]));
@@ -4136,7 +4154,7 @@ yyreduce:
   case 232:
 
 /* Line 1455 of yacc.c  */
-#line 2263 "osm_qos_parser_y.y"
+#line 2281 "osm_qos_parser_y.y"
     {
                         uint64_t * p_num = (uint64_t*)malloc(sizeof(uint64_t));
                         __parser_str2uint64(p_num,(yyvsp[(1) - (1)]));
@@ -4148,7 +4166,7 @@ yyreduce:
   case 233:
 
 /* Line 1455 of yacc.c  */
-#line 2271 "osm_qos_parser_y.y"
+#line 2289 "osm_qos_parser_y.y"
     {
                         uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
                         num_pair[0] = tmp_parser_struct.num_pair[0];
@@ -4160,7 +4178,7 @@ yyreduce:
   case 234:
 
 /* Line 1455 of yacc.c  */
-#line 2277 "osm_qos_parser_y.y"
+#line 2295 "osm_qos_parser_y.y"
     {
                         uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
                         num_pair[0] = tmp_parser_struct.num_pair[0];
@@ -4172,7 +4190,7 @@ yyreduce:
   case 235:
 
 /* Line 1455 of yacc.c  */
-#line 2285 "osm_qos_parser_y.y"
+#line 2303 "osm_qos_parser_y.y"
     {
                         __parser_str2uint64(&tmp_parser_struct.num_pair[0],(yyvsp[(1) - (1)]));
                         free((yyvsp[(1) - (1)]));
@@ -4182,7 +4200,7 @@ yyreduce:
   case 236:
 
 /* Line 1455 of yacc.c  */
-#line 2291 "osm_qos_parser_y.y"
+#line 2309 "osm_qos_parser_y.y"
     {
                         __parser_str2uint64(&tmp_parser_struct.num_pair[1],(yyvsp[(1) - (1)]));
                         free((yyvsp[(1) - (1)]));
@@ -4192,7 +4210,7 @@ yyreduce:
   case 238:
 
 /* Line 1455 of yacc.c  */
-#line 2300 "osm_qos_parser_y.y"
+#line 2318 "osm_qos_parser_y.y"
     {
                         uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
                         num_pair[0] = tmp_parser_struct.num_pair[0];
@@ -4204,7 +4222,7 @@ yyreduce:
   case 239:
 
 /* Line 1455 of yacc.c  */
-#line 2306 "osm_qos_parser_y.y"
+#line 2324 "osm_qos_parser_y.y"
     {
                         uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
                         if (tmp_parser_struct.num_pair[0] <= tmp_parser_struct.num_pair[1]) {
@@ -4222,7 +4240,7 @@ yyreduce:
   case 240:
 
 /* Line 1455 of yacc.c  */
-#line 2318 "osm_qos_parser_y.y"
+#line 2336 "osm_qos_parser_y.y"
     {
                         uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
                         if (tmp_parser_struct.num_pair[0] <= tmp_parser_struct.num_pair[1]) {
@@ -4240,7 +4258,7 @@ yyreduce:
   case 241:
 
 /* Line 1455 of yacc.c  */
-#line 2330 "osm_qos_parser_y.y"
+#line 2348 "osm_qos_parser_y.y"
     {
                         uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
                         num_pair[0] = tmp_parser_struct.num_pair[0];
@@ -4252,7 +4270,7 @@ yyreduce:
   case 242:
 
 /* Line 1455 of yacc.c  */
-#line 2338 "osm_qos_parser_y.y"
+#line 2356 "osm_qos_parser_y.y"
     {
                         __parser_str2uint64(&tmp_parser_struct.num_pair[0],(yyvsp[(1) - (1)]));
                         __parser_str2uint64(&tmp_parser_struct.num_pair[1],(yyvsp[(1) - (1)]));
@@ -4263,7 +4281,7 @@ yyreduce:
   case 243:
 
 /* Line 1455 of yacc.c  */
-#line 2345 "osm_qos_parser_y.y"
+#line 2363 "osm_qos_parser_y.y"
     {
                         __parser_str2uint64(&tmp_parser_struct.num_pair[0],(yyvsp[(1) - (1)]));
                         free((yyvsp[(1) - (1)]));
@@ -4273,7 +4291,7 @@ yyreduce:
   case 244:
 
 /* Line 1455 of yacc.c  */
-#line 2351 "osm_qos_parser_y.y"
+#line 2369 "osm_qos_parser_y.y"
     {
                         __parser_str2uint64(&tmp_parser_struct.num_pair[1],(yyvsp[(1) - (1)]));
                         free((yyvsp[(1) - (1)]));
@@ -4283,7 +4301,7 @@ yyreduce:
 
 
 /* Line 1455 of yacc.c  */
-#line 4287 "osm_qos_parser_y.c"
+#line 4305 "osm_qos_parser_y.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -4495,7 +4513,7 @@ yyreturn:
 
 
 /* Line 1675 of yacc.c  */
-#line 2357 "osm_qos_parser_y.y"
+#line 2375 "osm_qos_parser_y.y"
 
 
 /***************************************************
diff --git a/opensm/osm_qos_parser_y.y b/opensm/osm_qos_parser_y.y
index 0b567c8..e0f6580 100644
--- a/opensm/osm_qos_parser_y.y
+++ b/opensm/osm_qos_parser_y.y
@@ -61,6 +61,10 @@
 #define OSM_QOS_POLICY_MAX_LINE_LEN         1024*10
 #define OSM_QOS_POLICY_SL2VL_TABLE_LEN      IB_MAX_NUM_VLS
 #define OSM_QOS_POLICY_MAX_VL_NUM           IB_MAX_NUM_VLS
+#define OSM_QOS_POLICY_MAX_RATE             IB_MAX_RATE
+#define OSM_QOS_POLICY_MIN_RATE             IB_MIN_RATE
+#define OSM_QOS_POLICY_MAX_MTU              IB_MAX_MTU
+#define OSM_QOS_POLICY_MIN_MTU              IB_MIN_MTU
 
 typedef struct tmp_parser_struct_t_ {
     char       str[OSM_QOS_POLICY_MAX_LINE_LEN];
@@ -1853,6 +1857,13 @@ qos_level_mtu_limit:    qos_level_mtu_limit_start single_number {
                             }
                             list_iterator = cl_list_head(&tmp_parser_struct.num_list);
                             p_num = (uint64_t*)cl_list_obj(list_iterator);
+                            if (*p_num > OSM_QOS_POLICY_MAX_MTU || *p_num < OSM_QOS_POLICY_MIN_MTU)
+                            {
+                                yyerror("mtu limit is out of range, value: %d", *p_num);
+                                free(p_num);
+                                cl_list_remove_all(&tmp_parser_struct.num_list);
+                                return 1;
+                            }
                             p_current_qos_level->mtu_limit = (uint8_t)(*p_num);
                             free(p_num);
                             p_current_qos_level->mtu_limit_set = TRUE;
@@ -1879,6 +1890,13 @@ qos_level_rate_limit:    qos_level_rate_limit_start single_number {
                             }
                             list_iterator = cl_list_head(&tmp_parser_struct.num_list);
                             p_num = (uint64_t*)cl_list_obj(list_iterator);
+                            if (*p_num > OSM_QOS_POLICY_MAX_RATE || *p_num < OSM_QOS_POLICY_MIN_RATE)
+                            {
+                                yyerror("rate limit is out of range, value: %d", *p_num);
+                                free(p_num);
+                                cl_list_remove_all(&tmp_parser_struct.num_list);
+                                return 1;
+                            }
                             p_current_qos_level->rate_limit = (uint8_t)(*p_num);
                             free(p_num);
                             p_current_qos_level->rate_limit_set = TRUE;
diff --git a/opensm/osm_sa.c b/opensm/osm_sa.c
index ea4a4d0..e3128c7 100644
--- a/opensm/osm_sa.c
+++ b/opensm/osm_sa.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2012 Mellanox Technologies LTD. All rights reserved.
+ * Copyright (c) 2002-2014 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  * Copyright (c) 2008 Xsigo Systems Inc.  All rights reserved.
  *
@@ -782,8 +782,7 @@ int osm_sa_db_file_dump(osm_opensm_t * p_osm)
  *  SA DB Loader
  */
 static osm_mgrp_t *load_mcgroup(osm_opensm_t * p_osm, ib_net16_t mlid,
-				ib_member_rec_t * p_mcm_rec,
-				unsigned well_known)
+				ib_member_rec_t * p_mcm_rec)
 {
 	ib_net64_t comp_mask;
 	osm_mgrp_t *p_mgrp;
@@ -816,8 +815,7 @@ static osm_mgrp_t *load_mcgroup(osm_opensm_t * p_osm, ib_net16_t mlid,
 			cl_ntoh64(p_mcm_rec->mgid.unicast.prefix),
 			cl_ntoh64(p_mcm_rec->mgid.unicast.interface_id));
 		p_mgrp = NULL;
-	} else if (well_known)
-		p_mgrp->well_known = TRUE;
+	}
 
 _out:
 	cl_plock_release(&p_osm->lock);
@@ -1039,13 +1037,29 @@ static int unpack_string64(char *p, uint8_t * buf)
 	p += _ret; \
 }
 
+static void sa_db_file_load_handle_mgrp(osm_opensm_t * p_osm,
+					osm_mgrp_t * p_mgrp)
+{
+	/* decide whether to delete the mgrp object or not */
+	if (p_mgrp->full_members == 0 && !p_mgrp->well_known) {
+		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
+			"Closing MC group 0x%016" PRIx64 ":0x%016" PRIx64
+			" - no full members were added to not well known "
+			"group\n",
+			cl_ntoh64(p_mgrp->mcmember_rec.mgid.unicast.prefix),
+			cl_ntoh64(p_mgrp->mcmember_rec.mgid.unicast.interface_id));
+		osm_mgrp_cleanup(&p_osm->subn, p_mgrp);
+	}
+}
+
 int osm_sa_db_file_load(osm_opensm_t * p_osm)
 {
 	char line[1024];
 	char *file_name;
 	FILE *file;
 	int ret = 0;
-	osm_mgrp_t *p_mgrp = NULL;
+	osm_mgrp_t *p_next_mgrp = NULL;
+	osm_mgrp_t *p_prev_mgrp = NULL;
 	unsigned rereg_clients = 0;
 	unsigned lineno;
 
@@ -1092,14 +1106,11 @@ int osm_sa_db_file_load(osm_opensm_t * p_osm)
 		if (!strncmp(p, "MC Group", 8)) {
 			ib_member_rec_t mcm_rec;
 			ib_net16_t mlid;
-			unsigned well_known = 0;
 
-			p_mgrp = NULL;
+			p_next_mgrp = NULL;
 			memset(&mcm_rec, 0, sizeof(mcm_rec));
 
 			PARSE_AHEAD(p, net16, " 0x", &mlid);
-			if (strstr(p, "well known"))
-				well_known = 1;
 			PARSE_AHEAD(p, net64, " mgid=0x",
 				    &mcm_rec.mgid.unicast.prefix);
 			PARSE_AHEAD(p, net64, ":0x",
@@ -1122,13 +1133,12 @@ int osm_sa_db_file_load(osm_opensm_t * p_osm)
 			PARSE_AHEAD(p, net8, " proxy_join=0x", &val);
 			mcm_rec.proxy_join = val;
 
-			p_mgrp = load_mcgroup(p_osm, mlid, &mcm_rec,
-					      well_known);
-			if (!p_mgrp)
+			p_next_mgrp = load_mcgroup(p_osm, mlid, &mcm_rec);
+			if (!p_next_mgrp)
 				rereg_clients = 1;
 			if (cl_ntoh16(mlid) > p_osm->sm.mlids_init_max)
 				p_osm->sm.mlids_init_max = cl_ntoh16(mlid);
-		} else if (p_mgrp && !strncmp(p, "mcm_port", 8)) {
+		} else if (p_next_mgrp && !strncmp(p, "mcm_port", 8)) {
 			ib_member_rec_t mcmr;
 			ib_net64_t guid;
 			osm_port_t *port;
@@ -1145,16 +1155,16 @@ int osm_sa_db_file_load(osm_opensm_t * p_osm)
 			guid = mcmr.port_gid.unicast.interface_id;
 			port = osm_get_port_by_alias_guid(&p_osm->subn, guid);
 			if (port &&
-			    cl_qmap_get(&p_mgrp->mcm_port_tbl, guid) ==
-			    cl_qmap_end(&p_mgrp->mcm_port_tbl) &&
+			    cl_qmap_get(&p_next_mgrp->mcm_port_tbl, guid) ==
+			    cl_qmap_end(&p_next_mgrp->mcm_port_tbl) &&
 			    !osm_mgrp_add_port(&p_osm->subn, &p_osm->log,
-						p_mgrp, port, &mcmr, proxy))
+						p_next_mgrp, port, &mcmr, proxy))
 				rereg_clients = 1;
 		} else if (!strncmp(p, "Service Record:", 15)) {
 			ib_service_record_t s_rec;
 			uint32_t modified_time, lease_period;
 
-			p_mgrp = NULL;
+			p_next_mgrp = NULL;
 			memset(&s_rec, 0, sizeof(s_rec));
 
 			PARSE_AHEAD(p, net64, " id=0x", &s_rec.service_id);
@@ -1198,7 +1208,7 @@ int osm_sa_db_file_load(osm_opensm_t * p_osm)
 			osm_mad_addr_t rep_addr;
 			ib_net16_t val16;
 
-			p_mgrp = NULL;
+			p_next_mgrp = NULL;
 			memset(&i_rec, 0, sizeof(i_rec));
 			memset(&rep_addr, 0, sizeof(rep_addr));
 
@@ -1253,7 +1263,7 @@ int osm_sa_db_file_load(osm_opensm_t * p_osm)
 			ib_guidinfo_record_t gi_rec;
 			ib_net64_t base_guid;
 
-			p_mgrp = NULL;
+			p_next_mgrp = NULL;
 			memset(&gi_rec, 0, sizeof(gi_rec));
 
 			PARSE_AHEAD(p, net64, " base_guid=0x", &base_guid);
@@ -1280,8 +1290,25 @@ int osm_sa_db_file_load(osm_opensm_t * p_osm)
 			if (load_guidinfo(p_osm, base_guid, &gi_rec))
 				rereg_clients = 1;
 		}
+
+		/*
+		 * p_next_mgrp points to the multicast group now being parsed.
+		 * p_prev_mgrp points to the last multicast group we parsed.
+		 * We decide whether to keep or delete each multicast group
+		 * only when we finish parsing it's member records. if the
+		 * group has full members, or it is a "well known group" we
+		 * keep it.
+		 */
+		if (p_prev_mgrp != p_next_mgrp) {
+			if (p_prev_mgrp)
+				sa_db_file_load_handle_mgrp(p_osm, p_prev_mgrp);
+			p_prev_mgrp = p_next_mgrp;
+		}
 	}
 
+	if (p_next_mgrp)
+		sa_db_file_load_handle_mgrp(p_osm, p_prev_mgrp);
+
 	/*
 	 * If loading succeeded, do whatever 'no_clients_rereg' says.
 	 * If loading failed at some point, turn off the 'no_clients_rereg'
diff --git a/opensm/osm_sa_guidinfo_record.c b/opensm/osm_sa_guidinfo_record.c
index 28f6c0f..d96db54 100644
--- a/opensm/osm_sa_guidinfo_record.c
+++ b/opensm/osm_sa_guidinfo_record.c
@@ -396,11 +396,12 @@ static void del_guidinfo(IN osm_sa_t *sa, IN osm_madw_t *p_madw,
 	max_block = (p_port->p_physp->port_info.guid_cap + GUID_TABLE_MAX_ENTRIES - 1) /
 		     GUID_TABLE_MAX_ENTRIES;
 
-	if (block_num > max_block) {
+	if (block_num >= max_block) {
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 5116: "
 			"block_num %d is higher than Max GUID Cap block %d "
 			"for port GUID 0x%" PRIx64 "\n",
 			block_num, max_block, cl_ntoh64(p_port->p_physp->port_guid));
+		CL_PLOCK_RELEASE(sa->p_lock);
 		osm_sa_send_error(sa, p_madw,
 				  IB_SA_MAD_STATUS_NO_RECORDS);
 		return;
@@ -417,6 +418,7 @@ static void del_guidinfo(IN osm_sa_t *sa, IN osm_madw_t *p_madw,
 	     i++) {
 		/* can't delete block 0 index 0 (base guid is RO) for alias guid table */
 		if (i == 0 && p_sa_mad->comp_mask & IB_GIR_COMPMASK_GID0) {
+			CL_PLOCK_RELEASE(sa->p_lock);
 			OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
 				"Not allowed to delete RO GID 0\n");
 			osm_sa_send_error(sa, p_madw,
@@ -436,6 +438,7 @@ static void del_guidinfo(IN osm_sa_t *sa, IN osm_madw_t *p_madw,
 				p_list_item = cl_qlist_next(p_list_item);
 				p_mcm_alias_guid = osm_mgrp_get_mcm_alias_guid(p_mcm_port->mgrp, del_alias_guid);
 				if (p_mcm_alias_guid) {
+					CL_PLOCK_RELEASE(sa->p_lock);
 					osm_sa_send_error(sa, p_madw,
 							  IB_SA_MAD_STATUS_DENIED);
 					return;
@@ -481,6 +484,7 @@ static void del_guidinfo(IN osm_sa_t *sa, IN osm_madw_t *p_madw,
 	       sizeof(ib_guid_info_t));
 
 Exit:
+	CL_PLOCK_RELEASE(sa->p_lock);
 	gir_respond(sa, p_madw);
 }
 
@@ -499,11 +503,12 @@ static void set_guidinfo(IN osm_sa_t *sa, IN osm_madw_t *p_madw,
 
 	max_block = (p_port->p_physp->port_info.guid_cap + GUID_TABLE_MAX_ENTRIES - 1) /
 		     GUID_TABLE_MAX_ENTRIES;
-	if (block_num > max_block) {
+	if (block_num >= max_block) {
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 5118: "
 			"block_num %d is higher than Max GUID Cap block %d "
 			"for port GUID 0x%" PRIx64 "\n",
 			block_num, max_block, cl_ntoh64(p_port->p_physp->port_guid));
+		CL_PLOCK_RELEASE(sa->p_lock);
 		osm_sa_send_error(sa, p_madw,
 				  IB_SA_MAD_STATUS_NO_RECORDS);
 		return;
@@ -516,6 +521,7 @@ static void set_guidinfo(IN osm_sa_t *sa, IN osm_madw_t *p_madw,
 				"GUID table memory allocation failed for port "
 				"GUID 0x%" PRIx64 "\n",
 				cl_ntoh64(p_port->p_physp->port_guid));
+			CL_PLOCK_RELEASE(sa->p_lock);
 			osm_sa_send_error(sa, p_madw,
 					  IB_SA_MAD_STATUS_NO_RESOURCES);
 			return;
@@ -539,6 +545,7 @@ static void set_guidinfo(IN osm_sa_t *sa, IN osm_madw_t *p_madw,
 	     i++) {
 		/* can't set block 0 index 0 (base guid is RO) for alias guid table */
 		if (i == 0 && p_sa_mad->comp_mask & IB_GIR_COMPMASK_GID0) {
+			CL_PLOCK_RELEASE(sa->p_lock);
 			OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
 				"Not allowed to set RO GID 0\n");
 			osm_sa_send_error(sa, p_madw,
@@ -595,6 +602,7 @@ static void set_guidinfo(IN osm_sa_t *sa, IN osm_madw_t *p_madw,
 			for (j = 0; j < 1000; j++) {
 				assigned_guid = sm_assigned_guid(sa->p_subn->opt.sm_assigned_guid);
 				if (!assigned_guid) {
+					CL_PLOCK_RELEASE(sa->p_lock);
 					OSM_LOG(sa->p_log, OSM_LOG_ERROR,
 						"ERR 510E: No more assigned guids available\n");
 					osm_sa_send_error(sa, p_madw,
@@ -618,6 +626,7 @@ static void set_guidinfo(IN osm_sa_t *sa, IN osm_madw_t *p_madw,
 								OSM_LOG_ERROR,
 								"ERR 510D: osm_assigned_guids_new failed port GUID 0x%" PRIx64 " index %d\n",
 								cl_ntoh64(p_port->p_physp->port_guid), i);
+							CL_PLOCK_RELEASE(sa->p_lock);
 							osm_sa_send_error(sa, p_madw,
 									  IB_SA_MAD_STATUS_NO_RESOURCES);
 							return;
@@ -645,6 +654,7 @@ add_alias_guid:
 				"Alias guid %d memory allocation failed"
 				" for port GUID 0x%" PRIx64 "\n",
 				i, cl_ntoh64(p_port->p_physp->port_guid));
+			CL_PLOCK_RELEASE(sa->p_lock);
 			return;
 		}
 
@@ -702,6 +712,7 @@ add_alias_guid:
 	       &((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES]),
 	       sizeof(ib_guid_info_t));
 
+	CL_PLOCK_RELEASE(sa->p_lock);
 	gir_respond(sa, p_madw);
 }
 
@@ -725,12 +736,11 @@ static void get_guidinfo(IN osm_sa_t *sa, IN osm_madw_t *p_madw,
 	context.sa = sa;
 	context.p_req_physp = p_req_physp;
 
-	cl_plock_acquire(sa->p_lock);
 
 	cl_qmap_apply_func(&sa->p_subn->node_guid_tbl, sa_gir_by_comp_mask_cb,
 			   &context);
 
-	cl_plock_release(sa->p_lock);
+	CL_PLOCK_RELEASE(sa->p_lock);
 
 	osm_sa_respond(sa, p_madw, sizeof(ib_guidinfo_record_t), &rec_list);
 }
@@ -754,23 +764,25 @@ void osm_gir_rcv_process(IN void *ctx, IN void *data)
 
 	CL_ASSERT(p_rcvd_mad->attr_id == IB_MAD_ATTR_GUIDINFO_RECORD);
 
-	/* update the requester physical port */
-	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
-						osm_madw_get_mad_addr_ptr(p_madw));
-	if (p_req_physp == NULL) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 5104: "
-			"Cannot find requester physical port\n");
-		goto Exit;
-	}
-	OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
-		"Requester port GUID 0x%" PRIx64 "\n",
-		cl_ntoh64(osm_physp_get_port_guid(p_req_physp)));
-
 	switch(p_rcvd_mad->method) {
 	case IB_MAD_METHOD_GET:
 	case IB_MAD_METHOD_GETTABLE:
+		/* update the requester physical port */
+		CL_PLOCK_ACQUIRE(sa->p_lock);
+		p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
+							osm_madw_get_mad_addr_ptr(p_madw));
+		if (p_req_physp == NULL) {
+			CL_PLOCK_RELEASE(sa->p_lock);
+			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 5104: "
+				"Cannot find requester physical port\n");
+			goto Exit;
+		}
+		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
+			"Requester port GUID 0x%" PRIx64 "\n",
+			cl_ntoh64(osm_physp_get_port_guid(p_req_physp)));
+
 		get_guidinfo(sa, p_madw, p_req_physp);
-		break;
+		goto Exit;
 	case IB_MAD_METHOD_SET:
 	case IB_MAD_METHOD_DELETE:
 		if (!check_mod_comp_mask(p_rcvd_mad->comp_mask)) {
@@ -784,23 +796,40 @@ void osm_gir_rcv_process(IN void *ctx, IN void *data)
 			goto Exit;
 		}
 		p_rcvd_rec = (ib_guidinfo_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad);
+
+		/* update the requester physical port */
+		CL_PLOCK_EXCL_ACQUIRE(sa->p_lock);
+		p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
+							osm_madw_get_mad_addr_ptr(p_madw));
+		if (p_req_physp == NULL) {
+			CL_PLOCK_RELEASE(sa->p_lock);
+			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 5104: "
+				"Cannot find requester physical port\n");
+			goto Exit;
+		}
+		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
+			"Requester port GUID 0x%" PRIx64 "\n",
+			cl_ntoh64(osm_physp_get_port_guid(p_req_physp)));
+
 		p_port = osm_get_port_by_lid(sa->p_subn, p_rcvd_rec->lid);
 		if (!p_port) {
+			CL_PLOCK_RELEASE(sa->p_lock);
 			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 5117: "
 				"Port with LID %u not found\n",
 				cl_ntoh16(p_rcvd_rec->lid));
-			osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
+				osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
 			goto Exit;
 		}
 		if (!osm_physp_share_pkey(sa->p_log, p_req_physp, p_port->p_physp,
-					  sa->p_subn->opt.allow_both_pkeys))
+					  sa->p_subn->opt.allow_both_pkeys)) {
+			CL_PLOCK_RELEASE(sa->p_lock);
 			goto Exit;
-		CL_PLOCK_EXCL_ACQUIRE(sa->p_lock);
+		}
+
 		if (p_rcvd_mad->method == IB_MAD_METHOD_SET)
 			set_guidinfo(sa, p_madw, p_port, p_rcvd_rec->block_num);
 		else
 			del_guidinfo(sa, p_madw, p_port, p_rcvd_rec->block_num);
-		CL_PLOCK_RELEASE(sa->p_lock);
 		break;
 	default:
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 5105: "
diff --git a/opensm/osm_sa_informinfo.c b/opensm/osm_sa_informinfo.c
index 5543c9a..92855bf 100644
--- a/opensm/osm_sa_informinfo.c
+++ b/opensm/osm_sa_informinfo.c
@@ -338,11 +338,14 @@ static void infr_rcv_process_get_method(osm_sa_t * sa, IN osm_madw_t * p_madw)
 	p_rcvd_rec =
 	    (ib_inform_info_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad);
 
+	cl_plock_acquire(sa->p_lock);
+
 	/* update the requester physical port */
 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
 						osm_madw_get_mad_addr_ptr
 						(p_madw));
 	if (p_req_physp == NULL) {
+		cl_plock_release(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4309: "
 			"Cannot find requester physical port\n");
 		goto Exit;
@@ -375,13 +378,9 @@ static void infr_rcv_process_get_method(osm_sa_t * sa, IN osm_madw_t * p_madw)
 		cl_ntoh16(p_rcvd_rec->subscriber_enum),
 		(p_rcvd_mad->comp_mask & IB_IIR_COMPMASK_ENUM) != 0);
 
-	cl_plock_acquire(sa->p_lock);
-
 	cl_qlist_apply_func(&sa->p_subn->sa_infr_list,
 			    sa_inform_info_rec_by_comp_mask_cb, &context);
 
-	cl_plock_release(sa->p_lock);
-
 	/* clear reserved and pad fields in InformInfoRecord */
 	for (item = (osm_sa_item_t *) cl_qlist_head(&rec_list);
 	     item != (osm_sa_item_t *) cl_qlist_end(&rec_list);
@@ -390,6 +389,8 @@ static void infr_rcv_process_get_method(osm_sa_t * sa, IN osm_madw_t * p_madw)
 		memset(item->resp.inform_rec.pad, 0, sizeof(item->resp.inform_rec.pad));
 	}
 
+	cl_plock_release(sa->p_lock);
+
 	osm_sa_respond(sa, p_madw, sizeof(ib_inform_info_record_t), &rec_list);
 
 Exit:
diff --git a/opensm/osm_sa_lft_record.c b/opensm/osm_sa_lft_record.c
index cf651ef..8f4749e 100644
--- a/opensm/osm_sa_lft_record.c
+++ b/opensm/osm_sa_lft_record.c
@@ -204,11 +204,14 @@ void osm_lftr_rcv_process(IN void *ctx, IN void *data)
 		goto Exit;
 	}
 
+	cl_plock_acquire(sa->p_lock);
+
 	/* update the requester physical port */
 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
 						osm_madw_get_mad_addr_ptr
 						(p_madw));
 	if (p_req_physp == NULL) {
+		cl_plock_release(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4407: "
 			"Cannot find requester physical port\n");
 		goto Exit;
@@ -226,8 +229,6 @@ void osm_lftr_rcv_process(IN void *ctx, IN void *data)
 	context.sa = sa;
 	context.p_req_physp = p_req_physp;
 
-	cl_plock_acquire(sa->p_lock);
-
 	/* Go over all switches */
 	cl_qmap_apply_func(&sa->p_subn->sw_guid_tbl, lftr_rcv_by_comp_mask,
 			   &context);
diff --git a/opensm/osm_sa_link_record.c b/opensm/osm_sa_link_record.c
index 5073f96..5ab3d74 100644
--- a/opensm/osm_sa_link_record.c
+++ b/opensm/osm_sa_link_record.c
@@ -443,11 +443,14 @@ void osm_lr_rcv_process(IN void *context, IN void *data)
 		goto Exit;
 	}
 
+	cl_plock_acquire(sa->p_lock);
+
 	/* update the requester physical port */
 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
 						osm_madw_get_mad_addr_ptr
 						(p_madw));
 	if (p_req_physp == NULL) {
+		cl_plock_release(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1805: "
 			"Cannot find requester physical port\n");
 		goto Exit;
@@ -466,8 +469,6 @@ void osm_lr_rcv_process(IN void *context, IN void *data)
 	   Most SA functions (including this one) are read-only on the
 	   subnet object, so we grab the lock non-exclusively.
 	 */
-	cl_plock_acquire(sa->p_lock);
-
 	status = lr_rcv_get_end_points(sa, p_madw, &p_src_port, &p_dest_port);
 
 	if (status == IB_SA_MAD_STATUS_SUCCESS)
diff --git a/opensm/osm_sa_mad_ctrl.c b/opensm/osm_sa_mad_ctrl.c
index 902803e..c21f7d1 100644
--- a/opensm/osm_sa_mad_ctrl.c
+++ b/opensm/osm_sa_mad_ctrl.c
@@ -217,8 +217,9 @@ static void sa_mad_ctrl_process(IN osm_sa_mad_ctrl_t * p_ctrl,
 
 	default:
 		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A01: "
-			"Unsupported attribute 0x%X\n",
-			cl_ntoh16(p_sa_mad->attr_id));
+			"Unsupported attribute 0x%X (%s)\n",
+			cl_ntoh16(p_sa_mad->attr_id),
+			ib_get_sa_attr_str(p_sa_mad->attr_id));
 		osm_dump_sa_mad_v2(p_ctrl->p_log, p_sa_mad, FILE_ID, OSM_LOG_ERROR);
 	}
 
@@ -331,9 +332,12 @@ static void sa_mad_ctrl_rcv_callback(IN osm_madw_t * p_madw, IN void *context,
 	if (p_sa_mad->sm_key != 0 &&
 	    p_sa_mad->sm_key != p_ctrl->p_subn->opt.sa_key) {
 		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 1A04: "
-			"Non-Zero SA MAD SM_Key: 0x%" PRIx64 " != SM_Key: 0x%"
-			PRIx64 "; MAD ignored\n", cl_ntoh64(p_sa_mad->sm_key),
-			cl_ntoh64(p_ctrl->p_subn->opt.sa_key));
+			"Non-Zero MAD SM_Key: 0x%" PRIx64 " != SM_Key: 0x%"
+			PRIx64 "; SA MAD ignored for method 0x%X attribute 0x%X (%s)\n",
+			cl_ntoh64(p_sa_mad->sm_key),
+			cl_ntoh64(p_ctrl->p_subn->opt.sa_key),
+			p_sa_mad->method, cl_ntoh16(p_sa_mad->attr_id),
+			ib_get_sa_attr_str(p_sa_mad->attr_id));
 		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
 		goto Exit;
 	}
diff --git a/opensm/osm_sa_mcmember_record.c b/opensm/osm_sa_mcmember_record.c
index ad6d5cd..7e18e46 100644
--- a/opensm/osm_sa_mcmember_record.c
+++ b/opensm/osm_sa_mcmember_record.c
@@ -334,6 +334,7 @@ static boolean_t validate_port_caps(osm_log_t * p_log,
 	uint8_t mtu_mgrp;
 	uint8_t rate_required;
 	uint8_t rate_mgrp;
+	int extended;
 
 	mtu_required = ib_port_info_get_mtu_cap(&p_physp->port_info);
 	mtu_mgrp = (uint8_t) (p_mgrp->mcmember_rec.mtu & 0x3F);
@@ -345,8 +346,8 @@ static boolean_t validate_port_caps(osm_log_t * p_log,
 	}
 
 	p_pi = &p_physp->port_info;
-	rate_required = ib_port_info_compute_rate(p_pi,
-						  p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS);
+	extended = p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS;
+	rate_required = ib_port_info_compute_rate(p_pi, extended);
 	rate_mgrp = (uint8_t) (p_mgrp->mcmember_rec.rate & 0x3F);
 	if (ib_path_compare_rates(rate_required, rate_mgrp) < 0) {
 		OSM_LOG(p_log, OSM_LOG_VERBOSE,
@@ -652,6 +653,7 @@ static boolean_t mgrp_request_is_realizable(IN osm_sa_t * sa,
 	uint8_t rate_required, rate, port_rate;
 	const ib_port_info_t *p_pi;
 	osm_log_t *p_log = sa->p_log;
+	int extended;
 
 	OSM_LOG_ENTER(sa->p_log);
 
@@ -715,9 +717,12 @@ static boolean_t mgrp_request_is_realizable(IN osm_sa_t * sa,
 	}
 	p_mcm_rec->mtu = (mtu_sel << 6) | mtu;
 
-	port_rate =
-	    p_physp ? ib_port_info_compute_rate(p_pi,
-						p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS) : 0;
+	if (p_physp) {
+		extended = p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS;
+		port_rate = ib_port_info_compute_rate(p_pi, extended);
+	} else
+		port_rate = 0;
+
 	if (!(comp_mask & IB_MCR_COMPMASK_RATE)
 	    || !(comp_mask & IB_MCR_COMPMASK_RATE_SEL)
 	    || (rate_sel = (p_mcm_rec->rate >> 6)) == 3)
@@ -931,6 +936,8 @@ static void mcmr_rcv_leave_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 		goto Exit;
 	}
 
+	CL_PLOCK_EXCL_ACQUIRE(sa->p_lock);
+
 	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) {
 		osm_physp_t *p_req_physp;
 
@@ -948,7 +955,6 @@ static void mcmr_rcv_leave_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 		osm_dump_mc_record_v2(sa->p_log, &mcmember_rec, FILE_ID, OSM_LOG_DEBUG);
 	}
 
-	CL_PLOCK_EXCL_ACQUIRE(sa->p_lock);
 	p_mgrp = osm_get_mgrp_by_mgid(sa->p_subn, &p_recvd_mcmember_rec->mgid);
 	if (!p_mgrp) {
 		char gid_str[INET6_ADDRSTRLEN];
@@ -1030,6 +1036,8 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 		goto Exit;
 	}
 
+	CL_PLOCK_EXCL_ACQUIRE(sa->p_lock);
+
 	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) {
 		osm_physp_t *p_req_physp;
 
@@ -1047,8 +1055,6 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 		osm_dump_mc_record_v2(sa->p_log, &mcmember_rec, FILE_ID, OSM_LOG_DEBUG);
 	}
 
-	CL_PLOCK_EXCL_ACQUIRE(sa->p_lock);
-
 	/* make sure the requested port guid is known to the SM */
 	p_port = osm_get_port_by_alias_guid(sa->p_subn, portguid);
 	if (!p_port) {
@@ -1177,7 +1183,8 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 	    || !(join_state != 0)) {
 		char gid_str[INET6_ADDRSTRLEN];
 		/* since we might have created the new group we need to cleanup */
-		osm_mgrp_cleanup(sa->p_subn, p_mgrp);
+		if (is_new_group)
+			osm_mgrp_cleanup(sa->p_subn, p_mgrp);
 		CL_PLOCK_RELEASE(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B12: "
 			"validate_more_comp_fields, validate_port_caps, "
@@ -1214,7 +1221,8 @@ static void mcmr_rcv_join_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 					&mcmember_rec, proxy);
 	if (!p_mcmr_port) {
 		/* we fail to add the port so we might need to delete the group */
-		osm_mgrp_cleanup(sa->p_subn, p_mgrp);
+		if (is_new_group)
+			osm_mgrp_cleanup(sa->p_subn, p_mgrp);
 		CL_PLOCK_RELEASE(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B06: "
 			"osm_mgrp_add_port failed\n");
@@ -1254,7 +1262,7 @@ static ib_api_status_t mcmr_rcv_new_mcmr(IN osm_sa_t * sa,
 		goto Exit;
 	}
 
-	memset(p_rec_item, 0, SA_MCM_RESP_SIZE);
+	memset(p_rec_item, 0, sizeof(cl_list_item_t));
 
 	/* HACK: Untrusted requesters should result with 0 Join
 	   State, Port Guid, and Proxy */
@@ -1449,11 +1457,14 @@ static void mcmr_query_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 	 */
 	trusted_req = (p_rcvd_mad->sm_key != 0);
 
+	CL_PLOCK_ACQUIRE(sa->p_lock);
+
 	/* update the requester physical port */
 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
 						osm_madw_get_mad_addr_ptr
 						(p_madw));
 	if (p_req_physp == NULL) {
+		CL_PLOCK_RELEASE(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1B04: "
 			"Cannot find requester physical port\n");
 		goto Exit;
@@ -1469,8 +1480,6 @@ static void mcmr_query_mgrp(IN osm_sa_t * sa, IN osm_madw_t * p_madw)
 
 	cl_qlist_init(&rec_list);
 
-	CL_PLOCK_ACQUIRE(sa->p_lock);
-
 	/* simply go over all MCGs and match */
 	for (p_mgrp = (osm_mgrp_t *) cl_fmap_head(&sa->p_subn->mgrp_mgid_tbl);
 	     p_mgrp != (osm_mgrp_t *) cl_fmap_end(&sa->p_subn->mgrp_mgid_tbl);
diff --git a/opensm/osm_sa_mft_record.c b/opensm/osm_sa_mft_record.c
index 6f9763f..3f9b14a 100644
--- a/opensm/osm_sa_mft_record.c
+++ b/opensm/osm_sa_mft_record.c
@@ -237,11 +237,14 @@ void osm_mftr_rcv_process(IN void *ctx, IN void *data)
 		goto Exit;
 	}
 
+	cl_plock_acquire(sa->p_lock);
+
 	/* update the requester physical port */
 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
 						osm_madw_get_mad_addr_ptr
 						(p_madw));
 	if (p_req_physp == NULL) {
+		cl_plock_release(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4A07: "
 			"Cannot find requester physical port\n");
 		goto Exit;
@@ -258,8 +261,6 @@ void osm_mftr_rcv_process(IN void *ctx, IN void *data)
 	context.sa = sa;
 	context.p_req_physp = p_req_physp;
 
-	cl_plock_acquire(sa->p_lock);
-
 	/* Go over all switches */
 	cl_qmap_apply_func(&sa->p_subn->sw_guid_tbl, mftr_rcv_by_comp_mask,
 			   &context);
diff --git a/opensm/osm_sa_multipath_record.c b/opensm/osm_sa_multipath_record.c
index 9030278..e63a489 100644
--- a/opensm/osm_sa_multipath_record.c
+++ b/opensm/osm_sa_multipath_record.c
@@ -152,7 +152,7 @@ static ib_api_status_t mpr_rcv_get_path_parms(IN osm_sa_t * sa,
 	ib_slvl_table_t *p_slvl_tbl;
 	ib_api_status_t status = IB_SUCCESS;
 	uint8_t mtu;
-	uint8_t rate;
+	uint8_t rate, p0_extended_rate, dest_rate;
 	uint8_t pkt_life;
 	uint8_t required_mtu;
 	uint8_t required_rate;
@@ -165,6 +165,7 @@ static ib_api_status_t mpr_rcv_get_path_parms(IN osm_sa_t * sa,
 	uint8_t i;
 	osm_qos_level_t *p_qos_level = NULL;
 	uint16_t valid_sl_mask = 0xffff;
+	int extended, p0_extended;
 
 	OSM_LOG_ENTER(sa->p_log);
 
@@ -176,8 +177,8 @@ static ib_api_status_t mpr_rcv_get_path_parms(IN osm_sa_t * sa,
 	p_pi = &p_physp->port_info;
 
 	mtu = ib_port_info_get_mtu_cap(p_pi);
-	rate = ib_port_info_compute_rate(p_pi,
-					 p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS);
+	extended = p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS;
+	rate = ib_port_info_compute_rate(p_pi, extended);
 
 	/*
 	   Mellanox Tavor device performance is better using 1K MTU.
@@ -353,11 +354,10 @@ static ib_api_status_t mpr_rcv_get_path_parms(IN osm_sa_t * sa,
 
 		p_physp0 = osm_node_get_physp_ptr((osm_node_t *)p_node, 0);
 		p_pi0 = &p_physp0->port_info;
-		if (ib_path_compare_rates(rate,
-					  ib_port_info_compute_rate(p_pi,
-								    p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS)) > 0)
-			rate = ib_port_info_compute_rate(p_pi,
-							 p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS);
+		p0_extended = p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS;
+		p0_extended_rate = ib_port_info_compute_rate(p_pi, p0_extended);
+		if (ib_path_compare_rates(rate, p0_extended_rate) > 0)
+			rate = p0_extended_rate;
 
 		/*
 		   Continue with the egress port on this switch.
@@ -381,11 +381,10 @@ static ib_api_status_t mpr_rcv_get_path_parms(IN osm_sa_t * sa,
 
 		p_physp0 = osm_node_get_physp_ptr((osm_node_t *)p_node, 0);
 		p_pi0 = &p_physp0->port_info;
-		if (ib_path_compare_rates(rate,
-					  ib_port_info_compute_rate(p_pi,
-								    p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS)) > 0)
-			rate = ib_port_info_compute_rate(p_pi,
-							 p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS);
+		p0_extended = p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS;
+		p0_extended_rate = ib_port_info_compute_rate(p_pi, p0_extended);
+		if (ib_path_compare_rates(rate, p0_extended_rate) > 0)
+			rate = p0_extended_rate;
 
 		if (sa->p_subn->opt.qos) {
 			/*
@@ -417,11 +416,10 @@ static ib_api_status_t mpr_rcv_get_path_parms(IN osm_sa_t * sa,
 	if (mtu > ib_port_info_get_mtu_cap(p_pi))
 		mtu = ib_port_info_get_mtu_cap(p_pi);
 
-	if (ib_path_compare_rates(rate,
-				  ib_port_info_compute_rate(p_pi,
-							    p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS)) > 0)
-		rate = ib_port_info_compute_rate(p_pi,
-						 p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS);
+	extended = p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS;
+	dest_rate = ib_port_info_compute_rate(p_pi, extended);
+	if (ib_path_compare_rates(rate, dest_rate) > 0)
+		rate = dest_rate;
 
 	OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
 		"Path min MTU = %u, min rate = %u\n", mtu, rate);
@@ -1568,22 +1566,8 @@ void osm_mpr_rcv_process(IN void *context, IN void *data)
 		goto Exit;
 	}
 
-	/* update the requester physical port */
-	requester_port = osm_get_port_by_mad_addr(sa->p_log, sa->p_subn,
-						  osm_madw_get_mad_addr_ptr
-						  (p_madw));
-	if (requester_port == NULL) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4517: "
-			"Cannot find requester physical port\n");
-		goto Exit;
-	}
-
-	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) {
-		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
-			"Requester port GUID 0x%" PRIx64 "\n",
-			cl_ntoh64(osm_port_get_guid(requester_port)));
+	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG))
 		osm_dump_multipath_record_v2(sa->p_log, p_mpr, FILE_ID, OSM_LOG_DEBUG);
-	}
 
 	/* Make sure required components (S/DGIDCount) are supplied */
 	if (!(p_sa_mad->comp_mask & IB_MPR_COMPMASK_SGIDCOUNT) ||
@@ -1629,15 +1613,30 @@ void osm_mpr_rcv_process(IN void *context, IN void *data)
 	 */
 	cl_plock_acquire(sa->p_lock);
 
+	/* update the requester physical port */
+	requester_port = osm_get_port_by_mad_addr(sa->p_log, sa->p_subn,
+						  osm_madw_get_mad_addr_ptr
+						  (p_madw));
+	if (requester_port == NULL) {
+		cl_plock_release(sa->p_lock);
+		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4517: "
+			"Cannot find requester physical port\n");
+		goto Exit;
+	}
+
+	OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
+		"Requester port GUID 0x%" PRIx64 "\n",
+		cl_ntoh64(osm_port_get_guid(requester_port)));
+
 	sa_status = mpr_rcv_get_end_points(sa, p_madw, pp_alias_guids,
 					   &nsrc, &ndest);
 
 	if (sa_status != IB_SA_MAD_STATUS_SUCCESS || !nsrc || !ndest) {
+		cl_plock_release(sa->p_lock);
 		if (sa_status == IB_SA_MAD_STATUS_SUCCESS && (!nsrc || !ndest))
 			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4512: "
 				"mpr_rcv_get_end_points failed, # GIDs found; "
 				"src %d; dest %d)\n", nsrc, ndest);
-		cl_plock_release(sa->p_lock);
 		if (sa_status == IB_SA_MAD_STATUS_SUCCESS)
 			osm_sa_send_error(sa, p_madw,
 					  IB_SA_MAD_STATUS_REQ_INVALID);
diff --git a/opensm/osm_sa_node_record.c b/opensm/osm_sa_node_record.c
index 19c7cc3..0cb0ffb 100644
--- a/opensm/osm_sa_node_record.c
+++ b/opensm/osm_sa_node_record.c
@@ -312,11 +312,14 @@ void osm_nr_rcv_process(IN void *ctx, IN void *data)
 		goto Exit;
 	}
 
+	cl_plock_acquire(sa->p_lock);
+
 	/* update the requester physical port */
 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
 						osm_madw_get_mad_addr_ptr
 						(p_madw));
 	if (p_req_physp == NULL) {
+		cl_plock_release(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1D04: "
 			"Cannot find requester physical port\n");
 		goto Exit;
@@ -337,8 +340,6 @@ void osm_nr_rcv_process(IN void *ctx, IN void *data)
 	context.sa = sa;
 	context.p_req_physp = p_req_physp;
 
-	cl_plock_acquire(sa->p_lock);
-
 	cl_qmap_apply_func(&sa->p_subn->node_guid_tbl, nr_rcv_by_comp_mask,
 			   &context);
 
diff --git a/opensm/osm_sa_path_record.c b/opensm/osm_sa_path_record.c
index d9c59b8..499ed8d 100644
--- a/opensm/osm_sa_path_record.c
+++ b/opensm/osm_sa_path_record.c
@@ -162,7 +162,7 @@ static ib_api_status_t pr_rcv_get_path_parms(IN osm_sa_t * sa,
 	ib_api_status_t status = IB_SUCCESS;
 	ib_net16_t pkey;
 	uint8_t mtu;
-	uint8_t rate;
+	uint8_t rate, p0_extended_rate, dest_rate;
 	uint8_t pkt_life;
 	uint8_t required_mtu;
 	uint8_t required_rate;
@@ -175,6 +175,7 @@ static ib_api_status_t pr_rcv_get_path_parms(IN osm_sa_t * sa,
 	osm_qos_level_t *p_qos_level = NULL;
 	uint16_t valid_sl_mask = 0xffff;
 	int hops = 0;
+	int extended, p0_extended;
 
 	OSM_LOG_ENTER(sa->p_log);
 
@@ -188,8 +189,8 @@ static ib_api_status_t pr_rcv_get_path_parms(IN osm_sa_t * sa,
 	p_re = p_osm->routing_engine_used;
 
 	mtu = ib_port_info_get_mtu_cap(p_pi);
-	rate = ib_port_info_compute_rate(p_pi,
-					 p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS);
+	extended = p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS;
+	rate = ib_port_info_compute_rate(p_pi, extended);
 
 	/*
 	   Mellanox Tavor device performance is better using 1K MTU.
@@ -347,11 +348,10 @@ static ib_api_status_t pr_rcv_get_path_parms(IN osm_sa_t * sa,
 
 		p_physp0 = osm_node_get_physp_ptr((osm_node_t *)p_node, 0);
 		p_pi0 = &p_physp0->port_info;
-		if (ib_path_compare_rates(rate,
-					  ib_port_info_compute_rate(p_pi,
-								    p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS)) > 0)
-			rate = ib_port_info_compute_rate(p_pi,
-							 p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS);
+		p0_extended = p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS;
+		p0_extended_rate = ib_port_info_compute_rate(p_pi, p0_extended);
+		if (ib_path_compare_rates(rate, p0_extended_rate) > 0)
+			rate = p0_extended_rate;
 
 		/*
 		   Continue with the egress port on this switch.
@@ -375,11 +375,10 @@ static ib_api_status_t pr_rcv_get_path_parms(IN osm_sa_t * sa,
 
 		p_physp0 = osm_node_get_physp_ptr((osm_node_t *)p_node, 0);
 		p_pi0 = &p_physp0->port_info;
-		if (ib_path_compare_rates(rate,
-					  ib_port_info_compute_rate(p_pi,
-								    p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS)) > 0)
-			rate = ib_port_info_compute_rate(p_pi,
-							 p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS);
+		p0_extended = p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS;
+		p0_extended_rate = ib_port_info_compute_rate(p_pi, p0_extended);
+		if (ib_path_compare_rates(rate, p0_extended_rate) > 0)
+			rate = p0_extended_rate;
 
 		if (sa->p_subn->opt.qos) {
 			/*
@@ -431,11 +430,10 @@ static ib_api_status_t pr_rcv_get_path_parms(IN osm_sa_t * sa,
 	if (mtu > ib_port_info_get_mtu_cap(p_pi))
 		mtu = ib_port_info_get_mtu_cap(p_pi);
 
-	if (ib_path_compare_rates(rate,
-				  ib_port_info_compute_rate(p_pi,
-							    p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS)) > 0)
-		rate = ib_port_info_compute_rate(p_pi,
-						 p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS);
+	extended = p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS;
+	dest_rate = ib_port_info_compute_rate(p_pi, extended);
+	if (ib_path_compare_rates(rate, dest_rate) > 0)
+		rate = dest_rate;
 
 	OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
 		"Path min MTU = %u, min rate = %u\n", mtu, rate);
@@ -503,7 +501,7 @@ static ib_api_status_t pr_rcv_get_path_parms(IN osm_sa_t * sa,
 		case 1:	/* must be less than */
 			if (mtu >= required_mtu) {
 				/* adjust to use the highest mtu
-				   lower then the required one */
+				   lower than the required one */
 				if (required_mtu > 1)
 					mtu = required_mtu - 1;
 				else
@@ -545,7 +543,7 @@ static ib_api_status_t pr_rcv_get_path_parms(IN osm_sa_t * sa,
 		case 1:	/* must be less than */
 			if (ib_path_compare_rates(rate, required_rate) >= 0) {
 				/* adjust the rate to use the highest rate
-				   lower then the required one */
+				   lower than the required one */
 				rate = ib_path_rate_get_prev(required_rate);
 				if (!rate)
 					status = IB_NOT_FOUND;
@@ -586,7 +584,7 @@ static ib_api_status_t pr_rcv_get_path_parms(IN osm_sa_t * sa,
 		case 1:	/* must be less than */
 			if (pkt_life >= required_pkt_life) {
 				/* adjust the lifetime to use the highest possible
-				   lower then the required one */
+				   lower than the required one */
 				if (required_pkt_life > 1)
 					pkt_life = required_pkt_life - 1;
 				else
@@ -988,7 +986,7 @@ static osm_sa_item_t *pr_rcv_get_lid_pair_path(IN osm_sa_t * sa,
 	/* did we get a Reversible Path compmask ? */
 	/*
 	   NOTE that if the reversible component = 0, it is a don't care
-	   rather then requiring non-reversible paths ...
+	   rather than requiring non-reversible paths ...
 	   see Vol1 Ver1.2 p900 l16
 	 */
 	if ((comp_mask & IB_PR_COMPMASK_REVERSIBLE) &&
@@ -1113,7 +1111,7 @@ static void pr_rcv_get_port_pair_paths(IN osm_sa_t * sa,
 					  &src_lid_min_ho, &src_lid_max_ho);
 
 	if (src_lid_min_ho == 0) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1F20:"
+		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
 			"Obtained source LID of 0. No such LID possible "
 			"(%s port %d)\n",
 			p_src_alias_guid->p_base_port->p_node->print_desc,
@@ -1122,7 +1120,7 @@ static void pr_rcv_get_port_pair_paths(IN osm_sa_t * sa,
 	}
 
 	if (dest_lid_min_ho == 0) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1F21:"
+		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
 			"Obtained destination LID of 0. No such LID possible "
 			"(%s port %d)\n",
 			p_dest_alias_guid->p_base_port->p_node->print_desc,
@@ -1663,7 +1661,7 @@ static void pr_process_multicast(osm_sa_t * sa, const ib_sa_mad_t *sa_mad,
 			"Unable to allocate path record for MC group\n");
 		return;
 	}
-	memset(pr_item, 0, SA_PR_RESP_SIZE);
+	memset(pr_item, 0, sizeof(cl_list_item_t));
 
 	/* Copy PathRecord request into response */
 	pr_item->resp.path_rec = *pr;
@@ -1727,23 +1725,6 @@ void osm_pr_rcv_process(IN void *context, IN void *data)
 		goto Exit;
 	}
 
-	/* update the requester physical port */
-	requester_port = osm_get_port_by_mad_addr(sa->p_log, sa->p_subn,
-						  osm_madw_get_mad_addr_ptr
-						  (p_madw));
-	if (requester_port == NULL) {
-		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1F16: "
-			"Cannot find requester physical port\n");
-		goto Exit;
-	}
-
-	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) {
-		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
-			"Requester port GUID 0x%" PRIx64 "\n",
-			cl_ntoh64(osm_port_get_guid(requester_port)));
-		osm_dump_path_record_v2(sa->p_log, p_pr, FILE_ID, OSM_LOG_DEBUG);
-	}
-
 	/* Validate rate if supplied */
 	if ((p_sa_mad->comp_mask & IB_PR_COMPMASK_RATESELEC) &&
 	    (p_sa_mad->comp_mask & IB_PR_COMPMASK_RATE)) {
@@ -1781,6 +1762,24 @@ void osm_pr_rcv_process(IN void *context, IN void *data)
 	 */
 	cl_plock_acquire(sa->p_lock);
 
+	/* update the requester physical port */
+	requester_port = osm_get_port_by_mad_addr(sa->p_log, sa->p_subn,
+						  osm_madw_get_mad_addr_ptr
+						  (p_madw));
+	if (requester_port == NULL) {
+		cl_plock_release(sa->p_lock);
+		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1F16: "
+			"Cannot find requester physical port\n");
+		goto Exit;
+	}
+
+	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) {
+		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
+			"Requester port GUID 0x%" PRIx64 "\n",
+			cl_ntoh64(osm_port_get_guid(requester_port)));
+		osm_dump_path_record_v2(sa->p_log, p_pr, FILE_ID, OSM_LOG_DEBUG);
+	}
+
 	/* Handle multicast destinations separately */
 	if ((p_sa_mad->comp_mask & IB_PR_COMPMASK_DGID) &&
 	    ib_gid_is_multicast(&p_pr->dgid)) {
diff --git a/opensm/osm_sa_pkey_record.c b/opensm/osm_sa_pkey_record.c
index 586c3eb..296d0a5 100644
--- a/opensm/osm_sa_pkey_record.c
+++ b/opensm/osm_sa_pkey_record.c
@@ -259,11 +259,14 @@ void osm_pkey_rec_rcv_process(IN void *ctx, IN void *data)
 		goto Exit;
 	}
 
+	cl_plock_acquire(sa->p_lock);
+
 	/* update the requester physical port */
 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
 						osm_madw_get_mad_addr_ptr
 						(p_madw));
 	if (p_req_physp == NULL) {
+		cl_plock_release(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4604: "
 			"Cannot find requester physical port\n");
 		goto Exit;
@@ -288,8 +291,6 @@ void osm_pkey_rec_rcv_process(IN void *ctx, IN void *data)
 		(comp_mask & IB_PKEY_COMPMASK_PORT) != 0, context.block_num,
 		(comp_mask & IB_PKEY_COMPMASK_BLOCK) != 0);
 
-	cl_plock_acquire(sa->p_lock);
-
 	/*
 	   If the user specified a LID, it obviously narrows our
 	   work load, since we don't have to search every port
diff --git a/opensm/osm_sa_portinfo_record.c b/opensm/osm_sa_portinfo_record.c
index 78d8d16..c362c62 100644
--- a/opensm/osm_sa_portinfo_record.c
+++ b/opensm/osm_sa_portinfo_record.c
@@ -538,11 +538,14 @@ void osm_pir_rcv_process(IN void *ctx, IN void *data)
 		goto Exit;
 	}
 
+	cl_plock_acquire(sa->p_lock);
+
 	/* update the requester physical port */
 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
 						osm_madw_get_mad_addr_ptr
 						(p_madw));
 	if (p_req_physp == NULL) {
+		cl_plock_release(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2104: "
 			"Cannot find requester physical port\n");
 		goto Exit;
@@ -565,8 +568,6 @@ void osm_pir_rcv_process(IN void *ctx, IN void *data)
 	context.is_enhanced_comp_mask =
 	    cl_ntoh32(p_rcvd_mad->attr_mod) & (1 << 31);
 
-	cl_plock_acquire(sa->p_lock);
-
 	/*
 	   If the user specified a LID, it obviously narrows our
 	   work load, since we don't have to search every port
diff --git a/opensm/osm_sa_service_record.c b/opensm/osm_sa_service_record.c
index c2c6ea9..e55e203 100644
--- a/opensm/osm_sa_service_record.c
+++ b/opensm/osm_sa_service_record.c
@@ -453,11 +453,15 @@ static void sr_rcv_process_get_method(osm_sa_t * sa, IN osm_madw_t * p_madw)
 
 	CL_ASSERT(p_madw);
 
+	/* Grab the lock */
+	cl_plock_acquire(sa->p_lock);
+
 	/* update the requester physical port */
 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
 						osm_madw_get_mad_addr_ptr
 						(p_madw));
 	if (p_req_physp == NULL) {
+		cl_plock_release(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2409: "
 			"Cannot find requester physical port\n");
 		goto Exit;
@@ -483,9 +487,6 @@ static void sr_rcv_process_get_method(osm_sa_t * sa, IN osm_madw_t * p_madw)
 	context.p_sr_item = &sr_match_item;
 	context.p_req_physp = p_req_physp;
 
-	/* Grab the lock */
-	cl_plock_excl_acquire(sa->p_lock);
-
 	cl_qlist_apply_func(&sa->p_subn->sa_sr_list, get_matching_sr, &context);
 
 	cl_plock_release(sa->p_lock);
@@ -530,6 +531,7 @@ static void sr_rcv_process_set_method(osm_sa_t * sa, IN osm_madw_t * p_madw)
 
 	if ((comp_mask & (IB_SR_COMPMASK_SID | IB_SR_COMPMASK_SGID)) !=
 	    (IB_SR_COMPMASK_SID | IB_SR_COMPMASK_SGID)) {
+		cl_plock_release(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
 			"Component Mask RID check failed for METHOD_SET\n");
 		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
@@ -543,9 +545,6 @@ static void sr_rcv_process_set_method(osm_sa_t * sa, IN osm_madw_t * p_madw)
 		p_recvd_service_rec->service_lease = 0xFFFFFFFF;
 	}
 
-	/* Grab the lock */
-	cl_plock_excl_acquire(sa->p_lock);
-
 	/* If Record exists with matching RID */
 	p_svcr = osm_svcr_get_by_rid(sa->p_subn, sa->p_log,
 				     p_recvd_service_rec);
@@ -555,7 +554,6 @@ static void sr_rcv_process_set_method(osm_sa_t * sa, IN osm_madw_t * p_madw)
 		p_svcr = osm_svcr_new(p_recvd_service_rec);
 		if (p_svcr == NULL) {
 			cl_plock_release(sa->p_lock);
-
 			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2411: "
 				"Failed to create new service record\n");
 
@@ -626,9 +624,6 @@ static void sr_rcv_process_delete_method(osm_sa_t * sa, IN osm_madw_t * p_madw)
 		osm_dump_service_record_v2(sa->p_log, p_recvd_service_rec,
 					   FILE_ID, OSM_LOG_DEBUG);
 
-	/* Grab the lock */
-	cl_plock_excl_acquire(sa->p_lock);
-
 	/* If Record exists with matching RID */
 	p_svcr = osm_svcr_get_by_rid(sa->p_subn, sa->p_log,
 				     p_recvd_service_rec);
@@ -685,8 +680,10 @@ void osm_sr_rcv_process(IN void *context, IN void *data)
 
 	switch (p_sa_mad->method) {
 	case IB_MAD_METHOD_SET:
+		cl_plock_excl_acquire(sa->p_lock);
 		valid = validate_sr(sa, p_madw);
 		if (!valid) {
+			cl_plock_release(sa->p_lock);
 			OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
 				"Component Mask check failed for set request\n");
 			osm_sa_send_error(sa, p_madw,
@@ -696,8 +693,10 @@ void osm_sr_rcv_process(IN void *context, IN void *data)
 		sr_rcv_process_set_method(sa, p_madw);
 		break;
 	case IB_MAD_METHOD_DELETE:
+		cl_plock_excl_acquire(sa->p_lock);
 		valid = validate_sr(sa, p_madw);
 		if (!valid) {
+			cl_plock_release(sa->p_lock);
 			OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
 				"Component Mask check failed for delete request\n");
 			osm_sa_send_error(sa, p_madw,
diff --git a/opensm/osm_sa_slvl_record.c b/opensm/osm_sa_slvl_record.c
index 467ac0b..83f0cb1 100644
--- a/opensm/osm_sa_slvl_record.c
+++ b/opensm/osm_sa_slvl_record.c
@@ -232,11 +232,14 @@ void osm_slvl_rec_rcv_process(IN void *ctx, IN void *data)
 		goto Exit;
 	}
 
+	cl_plock_acquire(sa->p_lock);
+
 	/* update the requester physical port */
 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
 						osm_madw_get_mad_addr_ptr
 						(p_madw));
 	if (p_req_physp == NULL) {
+		cl_plock_release(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2603: "
 			"Cannot find requester physical port\n");
 		goto Exit;
@@ -254,8 +257,6 @@ void osm_slvl_rec_rcv_process(IN void *ctx, IN void *data)
 	context.in_port_num = p_rcvd_rec->in_port_num;
 	context.p_req_physp = p_req_physp;
 
-	cl_plock_acquire(sa->p_lock);
-
 	OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
 		"Got Query Lid:%u(%02X), In-Port:0x%02X(%02X), Out-Port:0x%02X(%02X)\n",
 		cl_ntoh16(p_rcvd_rec->lid),
diff --git a/opensm/osm_sa_sminfo_record.c b/opensm/osm_sa_sminfo_record.c
index 83991f4..243b6a4 100644
--- a/opensm/osm_sa_sminfo_record.c
+++ b/opensm/osm_sa_sminfo_record.c
@@ -208,11 +208,14 @@ void osm_smir_rcv_process(IN void *ctx, IN void *data)
 		goto Exit;
 	}
 
+	cl_plock_acquire(sa->p_lock);
+
 	/* update the requester physical port */
 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
 						osm_madw_get_mad_addr_ptr
 						(p_madw));
 	if (p_req_physp == NULL) {
+		cl_plock_release(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2803: "
 			"Cannot find requester physical port\n");
 		goto Exit;
@@ -235,8 +238,6 @@ void osm_smir_rcv_process(IN void *ctx, IN void *data)
 	context.sa = sa;
 	context.p_req_physp = p_req_physp;
 
-	cl_plock_acquire(sa->p_lock);
-
 	/*
 	   If the user specified a LID, it obviously narrows our
 	   work load, since we don't have to search every port
diff --git a/opensm/osm_sa_sw_info_record.c b/opensm/osm_sa_sw_info_record.c
index 0776c8b..acbe3a6 100644
--- a/opensm/osm_sa_sw_info_record.c
+++ b/opensm/osm_sa_sw_info_record.c
@@ -222,11 +222,14 @@ void osm_sir_rcv_process(IN void *ctx, IN void *data)
 		goto Exit;
 	}
 
+	cl_plock_acquire(sa->p_lock);
+
 	/* update the requester physical port */
 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
 						osm_madw_get_mad_addr_ptr
 						(p_madw));
 	if (p_req_physp == NULL) {
+		cl_plock_release(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 5304: "
 			"Cannot find requester physical port\n");
 		goto Exit;
@@ -248,8 +251,6 @@ void osm_sir_rcv_process(IN void *ctx, IN void *data)
 	context.sa = sa;
 	context.p_req_physp = p_req_physp;
 
-	cl_plock_acquire(sa->p_lock);
-
 	/* Go over all switches */
 	cl_qmap_apply_func(&sa->p_subn->sw_guid_tbl, sir_rcv_by_comp_mask,
 			   &context);
diff --git a/opensm/osm_sa_vlarb_record.c b/opensm/osm_sa_vlarb_record.c
index 17b21a5..8cb25fc 100644
--- a/opensm/osm_sa_vlarb_record.c
+++ b/opensm/osm_sa_vlarb_record.c
@@ -239,11 +239,14 @@ void osm_vlarb_rec_rcv_process(IN void *ctx, IN void *data)
 		goto Exit;
 	}
 
+	cl_plock_acquire(sa->p_lock);
+
 	/* update the requester physical port */
 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
 						osm_madw_get_mad_addr_ptr
 						(p_madw));
 	if (p_req_physp == NULL) {
+		cl_plock_release(sa->p_lock);
 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2A04: "
 			"Cannot find requester physical port\n");
 		goto Exit;
@@ -269,8 +272,6 @@ void osm_vlarb_rec_rcv_process(IN void *ctx, IN void *data)
 		p_rcvd_rec->block_num,
 		(comp_mask & IB_VLA_COMPMASK_BLOCK) != 0);
 
-	cl_plock_acquire(sa->p_lock);
-
 	/*
 	   If the user specified a LID, it obviously narrows our
 	   work load, since we don't have to search every port
diff --git a/opensm/osm_slvl_map_rcv.c b/opensm/osm_slvl_map_rcv.c
index f5f4240..67f0e19 100644
--- a/opensm/osm_slvl_map_rcv.c
+++ b/opensm/osm_slvl_map_rcv.c
@@ -92,6 +92,14 @@ void osm_slvl_rcv_process(IN void *context, IN void *p_data)
 
 	CL_ASSERT(p_smp->attr_id == IB_MAD_ATTR_SLVL_TABLE);
 
+	if (!sm->p_subn->opt.suppress_sl2vl_mad_status_errors &&
+	    ib_smp_get_status(p_smp)) {
+		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+			"MAD status 0x%x received\n",
+			cl_ntoh16(ib_smp_get_status(p_smp)));
+		goto Exit2;
+	}
+
 	cl_plock_excl_acquire(sm->p_lock);
 	p_port = osm_get_port_by_guid(sm->p_subn, port_guid);
 
@@ -159,5 +167,6 @@ void osm_slvl_rcv_process(IN void *context, IN void *p_data)
 Exit:
 	cl_plock_release(sm->p_lock);
 
+Exit2:
 	OSM_LOG_EXIT(sm->p_log);
 }
diff --git a/opensm/osm_sm.c b/opensm/osm_sm.c
index 6f88f59..e5e14ea 100644
--- a/opensm/osm_sm.c
+++ b/opensm/osm_sm.c
@@ -111,7 +111,7 @@ static void sm_sweeper(IN void *p_ptr)
 		if (status == CL_SUCCESS)
 			OSM_LOG(p_sm->p_log, OSM_LOG_DEBUG,
 				"Off schedule sweep signalled\n");
-		else if (status != CL_TIMEOUT) {
+		else {
 			OSM_LOG(p_sm->p_log, OSM_LOG_ERROR, "ERR 2E01: "
 				"Event wait failed (%s)\n",
 				CL_STATUS_MSG(status));
diff --git a/opensm/osm_sm_mad_ctrl.c b/opensm/osm_sm_mad_ctrl.c
index 11195e8..fd2cd17 100644
--- a/opensm/osm_sm_mad_ctrl.c
+++ b/opensm/osm_sm_mad_ctrl.c
@@ -262,8 +262,9 @@ static void sm_mad_ctrl_process_get_resp(IN osm_sm_mad_ctrl_t * p_ctrl,
 	default:
 		cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
 		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3103: "
-			"Unsupported attribute 0x%X\n",
-			cl_ntoh16(p_smp->attr_id));
+			"Unsupported attribute 0x%X (%s)\n",
+			cl_ntoh16(p_smp->attr_id),
+			ib_get_sm_attr_str(p_smp->attr_id));
 		osm_dump_dr_smp_v2(p_ctrl->p_log, p_smp, FILE_ID, OSM_LOG_ERROR);
 		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
 		goto Exit;
@@ -392,8 +393,9 @@ static void sm_mad_ctrl_process_set(IN osm_sm_mad_ctrl_t * p_ctrl,
 	default:
 		cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
 		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3107: "
-			"Unsupported attribute 0x%X\n",
-			cl_ntoh16(p_smp->attr_id));
+			"Unsupported attribute 0x%X (%s)\n",
+			cl_ntoh16(p_smp->attr_id),
+			ib_get_sm_attr_str(p_smp->attr_id));
 		osm_dump_dr_smp_v2(p_ctrl->p_log, p_smp, FILE_ID, OSM_LOG_ERROR);
 		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
 		goto Exit;
@@ -471,8 +473,9 @@ static void sm_mad_ctrl_process_trap(IN osm_sm_mad_ctrl_t * p_ctrl,
 	default:
 		cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
 		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3109: "
-			"Unsupported attribute 0x%X\n",
-			cl_ntoh16(p_smp->attr_id));
+			"Unsupported attribute 0x%X (%s)\n",
+			cl_ntoh16(p_smp->attr_id),
+			ib_get_sm_attr_str(p_smp->attr_id));
 		osm_dump_dr_smp_v2(p_ctrl->p_log, p_smp, FILE_ID, OSM_LOG_ERROR);
 		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
 		goto Exit;
@@ -540,8 +543,9 @@ static void sm_mad_ctrl_process_trap_repress(IN osm_sm_mad_ctrl_t * p_ctrl,
 	default:
 		cl_atomic_inc(&p_ctrl->p_stats->qp0_mads_rcvd_unknown);
 		OSM_LOG(p_ctrl->p_log, OSM_LOG_ERROR, "ERR 3105: "
-			"Unsupported attribute 0x%X\n",
-			cl_ntoh16(p_smp->attr_id));
+			"Unsupported attribute 0x%X (%s)\n",
+			cl_ntoh16(p_smp->attr_id),
+			ib_get_sm_attr_str(p_smp->attr_id));
 		osm_dump_dr_smp_v2(p_ctrl->p_log, p_smp, FILE_ID, OSM_LOG_ERROR);
 		osm_mad_pool_put(p_ctrl->p_mad_pool, p_madw);
 		break;
diff --git a/opensm/osm_sm_state_mgr.c b/opensm/osm_sm_state_mgr.c
index 0660fb9..76ccf81 100644
--- a/opensm/osm_sm_state_mgr.c
+++ b/opensm/osm_sm_state_mgr.c
@@ -1,6 +1,6 @@
 /*
+ * Copyright (c) 2002-2013 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  *
@@ -97,11 +97,11 @@ static boolean_t sm_state_mgr_send_master_sm_info_req(osm_sm_t * sm, uint8_t sm_
 	} else {
 		/*
 		 * We are not in STANDBY - this means we are in MASTER state -
-		 * so we need to poll the SM that is saved in p_polling_sm
+		 * so we need to poll the SM that is saved in polling_sm_guid
 		 * under sm.
 		 * Send a query of SubnGet(SMInfo) to that SM.
 		 */
-		guid = sm->p_polling_sm->smi.guid;
+		guid = sm->polling_sm_guid;
 	}
 
 	/* Verify that SM is not polling itself */
@@ -198,7 +198,7 @@ void osm_sm_state_mgr_polling_callback(IN void *context)
 	 * If we are not in one of these cases - don't need to restart the poller.
 	 */
 	if (!((sm_state == IB_SMINFO_STATE_MASTER &&
-	       sm->p_polling_sm != NULL) ||
+	       sm->polling_sm_guid != 0) ||
 	      sm_state == IB_SMINFO_STATE_STANDBY)) {
 		CL_PLOCK_RELEASE(sm->p_lock);
 		goto Exit;
@@ -297,15 +297,17 @@ ib_api_status_t osm_sm_state_mgr_process(osm_sm_t * sm,
 			 * Update the state of the SM to MASTER
 			 */
 			/* Turn on the first_time_master_sweep flag */
-			sm->p_subn->first_time_master_sweep = TRUE;
 			sm->p_subn->sm_state = IB_SMINFO_STATE_MASTER;
 			osm_report_sm_state(sm);
 			/*
 			 * Make sure to set the subnet master_sm_base_lid
 			 * to the sm_base_lid value
 			 */
+			CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
+			sm->p_subn->first_time_master_sweep = TRUE;
 			sm->p_subn->master_sm_base_lid =
 			    sm->p_subn->sm_base_lid;
+			CL_PLOCK_RELEASE(sm->p_lock);
 			break;
 		case OSM_SM_SIGNAL_MASTER_OR_HIGHER_SM_DETECTED:
 			/*
@@ -318,8 +320,9 @@ ib_api_status_t osm_sm_state_mgr_process(osm_sm_t * sm,
 			 * Since another SM is doing the LFT config - we should not
 			 * ignore the results of it
 			 */
+			CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
 			sm->p_subn->ignore_existing_lfts = FALSE;
-
+			CL_PLOCK_RELEASE(sm->p_lock);
 			sm_state_mgr_start_polling(sm);
 			break;
 		case OSM_SM_SIGNAL_HANDOVER:
@@ -351,7 +354,9 @@ ib_api_status_t osm_sm_state_mgr_process(osm_sm_t * sm,
 			 */
 			sm->p_subn->sm_state = IB_SMINFO_STATE_DISCOVERING;
 			osm_report_sm_state(sm);
+			CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
 			sm->p_subn->coming_out_of_standby = TRUE;
+			CL_PLOCK_RELEASE(sm->p_lock);
 			osm_sm_signal(sm, OSM_SIGNAL_SWEEP);
 			break;
 		case OSM_SM_SIGNAL_DISABLE:
@@ -367,6 +372,7 @@ ib_api_status_t osm_sm_state_mgr_process(osm_sm_t * sm,
 			 * OPTIONAL: send ACKNOWLEDGE
 			 */
 			/* Turn on the first_time_master_sweep flag */
+			CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
 			sm->p_subn->first_time_master_sweep = TRUE;
 			/*
 			 * Turn on the force_heavy_sweep - we want a
@@ -374,15 +380,19 @@ ib_api_status_t osm_sm_state_mgr_process(osm_sm_t * sm,
 			 */
 			sm->p_subn->force_heavy_sweep = TRUE;
 
-			sm->p_subn->sm_state = IB_SMINFO_STATE_MASTER;
-			osm_report_sm_state(sm);
 			/*
 			 * Make sure to set the subnet master_sm_base_lid
 			 * to the sm_base_lid value
 			 */
 			sm->p_subn->master_sm_base_lid =
 			    sm->p_subn->sm_base_lid;
+
 			sm->p_subn->coming_out_of_standby = TRUE;
+
+			CL_PLOCK_RELEASE(sm->p_lock);
+
+			sm->p_subn->sm_state = IB_SMINFO_STATE_MASTER;
+			osm_report_sm_state(sm);
 			osm_sm_signal(sm, OSM_SIGNAL_SWEEP);
 			break;
 		case OSM_SM_SIGNAL_ACKNOWLEDGE:
@@ -426,7 +436,7 @@ ib_api_status_t osm_sm_state_mgr_process(osm_sm_t * sm,
 			 * We want to force a heavy sweep - hopefully this
 			 * occurred because the remote sm died, and we'll find
 			 * this out and configure the subnet after a heavy sweep.
-			 * We also want to clear the p_polling_sm object - since
+			 * We also want to clear the polling_sm_guid - since
 			 * we are done polling on that remote sm - we are
 			 * sweeping again.
 			 */
@@ -438,19 +448,19 @@ ib_api_status_t osm_sm_state_mgr_process(osm_sm_t * sm,
 			 * change, or we are in idle state - since we
 			 * recognized a master SM before - so we want to make a
 			 * heavy sweep and reconfigure the new subnet.
-			 * We also want to clear the p_polling_sm object - since
+			 * We also want to clear the polling_sm_guid - since
 			 * we are done polling on that remote sm - we got a
 			 * handover from it.
 			 */
 			OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
 				"Forcing heavy sweep. Received signal %s\n",
 				osm_get_sm_mgr_signal_str(signal));
-			/* Force set_client_rereg_on_sweep, we don't know what the other
-			 * SM may have configure/done on the fabric.
-			 */
-			sm->p_subn->set_client_rereg_on_sweep = TRUE;
-			sm->p_polling_sm = NULL;
+			CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
+			sm->polling_sm_guid = 0;
+			sm->p_subn->first_time_master_sweep = TRUE;
+			sm->p_subn->coming_out_of_standby = TRUE;
 			sm->p_subn->force_heavy_sweep = TRUE;
+			CL_PLOCK_RELEASE(sm->p_lock);
 			osm_sm_signal(sm, OSM_SIGNAL_SWEEP);
 			break;
 		case OSM_SM_SIGNAL_HANDOVER_SENT:
diff --git a/opensm/osm_sminfo_rcv.c b/opensm/osm_sminfo_rcv.c
index 2e30ea0..100a82d 100644
--- a/opensm/osm_sminfo_rcv.c
+++ b/opensm/osm_sminfo_rcv.c
@@ -392,11 +392,16 @@ static void smi_rcv_process_get_sm(IN osm_sm_t * sm,
 			 * as it might not get it and we don't want to wait for a HANDOVER
 			 * forever.
 			 */
-			if (sm->p_polling_sm) {
+			if (sm->polling_sm_guid) {
 				if (smi_rcv_remote_sm_is_higher(sm, p_smi))
 					sm->p_subn->force_heavy_sweep = TRUE;
-				else
+				else {
+					/* Update master_sm_guid to the GUID of the newly
+					 * found MASTER SM and send trap 144 to it.
+					 */
+					sm->master_sm_guid = sm->polling_sm_guid;
 					osm_send_trap144(sm, TRAP_144_MASK_SM_PRIORITY_CHANGE);
+				}
 				osm_sm_state_mgr_signal_master_is_alive(sm);
 			} else {
 				/* This is a response we got while sweeping the subnet.
@@ -540,6 +545,12 @@ static void smi_rcv_process_set_response(IN osm_sm_t * sm,
 	CL_ASSERT(p_madw);
 
 	p_smp = osm_madw_get_smp_ptr(p_madw);
+	if (ib_smp_get_status(p_smp)) {
+		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+			"MAD status 0x%x received\n",
+			cl_ntoh16(ib_smp_get_status(p_smp)));
+		goto Exit;
+	}
 
 	if (p_smp->method != IB_MAD_METHOD_GET_RESP) {
 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F16: "
diff --git a/opensm/osm_state_mgr.c b/opensm/osm_state_mgr.c
index c86627d..b9d2135 100644
--- a/opensm/osm_state_mgr.c
+++ b/opensm/osm_state_mgr.c
@@ -531,6 +531,60 @@ static void query_sm_info(cl_map_item_t * item, void *cxt)
 			ib_get_err_str(ret));
 }
 
+static void state_mgr_reset_state_change_bit(IN cl_map_item_t * obj,
+					     IN void *context)
+{
+	osm_madw_context_t mad_context;
+	osm_switch_t *p_sw = (osm_switch_t *) obj;
+	osm_sm_t *sm = context;
+	osm_node_t *p_node;
+	osm_physp_t *p_physp;
+	osm_dr_path_t *p_path;
+	ib_api_status_t status;
+	ib_switch_info_t si;
+
+	OSM_LOG_ENTER(sm->p_log);
+
+	CL_ASSERT(p_sw);
+
+	p_node = p_sw->p_node;
+
+	CL_ASSERT(p_node);
+
+	p_physp = osm_node_get_physp_ptr(p_node, 0);
+	p_path = osm_physp_get_dr_path_ptr(p_physp);
+
+	if (!ib_switch_info_get_state_change(&p_sw->switch_info))
+		goto exit;
+
+	si = p_sw->switch_info;
+
+	ib_switch_info_state_change_set(&si);
+
+	OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+		"Resetting PortStateChange on switch GUID 0x%016" PRIx64 "\n",
+		cl_ntoh64(osm_node_get_node_guid(p_node)));
+
+	mad_context.si_context.light_sweep = FALSE;
+	mad_context.si_context.node_guid = osm_node_get_node_guid(p_node);
+	mad_context.si_context.set_method = TRUE;
+	mad_context.si_context.lft_top_change = FALSE;
+
+	status = osm_req_set(sm, p_path, (uint8_t *) &si,
+			     sizeof(si), IB_MAD_ATTR_SWITCH_INFO,
+			     0, FALSE,
+			     ib_port_info_get_m_key(&p_physp->port_info),
+			     CL_DISP_MSGID_NONE, &mad_context);
+
+	if (status != IB_SUCCESS)
+		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 332A: "
+			"Sending SwitchInfo attribute failed (%s)\n",
+			ib_get_err_str(status));
+
+exit:
+	OSM_LOG_EXIT(sm->p_log);
+}
+
 static void state_mgr_update_node_desc(IN cl_map_item_t * obj, IN void *context)
 {
 	osm_madw_context_t mad_context;
@@ -576,6 +630,14 @@ exit:
 	OSM_LOG_EXIT(sm->p_log);
 }
 
+void osm_reset_switch_state_change_bit(IN osm_opensm_t *osm)
+{
+	CL_PLOCK_ACQUIRE(&osm->lock);
+	cl_qmap_apply_func(&osm->subn.sw_guid_tbl, state_mgr_reset_state_change_bit,
+			   &osm->sm);
+	CL_PLOCK_RELEASE(&osm->lock);
+}
+
 void osm_update_node_desc(IN osm_opensm_t *osm)
 {
 	CL_PLOCK_ACQUIRE(&osm->lock);
@@ -957,6 +1019,11 @@ static void state_mgr_check_tbl_consistency(IN osm_sm_t * sm)
 
 	OSM_LOG_ENTER(sm->p_log);
 
+	if (sm->lid_mgr.dirty == FALSE)
+		goto Exit;
+
+	sm->lid_mgr.dirty = FALSE;
+
 	cl_ptr_vector_construct(&ref_port_lid_tbl);
 	cl_ptr_vector_init(&ref_port_lid_tbl,
 			   cl_ptr_vector_get_size(&sm->p_subn->port_lid_tbl),
@@ -995,7 +1062,7 @@ static void state_mgr_check_tbl_consistency(IN osm_sm_t * sm)
 			 * same for this lid. Nothing to do. */
 			continue;
 
-		if (p_port_ref == NULL)
+		if (p_port_ref == NULL) {
 			/* There is an object in the subnet database for this
 			 * lid, but no such object exists in the reference
 			 * port_list_tbl. This can occur if we wanted to assign
@@ -1012,7 +1079,8 @@ static void state_mgr_check_tbl_consistency(IN osm_sm_t * sm)
 				cl_ntoh64(osm_port_get_guid(p_port_stored)),
 				p_port_stored->p_node->print_desc,
 				p_port_stored->p_physp->port_num);
-		else if (p_port_stored == NULL)
+			cl_ptr_vector_set(p_port_lid_tbl, lid, NULL);
+		} else if (p_port_stored == NULL)
 			/* There is an object in the new database, but no
 			 * object in our subnet database. This is the matching
 			 * case of the prior check - the port still has its
@@ -1024,7 +1092,7 @@ static void state_mgr_check_tbl_consistency(IN osm_sm_t * sm)
 				cl_ntoh64(osm_port_get_guid(p_port_ref)),
 				p_port_ref->p_node->print_desc,
 				p_port_ref->p_physp->port_num, lid);
-		else
+		else {
 			/* if we reached here then p_port_stored != p_port_ref.
 			 * We were trying to set a lid to p_port_stored, but
 			 * it didn't reach it, and p_port_ref also didn't get
@@ -1040,15 +1108,15 @@ static void state_mgr_check_tbl_consistency(IN osm_sm_t * sm)
 				cl_ntoh64(osm_port_get_guid(p_port_stored)),
 				p_port_stored->p_node->print_desc,
 				p_port_stored->p_physp->port_num);
-
-		/* In any of these cases we want to set NULL in the
-		 * port_lid_tbl, since this entry is invalid. Also, make sure
-		 * we'll do another heavy sweep. */
-		cl_ptr_vector_set(p_port_lid_tbl, lid, NULL);
+			cl_ptr_vector_set(p_port_lid_tbl, lid, NULL);
+		}
+		/* Make sure we'll do another heavy sweep. */
 		sm->p_subn->subnet_initialization_error = TRUE;
 	}
 
 	cl_ptr_vector_destroy(&ref_port_lid_tbl);
+
+Exit:
 	OSM_LOG_EXIT(sm->p_log);
 }
 
@@ -1094,6 +1162,10 @@ static void do_sweep(osm_sm_t * sm)
 	osm_remote_sm_t *p_remote_sm;
 	unsigned config_parsed = 0;
 
+	/* after subnet initialization error, run heavy sweep */
+	if (sm->p_subn->subnet_initialization_error)
+		sm->p_subn->force_heavy_sweep = TRUE;
+
 	if (sm->p_subn->force_heavy_sweep) {
 		if (osm_subn_rescan_conf_files(sm->p_subn) < 0)
 			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 331A: "
@@ -1324,7 +1396,7 @@ repeat_discovery:
 				 * need to wait for that SM to relinquish control
 				 * of its portion of the subnet. C14-60.2.1.
 				 * Also - need to start polling on that SM. */
-				sm->p_polling_sm = p_remote_sm;
+				sm->polling_sm_guid = p_remote_sm->smi.guid;
 				osm_sm_state_mgr_process(sm,
 							 OSM_SM_SIGNAL_WAIT_FOR_HANDOVER);
 				return;
@@ -1340,6 +1412,10 @@ repeat_discovery:
 	if (sm->p_subn->sm_state == IB_SMINFO_STATE_DISCOVERING)
 		osm_sm_state_mgr_process(sm, OSM_SM_SIGNAL_DISCOVERY_COMPLETED);
 
+	osm_reset_switch_state_change_bit(sm->p_subn->p_osm);
+	if (wait_for_pending_transactions(&sm->p_subn->p_osm->stats))
+		return;
+
 	osm_pkey_mgr_process(sm->p_subn->p_osm);
 
 	/* try to restore SA DB (this should be before lid_mgr
@@ -1460,6 +1536,7 @@ repeat_discovery:
 
 	/* in any case we zero this flag */
 	sm->p_subn->coming_out_of_standby = FALSE;
+	sm->p_subn->first_time_master_sweep = FALSE;
 
 	/* If there were errors - then the subnet is not really up */
 	if (sm->p_subn->subnet_initialization_error == TRUE) {
@@ -1471,8 +1548,6 @@ repeat_discovery:
 		sm->p_subn->need_update = 0;
 		osm_dump_all(sm->p_subn->p_osm);
 		state_mgr_up_msg(sm);
-		sm->p_subn->first_time_master_sweep = FALSE;
-		sm->p_subn->set_client_rereg_on_sweep = FALSE;
 
 		if (OSM_LOG_IS_ACTIVE_V2(sm->p_log, OSM_LOG_VERBOSE) ||
 		    sm->p_subn->opt.sa_db_dump)
@@ -1489,8 +1564,7 @@ repeat_discovery:
 
 	/* if we got a signal to force heavy sweep or errors
 	 * in the middle of the sweep - try another sweep. */
-	if (sm->p_subn->force_heavy_sweep
-	    || sm->p_subn->subnet_initialization_error)
+	if (sm->p_subn->force_heavy_sweep)
 		osm_sm_signal(sm, OSM_SIGNAL_SWEEP);
 
 	/* Write a new copy of our persistent guid2mkey database */
diff --git a/opensm/osm_subnet.c b/opensm/osm_subnet.c
index 7bc9676..ad9f80b 100644
--- a/opensm/osm_subnet.c
+++ b/opensm/osm_subnet.c
@@ -275,12 +275,58 @@ static void opts_setup_sm_priority(osm_subn_t *p_subn, void *p_val)
 	osm_set_sm_priority(p_sm, sm_priority);
 }
 
+static int opts_strtoul(uint32_t *val, IN char *p_val_str,
+			IN char *p_key, uint32_t max_value)
+{
+	char *endptr;
+	unsigned long int tmp_val;
+
+	errno = 0;
+	tmp_val = strtoul(p_val_str, &endptr, 0);
+	*val = tmp_val;
+	if (*p_val_str == '\0' || *endptr != '\0') {
+		log_report("-E- Parsing error in field %s, expected "
+			   "numeric input received: %s\n", p_key, p_val_str);
+		return -1;
+	}
+	if (tmp_val > max_value ||
+	    ((tmp_val == ULONG_MAX) && errno == ERANGE)) {
+		log_report("-E- Parsing error in field %s, value out of range\n", p_key);
+		return -1;
+	}
+	return 0;
+}
+
+static int opts_strtoull(uint64_t *val, IN char *p_val_str,
+			 IN char *p_key, uint64_t max_value)
+{
+	char *endptr;
+	unsigned long long int tmp_val;
+
+	errno = 0;
+	tmp_val = strtoull(p_val_str, &endptr, 0);
+	*val = tmp_val;
+	if (*p_val_str == '\0' || *endptr != '\0') {
+		log_report("-E- Parsing error in field %s, expected "
+			   "numeric input received: %s\n", p_key, p_val_str);
+		return -1;
+	}
+	if (tmp_val > max_value || (tmp_val == ULLONG_MAX && errno == ERANGE)) {
+		log_report("-E- Parsing error in field %s, value out of range", p_key);
+		return -1;
+	}
+	return 0;
+}
+
 static void opts_parse_net64(IN osm_subn_t *p_subn, IN char *p_key,
 			     IN char *p_val_str, void *p_v1, void *p_v2,
 			     void (*pfn)(osm_subn_t *, void *))
 {
 	uint64_t *p_val1 = p_v1, *p_val2 = p_v2;
-	uint64_t val = strtoull(p_val_str, NULL, 0);
+	uint64_t val;
+
+	if (opts_strtoull(&val, p_val_str, p_key, UINT64_MAX))
+		return;
 
 	if (cl_hton64(val) != *p_val1) {
 		log_config_value(p_key, "0x%016" PRIx64, val);
@@ -295,7 +341,10 @@ static void opts_parse_uint32(IN osm_subn_t *p_subn, IN char *p_key,
 			      void (*pfn)(osm_subn_t *, void *))
 {
 	uint32_t *p_val1 = p_v1, *p_val2 = p_v2;
-	uint32_t val = strtoul(p_val_str, NULL, 0);
+	uint32_t val;
+
+	if (opts_strtoul(&val, p_val_str, p_key, UINT32_MAX))
+		return;
 
 	if (val != *p_val1) {
 		log_config_value(p_key, "%u", val);
@@ -310,7 +359,10 @@ static void opts_parse_net32(IN osm_subn_t *p_subn, IN char *p_key,
 			     void (*pfn)(osm_subn_t *, void *))
 {
 	uint32_t *p_val1 = p_v1, *p_val2 = p_v2;
-	uint32_t val = strtoul(p_val_str, NULL, 0);
+	uint32_t val;
+
+	if (opts_strtoul(&val, p_val_str, p_key, UINT32_MAX))
+		return;
 
 	if (cl_hton32(val) != *p_val1) {
 		log_config_value(p_key, "%u", val);
@@ -320,7 +372,6 @@ static void opts_parse_net32(IN osm_subn_t *p_subn, IN char *p_key,
 	}
 }
 
-
 static void opts_parse_int32(IN osm_subn_t *p_subn, IN char *p_key,
 			     IN char *p_val_str, void *p_v1, void *p_v2,
 			     void (*pfn)(osm_subn_t *, void *))
@@ -341,8 +392,12 @@ static void opts_parse_uint16(IN osm_subn_t *p_subn, IN char *p_key,
 			      void (*pfn)(osm_subn_t *, void *))
 {
 	uint16_t *p_val1 = p_v1, *p_val2 = p_v2;
-	uint16_t val = (uint16_t) strtoul(p_val_str, NULL, 0);
+	uint32_t tmp_val;
+
+	if (opts_strtoul(&tmp_val, p_val_str, p_key, UINT16_MAX))
+		return;
 
+	uint16_t val = (uint16_t) tmp_val;
 	if (val != *p_val1) {
 		log_config_value(p_key, "%u", val);
 		if (pfn)
@@ -356,8 +411,12 @@ static void opts_parse_net16(IN osm_subn_t *p_subn, IN char *p_key,
 			     void (*pfn)(osm_subn_t *, void *))
 {
 	uint16_t *p_val1 = p_v1, *p_val2 = p_v2;
-	uint16_t val = strtoul(p_val_str, NULL, 0);
+	uint32_t tmp_val;
 
+	if (opts_strtoul(&tmp_val, p_val_str, p_key, UINT16_MAX))
+		return;
+
+	uint16_t val = (uint16_t) tmp_val;
 	if (cl_hton16(val) != *p_val1) {
 		log_config_value(p_key, "0x%04x", val);
 		if (pfn)
@@ -371,8 +430,12 @@ static void opts_parse_uint8(IN osm_subn_t *p_subn, IN char *p_key,
 			     void (*pfn)(osm_subn_t *, void *))
 {
 	uint8_t *p_val1 = p_v1, *p_val2 = p_v2;
-	uint8_t val = strtoul(p_val_str, NULL, 0);
+	uint32_t tmp_val;
+
+	if (opts_strtoul(&tmp_val, p_val_str, p_key, UINT8_MAX))
+		return;
 
+	uint8_t val = (uint8_t) tmp_val;
 	if (val != *p_val1) {
 		log_config_value(p_key, "%u", val);
 		if (pfn)
@@ -756,6 +819,7 @@ static const opt_rec_t opt_tbl[] = {
 	{ "sm_assigned_guid", OPT_OFFSET(sm_assigned_guid), opts_parse_uint8, NULL, 1 },
 	{ "qos", OPT_OFFSET(qos), opts_parse_boolean, NULL, 1 },
 	{ "qos_policy_file", OPT_OFFSET(qos_policy_file), opts_parse_charp, NULL, 0 },
+	{ "suppress_sl2vl_mad_status_errors", OPT_OFFSET(suppress_sl2vl_mad_status_errors), opts_parse_boolean, NULL, 1 },
 	{ "dump_files_dir", OPT_OFFSET(dump_files_dir), opts_parse_charp, NULL, 0 },
 	{ "lid_matrix_dump_file", OPT_OFFSET(lid_matrix_dump_file), opts_parse_charp, NULL, 0 },
 	{ "lfts_file", OPT_OFFSET(lfts_file), opts_parse_charp, NULL, 0 },
@@ -790,6 +854,8 @@ static const opt_rec_t opt_tbl[] = {
 	{ "perfmgr_rm_nodes", OPT_OFFSET(perfmgr_rm_nodes), opts_parse_boolean, NULL, 0 },
 	{ "perfmgr_log_errors", OPT_OFFSET(perfmgr_log_errors), opts_parse_boolean, NULL, 0 },
 	{ "perfmgr_query_cpi", OPT_OFFSET(perfmgr_query_cpi), opts_parse_boolean, NULL, 0 },
+	{ "perfmgr_xmit_wait_log", OPT_OFFSET(perfmgr_xmit_wait_log), opts_parse_boolean, NULL, 0 },
+	{ "perfmgr_xmit_wait_threshold", OPT_OFFSET(perfmgr_xmit_wait_threshold), opts_parse_uint32, NULL, 0 },
 #endif				/* ENABLE_OSM_PERF_MGR */
 	{ "event_plugin_name", OPT_OFFSET(event_plugin_name), opts_parse_charp, NULL, 0 },
 	{ "event_plugin_options", OPT_OFFSET(event_plugin_options), opts_parse_charp, NULL, 0 },
@@ -893,6 +959,7 @@ static void subn_validate_g2m(osm_subn_t *p_subn)
 					"guid:0x%016" PRIx64 "\n",
 					p_item->guid);
 		}
+		free(p_item);
 	}
 
 Exit:
@@ -959,7 +1026,7 @@ static void subn_validate_neighbor(osm_subn_t *p_subn)
 			valid_entry = FALSE;
 		} else if (osm_db_neighbor_get(p_subn->p_neighbor,
 					       guid, port, &guid, &port) ||
-			guid != p_item->guid || port != p_item->portnum) {
+			   guid != p_item->guid || port != p_item->portnum) {
 			OSM_LOG(&(p_subn->p_osm->log), OSM_LOG_ERROR,
 				"ERR 7518: neighbor does not point "
 				"back at us (guid: 0x%016" PRIx64
@@ -977,6 +1044,7 @@ static void subn_validate_neighbor(osm_subn_t *p_subn)
 					"guid:0x%016" PRIx64 " port:%u\n",
 					p_item->guid, p_item->portnum);
 		}
+		free(p_item);
 	}
 
 Exit:
@@ -1496,7 +1564,9 @@ void osm_subn_set_default_opt(IN osm_subn_opt_t * p_opt)
 	p_opt->event_db_dump_file = NULL; /* use default */
 	p_opt->perfmgr_rm_nodes = TRUE;
 	p_opt->perfmgr_log_errors = TRUE;
-	p_opt->perfmgr_query_cpi = FALSE;
+	p_opt->perfmgr_query_cpi = TRUE;
+	p_opt->perfmgr_xmit_wait_log = FALSE;
+	p_opt->perfmgr_xmit_wait_threshold = OSM_PERFMGR_DEFAULT_XMIT_WAIT_THRESHOLD;
 #endif				/* ENABLE_OSM_PERF_MGR */
 
 	p_opt->event_plugin_name = NULL;
@@ -1517,6 +1587,7 @@ void osm_subn_set_default_opt(IN osm_subn_opt_t * p_opt)
 	p_opt->sm_assigned_guid = 0;
 	p_opt->qos = FALSE;
 	p_opt->qos_policy_file = strdup(OSM_DEFAULT_QOS_POLICY_FILE);
+	p_opt->suppress_sl2vl_mad_status_errors = FALSE;
 	p_opt->accum_log_file = TRUE;
 	p_opt->port_prof_ignore_file = NULL;
 	p_opt->hop_weights_file = NULL;
@@ -2180,7 +2251,7 @@ int osm_subn_rescan_conf_files(IN osm_subn_t * p_subn)
 
 			token_matched = 1;
 
-			if (!r->can_update || strcmp(r->name, p_key))
+			if (!r->can_update)
 				continue;
 
 			p_field1 = (void *)p_opts->file_opts + r->opt_offset;
@@ -2464,8 +2535,8 @@ int osm_subn_output_conf(FILE *out, IN osm_subn_opt_t * p_opts)
 		p_opts->port_shifting ? "TRUE" : "FALSE");
 
 	fprintf(out,
-		"# Assign ports in a random order instead of round-robin.\n"
-		"# If zero disable, otherwise use the value as a random seed\n"
+		"# Assign ports in a random order instead of round-robin\n"
+		"# If zero disable (default), otherwise use the value as a random seed\n"
 		"scatter_ports %d\n\n",
 		p_opts->scatter_ports);
 
@@ -2557,28 +2628,43 @@ int osm_subn_output_conf(FILE *out, IN osm_subn_opt_t * p_opts)
 	fprintf(out,
 		"#\n# Performance Manager Options\n#\n"
 		"# perfmgr enable\n"
+		"# PerfMgr is enabled if TRUE and disabled if FALSE (default FALSE)\n"
 		"perfmgr %s\n\n"
-		"# perfmgr redirection enable\n"
+		"# redirection enable\n"
+		"# Redirection supported if TRUE and not supported if FALSE (default TRUE)\n"
 		"perfmgr_redir %s\n\n"
-		"# sweep time in seconds\n"
+		"# sweep time in seconds (default %u seconds)\n"
 		"perfmgr_sweep_time_s %u\n\n"
-		"# Max outstanding queries\n"
-		"perfmgr_max_outstanding_queries %u\n"
+		"# Max outstanding queries (default %u)\n"
+		"perfmgr_max_outstanding_queries %u\n\n"
+		"# Ignore CAs on sweep (default FALSE)\n"
 		"perfmgr_ignore_cas %s\n\n"
-		"# Remove missing nodes from DB\n"
+		"# Remove missing nodes from DB (default TRUE)\n"
 		"perfmgr_rm_nodes %s\n\n"
-		"# Log error counters to opensm.log\n"
+		"# Log error counters to opensm.log (default TRUE)\n"
 		"perfmgr_log_errors %s\n\n"
-		"# Query PerfMgrGet(ClassPortInfo) for extended capabilities\n"
-		"perfmgr_query_cpi %s\n\n",
+		"# Query PerfMgt Get(ClassPortInfo) for extended capabilities\n"
+		"# Extended capabilities include 64 bit extended counters\n"
+		"# and transmit wait support (default TRUE)\n"
+		"perfmgr_query_cpi %s\n\n"
+		"# Log xmit_wait errors (default FALSE)\n"
+		"perfmgr_xmit_wait_log %s\n\n"
+		"# If logging xmit_wait's; set threshold (default %u)\n"
+		"perfmgr_xmit_wait_threshold %u\n\n"
+		,
 		p_opts->perfmgr ? "TRUE" : "FALSE",
 		p_opts->perfmgr_redir ? "TRUE" : "FALSE",
+		OSM_PERFMGR_DEFAULT_SWEEP_TIME_S,
 		p_opts->perfmgr_sweep_time_s,
+		OSM_PERFMGR_DEFAULT_MAX_OUTSTANDING_QUERIES,
 		p_opts->perfmgr_max_outstanding_queries,
 		p_opts->perfmgr_ignore_cas ? "TRUE" : "FALSE",
 		p_opts->perfmgr_rm_nodes ? "TRUE" : "FALSE",
 		p_opts->perfmgr_log_errors ? "TRUE" : "FALSE",
-		p_opts->perfmgr_query_cpi ? "TRUE" : "FALSE");
+		p_opts->perfmgr_query_cpi ? "TRUE" : "FALSE",
+		p_opts->perfmgr_xmit_wait_log ? "TRUE" : "FALSE",
+		OSM_PERFMGR_DEFAULT_XMIT_WAIT_THRESHOLD,
+		p_opts->perfmgr_xmit_wait_threshold);
 
 	fprintf(out,
 		"#\n# Event DB Options\n#\n"
@@ -2664,8 +2750,11 @@ int osm_subn_output_conf(FILE *out, IN osm_subn_opt_t * p_opts)
 		"# Enable QoS setup\n"
 		"qos %s\n\n"
 		"# QoS policy file to be used\n"
-		"qos_policy_file %s\n\n",
-		p_opts->qos ? "TRUE" : "FALSE", p_opts->qos_policy_file);
+		"qos_policy_file %s\n"
+		"# Supress QoS MAD status errors\n"
+		"suppress_sl2vl_mad_status_errors %s\n\n",
+		p_opts->qos ? "TRUE" : "FALSE", p_opts->qos_policy_file,
+		p_opts->suppress_sl2vl_mad_status_errors ? "TRUE" : "FALSE");
 
 	subn_dump_qos_options(out,
 			      "QoS default options", "qos",
diff --git a/opensm/osm_sw_info_rcv.c b/opensm/osm_sw_info_rcv.c
index 02f6ab2..e03a64c 100644
--- a/opensm/osm_sw_info_rcv.c
+++ b/opensm/osm_sw_info_rcv.c
@@ -222,7 +222,8 @@ static void si_rcv_process_new(IN osm_sm_t * sm, IN osm_node_t * p_node,
 	}
 
 	/* set subnet max mlid to the minimum MulticastFDBCap of all switches */
-	if (cl_ntoh16(p_si->mcast_cap) + IB_LID_MCAST_START_HO - 1 <
+	if (p_si->mcast_cap &&
+	    cl_ntoh16(p_si->mcast_cap) + IB_LID_MCAST_START_HO - 1 <
 	    sm->p_subn->max_mcast_lid_ho) {
 		sm->p_subn->max_mcast_lid_ho = cl_ntoh16(p_si->mcast_cap) +
 			IB_LID_MCAST_START_HO - 1;
@@ -333,6 +334,48 @@ static boolean_t si_rcv_process_existing(IN osm_sm_t * sm,
 	return is_change_detected;
 }
 
+static void si_rcv_get_sp0_info(IN osm_sm_t * sm, IN osm_node_t * node)
+{
+	osm_madw_context_t context;
+	osm_physp_t *physp;
+	ib_api_status_t status;
+	int mlnx_epi_supported = 0;
+
+	physp = osm_node_get_physp_ptr(node, 0);
+
+	context.pi_context.node_guid = osm_node_get_node_guid(node);
+	context.pi_context.port_guid = osm_physp_get_port_guid(physp);
+	context.pi_context.set_method = FALSE;
+	context.pi_context.light_sweep = FALSE;
+	context.pi_context.active_transition = FALSE;
+	context.pi_context.client_rereg = FALSE;
+
+	status = osm_req_get(sm, osm_physp_get_dr_path_ptr(physp),
+			     IB_MAD_ATTR_PORT_INFO, 0, TRUE, 0,
+			     CL_DISP_MSGID_NONE, &context);
+	if (status != IB_SUCCESS)
+		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3611: "
+			"Failure initiating PortInfo request (%s)\n",
+			ib_get_err_str(status));
+
+	if (ib_switch_info_is_enhanced_port0(&node->sw->switch_info) &&
+	    sm->p_subn->opt.fdr10) {
+		mlnx_epi_supported = is_mlnx_ext_port_info_supported(node->node_info.device_id);
+		if (mlnx_epi_supported) {
+			status = osm_req_get(sm,
+					     osm_physp_get_dr_path_ptr(physp),
+					     IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO,
+					     0, TRUE, 0,
+					     CL_DISP_MSGID_NONE, &context);
+			if (status != IB_SUCCESS)
+				OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3616: "
+					"Failure initiating MLNX ExtPortInfo request (%s)\n",
+					ib_get_err_str(status));
+		}
+	}
+
+}
+
 void osm_si_rcv_process(IN void *context, IN void *data)
 {
 	osm_sm_t *sm = context;
@@ -358,6 +401,13 @@ void osm_si_rcv_process(IN void *context, IN void *data)
 		"Switch GUID 0x%016" PRIx64 ", TID 0x%" PRIx64 "\n",
 		cl_ntoh64(node_guid), cl_ntoh64(p_smp->trans_id));
 
+	if (ib_smp_get_status(p_smp)) {
+		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+			"MAD status 0x%x received\n",
+			cl_ntoh16(ib_smp_get_status(p_smp)));
+		goto Exit2;
+	}
+
 	CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
 
 	p_node = osm_get_node_by_guid(sm->p_subn, node_guid);
@@ -390,7 +440,13 @@ void osm_si_rcv_process(IN void *context, IN void *data)
 		/* we might get back a request for signaling change was detected */
 		sm->p_subn->force_heavy_sweep = TRUE;
 
-	CL_PLOCK_RELEASE(sm->p_lock);
+	if (p_context->light_sweep || p_context->set_method)
+		goto Exit;
+
+	si_rcv_get_sp0_info(sm, p_node);
+
 Exit:
+	CL_PLOCK_RELEASE(sm->p_lock);
+Exit2:
 	OSM_LOG_EXIT(sm->p_log);
 }
diff --git a/opensm/osm_torus.c b/opensm/osm_torus.c
index 71753cf..330f55d 100644
--- a/opensm/osm_torus.c
+++ b/opensm/osm_torus.c
@@ -7262,7 +7262,7 @@ out:
 }
 
 static
-void build_torus(struct fabric *f, struct torus *t)
+bool build_torus(struct fabric *f, struct torus *t)
 {
 	int i, j, k;
 	int im1, jm1, km1;
@@ -7383,9 +7383,12 @@ again:
 	for (k = 0; k < (int)t->z_sz; k++)
 		for (j = 0; j < (int)t->y_sz; j++)
 			for (i = 0; i < (int)t->x_sz; i++)
-				link_srcsink(t, i, j, k);
+				if (!link_srcsink(t, i, j, k)) {
+					success = false;
+					goto out;
+				}
 out:
-	return;
+	return success;
 }
 
 /*
@@ -9493,7 +9496,11 @@ int torus_build_lfts(void *context)
 		(int)torus->x_sz, (int)torus->y_sz, (int)torus->z_sz,
 		(ALL_MESH(torus->flags) ? "mesh" : "torus"));
 
-	build_torus(fabric, torus);
+	if (!build_torus(fabric, torus)) {
+		OSM_LOG(&torus->osm->log, OSM_LOG_ERROR, "ERR 4E57: "
+			"build_torus finished with errors\n");
+		goto out;
+	}
 
 	OSM_LOG(&torus->osm->log, OSM_LOG_INFO,
 		"Built %d x %d x %d %s w/ %d links, %d switches, %d CA ports\n",
diff --git a/opensm/osm_trap_rcv.c b/opensm/osm_trap_rcv.c
index 472083d..2aef40e 100644
--- a/opensm/osm_trap_rcv.c
+++ b/opensm/osm_trap_rcv.c
@@ -338,7 +338,10 @@ static int shutup_noisy_port(osm_sm_t *sm, ib_net16_t lid, uint8_t port,
 			cl_ntoh16(lid), port);
 		if (disable_port(sm, p))
 			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3811: "
-				"Failed to disable.\n");
+				"Failed to disable noisy physical port 0x%016"
+				PRIx64 ": lid %u, num %u\n",
+				cl_ntoh64(osm_physp_get_port_guid(p)),
+				cl_ntoh16(lid), port);
 		else
 			return 1;
 	}
@@ -387,7 +390,7 @@ static void trap_rcv_process_request(IN osm_sm_t * sm,
 		   Otherwise we start a sweep on the trap 144 caused by
 		   cleaning up SM Cap bit...
 		 */
-		goto Exit;
+		goto Exit2;
 
 	/* update the is_gsi flag according to the mgmt_class field */
 	if (p_madw->p_mad->mgmt_class == IB_MCLASS_SUBN_LID ||
@@ -403,7 +406,7 @@ static void trap_rcv_process_request(IN osm_sm_t * sm,
 	if (p_smp->method != IB_MAD_METHOD_TRAP) {
 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3801: "
 			"Unsupported method 0x%X\n", p_smp->method);
-		goto Exit;
+		goto Exit2;
 	}
 
 	/*
@@ -429,7 +432,7 @@ static void trap_rcv_process_request(IN osm_sm_t * sm,
 			if (sm->p_subn->sm_base_lid == 0) {
 				OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
 					"Received SLID=0 Trap with local LID=0. Ignoring MAD\n");
-				goto Exit;
+				goto Exit2;
 			}
 			OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
 				"Received SLID=0 Trap. Using local LID:%u instead\n",
@@ -662,6 +665,7 @@ check_report:
 
 Exit:
 	CL_PLOCK_RELEASE(sm->p_lock);
+Exit2:
 	OSM_LOG_EXIT(sm->p_log);
 }
 
diff --git a/opensm/osm_ucast_dfsssp.c b/opensm/osm_ucast_dfsssp.c
index 5eaff3d..76a91e6 100644
--- a/opensm/osm_ucast_dfsssp.c
+++ b/opensm/osm_ucast_dfsssp.c
@@ -1541,14 +1541,15 @@ static int update_lft(osm_ucast_mgr_t * p_mgr, vertex_t * adj_list,
 		 */
 
 		if (port == OSM_NO_PATH) {	/* if clause shouldn't be possible in this routing, but who cares */
-			OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
-				"No path to get to LID %" PRIu16
+			OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR,
+				"ERR AD06: No path to get to LID %" PRIu16
 				" from switch 0x%" PRIx64 "\n", lid,
 				cl_ntoh64(osm_node_get_node_guid
 					  (p_sw->p_node)));
 
 			/* do not try to overwrite the ppro of non existing port ... */
 			is_ignored_by_port_prof = TRUE;
+			return 1;
 		} else {
 			OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
 				"Routing LID %" PRIu16 " to port %" PRIu8
@@ -1810,8 +1811,8 @@ static int dfsssp_remove_deadlocks(dfsssp_context_t * dfsssp_ctx)
 {
 	osm_ucast_mgr_t *p_mgr = (osm_ucast_mgr_t *) dfsssp_ctx->p_mgr;
 
-	cl_qmap_t *port_tbl = &p_mgr->p_subn->port_guid_tbl;	/* 1 management port per switch + 1 or 2 ports for each Hca */
-	cl_map_item_t *item1 = NULL, *item2 = NULL;
+	cl_qlist_t *port_tbl = &p_mgr->port_order_list;	/* 1 management port per switch + 1 or 2 ports for each Hca */
+	cl_list_item_t *item1 = NULL, *item2 = NULL;
 	osm_port_t *src_port = NULL, *dest_port = NULL;
 
 	uint32_t i = 0, j = 0, err = 0;
@@ -1858,9 +1859,10 @@ static int dfsssp_remove_deadlocks(dfsssp_context_t * dfsssp_ctx)
 
 	count = 0;
 	/* count all ports (also multiple LIDs) of type CA or SP0 for size of VL table */
-	for (item1 = cl_qmap_head(port_tbl); item1 != cl_qmap_end(port_tbl);
-	     item1 = cl_qmap_next(item1)) {
-		dest_port = (osm_port_t *) item1;
+	for (item1 = cl_qlist_head(port_tbl); item1 != cl_qlist_end(port_tbl);
+	     item1 = cl_qlist_next(item1)) {
+		dest_port = (osm_port_t *)cl_item_obj(item1, dest_port,
+						      list_item);
 		ntype = osm_node_get_type(dest_port->p_node);
 		if (ntype == IB_NODE_TYPE_CA || ntype == IB_NODE_TYPE_SWITCH) {
 			/* only SP0 with SLtoVLMapping support will be processed */
@@ -1883,9 +1885,10 @@ static int dfsssp_remove_deadlocks(dfsssp_context_t * dfsssp_ctx)
 
 	i = 0;
 	/* fill lids into indexing array */
-	for (item1 = cl_qmap_head(port_tbl); item1 != cl_qmap_end(port_tbl);
-	     item1 = cl_qmap_next(item1)) {
-		dest_port = (osm_port_t *) item1;
+	for (item1 = cl_qlist_head(port_tbl); item1 != cl_qlist_end(port_tbl);
+	     item1 = cl_qlist_next(item1)) {
+		dest_port = (osm_port_t *)cl_item_obj(item1, dest_port,
+						      list_item);
 		ntype = osm_node_get_type(dest_port->p_node);
 		if (ntype == IB_NODE_TYPE_CA || ntype == IB_NODE_TYPE_SWITCH) {
 			/* only SP0 with SLtoVLMapping support will be processed */
@@ -1905,19 +1908,21 @@ static int dfsssp_remove_deadlocks(dfsssp_context_t * dfsssp_ctx)
 
 	test_vl = 0;
 	/* fill cdg[0] with routes from each src/dest port combination for all Hca/SP0 in the subnet */
-	for (item1 = cl_qmap_head(port_tbl); item1 != cl_qmap_end(port_tbl);
-	     item1 = cl_qmap_next(item1)) {
-		dest_port = (osm_port_t *) item1;
+	for (item1 = cl_qlist_head(port_tbl); item1 != cl_qlist_end(port_tbl);
+	     item1 = cl_qlist_next(item1)) {
+		dest_port = (osm_port_t *)cl_item_obj(item1, dest_port,
+						      list_item);
 		ntype = osm_node_get_type(dest_port->p_node);
 		if ((ntype != IB_NODE_TYPE_CA && ntype != IB_NODE_TYPE_SWITCH)
 		    || !(dest_port->p_physp->port_info.capability_mask
 		    & IB_PORT_CAP_HAS_SL_MAP))
 			continue;
 
-		for (item2 = cl_qmap_head(port_tbl);
-		     item2 != cl_qmap_end(port_tbl);
-		     item2 = cl_qmap_next(item2)) {
-			src_port = (osm_port_t *) item2;
+		for (item2 = cl_qlist_head(port_tbl);
+		     item2 != cl_qlist_end(port_tbl);
+		     item2 = cl_qlist_next(item2)) {
+			src_port = (osm_port_t *)cl_item_obj(item2, src_port,
+							     list_item);
 			ntype = osm_node_get_type(src_port->p_node);
 			if ((ntype != IB_NODE_TYPE_CA
 			    && ntype != IB_NODE_TYPE_SWITCH)
@@ -2382,6 +2387,7 @@ static int dfsssp_do_dijkstra_routing(void *context)
 
 	/* the intermediate array lived long enough */
 	free(sw_list);
+	sw_list = NULL;
 	/* same is true for the compute node and I/O guid map */
 	destroy_guid_map(&cn_tbl);
 	cn_nodes_provided = FALSE;
@@ -2444,9 +2450,6 @@ static int dfsssp_do_dijkstra_routing(void *context)
 		}
 	}
 
-	/* ordered port list not needed after the dijkstra step */
-	cl_qlist_remove_all(&p_mgr->port_order_list);
-
 	/* try deadlock removal only for the dfsssp routing (not for the sssp case, which is a subset of the dfsssp algorithm) */
 	if (dfsssp_ctx->routing_type == OSM_ROUTING_ENGINE_TYPE_DFSSSP) {
 		/* remove potential deadlocks by assigning different virtual lanes to src/dest paths and balance the lanes */
@@ -2462,6 +2465,9 @@ static int dfsssp_do_dijkstra_routing(void *context)
 		goto ERROR;
 	}
 
+	/* list not needed after the dijkstra steps and deadlock removal */
+	cl_qlist_remove_all(&p_mgr->port_order_list);
+
 	/* print the new_lft for each switch after routing is done */
 	if (OSM_LOG_IS_ACTIVE_V2(p_mgr->p_log, OSM_LOG_DEBUG)) {
 		for (item = cl_qmap_head(sw_tbl); item != cl_qmap_end(sw_tbl);
diff --git a/opensm/osm_ucast_ftree.c b/opensm/osm_ucast_ftree.c
index ee37e79..f646bd0 100644
--- a/opensm/osm_ucast_ftree.c
+++ b/opensm/osm_ucast_ftree.c
@@ -3555,7 +3555,6 @@ static boolean_t fabric_load_roots(IN ftree_fabric_t * p_ftree,
 	unsigned num_roots;
 
 	if (p_ranking_bfs_list) {
-		cl_list_init(p_ranking_bfs_list, 10);
 
 		/* Rank all the roots and add them to list */
 		OSM_LOG(&p_ftree->p_osm->log, OSM_LOG_DEBUG,
@@ -3709,7 +3708,6 @@ static int fabric_rerank_using_root(IN ftree_fabric_t * p_ftree,
 	int res;
 
 	OSM_LOG_ENTER(&p_ftree->p_osm->log);
-	cl_list_init(p_ranking_bfs_list, 10);
 
 	p_next_sw = (ftree_sw_t *) cl_qmap_head(&p_ftree->sw_tbl);
 	while (p_next_sw != (ftree_sw_t *) cl_qmap_end(&p_ftree->sw_tbl)) {
@@ -3732,10 +3730,11 @@ static int fabric_rank(IN ftree_fabric_t * p_ftree)
 	cl_list_t ranking_bfs_list;
 
 	OSM_LOG_ENTER(&p_ftree->p_osm->log);
+	cl_list_init(&ranking_bfs_list, 10);
 
 	if (fabric_roots_provided(p_ftree) &&
 	    fabric_load_roots(p_ftree, &ranking_bfs_list))
-			res = fabric_rank_from_roots(p_ftree, &ranking_bfs_list);
+		res = fabric_rank_from_roots(p_ftree, &ranking_bfs_list);
 	else {
 		res = fabric_rank_from_hcas(p_ftree);
 		if (!res)
diff --git a/opensm/osm_ucast_mgr.c b/opensm/osm_ucast_mgr.c
index f53e288..bb874de 100644
--- a/opensm/osm_ucast_mgr.c
+++ b/opensm/osm_ucast_mgr.c
@@ -700,7 +700,7 @@ static int ucast_mgr_setup_all_switches(osm_subn_t * p_subn)
 			p_subn->opt.port_search_ordering_file);
 		if (parse_node_map(p_subn->opt.port_search_ordering_file,
 				   set_search_ordering_ports, p_subn)) {
-			OSM_LOG(&p_subn->p_osm->log, OSM_LOG_ERROR, "ERR 3A05: "
+			OSM_LOG(&p_subn->p_osm->log, OSM_LOG_ERROR, "ERR 3A0F: "
 				"cannot parse port_search_ordering_file \'%s\'\n",
 				p_subn->opt.port_search_ordering_file);
 		}
@@ -938,18 +938,11 @@ static void ucast_mgr_set_fwd_top(IN cl_map_item_t * p_map_item,
 	} else
 		context.si_context.lft_top_change = FALSE;
 
-	/* check to see if the change state bit is on. If it is - then we
-	   need to clear it. */
-	if (ib_switch_info_get_state_change(&si))
-		life_state = ((p_mgr->p_subn->opt.packet_life_time << 3)
-			      | (si.life_state & IB_SWITCH_PSC)) & 0xfc;
-	else
-		life_state = (p_mgr->p_subn->opt.packet_life_time << 3) & 0xf8;
+	life_state = si.life_state;
+	ib_switch_info_set_life_time(&si, p_mgr->p_subn->opt.packet_life_time);
 
-	if (life_state != si.life_state || ib_switch_info_get_state_change(&si)) {
+	if (life_state != si.life_state)
 		set_swinfo_require = TRUE;
-		si.life_state = life_state;
-	}
 
 	if (set_swinfo_require) {
 		OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
@@ -1009,6 +1002,13 @@ static int set_lft_block(IN osm_switch_t *p_sw, IN osm_ucast_mgr_t *p_mgr,
 		    IB_SMP_DATA_SIZE))
 		return 0;
 
+	/*
+	 * Zero the stored LFT block, so in case the MAD will end up
+	 * with error, we will resend it in the next sweep.
+	 */
+	memset(p_sw->lft + block_id_ho * IB_SMP_DATA_SIZE, 0,
+	       IB_SMP_DATA_SIZE);
+
 	OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG,
 		"Writing FT block %u to switch 0x%" PRIx64 "\n", block_id_ho,
 		cl_ntoh64(context.lft_context.node_guid));
@@ -1021,7 +1021,7 @@ static int set_lft_block(IN osm_switch_t *p_sw, IN osm_ucast_mgr_t *p_mgr,
 			     CL_DISP_MSGID_NONE, &context);
 
 	if (status != IB_SUCCESS) {
-		OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 3A05: "
+		OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 3A10: "
 			"Sending linear fwd. tbl. block failed (%s)\n",
 			ib_get_err_str(status));
 		return -1;
diff --git a/opensm/osm_ucast_updn.c b/opensm/osm_ucast_updn.c
index 2da17de..5048cfa 100644
--- a/opensm/osm_ucast_updn.c
+++ b/opensm/osm_ucast_updn.c
@@ -360,7 +360,7 @@ static int updn_build_lid_matrices(IN updn_t * p_updn)
 
 	/* Check if it's not a switched subnet */
 	if (cl_is_qmap_empty(&p_updn->p_osm->subn.sw_guid_tbl)) {
-		OSM_LOG(&p_updn->p_osm->log, OSM_LOG_ERROR, "ERR AAOB: "
+		OSM_LOG(&p_updn->p_osm->log, OSM_LOG_ERROR, "ERR AA0B: "
 			"This is not a switched subnet, cannot perform UPDN algorithm\n");
 		status = -1;
 		goto _exit;
@@ -528,7 +528,7 @@ static int update_id(void *cxt, uint64_t guid, char *p)
 	id = strtoull(p, &e, 0);
 	if (*e && !isspace(*e)) {
 		OSM_LOG(&osm->log, OSM_LOG_ERROR,
-			"ERR: cannot parse node id \'%s\'", p);
+			"ERR AA05: cannot parse node id \'%s\'", p);
 		return -1;
 	}
 
diff --git a/opensm/osm_vl15intf.c b/opensm/osm_vl15intf.c
index f85252c..06a5001 100644
--- a/opensm/osm_vl15intf.c
+++ b/opensm/osm_vl15intf.c
@@ -60,6 +60,13 @@ static void vl15_send_mad(osm_vl15_t * p_vl, osm_madw_t * p_madw)
 {
 	ib_api_status_t status;
 	boolean_t resp_expected = p_madw->resp_expected;
+	ib_smp_t * p_smp;
+	ib_net16_t attr_id;
+	uint8_t method;
+
+	p_smp = osm_madw_get_smp_ptr(p_madw);
+	method = p_smp->method;
+	attr_id = p_smp->attr_id;
 
 	/*
 	   Non-response-expected mads are not throttled on the wire
@@ -106,8 +113,19 @@ static void vl15_send_mad(osm_vl15_t * p_vl, osm_madw_t * p_madw)
 	   qp0_mads_outstanding will be decremented by send error callback
 	   (called by osm_vendor_send() */
 	cl_atomic_dec(&p_vl->p_stats->qp0_mads_sent);
-	if (!resp_expected)
+	if (!resp_expected) {
 		cl_atomic_dec(&p_vl->p_stats->qp0_unicasts_sent);
+		return;
+	}
+
+	/* need to cause heavy-sweep if resp_expected MAD sending failed */
+	OSM_LOG(p_vl->p_log, OSM_LOG_ERROR, "ERR 3E04: "
+		"%s method failed for attribute 0x%X (%s)\n",
+		method == IB_MAD_METHOD_SET ? "SET" : "GET",
+		cl_ntoh16(attr_id), ib_get_sm_attr_str(attr_id));
+
+	p_vl->p_subn->subnet_initialization_error = TRUE;
+
 }
 
 static void vl15_poller(IN void *p_ptr)
@@ -246,6 +264,7 @@ void osm_vl15_destroy(IN osm_vl15_t * p_vl, IN struct osm_mad_pool *p_pool)
 
 ib_api_status_t osm_vl15_init(IN osm_vl15_t * p_vl, IN osm_vendor_t * p_vend,
 			      IN osm_log_t * p_log, IN osm_stats_t * p_stats,
+			      IN osm_subn_t * p_subn,
 			      IN int32_t max_wire_smps,
 			      IN int32_t max_wire_smps2,
 			      IN uint32_t max_smps_timeout)
@@ -257,6 +276,7 @@ ib_api_status_t osm_vl15_init(IN osm_vl15_t * p_vl, IN osm_vendor_t * p_vend,
 	p_vl->p_vend = p_vend;
 	p_vl->p_log = p_log;
 	p_vl->p_stats = p_stats;
+	p_vl->p_subn = p_subn;
 	p_vl->max_wire_smps = max_wire_smps;
 	p_vl->max_wire_smps2 = max_wire_smps2;
 	p_vl->max_smps_timeout = max_wire_smps < max_wire_smps2 ?
diff --git a/opensm/osm_vl_arb_rcv.c b/opensm/osm_vl_arb_rcv.c
index 3967574..fe6b8c7 100644
--- a/opensm/osm_vl_arb_rcv.c
+++ b/opensm/osm_vl_arb_rcv.c
@@ -92,6 +92,13 @@ void osm_vla_rcv_process(IN void *context, IN void *data)
 
 	CL_ASSERT(p_smp->attr_id == IB_MAD_ATTR_VL_ARBITRATION);
 
+	if (ib_smp_get_status(p_smp)) {
+		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
+			"MAD status 0x%x received\n",
+			cl_ntoh16(ib_smp_get_status(p_smp)));
+		goto Exit2;
+	}
+
 	cl_plock_excl_acquire(sm->p_lock);
 	p_port = osm_get_port_by_guid(sm->p_subn, port_guid);
 	if (!p_port) {
@@ -149,5 +156,6 @@ void osm_vla_rcv_process(IN void *context, IN void *data)
 Exit:
 	cl_plock_release(sm->p_lock);
 
+Exit2:
 	OSM_LOG_EXIT(sm->p_log);
 }
diff --git a/osmeventplugin/src/osmeventplugin.c b/osmeventplugin/src/osmeventplugin.c
index 0f3f9fb..23986db 100644
--- a/osmeventplugin/src/osmeventplugin.c
+++ b/osmeventplugin/src/osmeventplugin.c
@@ -105,7 +105,9 @@ static void handle_port_counter(_log_events_t * log, osm_epi_pe_event_t * pc)
 	    || pc->xmit_constraint_err > 0
 	    || pc->rcv_constraint_err > 0
 	    || pc->link_integrity > 0
-	    || pc->buffer_overrun > 0 || pc->vl15_dropped > 0) {
+	    || pc->buffer_overrun > 0
+	    || pc->vl15_dropped > 0
+	    || pc->xmit_wait > 0) {
 		fprintf(log->log_file,
 			"Port counter errors for node 0x%" PRIx64
 			" (%s) port %d\n", pc->port_id.node_guid,
diff --git a/osmtest/include/osmtest.h b/osmtest/include/osmtest.h
index f63ea74..f66d3a8 100644
--- a/osmtest/include/osmtest.h
+++ b/osmtest/include/osmtest.h
@@ -78,6 +78,7 @@ typedef struct _osmtest_opt {
 	uint32_t transaction_timeout;
 	boolean_t force_log_flush;
 	boolean_t create;
+	boolean_t with_grh;
 	uint32_t retry_count;
 	uint32_t stress;
 	uint32_t mmode;
@@ -129,6 +130,7 @@ typedef struct _osmtest {
 	osmtest_opt_t opt;
 	ib_port_attr_t local_port;
 	ib_gid_t local_port_gid;
+	ib_gid_t sm_port_gid;
 	subnet_t exp_subn;
 	cl_qpool_t node_pool;
 	cl_qpool_t port_pool;
diff --git a/osmtest/main.c b/osmtest/main.c
index f48910b..585b455 100644
--- a/osmtest/main.c
+++ b/osmtest/main.c
@@ -145,6 +145,10 @@ void show_usage()
 	       "          -s3  - Multi-MAD (RMPP) Path Record SA queries\n"
 	       "          -s4  - Single-MAD (non RMPP) get Path Record SA queries\n"
 	       "          Without -s, stress testing is not performed\n\n");
+	printf("-G\n"
+	       "--grh\n"
+	       "          sends all SA queries with GRH with exception of\n"
+	       "	  GetMulti MultiPathRecord\n\n");
 	printf("-M\n"
 	       "--Multicast_Mode\n"
 	       "          This option specify length of Multicast test:\n"
@@ -277,7 +281,7 @@ int main(int argc, char *argv[])
 	int32_t vendor_debug = 0;
 	char flow_name[64];
 	uint32_t next_option;
-	const char *const short_option = "f:l:m:M:d:g:s:t:i:pcvVh";
+	const char *const short_option = "f:l:m:M:d:g:s:t:i:pcvGVh";
 
 	/*
 	 * In the array below, the 2nd parameter specified the number
@@ -297,6 +301,7 @@ int main(int argc, char *argv[])
 		{"port", 0, NULL, 'p'},
 		{"help", 0, NULL, 'h'},
 		{"stress", 1, NULL, 's'},
+		{"grh", 0, NULL, 'G'},
 		{"Multicast_Mode", 1, NULL, 'M'},
 		{"timeout", 1, NULL, 't'},
 		{"verbose", 0, NULL, 'v'},
@@ -330,6 +335,7 @@ int main(int argc, char *argv[])
 	opt.ignore_path_records = FALSE;	/*  Do path Records too */
 	opt.full_world_path_recs = FALSE;
 	opt.flow = OSMT_FLOW_ALL;	/*  run all validation tests */
+	opt.with_grh = FALSE;
 	strcpy(flow_name, "All Validations");
 	strcpy(opt.file_name, "osmtest.dat");
 
@@ -554,11 +560,12 @@ int main(int argc, char *argv[])
 
 		case 'x':
 			log_flags = strtol(optarg, NULL, 0);
-			printf
-			    ("\t\t\t\tVerbose option -vf (log flags = 0x%X)\n",
-			     log_flags);
+			printf("\tVerbose option -vf (log flags = 0x%X)\n",
+			       log_flags);
+			break;
+		case 'G':
+			opt.with_grh = TRUE;
 			break;
-
 		case -1:
 			printf("Done with args\n");
 			break;
diff --git a/osmtest/osmt_multicast.c b/osmtest/osmt_multicast.c
index 93b04a2..9e2f74b 100644
--- a/osmtest/osmt_multicast.c
+++ b/osmtest/osmt_multicast.c
@@ -76,6 +76,10 @@ static void __osmt_print_all_multicast_records(IN osmtest_t * const p_osmt)
 	req.pfn_query_cb = osmtest_query_res_cb;
 	req.p_query_input = &user;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
 	/* UnTrusted (SMKey of 0)  - get the multicast groups */
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 
@@ -176,6 +180,11 @@ ib_api_status_t osmt_query_mcast(IN osmtest_t * const p_osmt)
 	req.pfn_query_cb = osmtest_query_res_cb;
 	req.p_query_input = &user;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 
 	if (status != IB_SUCCESS) {
@@ -327,6 +336,11 @@ osmt_send_mcast_request(IN osmtest_t * const p_osmt,
 	req.pfn_query_cb = osmtest_query_res_cb;
 	req.p_query_input = &user;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 
 	if (status != IB_SUCCESS) {
diff --git a/osmtest/osmt_service.c b/osmtest/osmt_service.c
index 961c904..ae30beb 100644
--- a/osmtest/osmt_service.c
+++ b/osmtest/osmt_service.c
@@ -124,6 +124,11 @@ osmt_register_service(IN osmtest_t * const p_osmt,
 	}
 	user.p_attr = &svc_rec;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A01: "
@@ -228,6 +233,11 @@ osmt_register_service_with_full_key(IN osmtest_t * const p_osmt,
 	}
 	user.p_attr = &svc_rec;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A03: "
@@ -379,6 +389,11 @@ osmt_register_service_with_data(IN osmtest_t * const p_osmt,
 		"Dumping service data b4 send\n");
 	osm_dump_service_record(&p_osmt->log, &svc_rec, OSM_LOG_VERBOSE);
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A05: "
@@ -486,6 +501,11 @@ osmt_get_service_by_id_and_name(IN osmtest_t * const p_osmt,
 	user.comp_mask = IB_SR_COMPMASK_SID | IB_SR_COMPMASK_SNAME;
 	user.p_attr = &svc_rec;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A07: "
@@ -606,6 +626,11 @@ osmt_get_service_by_id(IN osmtest_t * const p_osmt,
 	user.comp_mask = IB_SR_COMPMASK_SID;
 	user.p_attr = &svc_rec;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A09: "
@@ -736,6 +761,12 @@ osmt_get_service_by_name_and_key(IN osmtest_t * const p_osmt,
 	user.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
 	user.comp_mask = IB_SR_COMPMASK_SNAME | IB_SR_COMPMASK_SKEY;
 	user.p_attr = &svc_rec;
+
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A0C: "
@@ -850,6 +881,11 @@ osmt_get_service_by_name(IN osmtest_t * const p_osmt,
 	memcpy(service_name, sr_name, (strlen(sr_name) + 1) * sizeof(char));
 	req.p_query_input = service_name;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A0E: "
@@ -966,6 +1002,11 @@ osmt_get_all_services_and_check_names(IN osmtest_t * const p_osmt,
 	req.pfn_query_cb = osmtest_query_res_cb;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A12: "
@@ -1089,6 +1130,11 @@ osmt_delete_service_by_name(IN osmtest_t * const p_osmt,
 	user.comp_mask = IB_SR_COMPMASK_SNAME;
 	user.p_attr = &svc_rec;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A16: "
diff --git a/osmtest/osmt_slvl_vl_arb.c b/osmtest/osmt_slvl_vl_arb.c
index 49123ad..9e36c04 100644
--- a/osmtest/osmt_slvl_vl_arb.c
+++ b/osmtest/osmt_slvl_vl_arb.c
@@ -135,6 +135,11 @@ osmt_query_vl_arb(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 
 	if (status != IB_SUCCESS) {
@@ -336,6 +341,11 @@ osmt_query_slvl_map(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 
 	if (status != IB_SUCCESS) {
diff --git a/osmtest/osmtest.c b/osmtest/osmtest.c
index 11baa98..1dcadea 100644
--- a/osmtest/osmtest.c
+++ b/osmtest/osmtest.c
@@ -571,6 +571,11 @@ osmtest_get_all_recs(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0004: "
@@ -631,6 +636,12 @@ ib_api_status_t osmtest_validate_sa_class_port_info(IN osmtest_t * const p_osmt)
 	req.p_query_input = 0;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.flow != OSMT_FLOW_CREATE_INVENTORY &&
+	    p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0065: "
@@ -727,6 +738,11 @@ osmtest_get_node_rec(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0071: "
@@ -800,6 +816,11 @@ osmtest_get_node_rec_by_lid(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0073: "
@@ -865,6 +886,11 @@ osmtest_get_path_rec_by_half_world_query(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0063: "
@@ -928,6 +954,11 @@ osmtest_get_path_rec_by_guid_pair(IN osmtest_t * const p_osmt,
 		"Query for path from 0x%" PRIx64 " to 0x%" PRIx64 "\n",
 		cl_ntoh64(sguid), cl_ntoh64(dguid));
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0063: "
@@ -995,6 +1026,11 @@ osmtest_get_path_rec_by_gid_pair(IN osmtest_t * const p_osmt,
 		cl_ntoh64(dgid.unicast.prefix),
 		cl_ntoh64(dgid.unicast.interface_id));
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 006A: "
@@ -1128,6 +1164,11 @@ osmtest_get_port_rec(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0075: "
@@ -1200,6 +1241,11 @@ osmtest_get_port_rec_by_num(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0077: "
@@ -1690,6 +1736,11 @@ ib_api_status_t osmtest_wrong_sm_key_ignored(IN osmtest_t * const p_osmt)
 	req.sm_key = 9999;
 	context.result.p_result_madw = NULL;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
@@ -2046,6 +2097,10 @@ osmtest_get_path_rec_by_lid_pair(IN osmtest_t * const p_osmt,
 
 	req.p_query_input = &lid_pair;
 	req.sm_key = 0;
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
 
 	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
 		"Query for path from 0x%X to 0x%X\n",
@@ -4306,6 +4361,11 @@ osmtest_get_link_rec_by_lid(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 007A: "
@@ -4384,6 +4444,11 @@ osmtest_get_guidinfo_rec_by_lid(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 007C: "
@@ -4462,6 +4527,11 @@ osmtest_get_pkeytbl_rec_by_lid(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = sm_key;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 007E: "
@@ -4540,6 +4610,11 @@ osmtest_get_sw_info_rec_by_lid(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 006C: "
@@ -4618,6 +4693,11 @@ osmtest_get_lft_rec_by_lid(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 008A: "
@@ -4696,6 +4776,11 @@ osmtest_get_mft_rec_by_lid(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 009B: "
@@ -4787,6 +4872,11 @@ osmtest_sminfo_record_request(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 008C: "
@@ -4896,6 +4986,11 @@ osmtest_informinfo_request(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 008E: "
@@ -5026,6 +5121,11 @@ osmtest_validate_single_node_rec_lid(IN osmtest_t * const p_osmt,
 	req.p_query_input = &user;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 
 	if (status != IB_SUCCESS) {
@@ -5095,9 +5195,9 @@ osmtest_validate_single_port_rec_lid(IN osmtest_t * const p_osmt,
 	memset(&context, 0, sizeof(context));
 
 	context.p_osmt = p_osmt;
-	osmtest_get_port_rec_by_num(p_osmt,
-				    p_port->rec.lid,
-				    p_port->rec.port_num, &context);
+	status = osmtest_get_port_rec_by_num(p_osmt,
+					     p_port->rec.lid,
+					     p_port->rec.port_num, &context);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0108: "
 			"ib_query failed (%s)\n", ib_get_err_str(status));
@@ -5163,6 +5263,11 @@ osmtest_validate_single_path_rec_guid_pair(IN osmtest_t * const p_osmt,
 	req.p_query_input = p_pair;
 	req.sm_key = 0;
 
+	if (p_osmt->opt.with_grh) {
+		req.with_grh = 1;
+		memcpy(&req.gid, &p_osmt->sm_port_gid, 16);
+	}
+
 	status = osmv_query_sa(p_osmt->h_bind, &req);
 	if (status != IB_SUCCESS) {
 		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0110: "
@@ -5247,6 +5352,49 @@ Exit:
 }
 
 static ib_api_status_t
+osmtest_get_sm_gid(IN osmtest_t * const p_osmt)
+{
+	cl_status_t status = IB_SUCCESS;
+	node_t *p_node;
+	const cl_qmap_t *p_tbl;
+	ib_port_attr_t *local_port;
+
+	OSM_LOG_ENTER(&p_osmt->log);
+
+	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
+		"Calculate SM GID for use in subsequent SA queries\n");
+
+	local_port = &p_osmt->local_port;
+	p_osmt->sm_port_gid.unicast.prefix =
+		cl_hton64(p_osmt->local_port_gid.unicast.prefix);
+
+	if (local_port->lid != local_port->sm_lid) {
+		p_tbl = &p_osmt->exp_subn.node_lid_tbl;
+		p_node = (node_t *) cl_qmap_get(p_tbl, local_port->sm_lid);
+		if (p_node == (node_t *) cl_qmap_end(p_tbl)) {
+			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
+				"ERR 0154: SM LID 0x%X doesn't exist\n",
+				local_port->sm_lid);
+			status = IB_ERROR;
+			goto Exit;
+		}
+		p_osmt->sm_port_gid.unicast.interface_id = p_node->rec.node_info.port_guid;
+	} else {
+		p_osmt->sm_port_gid.unicast.interface_id =
+			cl_hton64(p_osmt->local_port_gid.unicast.interface_id);
+	}
+
+	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
+		"SM GID 0x%016" PRIx64 " 0x%016" PRIx64 "\n",
+		cl_ntoh64(p_osmt->sm_port_gid.unicast.prefix),
+		cl_ntoh64(p_osmt->sm_port_gid.unicast.interface_id));
+
+Exit:
+	OSM_LOG_EXIT(&p_osmt->log);
+	return (status);
+}
+
+static ib_api_status_t
 osmtest_validate_single_path_recs(IN osmtest_t * const p_osmt)
 {
 	path_t *p_path;
@@ -7299,6 +7447,17 @@ ib_api_status_t osmtest_run(IN osmtest_t * const p_osmt)
 	ib_api_status_t status = IB_SUCCESS;
 
 	OSM_LOG_ENTER(&p_osmt->log);
+	if (p_osmt->opt.flow != OSMT_FLOW_CREATE_INVENTORY &&
+	    p_osmt->opt.with_grh) {
+		/* Get SM GID for GRH DGID */
+		status = osmtest_get_sm_gid(p_osmt);
+		if (status != IB_SUCCESS) {
+			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
+				"ERR 0153: calculating SM GID failed: (%s)\n",
+				ib_get_err_str(status));
+			goto Exit;
+		}
+	}
 
 	status = osmtest_validate_sa_class_port_info(p_osmt);
 	if (status != IB_SUCCESS) {
diff --git a/scripts/opensm.init b/scripts/opensm.init
index ff86b32..8ddaa45 100644
--- a/scripts/opensm.init
+++ b/scripts/opensm.init
@@ -80,6 +80,7 @@ start () {
     fi
     echo -n "Starting opensm: "
     ${exec_prefix}/sbin/opensm --daemon --pidfile $pidfile $OPTIONS > /dev/null
+    RETVAL=$?
     if [[ $RETVAL -eq 0 ]]; then
         success
     else
@@ -91,6 +92,7 @@ start () {
 stop () {
     echo -n "Shutting down opensm: "
     killproc opensm
+    RETVAL=$?
     if [[ $RETVAL -eq 0 ]]; then
         success
     else
diff --git a/scripts/opensm.init.in b/scripts/opensm.init.in
index 227c38c..f1c6c1a 100644
--- a/scripts/opensm.init.in
+++ b/scripts/opensm.init.in
@@ -80,6 +80,7 @@ start () {
     fi
     echo -n "Starting opensm: "
     @sbindir@/opensm --daemon --pidfile $pidfile $OPTIONS > /dev/null
+    RETVAL=$?
     if [[ $RETVAL -eq 0 ]]; then
         success
     else
@@ -91,6 +92,7 @@ start () {
 stop () {
     echo -n "Shutting down opensm: "
     killproc opensm
+    RETVAL=$?
     if [[ $RETVAL -eq 0 ]]; then
         success
     else

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ofed/opensm.git



More information about the Pkg-ofed-commits mailing list