Support the Linux 2.6 sysfs interface to EEPROMs. Original patch

by Burkart Lingner.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@3034 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Jean Delvare committed 2005-07-15 16:05:25 +00:00
1 parent 421f1c7c33
commit ac53cebc4d
1 file changed
+64 -21
+64 -21
View File
@@ -2,6 +2,7 @@
#
# Copyright 1998, 1999 Philip Edelbrock <phil@netroedge.com>
# modified by Christian Zuckschwerdt <zany@triq.net>
# modified by Burkart Lingner <burkart@bollchen.de>
#
# 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
@@ -29,6 +30,8 @@
# miscellaneous formatting enhancements and bug fixes
# clearer HTML output (original patch by Nick Kurshev <nickols_k@mail.ru>)
# stop decoding on checksum error by default (--checksum option forces)
# Version 0.8 2005-06-20 Burkart Lingner <burkart@bollchen.de>
# adapted to Kernel 2.6's /sys filesystem
#
#
# EEPROM data decoding for SDRAM DIMM modules.
@@ -115,6 +118,47 @@ sub printh ($) # print header w/ given text
}
}
sub readspd16 ($$) { # reads 16 bytes from SPD-EEPROM
my ($offset, $dimm_i) = @_;
if (-e "/sys/bus/i2c/drivers/eeprom") {
# Kernel 2.6 with sysfs
open (HANDLE, "/sys/bus/i2c/drivers/eeprom/$dimm_i/eeprom")
or die "Cannot open /sys/bus/i2c/drivers/eeprom/$dimm_i/eeprom";
binmode HANDLE;
seek (HANDLE, $offset, 0);
read (HANDLE, my $eeprom, 16);
close HANDLE;
my @bytes = ();
for my $i ( 0 .. 15 ) {
$_ = ord substr($eeprom, $i, 1);
push(@bytes, $_);
}
return @bytes;
} else {
# Kernel 2.4 with procfs
if ($offset == 0) { # bytes 0..15
$_=`cat /proc/sys/dev/sensors/$dimm_i/00`;
} elsif ($offset == 16) { # bytes 16..31
$_=`cat /proc/sys/dev/sensors/$dimm_i/10`;
} elsif ($offset == 32) { # bytes 32..47
$_=`cat /proc/sys/dev/sensors/$dimm_i/20`;
} elsif ($offset == 48) { # bytes 48..63
$_=`cat /proc/sys/dev/sensors/$dimm_i/30`;
} elsif ($offset == 64) { # bytes 64..79
$_=`cat /proc/sys/dev/sensors/$dimm_i/40`;
} elsif ($offset == 80) { # bytes 80..95
$_=`cat /proc/sys/dev/sensors/$dimm_i/50`;
} elsif ($offset == 96) { # bytes 96..111
$_=`cat /proc/sys/dev/sensors/$dimm_i/60`;
} elsif ($offset == 112) { # bytes 112..127
$_=`cat /proc/sys/dev/sensors/$dimm_i/70`;
} else { # illegal offset
$_='255 'x15 . '255';
}
return split(" ");
}
}
for (@ARGV) {
if (/-h/) {
print "Usage: $0 [-f|-b|-h]\n\n",
@@ -142,34 +186,39 @@ if ($opt_body)
printh '
PC DIMM Serial Presence Detect Tester/Decoder
By Philip Edelbrock, Christian Zuckschwerdt and others
By Philip Edelbrock, Christian Zuckschwerdt, Burkart Lingner and others
Version 2.6.6
';
my $dimm_count=0;
$_=`ls /proc/sys/dev/sensors/`;
if (-e "/sys/bus/i2c/drivers/eeprom") { $_=`ls /sys/bus/i2c/drivers/eeprom`; }
else { $_=`ls /proc/sys/dev/sensors/`; }
my @dimm_list=split();
for my $i ( 0 .. $#dimm_list ) {
$_=$dimm_list[$i];
if (/^eeprom-/) {
if ((-e "/sys/bus/i2c/drivers/eeprom" && /^\d+-\d+$/) || /^eeprom-/) {
my $dimm_checksum=0;
$dimm_count += 1;
print "<b><u><br><br>" if $opt_html;
printl2 "Decoding EEPROM" , " /proc/sys/dev/sensors/$dimm_list[$i]";
if (-e "/sys/bus/i2c/drivers/eeprom") {
printl2 "Decoding EEPROM", "/sys/bus/i2c/drivers/eeprom/$dimm_list[$i]";
} else {
printl2 "Decoding EEPROM", "/proc/sys/dev/sensors/$dimm_list[$i]";
}
print "</u></b>" if $opt_html;
print "<table border=1>\n" if $opt_html;
if (/^[^-]+-[^-]+-[^-]+-([^-]+)$/) {
if ((-e "/sys/bus/i2c/drivers/eeprom" && /^[^-]+-([^-]+)$/)
|| /^[^-]+-[^-]+-[^-]+-([^-]+)$/) {
my $dimm_num=$1 - 49;
printl "Guessing DIMM is in", "bank $dimm_num";
}
# Decode first 16 bytes
prints "The Following is Required Data and is Applicable to all DIMM Types";
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/00`;
my @bytes=split(" ");
my @bytes = readspd16(0, $dimm_list[$i]);
for my $j ( 0 .. 15 ) { $dimm_checksum = $dimm_checksum + $bytes[$j]; }
printl "# of bytes written to SDRAM EEPROM",$bytes[0];
@@ -274,8 +323,7 @@ for my $i ( 0 .. $#dimm_list ) {
prints "The Following Apply to SDRAM DIMMs ONLY";
# Decode next 16 bytes
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/10`;
@bytes=split(" ");
@bytes = readspd16(16, $dimm_list[$i]);
for my $j ( 0 .. 15 ) { $dimm_checksum = $dimm_checksum + $bytes[$j]; }
$l = "Burst lengths supported";
@@ -425,8 +473,7 @@ for my $i ( 0 .. $#dimm_list ) {
# Decode next 16 bytes (32-47)
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/20`;
@bytes=split(" ");
@bytes = readspd16(32, $dimm_list[$i]);
for my $j ( 0 .. 15 ) { $dimm_checksum = $dimm_checksum + $bytes[$j]; }
prints "The Following are Proposed and Apply to SDRAM DIMMs";
@@ -449,8 +496,7 @@ for my $i ( 0 .. $#dimm_list ) {
# That's it for the lower part of an SDRAM EEPROM's memory!
# Decode next 16 bytes (48-63)
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/30`;
@bytes=split(" ");
@bytes = readspd16(48, $dimm_list[$i]);
for my $j ( 0 .. 14 ) { $dimm_checksum = $dimm_checksum + $bytes[$j]; }
printl "SPD Revision code ", sprintf("%x", $bytes[14]);
@@ -462,8 +508,7 @@ for my $i ( 0 .. $#dimm_list ) {
if($bytes[15]==$dimm_checksum || $opt_igncheck) {
# Decode next 16 bytes (64-79)
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/40`;
@bytes=split(" ");
@bytes = readspd16(64, $dimm_list[$i]);
$l = "Manufacturer's JEDEC ID Code";
$temp = sprintf("0x%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X\n",$bytes[0],$bytes[1],$bytes[2],$bytes[3],$bytes[4],$bytes[5],$bytes[6],$bytes[7]);
@@ -478,8 +523,8 @@ for my $i ( 0 .. $#dimm_list ) {
$l = "Manufacurer's Part Number";
# Decode next 16 bytes (80-95)
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/50`;
my @bytes2 = split ' ';
my @bytes2= readspd16(80, $dimm_list[$i]);
$temp = pack("c18",$bytes[9],$bytes[10],$bytes[11],$bytes[12],$bytes[13],$bytes[14],$bytes[15],
$bytes2[0],$bytes2[1],$bytes2[2],$bytes2[3],$bytes2[4],$bytes2[5],$bytes2[6],$bytes2[7],$bytes2[8],$bytes2[9],$bytes2[10]);
printl $l, $temp;
@@ -494,13 +539,11 @@ for my $i ( 0 .. $#dimm_list ) {
$l = "Assembly Serial Number";
# Decode next 16 bytes (96-111)
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/60`;
@bytes=split(" ");
@bytes = readspd16(96, $dimm_list[$i]);
$temp = sprintf("0x%.2X%.2X%.2X%.2X\n",$bytes2[15],$bytes[0],$bytes[1],$bytes[2]);
# Decode next 16 bytes (112-127)
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/70`;
@bytes=split(" ");
@bytes = readspd16(112, $dimm_list[$i]);
$l = "Intel Specification for Frequency";
if ($bytes[14] == 102) { printl $l, "66MHz\n"; }