Suggested enhancements (with patches) to i2c-tools/decode-dimms

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



(Hopefully this is the correct mailing list - there does not appear to 
be a list dedicated to i2c-tools.)

Dear list readers,

Attached are three patches to the decode-dimms that I've found to be 
rather useful.

First, there are several places where the printl_cond() function should 
be used to display some manufacturing data.  With existing code, if only 
some DIMMs have this data, the side-by-side feature will be disabled. 
This patch completes the implementation of printl_cond().

Second, when decoding more than two DIMMs, it might well be useful to 
have the side-by-side merge-cells work even if only some of the DIMMs 
have equal values.  This improves the display when, for example, you 
have two pairs of DIMMs.  Even though the DIMMs in each pair are the 
same, the existing code will not merge cells unless all four DIMMs are 
the same.  This patch allows merging of the partial rows.

The third patch is useful to expand the OS base where decode-dimms is 
useful.  This patch teaches decode-dimms how to retrieve SPD EEPROM data 
from a NetBSD sysctl(8) node.  Without this, the only way to use 
decode-dimms on NetBSD is to manually extract the sysctl(8) entries, run 
them through hexdump, supply hexdump's output file(s) as input to 
decode-dimms with -x, and then clean up (delete) the hexdump output!

All three of these patches are relative to the most recent version of 
decode-dimms that I can find:

http://lm-sensors.org/browser/i2c-tools/trunk/eeprom/decode-dimms?rev=5714




-------------------------------------------------------------------------
|   Paul Goyette   | PGP DSS Key fingerprint: |  E-mail addresses:      |
| Customer Service | FA29 0E3B 35AF E8AE 6651 |  paul at whooppee.com   |
| Network Engineer | 0786 F758 55DE 53BA 7731 | pgoyette at juniper.net |
| Kernel Developer |                          | pgoyette at netbsd.org  |
-------------------------------------------------------------------------
-------------- next part --------------
--- decode-dimms-5714	2009-05-23 14:02:10.000000000 -0700
+++ my-decode-dimms	2009-05-24 07:02:48.000000000 -0700
@@ -1373,26 +1388,20 @@
 	printl("Module Manufacturer",
 	       manufacturer_ddr3($bytes->[117], $bytes->[118]));
 
-	if (spd_written(@{$bytes}[148..149])) {
-		printl("DRAM Manufacturer",
-		       manufacturer_ddr3($bytes->[148], $bytes->[149]));
-	}
+	printl_cond(spd_written(@{$bytes}[148..149]), "DRAM Manufacturer",
+		    manufacturer_ddr3($bytes->[148], $bytes->[149]));
 
 	printl_mfg_location_code($bytes->[119]);
 
-	if (spd_written(@{$bytes}[120..121])) {
-		printl("Manufacturing Date",
-		       manufacture_date($bytes->[120], $bytes->[121]));
-	}
+	printl_cond(spd_written(@{$bytes}[120..121]), "Manufacturing Date",
+		    manufacture_date($bytes->[120], $bytes->[121]));
 
 	printl_mfg_assembly_serial(@{$bytes}[122..125]);
 
 	printl("Part Number", part_number(@{$bytes}[128..145]));
 
-	if (spd_written(@{$bytes}[146..147])) {
-		printl("Revision Code",
-		       sprintf("0x%02X%02X", $bytes->[146], $bytes->[147]));
-	}
+	printl_cond(spd_written(@{$bytes}[146..147]), "Revision Code",
+		    sprintf("0x%02X%02X", $bytes->[146], $bytes->[147]));
 }
 
 # Parameter: EEPROM bytes 0-127 (using 64-98)
-------------- next part --------------
--- decode-dimms-5714	2009-05-23 14:02:10.000000000 -0700
+++ my-decode-dimms	2009-05-24 07:02:48.000000000 -0700
@@ -381,10 +381,25 @@
 		$label = html_encode($label);
 		@values = map { html_encode($_) } @values;
 		print "<tr><td valign=top>$label</td>";
-		if ($opt_merge && $same_values) {
+		if (!$opt_merge) {
+			print "<td>$_</td>" foreach @values;
+		} elsif ($same_values) {
 			print "<td colspan=".(scalar @values).">$values[0]</td>";
 		} else {
-			print "<td>$_</td>" foreach @values;
+			# For HTML output, merge adjacent cells even if
+			# the whole line cannot be merged.
+			my $colcnt = 0;
+			my $value;
+			while (@values) {
+				$colcnt++;
+				$value = shift @values;
+				next if (@values && $value eq $values[0]);
+				print "<td colspan=" . $colcnt . ">$value</td>";
+				$colcnt = 0;
+			}
+			if ($colcnt) {
+				print "<td colspan=" . $colcnt . ">$value</td>";
+			}
 		}
 		print "</tr>\n";
 	} else {
-------------- next part --------------
--- decode-dimms-5714.orig	2009-05-23 12:49:26.000000000 -0700
+++ decode-dimms-5714.sysctl	2009-05-23 14:02:10.000000000 -0700
@@ -41,8 +41,9 @@
 use POSIX qw(ceil);
 use Fcntl qw(:DEFAULT :seek);
 use vars qw($opt_html $opt_bodyonly $opt_side_by_side $opt_merge
-	    $opt_igncheck $use_sysfs $use_hexdump $sbs_col_width
-	    @vendors %decode_callback $revision @dimm $current %hexdump_cache);
+	    $opt_igncheck $use_sysfs $use_hexdump $use_sysctl $sbs_col_width
+	    @vendors %decode_callback $revision @dimm $current %hexdump_cache
+	    %sysctl_cache);
 
 use constant LITTLEENDIAN	=> "little-endian";
 use constant BIGENDIAN		=> "big-endian";
