sensors/lm_sensors-r5930-fix-DDR3-SPD-detection.patch

62 lines
1.9 KiB
Diff

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.
---
prog/detect/sensors-detect | 37 +++++++++++++++++++++++++++++++------
1 file changed, 31 insertions(+), 6 deletions(-)
--- lm_sensors-3.2.0.orig/prog/detect/sensors-detect
+++ lm_sensors-3.2.0/prog/detect/sensors-detect
@@ -5134,19 +5134,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++) {
- $checksum += i2c_smbus_read_byte_data($file, $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 &= 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
}
- $checksum &= 255;
- return 8 if $checksum == i2c_smbus_read_byte_data($file, 63);
return;
}