2
0
mirror of https://github.com/lm-sensors/lm-sensors synced 2025-08-30 13:57:41 +00:00

Fix detection of SPD EEPROM on DDR3 memory modules. DDR3 uses CRC16 over

128 bytes instead of basic checksum over 64 bytes. Contributed by
Clemens Ladisch.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@5930 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Jean Delvare
2011-02-16 15:08:25 +00:00
parent edb64c42ca
commit 1ca80a309e
2 changed files with 33 additions and 7 deletions

View File

@@ -26,6 +26,7 @@ SVN HEAD
Add detection of SMSC EMC1002, EMC1033, EMC1046, EMC1047,
EMC1072, EMC1073, EMC1074, EMC1402, and EMC1424
Fixed address ranges checked for SMSC EMC1403 and EMC1404.
Fix detection of SPD EEPROM on DDR3 memory modules
3.2.0 (2010-10-10)
libsensors: Increase MAX_SENSORS_PER_TYPE to 24

View File

@@ -5264,19 +5264,44 @@ sub it8712_i2c_detect
}
# Registers used:
# 0-63: SPD Data and Checksum
# 0-63: SPD Data and Checksum (up to DDR2)
# 0-127: SPD data and CRC (DDR3)
sub eeprom_detect
{
my ($file, $addr) = @_;
my $device_type = i2c_smbus_read_byte_data($file, 2);
my $checksum = 0;
# Check the checksum for validity (works for most DIMMs and RIMMs)
for (my $i = 0; $i <= 62; $i++) {
# Check the checksum or CRC16 for validity
if ($device_type >= 1 and $device_type <= 8) {
for (my $i = 0; $i < 63; $i++) {
$checksum += i2c_smbus_read_byte_data($file, $i);
}
$checksum &= 255;
$checksum &= 0xff;
return 8 if $checksum == i2c_smbus_read_byte_data($file, 63);
} elsif ($device_type => 9 && $device_type <= 11) {
# see JEDEC 21-C 4.1.2.11 2.4
my $crc_coverage = i2c_smbus_read_byte_data($file, 0);
$crc_coverage = ($crc_coverage & 0x80) ? 117 : 126;
for (my $i = 0; $i < $crc_coverage; $i++) {
$checksum ^= i2c_smbus_read_byte_data($file, $i) << 8;
for (my $bit = 0; $bit < 8; $bit++) {
if ($checksum & 0x8000) {
$checksum = ($checksum << 1) ^ 0x1021;
} else {
$checksum <<= 1;
}
}
}
$checksum &= 0xffff;
return 8 if ($checksum & 0xff) == i2c_smbus_read_byte_data($file, 126) and
($checksum >> 8) == i2c_smbus_read_byte_data($file, 127);
# note: if bit 7 of byte 32 is set, a jc42 sensor is at $addr-0x38
}
return;
}