@@ -253,6 +254,7 @@
  "SiliconBlue Technologies", "Rambus Inc."]);
 
 $use_sysfs = -d '/sys/bus';
+$use_sysctl = 0;
 
 # We consider that no data was written to this area of the SPD EEPROM if
 # all bytes read 0x00 or all bytes read 0xff
@@ -1543,6 +1545,26 @@
 	}
 }
 
+# read data from a NetBSD (or equivalent) sysctl variable
+
+sub read_sysctl($)
+{
+
+	# Look in the cache first
+	return @{$sysctl_cache{$_[0]}} if exists $sysctl_cache{$_[0]};
+
+	my $sysctl_var = sprintf("hw.%s.spd_data", $_[0]);
+	open(PIPE, "-|", "sysctl -r $sysctl_var")
+		or die "Cannot read sysctl variable $sysctl_var";
+	sysread(PIPE, my $eeprom, 512); # XXX Assumed maximum size! XXX
+	close PIPE or die "sysctl returned $?";
+	my @bytes = unpack("C*", $eeprom);
+
+	# Cache the data for later use
+	$hexdump_cache{$_[0]} = \@bytes;
+	return @bytes;
+}
+
 # Read bytes from SPD-EEPROM
 # Note: offset must be a multiple of 16!
 sub readspd($$$)
@@ -1552,6 +1574,9 @@
 	if ($use_hexdump) {
 		@bytes = read_hexdump($dimm_i);
 		return @bytes[$offset..($offset + $size - 1)];
+	} elsif ($use_sysctl) {
+		@bytes = read_sysctl($dimm_i);
+		return @bytes[$offset..($offset + $size - 1)];
 	} elsif ($use_sysfs) {
 		# Kernel 2.6 with sysfs
 		sysopen(HANDLE, "$dimm_i/eeprom", O_RDONLY)
@@ -1621,7 +1646,7 @@
 # Parse command-line
 foreach (@ARGV) {
 	if ($_ eq '-h' || $_ eq '--help') {
-		print "Usage: $0 [-c] [-f [-b]] [-x|-X file [files..]]\n",
+		print "Usage: $0 [-c] [-f [-b]] [-x|-X|-s file [files..]]\n",
 			"       $0 -h\n\n",
 			"  -f, --format            Print nice html output\n",
 			"  -b, --bodyonly          Don't print html header\n",
@@ -1633,6 +1658,8 @@
 			"  -x,                     Read data from hexdump files\n",
 			"  -X,                     Same as -x except treat multibyte hex\n",
 			"                          data as little endian\n",
+			"  -s,                     Use NetBSD-compatible sysctl(8) to obtain\n",
+			"                          EEPROM data\n",
 			"  -h, --help              Display this usage summary\n";
 		print <<"EOF";
 
@@ -1673,13 +1700,20 @@
 		$use_hexdump = LITTLEENDIAN;
 		next;
 	}
+	if ($_ eq '-s') {
+		if (-x "/sbin/sysctl") {
+			$use_sysctl = 1;
+		} else { die "No /sbin/sysctl available for -s"; }
+		next;
+	}
 
 	if (m/^-/) {
 		print STDERR "Unrecognized option $_\n";
 		exit;
 	}
 
-	push @dimm, { eeprom => $_, file => $_ } if $use_hexdump;
+	push @dimm, { eeprom => $_, file => $_ }
+		if ($use_sysctl || $use_hexdump);
 }
 
 if ($opt_html && !$opt_bodyonly) {
@@ -1732,7 +1766,7 @@
 #  * chk_spd: The checksum or CRC value found in the EEPROM
 #  * chk_calc: The checksum or CRC computed from the EEPROM data
 # Keys are added over time.
- at dimm = get_dimm_list() unless $use_hexdump;
+ at dimm = get_dimm_list() unless ($use_sysctl || $use_hexdump);
 
 for my $i (0 .. $#dimm) {
 	my @bytes = readspd(0, 128, $dimm[$i]->{file});
@@ -1768,7 +1802,7 @@
 		printl("Decoding EEPROM", $dimm[$current]->{eeprom});
 	}
 
-	if (!$use_hexdump) {
+	if (!$use_hexdump && !$use_sysctl) {
 		if ($dimm[$current]->{file} =~ /-([\da-f]+)$/i) {
 			my $dimm_num = hex($1) - 0x50 + 1;
 			if ($dimm_num >= 1 && $dimm_num <= 8) {


[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux