comparison. OBS-URL: https://build.opensuse.org/package/show/Base:System/sensors?expand=0&rev=35
62 lines
1.9 KiB
Diff
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;
|
|
}
|
|
|