File lm_sensors-r5930-fix-DDR3-SPD-detection.patch of Package sensors

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;
 }
 
openSUSE Build Service is sponsored by