>From 4ce90ea725bf8aa78dae50854673faff0389fb77 Mon Sep 17 00:00:00 2001
From: Tim Meier <meier3@llnl.gov>
Date: Wed, 30 Jan 2008 14:03:50 -0800
Subject: [PATCH] opensm: diags better error checking for DR option

The -D option for specifying a direct route for both
iblinkinfo.pl and ibqueryerrors.pl aborts with an
error message if the route does not lead to a switch.

Signed-off-by: Tim Meier <meier3@llnl.gov>
---
 infiniband-diags/scripts/IBswcountlimits.pm |  594 ++++++++++++++-------------
 infiniband-diags/scripts/iblinkinfo.pl      |  436 +++++++++++---------
 infiniband-diags/scripts/ibqueryerrors.pl   |  259 ++++++------
 3 files changed, 695 insertions(+), 594 deletions(-)

diff --git a/infiniband-diags/scripts/IBswcountlimits.pm b/infiniband-diags/scripts/IBswcountlimits.pm
index e6ffc82..bddc421 100755
--- a/infiniband-diags/scripts/IBswcountlimits.pm
+++ b/infiniband-diags/scripts/IBswcountlimits.pm
@@ -38,106 +38,120 @@
 
 use strict;
 
-%IBswcountlimits::cur_counts = ();
-%IBswcountlimits::new_counts = ();
+%IBswcountlimits::cur_counts      = ();
+%IBswcountlimits::new_counts      = ();
 @IBswcountlimits::suppress_errors = ();
-$IBswcountlimits::link_ends = undef;
-$IBswcountlimits::pause_time = 10;
-$IBswcountlimits::cache_dir = "/var/cache/infiniband-diags";
+$IBswcountlimits::link_ends       = undef;
+$IBswcountlimits::pause_time      = 10;
+$IBswcountlimits::cache_dir       = "/var/cache/infiniband-diags";
 
 # all the PerfMgt counters
 @IBswcountlimits::counters = (
-   "SymbolErrors",
-   "LinkRecovers",
-   "LinkDowned",
-   "RcvErrors",
-   "RcvRemotePhysErrors",
-   "RcvSwRelayErrors",
-   "XmtDiscards",
-   "XmtConstraintErrors",
-   "RcvConstraintErrors",
-   "LinkIntegrityErrors",
-   "ExcBufOverrunErrors",
-   "VL15Dropped",
-   "XmtData",
-   "RcvData",
-   "XmtPkts",
-   "RcvPkts"
+	"SymbolErrors",        "LinkRecovers",
+	"LinkDowned",          "RcvErrors",
+	"RcvRemotePhysErrors", "RcvSwRelayErrors",
+	"XmtDiscards",         "XmtConstraintErrors",
+	"RcvConstraintErrors", "LinkIntegrityErrors",
+	"ExcBufOverrunErrors", "VL15Dropped",
+	"XmtData",             "RcvData",
+	"XmtPkts",             "RcvPkts"
 );
 
 # non-critical counters
 %IBswcountlimits::error_counters = (
-   "SymbolErrors", "No action is required except if counter is increasing along with LinkRecovers",
-   "LinkRecovers", "If this is increasing along with SymbolErrors this may indicate a bad link, run ibswportwatch.pl on this port",
-   "LinkDowned", "Number of times the port has gone down (Usually for valid reasons)",
-   "RcvErrors", "This is a bad link, if the link is internal to a 288 try setting SDR, otherwise check the cable",
-   "RcvRemotePhysErrors", "This indicates a problem ELSEWHERE in the fabric.",
-   "XmtDiscards", "This is a symptom of congestion and may require tweaking either HOQ or switch lifetime values",
-   "XmtConstraintErrors", "This is a result of bad partitioning, check partition configuration.",
-   "RcvConstraintErrors", "This is a result of bad partitioning, check partition configuration.",
-   "LinkIntegrityErrors", "May indicate a bad link, run ibswportwatch.pl on this port",
-   "ExcBufOverrunErrors", "This is a flow control state machine error and can be caused by packets with physical errors",
-   "VL15Dropped", "check with ibswportwatch.pl, if increasing in SMALL increments, OK",
-   "RcvSwRelayErrors", "This counter can increase due to a valid network event"
+	"SymbolErrors",
+"No action is required except if counter is increasing along with LinkRecovers",
+	"LinkRecovers",
+"If this is increasing along with SymbolErrors this may indicate a bad link, run ibswportwatch.pl on this port",
+	"LinkDowned",
+	"Number of times the port has gone down (Usually for valid reasons)",
+	"RcvErrors",
+"This is a bad link, if the link is internal to a 288 try setting SDR, otherwise check the cable",
+	"RcvRemotePhysErrors",
+	"This indicates a problem ELSEWHERE in the fabric.",
+	"XmtDiscards",
+"This is a symptom of congestion and may require tweaking either HOQ or switch lifetime values",
+	"XmtConstraintErrors",
+	"This is a result of bad partitioning, check partition configuration.",
+	"RcvConstraintErrors",
+	"This is a result of bad partitioning, check partition configuration.",
+	"LinkIntegrityErrors",
+	"May indicate a bad link, run ibswportwatch.pl on this port",
+	"ExcBufOverrunErrors",
+"This is a flow control state machine error and can be caused by packets with physical errors",
+	"VL15Dropped",
+	"check with ibswportwatch.pl, if increasing in SMALL increments, OK",
+	"RcvSwRelayErrors",
+	"This counter can increase due to a valid network event"
 );
 
 sub check_counters
 {
-   my $print_action = $_[0];
-   my $actions = undef;
-
-   COUNTER: foreach my $cnt (keys %IBswcountlimits::error_counters) {
-      if ($IBswcountlimits::cur_counts{$cnt} > 0)
-      {
-         foreach my $sup_cnt (@IBswcountlimits::suppress_errors) {
-            if ("$cnt" eq $sup_cnt) { next COUNTER; }
-         }
-         print " [$cnt == $IBswcountlimits::cur_counts{$cnt}]";
-         if ("$print_action" eq "yes")
-         {
-            $actions = join " ",($actions,"         $cnt: $IBswcountlimits::error_counters{$cnt}\n");
-         }
-      }
-   }
-
-   if ($actions)
-   {
-      print "\n         Actions:\n$actions";
-   }
+	my $print_action = $_[0];
+	my $actions      = undef;
+
+	COUNTER: foreach my $cnt (keys %IBswcountlimits::error_counters) {
+		if ($IBswcountlimits::cur_counts{$cnt} > 0) {
+			foreach my $sup_cnt (@IBswcountlimits::suppress_errors) {
+				if ("$cnt" eq $sup_cnt) { next COUNTER; }
+			}
+			print " [$cnt == $IBswcountlimits::cur_counts{$cnt}]";
+			if ("$print_action" eq "yes") {
+				$actions = join " ",
+				  (
+					$actions,
+					"         $cnt: $IBswcountlimits::error_counters{$cnt}\n"
+				  );
+			}
+		}
+	}
+
+	if ($actions) {
+		print "\n         Actions:\n$actions";
+	}
 }
 
 # Data counters
 %IBswcountlimits::data_counters = (
-   "XmtData", "Total number of data octets, divided by 4, transmitted on all VLs from the port",
-   "RcvData", "Total number of data octets, divided by 4, received on all VLs to the port",
-   "XmtPkts", "Total number of packets, excluding link packets, transmitted on all VLs from the port",
-   "RcvPkts", "Total number of packets, excluding link packets, received on all VLs to the port"
+	"XmtData",
+"Total number of data octets, divided by 4, transmitted on all VLs from the port",
+	"RcvData",
+"Total number of data octets, divided by 4, received on all VLs to the port",
+	"XmtPkts",
+"Total number of packets, excluding link packets, transmitted on all VLs from the port",
+	"RcvPkts",
+"Total number of packets, excluding link packets, received on all VLs to the port"
 );
 
 sub check_data_counters
 {
-   my $print_action = $_[0];
-   my $actions = undef;
-
-   COUNTER: foreach my $cnt (keys %IBswcountlimits::data_counters) {
-      print " [$cnt == $IBswcountlimits::cur_counts{$cnt}]";
-      if ("$print_action" eq "yes")
-      {
-         $actions = join " ",($actions,"         $cnt: $IBswcountlimits::data_counters{$cnt}\n");
-      }
-   }
-   if ($actions)
-   {
-      print "\n         Descriptions:\n$actions";
-   }
+	my $print_action = $_[0];
+	my $actions      = undef;
+
+	COUNTER: foreach my $cnt (keys %IBswcountlimits::data_counters) {
+		print " [$cnt == $IBswcountlimits::cur_counts{$cnt}]";
+		if ("$print_action" eq "yes") {
+			$actions = join " ",
+			  (
+				$actions,
+				"         $cnt: $IBswcountlimits::data_counters{$cnt}\n"
+			  );
+		}
+	}
+	if ($actions) {
+		print "\n         Descriptions:\n$actions";
+	}
 }
 
 sub print_data_rates
 {
-   COUNTER: foreach my $cnt (keys %IBswcountlimits::data_counters) {
-      my $cnt_per_second = calculate_rate($IBswcountlimits::cur_counts{$cnt}, $IBswcountlimits::new_counts{$cnt});
-      print "   $cnt_per_second $cnt/second\n";
-   }
+	COUNTER: foreach my $cnt (keys %IBswcountlimits::data_counters) {
+		my $cnt_per_second = calculate_rate(
+			$IBswcountlimits::cur_counts{$cnt},
+			$IBswcountlimits::new_counts{$cnt}
+		);
+		print "   $cnt_per_second $cnt/second\n";
+	}
 }
 
 # =========================================================================
