diff --git a/smartmontools/CHANGELOG b/smartmontools/CHANGELOG
index c860c3cfcfc262cf6e45b94c773aeebfb1386810..f6d1121a42ebdb11ecf5035d1d572817a4f677fc 100644
--- a/smartmontools/CHANGELOG
+++ b/smartmontools/CHANGELOG
@@ -42,6 +42,9 @@ NOTES FOR FUTURE RELEASES: see TODO file.
 
 <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE>
 
+  [CF] Print only one warning on checksum errors in multi sector log.
+       Remove casts from calls of checksum().
+
   [DG] minor changes to SCSI background scan strings
 
   [MS] knowndrives.cpp updates:
diff --git a/smartmontools/atacmds.cpp b/smartmontools/atacmds.cpp
index e1c7f427d0570c08d0c4581f557b326ff19d7adb..f7ed4e2c8a1b1f22aeac951ea625841a2af1048f 100644
--- a/smartmontools/atacmds.cpp
+++ b/smartmontools/atacmds.cpp
@@ -40,8 +40,8 @@
 
 #include <algorithm> // std::sort
 
-const char *atacmds_c_cvsid="$Id: atacmds.cpp,v 1.219 2009/07/07 19:28:29 chrfranke Exp $"
-ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSIATA_H_CVSID UTILITY_H_CVSID;
+const char * atacmds_cpp_cvsid = "$Id$"
+                                 ATACMDS_H_CVSID;
 
 // for passing global control variables
 extern smartmonctrl *con;
@@ -633,14 +633,11 @@ uint64_t get_num_sectors(const ata_identify_device * drive)
 // This function computes the checksum of a single disk sector (512
 // bytes).  Returns zero if checksum is OK, nonzero if the checksum is
 // incorrect.  The size (512) is correct for all SMART structures.
-unsigned char checksum(const unsigned char *buffer)
+unsigned char checksum(const void * data)
 {
-  unsigned char sum=0;
-  int i;
-  
-  for (i=0; i<512; i++)
-    sum+=buffer[i];
-
+  unsigned char sum = 0;
+  for (int i = 0; i < 512; i++)
+    sum += ((const unsigned char *)data)[i];
   return sum;
 }
 
@@ -886,7 +883,7 @@ int ataReadSmartValues(ata_device * device, struct ata_smart_values *data){
   }
 
   // compute checksum
-  if (checksum((unsigned char *)data))
+  if (checksum(data))
     checksumwarning("SMART Attribute Data Structure");
   
   // swap endian order if needed
@@ -935,7 +932,7 @@ int ataReadSelfTestLog (ata_device * device, ata_smart_selftestlog * data,
   }
 
   // compute its checksum, and issue a warning if needed
-  if (checksum((unsigned char *)data))
+  if (checksum(data))
     checksumwarning("SMART Self-Test Log Structure");
   
   // fix firmware bugs in self-test log
@@ -956,6 +953,22 @@ int ataReadSelfTestLog (ata_device * device, ata_smart_selftestlog * data,
   return 0;
 }
 
+// Print checksum warning for multi sector log
+static void check_multi_sector_sum(const void * data, unsigned nsectors, const char * msg)
+{
+    unsigned errs = 0;
+    for (unsigned i = 0; i < nsectors; i++) {
+      if (checksum((const unsigned *)data + i*512))
+        errs++;
+    }
+    if (errs > 0) {
+      if (nsectors == 1)
+        checksumwarning(msg);
+      else
+        checksumwarning(strprintf("%s (%u/%u)", msg, errs, nsectors).c_str());
+    }
+}
+
 // Read SMART Extended Self-test Log
 bool ataReadExtSelfTestLog(ata_device * device, ata_smart_extselftestlog * log,
                            unsigned nsectors)
@@ -963,10 +976,7 @@ bool ataReadExtSelfTestLog(ata_device * device, ata_smart_extselftestlog * log,
   if (!ataReadLogExt(device, 0x07, 0x00, 0, log, nsectors))
     return false;
 
-  for (unsigned i = 0; i < nsectors; i++) {
-    if (checksum((const unsigned char *)(log + i)))
-      checksumwarning("SMART Extended Self-test Log Structure");
-  }
+  check_multi_sector_sum(log, nsectors, "SMART Extended Self-test Log Structure");
 
   if (isbigendian()) {
     swapx(&log->log_desc_index);
@@ -1062,7 +1072,7 @@ int ataReadSelectiveSelfTestLog(ata_device * device, struct ata_selective_self_t
   }
    
   // compute its checksum, and issue a warning if needed
-  if (checksum((unsigned char *)data))
+  if (checksum(data))
     checksumwarning("SMART Selective Self-Test Log Structure");
   
   // swap endian order if needed
@@ -1295,7 +1305,7 @@ int ataReadErrorLog (ata_device * device, ata_smart_errorlog *data,
   }
   
   // compute its checksum, and issue a warning if needed
-  if (checksum((unsigned char *)data))
+  if (checksum(data))
     checksumwarning("SMART ATA Error Log Structure");
   
   // Some disks have the byte order reversed in some SMART Summary
@@ -1333,10 +1343,7 @@ bool ataReadExtErrorLog(ata_device * device, ata_smart_exterrlog * log,
   if (!ataReadLogExt(device, 0x03, 0x00, 0, log, nsectors))
     return false;
 
-  for (unsigned i = 0; i < nsectors; i++) {
-    if (checksum((const unsigned char *)(log + i)))
-      checksumwarning("SMART ATA Extended Comprehensive Error Log Structure");
-  }
+  check_multi_sector_sum(log, nsectors, "SMART Extended Comprehensive Error Log Structure");
 
   if (isbigendian()) {
     swapx(&log->device_error_count);
@@ -1362,7 +1369,7 @@ int ataReadSmartThresholds (ata_device * device, struct ata_smart_thresholds_pvt
   }
   
   // compute its checksum, and issue a warning if needed
-  if (checksum((unsigned char *)data))
+  if (checksum(data))
     checksumwarning("SMART Attribute Thresholds Structure");
   
   // swap endian order if needed
diff --git a/smartmontools/atacmds.h b/smartmontools/atacmds.h
index 5d61f947a83e2261d7d3e085855623124f26e25e..7b18b5213502e2cb5c5ea2b23a7e4879ee0b657b 100644
--- a/smartmontools/atacmds.h
+++ b/smartmontools/atacmds.h
@@ -26,7 +26,7 @@
 #ifndef ATACMDS_H_
 #define ATACMDS_H_
 
-#define ATACMDS_H_CVSID "$Id: atacmds.h,v 1.108 2009/07/07 19:28:29 chrfranke Exp $\n"
+#define ATACMDS_H_CVSID "$Id$"
 
 #include "dev_interface.h" // ata_device
 
@@ -842,7 +842,7 @@ inline void format_ata_string(char * out, const unsigned char * in, int n, bool
   { format_ata_string(out, (const char *)in, n, fix_swap); }
 
 // Utility routines.
-unsigned char checksum(const unsigned char * buffer);
+unsigned char checksum(const void * data);
 
 void swap2(char *location);
 void swap4(char *location);