@@ -146,72 +160,68 @@ sub print_data_rates
 # calculate_rate old_count new_count
 sub calculate_rate
 {
-   my $rate = 0;
-   my $old_val = $_[0];
-   my $new_val = $_[1];
-   my $rate = ($new_val - $old_val)/$IBswcountlimits::pause_time;
-   return ($rate);
+	my $rate    = 0;
+	my $old_val = $_[0];
+	my $new_val = $_[1];
+	my $rate    = ($new_val - $old_val) / $IBswcountlimits::pause_time;
+	return ($rate);
 }
 %IBswcountlimits::rate_dep_thresholds = (
-   "SymbolErrors", 10,
-   "LinkRecovers", 10,
-   "RcvErrors", 10,
-   "LinkIntegrityErrors", 10,
-   "XmtDiscards", 10
+	"SymbolErrors", 10, "LinkRecovers",        10,
+	"RcvErrors",    10, "LinkIntegrityErrors", 10,
+	"XmtDiscards",  10
 );
 
 sub check_counter_rates
 {
-   foreach my $rate_count (keys %IBswcountlimits::rate_dep_thresholds)
-   {
-      my $rate = calculate_rate ($IBswcountlimits::cur_counts{$rate_count}, $IBswcountlimits::new_counts{$rate_count});
-      if ($rate > $IBswcountlimits::rate_dep_thresholds{$rate_count})
-      {
-         print "Detected excessive rate for $rate_count ($rate cnts/sec)\n";
-      }
-      elsif ($rate > 0)
-      {
-         print "Detected rate for $rate_count ($rate cnts/sec)\n";
-      }
-   }
+	foreach my $rate_count (keys %IBswcountlimits::rate_dep_thresholds) {
+		my $rate = calculate_rate(
+			$IBswcountlimits::cur_counts{$rate_count},
+			$IBswcountlimits::new_counts{$rate_count}
+		);
+		if ($rate > $IBswcountlimits::rate_dep_thresholds{$rate_count}) {
+			print "Detected excessive rate for $rate_count ($rate cnts/sec)\n";
+		} elsif ($rate > 0) {
+			print "Detected rate for $rate_count ($rate cnts/sec)\n";
+		}
+	}
 }
 
 # =========================================================================
 #
 sub clear_counters
 {
-   # clear the counters
-   foreach my $count (@IBswcountlimits::counters)
-   {
-      $IBswcountlimits::cur_counts{$count} = 0;
-   }
+	# clear the counters
+	foreach my $count (@IBswcountlimits::counters) {
+		$IBswcountlimits::cur_counts{$count} = 0;
+	}
 }
 
 # =========================================================================
 #
 sub any_counts
 {
-   my $total = 0;
-   my $count = 0;
-   foreach $count (keys %IBswcountlimits::critical) {
-      $total = $total + $IBswcountlimits::cur_counts{$count};
-   }
-   COUNTER: foreach $count (keys %IBswcountlimits::error_counters) {
-      foreach my $sup_cnt (@IBswcountlimits::suppress_errors) {
-         if ("$count" eq $sup_cnt) { next COUNTER; }
-      }
-      $total = $total + $IBswcountlimits::cur_counts{$count};
-   }
-   return ($total);
+	my $total = 0;
+	my $count = 0;
+	foreach $count (keys %IBswcountlimits::critical) {
+		$total = $total + $IBswcountlimits::cur_counts{$count};
+	}
+	COUNTER: foreach $count (keys %IBswcountlimits::error_counters) {
+		foreach my $sup_cnt (@IBswcountlimits::suppress_errors) {
+			if ("$count" eq $sup_cnt) { next COUNTER; }
+		}
+		$total = $total + $IBswcountlimits::cur_counts{$count};
+	}
+	return ($total);
 }
 
 # =========================================================================
 #
 sub ensure_cache_dir
 {
-   if (!(-d "$IBswcountlimits::cache_dir")) {
-       mkdir $IBswcountlimits::cache_dir, 0700;
-   }
+	if (!(-d "$IBswcountlimits::cache_dir")) {
+		mkdir $IBswcountlimits::cache_dir, 0700;
+	}
 }
 
 # =========================================================================
@@ -219,10 +229,11 @@ sub ensure_cache_dir
 #
 sub get_cache_file
 {
-   my $ca_name = $_[0];
-   my $ca_port = $_[1];
-   ensure_cache_dir;
-   return ("$IBswcountlimits::cache_dir/ibnetdiscover-$ca_name-$ca_port.topology");
+	my $ca_name = $_[0];
+	my $ca_port = $_[1];
+	ensure_cache_dir;
+	return (
+		"$IBswcountlimits::cache_dir/ibnetdiscover-$ca_name-$ca_port.topology");
 }
 
 # =========================================================================
@@ -230,13 +241,13 @@ sub get_cache_file
 #
 sub get_ca_name_port_param_string
 {
-   my $ca_name = $_[0];
-   my $ca_port = $_[1];
+	my $ca_name = $_[0];
+	my $ca_port = $_[1];
 
-   if ("$ca_name" ne "") { $ca_name = "-C $ca_name"; }
-   if ("$ca_port" ne "") { $ca_port = "-P $ca_port"; }
+	if ("$ca_name" ne "") { $ca_name = "-C $ca_name"; }
+	if ("$ca_port" ne "") { $ca_port = "-P $ca_port"; }
 
-   return ("$ca_name $ca_port");
+	return ("$ca_name $ca_port");
 }
 
 # =========================================================================
@@ -244,15 +255,15 @@ sub get_ca_name_port_param_string
 #
 sub generate_ibnetdiscover_topology
 {
-   my $ca_name = $_[0];
-   my $ca_port = $_[1];
-   my $cache_file = get_cache_file($ca_name, $ca_port);
-   my $extra_params = get_ca_name_port_param_string($ca_name, $ca_port);
-
-   `ibnetdiscover -g $extra_params > $cache_file`;
-   if ($? != 0) {
-       die "Execution of ibnetdiscover failed with errors\n";
-   }
+	my $ca_name      = $_[0];
+	my $ca_port      = $_[1];
+	my $cache_file   = get_cache_file($ca_name, $ca_port);
+	my $extra_params = get_ca_name_port_param_string($ca_name, $ca_port);
+
+	`ibnetdiscover -g $extra_params > $cache_file`;
+	if ($? != 0) {
+		die "Execution of ibnetdiscover failed with errors\n";
+	}
 }
 
 # =========================================================================
@@ -260,106 +271,143 @@ sub generate_ibnetdiscover_topology
 #
 sub get_link_ends
 {
-   my $regenerate_map = $_[0];
-   my $ca_name = $_[1];
-   my $ca_port = $_[2];
-
-   my $cache_file = get_cache_file($ca_name, $ca_port);
-
-   if ($regenerate_map || !(-f "$cache_file")) { generate_ibnetdiscover_topology($ca_name, $ca_port); }
-   open IBNET_TOPO, "<$cache_file" or die "Failed to open ibnet topology: $!\n";
-   my $in_switch = "no";
-   my $desc = "";
-   my $guid = "";
-   my $loc_sw_lid = "";
-
-   my $loc_port = "";
-   my $line = "";
-
-   while ($line = <IBNET_TOPO>)
-   {
-      if ($line =~ /^Switch.*\"S-(.*)\"\s+#.*\"(.*)\".* lid (\d+).*/)
-      {
-         $guid = $1;
-         $desc = $2;
-         $loc_sw_lid = $3;
-         $in_switch = "yes";
-      }
-      if ( $in_switch eq "yes" )
-      {
-	 my $rec = undef;
-         if ($line =~ /^\[(\d+)\]\s+\"[HSR]-(.+)\"\[(\d+)\](\(.+\))?\s+#.*\"(.*)\"\.* lid (\d+).*/)
-         {
-            $loc_port = $1;
-            my $rem_guid = $2;
-            my $rem_port = $3;
-	    my $rem_port_guid = $4;
-            my $rem_desc = $5;
-            my $rem_lid = $6;
-            $rec = { loc_guid => "0x$guid", loc_port => $loc_port, loc_ext_port => "",
-			loc_desc => $desc, loc_sw_lid => $loc_sw_lid,
-			rem_guid => "0x$rem_guid", rem_lid => $rem_lid,
-			rem_port => $rem_port, rem_ext_port => "", rem_desc => $rem_desc,
-			rem_port_guid => $rem_port_guid };
-         }
-         if ($line =~ /^\[(\d+)\]\[ext (\d+)\]\s+\"[HSR]-(.+)\"\[(\d+)\](\(.+\))?\s+#.*\"(.*)\"\.* lid (\d+).*/)
-         {
-            $loc_port = $1;
-            my $loc_ext_port = $2;
-            my $rem_guid = $3;
-            my $rem_port = $4;
-	    my $rem_port_guid = $5;
-            my $rem_desc = $6;
-            my $rem_lid = $7;
-            $rec = { loc_guid => "0x$guid", loc_port => $loc_port, loc_ext_port => $loc_ext_port,
-			loc_desc => $desc, loc_sw_lid => $loc_sw_lid,
-			rem_guid => "0x$rem_guid", rem_lid => $rem_lid,
-			rem_port => $rem_port, rem_ext_port => "", rem_desc => $rem_desc,
-			rem_port_guid => $rem_port_guid };
-         }
-         if ($line =~ /^\[(\d+)\]\s+\"[HSR]-(.+)\"\[(\d+)\]\[ext (\d+)\](\(.+\))?\s+#.*\"(.*)\"\.* lid (\d+).*/)
-         {
-            $loc_port = $1;
-            my $rem_guid = $2;
-            my $rem_port = $3;
-            my $rem_ext_port = $4;
-	    my $rem_port_guid = $5;
-            my $rem_desc = $6;
-            my $rem_lid = $7;
-            $rec = { loc_guid => "0x$guid", loc_port => $loc_port, loc_ext_port => "",
-			loc_desc => $desc, loc_sw_lid => $loc_sw_lid,
-			rem_guid => "0x$rem_guid", rem_lid => $rem_lid,
-			rem_port => $rem_port, rem_ext_port => $rem_ext_port,
-			rem_desc => $rem_desc,
-			rem_port_guid => $rem_port_guid };
-         }
-         if ($line =~ /^\[(\d+)\]\[ext (\d+)\]\s+\"[HSR]-(.+)\"\[(\d+)\]\[ext (\d+)\](\(.+\))?\s+#.*\"(.*)\"\.* lid (\d+).*/)
-         {
-            $loc_port = $1;
-            my $loc_ext_port = $2;
-            my $rem_guid = $3;
-            my $rem_port = $4;
-            my $rem_ext_port = $5;
-	    my $rem_port_guid = $6;
-            my $rem_desc = $7;
-            my $rem_lid = $8;
-            $rec = { loc_guid => "0x$guid", loc_port => $loc_port, loc_ext_port => $loc_ext_port,
-			loc_desc => $desc, loc_sw_lid => $loc_sw_lid,
-			rem_guid => "0x$rem_guid", rem_lid => $rem_lid,
-			rem_port => $rem_port, rem_ext_port => $rem_ext_port,
-			rem_desc => $rem_desc,
-			rem_port_guid => $rem_port_guid };
-         }
-	 if ($rec)
-	 {
-	    $rec->{rem_port_guid} =~ s/\((.*)\)/$1/;
-	    $IBswcountlimits::link_ends{"0x$guid"}{$loc_port} = $rec;
-	 }
-      }
-
-      if ($line =~ /^Ca.*/ || $line =~ /^Rt.*/) { $in_switch = "no"; }
-   }
-   close IBNET_TOPO;
+	my $regenerate_map = $_[0];
+	my $ca_name        = $_[1];
+	my $ca_port        = $_[2];
+
+	my $cache_file = get_cache_file($ca_name, $ca_port);
+
+	if ($regenerate_map || !(-f "$cache_file")) {
+		generate_ibnetdiscover_topology($ca_name, $ca_port);
+	}
+	open IBNET_TOPO, "<$cache_file"
+	  or die "Failed to open ibnet topology: $!\n";
+	my $in_switch  = "no";
+	my $desc       = "";
+	my $guid       = "";
+	my $loc_sw_lid = "";
+
+	my $loc_port = "";
+	my $line     = "";
+
+	while ($line = <IBNET_TOPO>) {
+		if ($line =~ /^Switch.*\"S-(.*)\"\s+#.*\"(.*)\".* lid (\d+).*/) {
+			$guid       = $1;
+			$desc       = $2;
+			$loc_sw_lid = $3;
+			$in_switch  = "yes";
+		}
+		if ($in_switch eq "yes") {
+			my $rec = undef;
+			if ($line =~
+/^\[(\d+)\]\s+\"[HSR]-(.+)\"\[(\d+)\](\(.+\))?\s+#.*\"(.*)\"\.* lid (\d+).*/
+			  )
+			{
+				$loc_port = $1;
+				my $rem_guid      = $2;
+				my $rem_port      = $3;
+				my $rem_port_guid = $4;
+				my $rem_desc      = $5;
+				my $rem_lid       = $6;
+				$rec = {
+					loc_guid      => "0x$guid",
+					loc_port      => $loc_port,
+					loc_ext_port  => "",
+					loc_desc      => $desc,
+					loc_sw_lid    => $loc_sw_lid,
+					rem_guid      => "0x$rem_guid",
+					rem_lid       => $rem_lid,
+					rem_port      => $rem_port,
+					rem_ext_port  => "",
+					rem_desc      => $rem_desc,
+					rem_port_guid => $rem_port_guid
+				};
+			}
+			if ($line =~
+/^\[(\d+)\]\[ext (\d+)\]\s+\"[HSR]-(.+)\"\[(\d+)\](\(.+\))?\s+#.*\"(.*)\"\.* lid (\d+).*/
+			  )
+			{
+				$loc_port = $1;
+				my $loc_ext_port  = $2;
+				my $rem_guid      = $3;
+				my $rem_port      = $4;
+				my $rem_port_guid = $5;
+				my $rem_desc      = $6;
+				my $rem_lid       = $7;
+				$rec = {
+					loc_guid      => "0x$guid",
+					loc_port      => $loc_port,
+					loc_ext_port  => $loc_ext_port,
+					loc_desc      => $desc,
+					loc_sw_lid    => $loc_sw_lid,
+					rem_guid      => "0x$rem_guid",
+					rem_lid       => $rem_lid,
+					rem_port      => $rem_port,
+					rem_ext_port  => "",
+					rem_desc      => $rem_desc,
+					rem_port_guid => $rem_port_guid
+				};
+			}
+			if ($line =~
+/^\[(\d+)\]\s+\"[HSR]-(.+)\"\[(\d+)\]\[ext (\d+)\](\(.+\))?\s+#.*\"(.*)\"\.* lid (\d+).*/
+			  )
+			{
+				$loc_port = $1;
+				my $rem_guid      = $2;
+				my $rem_port      = $3;
+				my $rem_ext_port  = $4;
+				my $rem_port_guid = $5;
+				my $rem_desc      = $6;
+				my $rem_lid       = $7;
+				$rec = {
+					loc_guid      => "0x$guid",
+					loc_port      => $loc_port,
+					loc_ext_port  => "",
+					loc_desc      => $desc,
+					loc_sw_lid    => $loc_sw_lid,
+					rem_guid      => "0x$rem_guid",
+					rem_lid       => $rem_lid,
+					rem_port      => $rem_port,
+					rem_ext_port  => $rem_ext_port,
+					rem_desc      => $rem_desc,
+					rem_port_guid => $rem_port_guid
+				};
+			}
+			if ($line =~
+/^\[(\d+)\]\[ext (\d+)\]\s+\"[HSR]-(.+)\"\[(\d+)\]\[ext (\d+)\](\(.+\))?\s+#.*\"(.*)\"\.* lid (\d+).*/
+			  )
+			{
+				$loc_port = $1;
+				my $loc_ext_port  = $2;
+				my $rem_guid      = $3;
+				my $rem_port      = $4;
+				my $rem_ext_port  = $5;
+				my $rem_port_guid = $6;
+				my $rem_desc      = $7;
+				my $rem_lid       = $8;
+				$rec = {
+					loc_guid      => "0x$guid",
+					loc_port      => $loc_port,
+					loc_ext_port  => $loc_ext_port,
+					loc_desc      => $desc,
+					loc_sw_lid    => $loc_sw_lid,
+					rem_guid      => "0x$rem_guid",
+					rem_lid       => $rem_lid,
+					rem_port      => $rem_port,
+					rem_ext_port  => $rem_ext_port,
+					rem_desc      => $rem_desc,
+					rem_port_guid => $rem_port_guid
+				};
+			}
+			if ($rec) {
+				$rec->{rem_port_guid} =~ s/\((.*)\)/$1/;
+				$IBswcountlimits::link_ends{"0x$guid"}{$loc_port} = $rec;
+			}
+		}
+
+		if ($line =~ /^Ca.*/ || $line =~ /^Rt.*/) { $in_switch = "no"; }
+	}
+	close IBNET_TOPO;
 }
 
 # =========================================================================
@@ -367,19 +415,19 @@ sub get_link_ends
 #
 sub get_num_ports
 {
-        my $guid = $_[0];
-	my $ca_name = $_[1];
-	my $ca_port = $_[2];
-        my $num_ports = 0;
-        my $extra_params = get_ca_name_port_param_string($ca_name, $ca_port);
-
-        my $data = `smpquery $extra_params -G nodeinfo $guid`;
-        my @lines = split("\n", $data);
-        my $pkt_lifetime = "";
-        foreach my $line (@lines) {
-                if ($line =~ /^NumPorts:\.+(.*)/) { $num_ports = $1; }
-        }
-        return ($num_ports);
+	my $guid         = $_[0];
+	my $ca_name      = $_[1];
+	my $ca_port      = $_[2];
+	my $num_ports    = 0;
+	my $extra_params = get_ca_name_port_param_string($ca_name, $ca_port);
+
+	my $data         = `smpquery $extra_params -G nodeinfo $guid`;
+	my @lines        = split("\n", $data);
+	my $pkt_lifetime = "";
+	foreach my $line (@lines) {
+		if ($line =~ /^NumPorts:\.+(.*)/) { $num_ports = $1; }
+	}
+	return ($num_ports);
 }
 
 # =========================================================================
@@ -387,14 +435,14 @@ sub get_num_ports
 #
 sub convert_dr_to_guid
 {
-        my $guid = undef;
-
-        my $data = `smpquery nodeinfo -D $_[0]`;
-        my @lines = split("\n", $data);
-        foreach my $line (@lines) {
-                if ($line =~ /^PortGuid:\.+(.*)/) { $guid = $1; }
-        }
-        $guid;
+	my $guid = undef;
+
+	my $data = `smpquery nodeinfo -D $_[0]`;
+	my @lines = split("\n", $data);
+	foreach my $line (@lines) {
+		if ($line =~ /^PortGuid:\.+(.*)/) { $guid = $1; }
+	}
+	return $guid;
 }
 
 # =========================================================================
@@ -402,26 +450,22 @@ sub convert_dr_to_guid
 #
 sub get_node_type
 {
-    my $type = undef;
+	my $type      = undef;
 	my $query_arg = "smpquery nodeinfo ";
-    if($_[0] =~ /x/)
-	{
-	  # assume arg is a guid if contains an x
-	  $query_arg .= "-G " . $_[0];
-	}
-	else
-	{
-      # assume arg is a direct path
-	  $query_arg .= "-D " . $_[0];
+	if ($_[0] =~ /x/) {
+		# assume arg is a guid if contains an x
+		$query_arg .= "-G " . $_[0];
+	} else {
+		# assume arg is a direct path
+		$query_arg .= "-D " . $_[0];
 	}
 
-    my $data = `$query_arg`;
-    my @lines = split("\n", $data);
-    foreach my $line (@lines)
-    {
-       if ($line =~ /^NodeType:\.+(.*)/) { $type = $1; }
-    }
-    $type;
+	my $data = `$query_arg`;
+	my @lines = split("\n", $data);
+	foreach my $line (@lines) {
+		if ($line =~ /^NodeType:\.+(.*)/) { $type = $1; }
+	}
+	return $type;
 }
 
 # =========================================================================
@@ -430,5 +474,5 @@ sub get_node_type
 sub is_switch
 {
 	my $node_type = &get_node_type($_[0]);
-    ($node_type =~ /Switch/);
+	return ($node_type =~ /Switch/);
 }
diff --git a/infiniband-diags/scripts/iblinkinfo.pl b/infiniband-diags/scripts/iblinkinfo.pl
index 234f5be..5f268dd 100755
--- a/infiniband-diags/scripts/iblinkinfo.pl
+++ b/infiniband-diags/scripts/iblinkinfo.pl
@@ -42,214 +42,266 @@ use IBswcountlimits;
 
 sub usage_and_exit
 {
-   my $prog = $_[0];
-   print "Usage: $prog [-Rhclp -S <guid> -D <direct route> -C <ca_name> -P <ca_port>]\n";
-   print "   Report link speed and connection for each port of each switch which is active\n";
-   print "   -h This help message\n";
-   print "   -R Recalculate ibnetdiscover information (Default is to reuse ibnetdiscover output)\n";
-   print "   -D <direct route> output only the switch specified by direct route path\n";
-   print "   -S <guid> output only the switch specified by guid\n";
-   print "   -d print only down links\n";
-   print "   -l (line mode) print all information for each link on each line\n";
-   print "   -p print additional switch settings (PktLifeTime,HoqLife,VLStallCount)\n";
-   print "   -c print port capabilities (enabled/supported values)\n";
-   print "   -C <ca_name> use selected Channel Adaptor name for queries\n";
-   print "   -P <ca_port> use selected channel adaptor port for queries\n";
-   print "   -g print port guids instead of node guids\n";
-   exit 0;
+	my $prog = $_[0];
+	print
+"Usage: $prog [-Rhclp -S <guid> -D <direct route> -C <ca_name> -P <ca_port>]\n";
+	print
+"   Report link speed and connection for each port of each switch which is active\n";
+	print "   -h This help message\n";
+	print
+"   -R Recalculate ibnetdiscover information (Default is to reuse ibnetdiscover output)\n";
+	print
+"   -D <direct route> output only the switch specified by direct route path\n";
+	print "   -S <guid> output only the switch specified by guid\n";
+	print "   -d print only down links\n";
+	print
+	  "   -l (line mode) print all information for each link on each line\n";
+	print
+"   -p print additional switch settings (PktLifeTime,HoqLife,VLStallCount)\n";
+	print "   -c print port capabilities (enabled/supported values)\n";
+	print "   -C <ca_name> use selected Channel Adaptor name for queries\n";
+	print "   -P <ca_port> use selected channel adaptor port for queries\n";
+	print "   -g print port guids instead of node guids\n";
+	exit 0;
 }
 
-my $argv0 = `basename $0`;
-my $regenerate_map = undef;
-my $single_switch = undef;
-my $direct_route = undef;
-my $line_mode = undef;
-my $print_add_switch = undef;
+my $argv0              = `basename $0`;
+my $regenerate_map     = undef;
+my $single_switch      = undef;
+my $direct_route       = undef;
+my $line_mode          = undef;
+my $print_add_switch   = undef;
 my $print_extended_cap = undef;
-my $only_down_links = undef;
-my $ca_name = "";
-my $ca_port = "";
-my $print_port_guids = undef;
+my $only_down_links    = undef;
+my $ca_name            = "";
+my $ca_port            = "";
+my $print_port_guids   = undef;
 chomp $argv0;
 
 if (!getopts("hcpldRS:D:C:P:g")) { usage_and_exit $argv0; }
 if (defined $Getopt::Std::opt_h) { usage_and_exit $argv0; }
-if (defined $Getopt::Std::opt_D) { $direct_route = $Getopt::Std::opt_D; }
-if (defined $Getopt::Std::opt_R) { $regenerate_map = $Getopt::Std::opt_R; }
-if (defined $Getopt::Std::opt_S) { $single_switch = $Getopt::Std::opt_S; }
-if (defined $Getopt::Std::opt_d) { $only_down_links = $Getopt::Std::opt_d; }
-if (defined $Getopt::Std::opt_l) { $line_mode = $Getopt::Std::opt_l; }
-if (defined $Getopt::Std::opt_p) { $print_add_switch = $Getopt::Std::opt_p; }
+if (defined $Getopt::Std::opt_D) { $direct_route       = $Getopt::Std::opt_D; }
+if (defined $Getopt::Std::opt_R) { $regenerate_map     = $Getopt::Std::opt_R; }
+if (defined $Getopt::Std::opt_S) { $single_switch      = $Getopt::Std::opt_S; }
+if (defined $Getopt::Std::opt_d) { $only_down_links    = $Getopt::Std::opt_d; }
+if (defined $Getopt::Std::opt_l) { $line_mode          = $Getopt::Std::opt_l; }
+if (defined $Getopt::Std::opt_p) { $print_add_switch   = $Getopt::Std::opt_p; }
 if (defined $Getopt::Std::opt_c) { $print_extended_cap = $Getopt::Std::opt_c; }
-if (defined $Getopt::Std::opt_C) { $ca_name = $Getopt::Std::opt_C; }
-if (defined $Getopt::Std::opt_P) { $ca_port = $Getopt::Std::opt_P; }
-if (defined $Getopt::Std::opt_g) { $print_port_guids = $Getopt::Std::opt_g; }
+if (defined $Getopt::Std::opt_C) { $ca_name            = $Getopt::Std::opt_C; }
+if (defined $Getopt::Std::opt_P) { $ca_port            = $Getopt::Std::opt_P; }
+if (defined $Getopt::Std::opt_g) { $print_port_guids   = $Getopt::Std::opt_g; }
 
 my $extra_smpquery_params = get_ca_name_port_param_string($ca_name, $ca_port);
 
 sub main
 {
-   get_link_ends($regenerate_map, $ca_name, $ca_port);
-   if ($direct_route)
-   {
-	# convert DR to guid, then use original single_switch option
-	$single_switch = $IBswcountlimits::convert_dr_to_guid{$direct_route};
-   }
-   foreach my $switch (sort (keys (%IBswcountlimits::link_ends))) {
-      if ($single_switch && $switch ne $single_switch)
-      {
-         next;
-      }
-      my $switch_prompt = "no";
-      my $num_ports = get_num_ports($switch, $ca_name, $ca_port);
-      if ($num_ports == 0) {
-            printf("ERROR: switch $switch has 0 ports???\n");
-      }
-      my @output_lines = undef;
-      my $pkt_lifetime = "";
-      my $pkt_life_prompt = "";
-      my $port_timeouts = "";
-      my $print_switch = "yes";
-      if ($only_down_links) { $print_switch = "no"; }
-      if ($print_add_switch)
-      {
-         my $data = `smpquery $extra_smpquery_params -G switchinfo $switch`;
-         if ($data eq "") {
-            printf("ERROR: failed to get switchinfo for $switch\n");
-         }
-         my @lines = split("\n", $data);
-         foreach my $line (@lines) { if ($line =~ /^LifeTime:\.+(.*)/) { $pkt_lifetime = $1; } }
-         $pkt_life_prompt = sprintf(" (LT: %2s)", $pkt_lifetime);
-      }
-      foreach my $port (1 .. $num_ports) {
-         my $hr = $IBswcountlimits::link_ends{$switch}{$port};
-         if ($switch_prompt eq "no" && !$line_mode)
-         {
-            push (@output_lines,
-                sprintf ("Switch %18s %s%s:\n", $switch, $hr->{loc_desc}, $pkt_life_prompt));
-            $switch_prompt = "yes";
-         }
-         my $data = `smpquery $extra_smpquery_params -G portinfo $switch $port`;
-         if ($data eq "") {
-            printf("ERROR: failed to get portinfo for $switch port $port\n");
-         }
-         my @lines = split("\n", $data);
-         my $speed = "";
-         my $speed_sup = "";
-         my $speed_enable = "";
-         my $width = "";
-         my $width_sup = "";
-         my $width_enable = "";
-         my $state = "";
-         my $hoq_life = "";
-         my $vl_stall = "";
-         my $phy_link_state = "";
-         foreach my $line (@lines) {
-            if ($line =~ /^LinkSpeedActive:\.+(.*)/) { $speed = $1; }
-            if ($line =~ /^LinkSpeedEnabled:\.+(.*)/)   { $speed_enable = $1; }
-            if ($line =~ /^LinkSpeedSupported:\.+(.*)/) { $speed_sup = $1; }
-            if ($line =~ /^LinkWidthActive:\.+(.*)/) { $width = $1; }
-            if ($line =~ /^LinkWidthEnabled:\.+(.*)/)   { $width_enable = $1; }
-            if ($line =~ /^LinkWidthSupported:\.+(.*)/) { $width_sup = $1; }
-            if ($line =~ /^LinkState:\.+(.*)/)          { $state = $1; }
-            if ($line =~ /^HoqLife:\.+(.*)/)            { $hoq_life = $1; }
-            if ($line =~ /^VLStallCount:\.+(.*)/)       { $vl_stall = $1; }
-            if ($line =~ /^PhysLinkState:\.+(.*)/)      { $phy_link_state = $1; }
-         }
-         my $rem_port = $hr->{rem_port};
-         my $rem_lid = $hr->{rem_lid};
-         my $rem_speed_sup = "";
-         my $rem_speed_enable = "";
-         my $rem_width_sup = "";
-         my $rem_width_enable = "";
-         if ($rem_lid ne "" && $rem_port ne "")
-         {
-            $data = `smpquery $extra_smpquery_params portinfo $rem_lid $rem_port`;
-            if ($data eq "") {
-               printf("ERROR: failed to get portinfo for $switch port $port\n");
-            }
-            my @lines = split("\n", $data);
-            foreach my $line (@lines) {
-               if ($line =~ /^LinkSpeedEnabled:\.+(.*)/)   { $rem_speed_enable = $1; }
-               if ($line =~ /^LinkSpeedSupported:\.+(.*)/) { $rem_speed_sup = $1; }
-               if ($line =~ /^LinkWidthEnabled:\.+(.*)/)   { $rem_width_enable = $1; }
-               if ($line =~ /^LinkWidthSupported:\.+(.*)/) { $rem_width_sup = $1; }
-            }
-         }
-	 my $capabilities = "";
-	 if ($print_extended_cap)
-	 {
-		$capabilities = sprintf("(%3s %s %6s / %8s [%s/%s][%s/%s])",
-				$width, $speed, $state, $phy_link_state,
-				$width_enable, $width_sup,
-				$speed_enable, $speed_sup);
-         }
-	 else
-	 {
-		$capabilities = sprintf("(%3s %s %6s / %8s)",
-                                        $width, $speed, $state, $phy_link_state);
-	 }
-	 if ($print_add_switch)
-	 {
-                $port_timeouts = sprintf (" (HOQ:%s VL_Stall:%s)", $hoq_life, $vl_stall);
-	 }
-         if (!$only_down_links || ($only_down_links && $state eq "Down"))
-         {
-	        my $width_msg = "";
-	        my $speed_msg = "";
-	        if ($rem_width_enable ne "" && $rem_width_sup ne "")
-	        {
-	           if ($width_enable =~ /12X/ && $rem_width_enable =~ /12X/ && $width !~ /12X/) {
-	              $width_msg = "Could be 12X";
-	           } else {
-	              if ($width_enable =~ /8X/ && $rem_width_enable =~ /8X/ && $width !~ /8X/) {
-	                 $width_msg = "Could be 8X";
-	              } else {
-	                 if ($width_enable =~ /4X/ && $rem_width_enable =~ /4X/ && $width !~ /4X/) {
-	                    $width_msg = "Could be 4X";
-	                 }
-	              }
-	           }
-	        }
-	        if ($rem_speed_enable ne "" && $rem_speed_sup ne "")
-	        {
-	           if ($speed_enable =~ /10\.0/ && $rem_speed_enable =~ /10\.0/&& $speed !~ /10\.0/) {
-	              $speed_msg = "Could be 10.0 Gbps";
-	           } else {
-	              if ($speed_enable =~ /5\.0/ && $rem_speed_enable =~ /5\.0/&& $speed !~ /5\.0/) {
-	                 $speed_msg = "Could be 5.0 Gbps";
-	              }
-	           }
-	        }
+	get_link_ends($regenerate_map, $ca_name, $ca_port);
+	if (defined($direct_route)) {
+		# convert DR to guid, then use original single_switch option
+		$single_switch = $IBswcountlimits::convert_dr_to_guid{$direct_route};
+		if (!defined($single_switch) || !is_switch($single_switch)) {
+			printf("The direct route (%s) does not map to a switch.\n",
+				$direct_route);
+			return;
+		}
+	}
+	foreach my $switch (sort (keys(%IBswcountlimits::link_ends))) {
+		if ($single_switch && $switch ne $single_switch) {
+			next;
+		}
+		my $switch_prompt = "no";
+		my $num_ports = get_num_ports($switch, $ca_name, $ca_port);
+		if ($num_ports == 0) {
+			printf("ERROR: switch $switch has 0 ports???\n");
+		}
+		my @output_lines    = undef;
+		my $pkt_lifetime    = "";
+		my $pkt_life_prompt = "";
+		my $port_timeouts   = "";
+		my $print_switch    = "yes";
+		if ($only_down_links) { $print_switch = "no"; }
+		if ($print_add_switch) {
+			my $data = `smpquery $extra_smpquery_params -G switchinfo $switch`;
+			if ($data eq "") {
+				printf("ERROR: failed to get switchinfo for $switch\n");
+			}
+			my @lines = split("\n", $data);
+			foreach my $line (@lines) {
+				if ($line =~ /^LifeTime:\.+(.*)/) { $pkt_lifetime = $1; }
+			}
+			$pkt_life_prompt = sprintf(" (LT: %2s)", $pkt_lifetime);
+		}
+		foreach my $port (1 .. $num_ports) {
+			my $hr = $IBswcountlimits::link_ends{$switch}{$port};
+			if ($switch_prompt eq "no" && !$line_mode) {
+				push(
+					@output_lines,
+					sprintf(
+						"Switch %18s %s%s:\n",
+						$switch, $hr->{loc_desc}, $pkt_life_prompt
+					)
+				);
+				$switch_prompt = "yes";
+			}
+			my $data =
+			  `smpquery $extra_smpquery_params -G portinfo $switch $port`;
+			if ($data eq "") {
+				printf(
+					"ERROR: failed to get portinfo for $switch port $port\n");
+			}
+			my @lines          = split("\n", $data);
+			my $speed          = "";
+			my $speed_sup      = "";
+			my $speed_enable   = "";
+			my $width          = "";
+			my $width_sup      = "";
+			my $width_enable   = "";
+			my $state          = "";
+			my $hoq_life       = "";
+			my $vl_stall       = "";
+			my $phy_link_state = "";
 
-		if ($line_mode)
-		{
-			my $line_begin = sprintf ("%18s \"%30s\"%s", $switch, $hr->{loc_desc}, $pkt_life_prompt);
-			my $ext_guid = sprintf ("%18s", $hr->{rem_guid});
-			if ($print_port_guids && $hr->{rem_port_guid} ne "") {
-				$ext_guid = sprintf ("0x%016s", $hr->{rem_port_guid});
+			foreach my $line (@lines) {
+				if ($line =~ /^LinkSpeedActive:\.+(.*)/) { $speed = $1; }
+				if ($line =~ /^LinkSpeedEnabled:\.+(.*)/) {
+					$speed_enable = $1;
+				}
+				if ($line =~ /^LinkSpeedSupported:\.+(.*)/) { $speed_sup = $1; }
+				if ($line =~ /^LinkWidthActive:\.+(.*)/)    { $width     = $1; }
+				if ($line =~ /^LinkWidthEnabled:\.+(.*)/) {
+					$width_enable = $1;
+				}
+				if ($line =~ /^LinkWidthSupported:\.+(.*)/) { $width_sup = $1; }
+				if ($line =~ /^LinkState:\.+(.*)/)          { $state     = $1; }
+				if ($line =~ /^HoqLife:\.+(.*)/)            { $hoq_life  = $1; }
+				if ($line =~ /^VLStallCount:\.+(.*)/)       { $vl_stall  = $1; }
+				if ($line =~ /^PhysLinkState:\.+(.*)/) { $phy_link_state = $1; }
+			}
+			my $rem_port         = $hr->{rem_port};
+			my $rem_lid          = $hr->{rem_lid};
+			my $rem_speed_sup    = "";
+			my $rem_speed_enable = "";
+			my $rem_width_sup    = "";
+			my $rem_width_enable = "";
+			if ($rem_lid ne "" && $rem_port ne "") {
+				$data =
+				  `smpquery $extra_smpquery_params portinfo $rem_lid $rem_port`;
+				if ($data eq "") {
+					printf(
+						"ERROR: failed to get portinfo for $switch port $port\n"
+					);
+				}
+				my @lines = split("\n", $data);
+				foreach my $line (@lines) {
+					if ($line =~ /^LinkSpeedEnabled:\.+(.*)/) {
+						$rem_speed_enable = $1;
+					}
+					if ($line =~ /^LinkSpeedSupported:\.+(.*)/) {
+						$rem_speed_sup = $1;
+					}
+					if ($line =~ /^LinkWidthEnabled:\.+(.*)/) {
+						$rem_width_enable = $1;
+					}
+					if ($line =~ /^LinkWidthSupported:\.+(.*)/) {
+						$rem_width_sup = $1;
+					}
+				}
+			}
+			my $capabilities = "";
+			if ($print_extended_cap) {
+				$capabilities = sprintf("(%3s %s %6s / %8s [%s/%s][%s/%s])",
+					$width, $speed, $state, $phy_link_state, $width_enable,
+					$width_sup, $speed_enable, $speed_sup);
+			} else {
+				$capabilities = sprintf("(%3s %s %6s / %8s)",
+					$width, $speed, $state, $phy_link_state);
+			}
+			if ($print_add_switch) {
+				$port_timeouts =
+				  sprintf(" (HOQ:%s VL_Stall:%s)", $hoq_life, $vl_stall);
 			}
-			push (@output_lines, sprintf ("%s %6s %4s[%2s]  ==%s%s==>  %18s %6s %4s[%2s] \"%s\" ( %s %s)\n",
-				$line_begin,
-				$hr->{loc_sw_lid}, $port, $hr->{loc_ext_port},
-				$capabilities, $port_timeouts,
-				$ext_guid, $hr->{rem_lid}, $hr->{rem_port}, $hr->{rem_ext_port},
-				$hr->{rem_desc}, $width_msg, $speed_msg));
-		} else {
-			push (@output_lines, sprintf (" %6s %4s[%2s]  ==%s%s==>  %6s %4s[%2s] \"%s\" ( %s %s)\n",
-				$hr->{loc_sw_lid}, $port, $hr->{loc_ext_port},
-				$capabilities, $port_timeouts,
-				$hr->{rem_lid}, $hr->{rem_port}, $hr->{rem_ext_port},
-				$hr->{rem_desc}, $width_msg, $speed_msg));
+			if (!$only_down_links || ($only_down_links && $state eq "Down")) {
+				my $width_msg = "";
+				my $speed_msg = "";
+				if ($rem_width_enable ne "" && $rem_width_sup ne "") {
+					if (   $width_enable =~ /12X/
+						&& $rem_width_enable =~ /12X/
+						&& $width !~ /12X/)
+					{
+						$width_msg = "Could be 12X";
+					} else {
+						if (   $width_enable =~ /8X/
+							&& $rem_width_enable =~ /8X/
+							&& $width !~ /8X/)
+						{
+							$width_msg = "Could be 8X";
+						} else {
+							if (   $width_enable =~ /4X/
+								&& $rem_width_enable =~ /4X/
+								&& $width !~ /4X/)
+							{
+								$width_msg = "Could be 4X";
+							}
+						}
+					}
+				}
+				if ($rem_speed_enable ne "" && $rem_speed_sup ne "") {
+					if (   $speed_enable =~ /10\.0/
+						&& $rem_speed_enable =~ /10\.0/
+						&& $speed !~ /10\.0/)
+					{
+						$speed_msg = "Could be 10.0 Gbps";
+					} else {
+						if (   $speed_enable =~ /5\.0/
+							&& $rem_speed_enable =~ /5\.0/
+							&& $speed !~ /5\.0/)
+						{
+							$speed_msg = "Could be 5.0 Gbps";
+						}
+					}
+				}
+
+				if ($line_mode) {
+					my $line_begin = sprintf("%18s \"%30s\"%s",
+						$switch, $hr->{loc_desc}, $pkt_life_prompt);
+					my $ext_guid = sprintf("%18s", $hr->{rem_guid});
+					if ($print_port_guids && $hr->{rem_port_guid} ne "") {
+						$ext_guid = sprintf("0x%016s", $hr->{rem_port_guid});
+					}
+					push(
+						@output_lines,
+						sprintf(
+"%s %6s %4s[%2s]  ==%s%s==>  %18s %6s %4s[%2s] \"%s\" ( %s %s)\n",
+							$line_begin,     $hr->{loc_sw_lid},
+							$port,           $hr->{loc_ext_port},
+							$capabilities,   $port_timeouts,
+							$ext_guid,       $hr->{rem_lid},
+							$hr->{rem_port}, $hr->{rem_ext_port},
+							$hr->{rem_desc}, $width_msg,
+							$speed_msg
+						)
+					);
+				} else {
+					push(
+						@output_lines,
+						sprintf(
+" %6s %4s[%2s]  ==%s%s==>  %6s %4s[%2s] \"%s\" ( %s %s)\n",
+							$hr->{loc_sw_lid},   $port,
+							$hr->{loc_ext_port}, $capabilities,
+							$port_timeouts,      $hr->{rem_lid},
+							$hr->{rem_port},     $hr->{rem_ext_port},
+							$hr->{rem_desc},     $width_msg,
+							$speed_msg
+						)
+					);
+				}
+				$print_switch = "yes";
+			}
+		}
+		if ($print_switch eq "yes") {
+			foreach my $line (@output_lines) { print $line; }
 		}
-                $print_switch = "yes";
-         }
-      }
-      if ($print_switch eq "yes")
-      {
-        foreach my $line (@output_lines) { print $line; }
-      }
-   }
+	}
 }
 main;
 
diff --git a/infiniband-diags/scripts/ibqueryerrors.pl b/infiniband-diags/scripts/ibqueryerrors.pl
index e27bfa2..ef61e9b 100755
--- a/infiniband-diags/scripts/ibqueryerrors.pl
+++ b/infiniband-diags/scripts/ibqueryerrors.pl
@@ -39,139 +39,142 @@ use strict;
 use Getopt::Std;
 use IBswcountlimits;
 
-my $print_action = "no";
-my $report_port_info = undef;
-my $single_switch = undef;
+my $print_action          = "no";
+my $report_port_info      = undef;
+my $single_switch         = undef;
 my $include_data_counters = undef;
-my $cache_file = "";
+my $cache_file            = "";
 
 # =========================================================================
 #
 sub report_counts
 {
-   my $addr = $_[0];
-   my $port = $_[1];
-   my $ca_name = $_[2];
-   my $ca_port = $_[3];
-   my $extra_params = get_ca_name_port_param_string($ca_name, $ca_port);
-
-   if (any_counts())
-   {
-      print ("   GUID $addr port $port:");
-      check_counters($print_action);
-      if ($include_data_counters)
-      {
-         check_data_counters($print_action);
-      }
-      print ("\n");
-
-      if ($report_port_info) {
-         my $lid = "";
-         my $speed = "";
-         my $width = "";
-         my $data = `smpquery $extra_params -G portinfo $addr $port`;
-         my @lines = split("\n", $data);
-         foreach my $line (@lines) {
-            if ($line =~ /^# Port info: Lid (\w+) port.*/) { $lid = $1; }
-            if ($line =~ /^LinkSpeedActive:\.+(.*)/) { $speed = $1; }
-            if ($line =~ /^LinkWidthActive:\.+(.*)/) { $width = $1; }
-         }
-         my $hr = $IBswcountlimits::link_ends{"$addr"}{$port};
-	 if ($hr)
-	 {
-	     printf ("         Link info: %6s %4s[%2s]  ==(%3s %s)==>  %18s %4s[%2s] \"%s\"\n",
-		     $lid, $port, $hr->{loc_ext_port}, $width, $speed,
-		     $hr->{rem_guid}, $hr->{rem_port}, $hr->{rem_ext_port}, $hr->{rem_desc});
-	 }
-	 else
-	 {
-	     printf ("         Link info: %6s %4s[  ]  ==(%3s %s)==>     (Disconnected)\n",
-		     $lid, $port, $width, $speed);
-	 }
-      }
-   }
+	my $addr         = $_[0];
+	my $port         = $_[1];
+	my $ca_name      = $_[2];
+	my $ca_port      = $_[3];
+	my $extra_params = get_ca_name_port_param_string($ca_name, $ca_port);
+
+	if (any_counts()) {
+		print("   GUID $addr port $port:");
+		check_counters($print_action);
+		if ($include_data_counters) {
+			check_data_counters($print_action);
+		}
+		print("\n");
+
+		if ($report_port_info) {
+			my $lid   = "";
+			my $speed = "";
+			my $width = "";
+			my $data  = `smpquery $extra_params -G portinfo $addr $port`;
+			my @lines = split("\n", $data);
+			foreach my $line (@lines) {
+				if ($line =~ /^# Port info: Lid (\w+) port.*/) { $lid   = $1; }
+				if ($line =~ /^LinkSpeedActive:\.+(.*)/)       { $speed = $1; }
+				if ($line =~ /^LinkWidthActive:\.+(.*)/)       { $width = $1; }
+			}
+			my $hr = $IBswcountlimits::link_ends{"$addr"}{$port};
+			if ($hr) {
+				printf(
+"         Link info: %6s %4s[%2s]  ==(%3s %s)==>  %18s %4s[%2s] \"%s\"\n",
+					$lid,                $port,
+					$hr->{loc_ext_port}, $width,
+					$speed,              $hr->{rem_guid},
+					$hr->{rem_port},     $hr->{rem_ext_port},
+					$hr->{rem_desc}
+				);
+			} else {
+				printf(
+"         Link info: %6s %4s[  ]  ==(%3s %s)==>     (Disconnected)\n",
+					$lid, $port, $width, $speed);
+			}
+		}
+	}
 }
 
 # =========================================================================
 # use perfquery to get the counters.
 sub get_counts
 {
-   my $addr = $_[0];
-   my $port = $_[1];
-   my $ca_name = $_[2];
-   my $ca_port = $_[3];
-   my $extra_params = get_ca_name_port_param_string($ca_name, $ca_port);
-
-   my $data = `perfquery $extra_params -G $addr $port`;
-   my @lines = split("\n", $data);
-   foreach my $line (@lines)
-   {
-      foreach my $count (@IBswcountlimits::counters)
-      {
-         if ($line =~ /^$count:\.+(\d+)/)
-         {
-            $IBswcountlimits::cur_counts{$count} = $1;
-         }
-      }
-   }
+	my $addr         = $_[0];
+	my $port         = $_[1];
+	my $ca_name      = $_[2];
+	my $ca_port      = $_[3];
+	my $extra_params = get_ca_name_port_param_string($ca_name, $ca_port);
+
+	my $data = `perfquery $extra_params -G $addr $port`;
+	my @lines = split("\n", $data);
+	foreach my $line (@lines) {
+		foreach my $count (@IBswcountlimits::counters) {
+			if ($line =~ /^$count:\.+(\d+)/) {
+				$IBswcountlimits::cur_counts{$count} = $1;
+			}
+		}
+	}
 }
 
 # =========================================================================
 #
 my %switches = ();
+
 sub get_switches
 {
-   my $data = `ibswitches $cache_file`;
-   my @lines = split("\n", $data);
-   foreach my $line (@lines) {
-      if ($line =~ /^Switch\s+:\s+(\w+)\s+ports\s+(\d+)\s+.*/)
-      {
-         $switches{$1} = $2;
-      }
-   }
+	my $data = `ibswitches $cache_file`;
+	my @lines = split("\n", $data);
+	foreach my $line (@lines) {
+		if ($line =~ /^Switch\s+:\s+(\w+)\s+ports\s+(\d+)\s+.*/) {
+			$switches{$1} = $2;
+		}
+	}
 }
 
 # =========================================================================
 #
 sub usage_and_exit
 {
-   my $prog = $_[0];
-   print "Usage: $prog [-a -c -r -R -s <err1,err2,...> -S <switch_guid> -D <direct route> -d -C <ca_name> -P <ca_port>]\n";
-   print "   Report counters on all switches in subnet\n";
-   print "   -a Report an action to take\n";
-   print "   -c suppress some of the common counters\n";
-   print "   -r report port configuration information\n";
-   print "   -R Recalculate ibnetdiscover information\n";
-   print "   -s <err1,err2,...> suppress errors listed\n";
-   print "   -D <direct route> output only the switch specified by direct route path\n";
-   print "   -S <switch_guid> query only <switch_guid>\n";
-   print "   -d include the data counters in the output\n";
-   print "   -C <ca_name> use selected Channel Adaptor name for queries\n";
-   print "   -P <ca_port> use selected channel adaptor port for queries\n";
-   exit 0;
+	my $prog = $_[0];
+	print
+"Usage: $prog [-a -c -r -R -s <err1,err2,...> -S <switch_guid> -D <direct route> -d -C <ca_name> -P <ca_port>]\n";
+	print "   Report counters on all switches in subnet\n";
+	print "   -a Report an action to take\n";
+	print "   -c suppress some of the common counters\n";
+	print "   -r report port configuration information\n";
+	print "   -R Recalculate ibnetdiscover information\n";
+	print "   -s <err1,err2,...> suppress errors listed\n";
+	print
+"   -D <direct route> output only the switch specified by direct route path\n";
+	print "   -S <switch_guid> query only <switch_guid>\n";
+	print "   -d include the data counters in the output\n";
+	print "   -C <ca_name> use selected Channel Adaptor name for queries\n";
+	print "   -P <ca_port> use selected channel adaptor port for queries\n";
+	exit 0;
 }
 
-my $argv0 = `basename $0`;
+my $argv0          = `basename $0`;
 my $regenerate_map = undef;
-my $single_switch = undef;
-my $direct_route = undef;
-my $ca_name = "";
-my $ca_port = "";
+my $single_switch  = undef;
+my $direct_route   = undef;
+my $ca_name        = "";
+my $ca_port        = "";
 
 chomp $argv0;
 if (!getopts("has:crRS:D:dC:P:")) { usage_and_exit $argv0; }
-if (defined $Getopt::Std::opt_h) { usage_and_exit $argv0; }
+if (defined $Getopt::Std::opt_h)  { usage_and_exit $argv0; }
 if (defined $Getopt::Std::opt_a) { $print_action = "yes"; }
-if (defined $Getopt::Std::opt_s) { @IBswcountlimits::suppress_errors = split (",", $Getopt::Std::opt_s); }
-if (defined $Getopt::Std::opt_c)
-{
-   @IBswcountlimits::suppress_errors = split (",", "RcvSwRelayErrors");
+if (defined $Getopt::Std::opt_s) {
+	@IBswcountlimits::suppress_errors = split(",", $Getopt::Std::opt_s);
+}
+if (defined $Getopt::Std::opt_c) {
+	@IBswcountlimits::suppress_errors = split(",", "RcvSwRelayErrors");
 }
 if (defined $Getopt::Std::opt_r) { $report_port_info = $Getopt::Std::opt_r; }
-if (defined $Getopt::Std::opt_R) { $regenerate_map = $Getopt::Std::opt_R; }
-if (defined $Getopt::Std::opt_D) { $direct_route = $Getopt::Std::opt_D; }
-if (defined $Getopt::Std::opt_S) { $single_switch = $Getopt::Std::opt_S; }
-if (defined $Getopt::Std::opt_d) { $include_data_counters = $Getopt::Std::opt_d; }
+if (defined $Getopt::Std::opt_R) { $regenerate_map   = $Getopt::Std::opt_R; }
+if (defined $Getopt::Std::opt_D) { $direct_route     = $Getopt::Std::opt_D; }
+if (defined $Getopt::Std::opt_S) { $single_switch    = $Getopt::Std::opt_S; }
+if (defined $Getopt::Std::opt_d) {
+	$include_data_counters = $Getopt::Std::opt_d;
+}
 if (defined $Getopt::Std::opt_C) { $ca_name = $Getopt::Std::opt_C; }
 if (defined $Getopt::Std::opt_P) { $ca_port = $Getopt::Std::opt_P; }
 
@@ -179,34 +182,36 @@ $cache_file = get_cache_file($ca_name, $ca_port);
 
 sub main
 {
-   if (@IBswcountlimits::suppress_errors)
-   {
-      my $msg = join(",", @IBswcountlimits::suppress_errors);
-      print "Suppressing: $msg\n";
-   }
-   get_link_ends($regenerate_map, $ca_name, $ca_port);
-   get_switches;
-   if ($direct_route)
-   {
-	# convert DR to guid, then use original single_switch option
-	$single_switch = $IBswcountlimits::convert_dr_to_guid{$direct_route};
-   }
-   foreach my $sw_addr (keys %switches) {
-      if ($single_switch && $sw_addr ne "$single_switch") { next; }
-
-      my $switch_prompt = "no";
-      foreach my $sw_port (1 .. $switches{$sw_addr}) {
-         clear_counters;
-         get_counts($sw_addr, $sw_port, $ca_name, $ca_port);
-         if (any_counts() && $switch_prompt eq "no")
-         {
-            my $hr = $IBswcountlimits::link_ends{"$sw_addr"}{$sw_port};
-            printf ("Errors for %18s \"%s\"\n", $sw_addr, $hr->{loc_desc});
-            $switch_prompt = "yes";
-         }
-         report_counts($sw_addr, $sw_port);
-      }
-   }
+	if (@IBswcountlimits::suppress_errors) {
+		my $msg = join(",", @IBswcountlimits::suppress_errors);
+		print "Suppressing: $msg\n";
+	}
+	get_link_ends($regenerate_map, $ca_name, $ca_port);
+	get_switches;
+	if (defined($direct_route)) {
+		# convert DR to guid, then use original single_switch option
+		$single_switch = convert_dr_to_guid($direct_route);
+		if (!defined($single_switch) || !is_switch($single_switch)) {
+			printf("The direct route (%s) does not map to a switch.\n",
+				$direct_route);
+			return;
+		}
+	}
+	foreach my $sw_addr (keys %switches) {
+		if ($single_switch && $sw_addr ne "$single_switch") { next; }
+
+		my $switch_prompt = "no";
+		foreach my $sw_port (1 .. $switches{$sw_addr}) {
+			clear_counters;
+			get_counts($sw_addr, $sw_port, $ca_name, $ca_port);
+			if (any_counts() && $switch_prompt eq "no") {
+				my $hr = $IBswcountlimits::link_ends{"$sw_addr"}{$sw_port};
+				printf("Errors for %18s \"%s\"\n", $sw_addr, $hr->{loc_desc});
+				$switch_prompt = "yes";
+			}
+			report_counts($sw_addr, $sw_port);
+		}
+	}
 }
 main;
 
-- 
1.5.1

