From 2619efab6cc25add5e3629cefbf3ee30df2490c4 Mon Sep 17 00:00:00 2001
From: ballen4705 <ballen4705@4ea69e1a-61f1-4043-bf83-b5c94c648137>
Date: Thu, 12 Dec 2002 13:42:59 +0000
Subject: [PATCH] Simplified checksum handling for easier porting to Darwin.

git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@372 4ea69e1a-61f1-4043-bf83-b5c94c648137
---
 sm5/CHANGELOG   |  5 ++-
 sm5/VERSION     |  2 +-
 sm5/atacmds.c   | 87 ++++++++++++++++++++++---------------------------
 sm5/atacmds.cpp | 87 ++++++++++++++++++++++---------------------------
 4 files changed, 83 insertions(+), 98 deletions(-)

diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG
index 8eb02fcd3..4ee3216ad 100644
--- a/sm5/CHANGELOG
+++ b/sm5/CHANGELOG
@@ -1,6 +1,6 @@
 CHANGELOG for smartmontools
 
-$Id: CHANGELOG,v 1.68 2002/12/08 14:37:42 ballen4705 Exp $
+$Id: CHANGELOG,v 1.69 2002/12/12 13:42:59 ballen4705 Exp $
 
 Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
 
@@ -32,6 +32,9 @@ NOTES FOR FUTURE RELEASES: see TODO file.
 
 CURRENT RELEASE (see VERSION file in this directory):
 
+  [BA] smartctl, smartd simplified internal handling of checksums
+  for simpler porting and less code.
+
 smartmontools-5.0.49
 
   [PW] smartd --debugmode changed to --debug
diff --git a/sm5/VERSION b/sm5/VERSION
index 95f9650f0..e373ee695 100644
--- a/sm5/VERSION
+++ b/sm5/VERSION
@@ -1 +1 @@
-49
+50
diff --git a/sm5/atacmds.c b/sm5/atacmds.c
index 10e17b848..8ee0135ff 100644
--- a/sm5/atacmds.c
+++ b/sm5/atacmds.c
@@ -29,7 +29,7 @@
 #include <stdlib.h>
 #include "atacmds.h"
 
-const char *CVSid1="$Id: atacmds.c,v 1.44 2002/12/04 14:17:51 ballen4705 Exp $" CVSID1;
+const char *CVSid1="$Id: atacmds.c,v 1.45 2002/12/12 13:42:59 ballen4705 Exp $" CVSID1;
 
 // These Drive Identity tables are taken from hdparm 5.2, and are also
 // given in the ATA/ATAPI specs for the IDENTIFY DEVICE command.  Note
@@ -152,6 +152,20 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){
 }
 #endif
 
+
+// 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(unsigned char *buffer){
+  unsigned char sum=0;
+  int i;
+  
+  for (i=0; i<512; i++)
+    sum+=buffer[i];
+
+  return sum;
+}
+
 // Reads current Device Identity info (512 bytes) into buf
 int ataReadHDIdentity (int device, struct hd_driveid *buf){
   unsigned short driveidchecksum;
@@ -191,19 +205,10 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){
   }
 #endif
   
-  if ((driveidchecksum & 0x00ff) == 0x00a5){
-    // Device identity structure contains a checksum
-    unsigned char cksum=0;
-    int i;
-    
-    for (i=0;i<sizeof(*buf);i++)
-      cksum+=parms[i+HDIO_DRIVE_CMD_HDR_SIZE];
-    
-    if (cksum)
-      checksumwarning("Drive Identity Structure");
-  }
- 
- return 0;
+  if ((driveidchecksum & 0x00ff) == 0x00a5 && checksum((unsigned char *)buf))
+    checksumwarning("Drive Identity Structure");
+  
+  return 0;
 }
 
 // Returns ATA version as an integer, and a pointer to a string
@@ -294,8 +299,6 @@ int ataIsSmartEnabled(struct hd_driveid *drive){
 
 // Reads SMART attributes into *data
 int ataReadSmartValues(int device, struct ata_smart_values *data){	
-  int i;
-  unsigned char chksum=0;
   unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE]= 
     {WIN_SMART, 0, SMART_READ_VALUES, 1, };
   
@@ -303,25 +306,20 @@ int ataReadSmartValues(int device, struct ata_smart_values *data){
     syserror("Error SMART Values Read failed");
     return -1;
   }
-  
+
+  // copy data
+  memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE,ATA_SMART_SEC_SIZE);
+
   // compute checksum
-  for (i=0;i<ATA_SMART_SEC_SIZE;i++)
-    chksum+=buf[i+HDIO_DRIVE_CMD_HDR_SIZE];
-  
-  // verify that checksum vanishes
-  if (chksum)
+  if (checksum((unsigned char *)data))
     checksumwarning("SMART Attribute Data Structure");
   
-  // copy data and return
-  memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE,ATA_SMART_SEC_SIZE);
   return 0;
 }
 
 
 // Reads the Self Test Log (log #6)
 int ataReadSelfTestLog (int device, struct ata_smart_selftestlog *data){	
-  int i;
-  unsigned char chksum=0;	
   unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE] = 
     {WIN_SMART, 0x06, SMART_READ_LOG_SECTOR, 1,};
   
@@ -330,22 +328,19 @@ int ataReadSelfTestLog (int device, struct ata_smart_selftestlog *data){
     syserror("Error SMART Error Self-Test Log Read failed");
     return -1;
   }
-  
+
+  // copy data back to the user
+  memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE); 
+
   // compute its checksum, and issue a warning if needed
-  for (i=0;i<ATA_SMART_SEC_SIZE;i++)
-    chksum+=buf[HDIO_DRIVE_CMD_HDR_SIZE+i];
-  if (chksum)
+  if (checksum((unsigned char *)data))
     checksumwarning("SMART Self-Test Log Structure");
   
-  // copy data back to the user and return
-  memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE); 
   return 0;
 }
 
 // Reads the Error Log (log #1)
 int ataReadErrorLog (int device, struct ata_smart_errorlog *data){	
-  int i;
-  unsigned char chksum=0;	
   unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE] = 
     {WIN_SMART, 0x01, SMART_READ_LOG_SECTOR, 1,};
   
@@ -355,21 +350,18 @@ int ataReadErrorLog (int device, struct ata_smart_errorlog *data){
     return -1;
   }
   
-  // compute checksum and issue warning if needed
-  for (i=0;i<ATA_SMART_SEC_SIZE;i++)
-    chksum+=buf[HDIO_DRIVE_CMD_HDR_SIZE+i];
-  if (chksum)
+  //copy data back to user
+  memcpy(data, buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE);
+  
+  // compute its checksum, and issue a warning if needed
+  if (checksum((unsigned char *)data))
     checksumwarning("SMART ATA Error Log Structure");
   
-  //copy data back to user and return
-  memcpy(data, buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE);
   return 0;
 }
 
 
 int ataReadSmartThresholds (int device, struct ata_smart_thresholds *data){
-  int i;
-  unsigned char chksum=0;	
   unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE] = 
     {WIN_SMART, 1, SMART_READ_THRESHOLDS, 1,};
   
@@ -378,15 +370,14 @@ int ataReadSmartThresholds (int device, struct ata_smart_thresholds *data){
     syserror("Error SMART Thresholds Read failed");
     return -1;
   }
+
+  // copy data back to user
+  memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE);
   
-  // compute checksum and issue warning if needed
-  for (i=0;i<ATA_SMART_SEC_SIZE;i++)
-    chksum+=buf[HDIO_DRIVE_CMD_HDR_SIZE+i];
-  if (chksum)
+  // compute its checksum, and issue a warning if needed
+  if (checksum((unsigned char *)data))
     checksumwarning("SMART Attribute Thresholds Structure");
   
-  // copy data back to user and return
-  memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE);
   return 0;
 }
 
diff --git a/sm5/atacmds.cpp b/sm5/atacmds.cpp
index 7a3473f98..47b333e10 100644
--- a/sm5/atacmds.cpp
+++ b/sm5/atacmds.cpp
@@ -29,7 +29,7 @@
 #include <stdlib.h>
 #include "atacmds.h"
 
-const char *CVSid1="$Id: atacmds.cpp,v 1.44 2002/12/04 14:17:51 ballen4705 Exp $" CVSID1;
+const char *CVSid1="$Id: atacmds.cpp,v 1.45 2002/12/12 13:42:59 ballen4705 Exp $" CVSID1;
 
 // These Drive Identity tables are taken from hdparm 5.2, and are also
 // given in the ATA/ATAPI specs for the IDENTIFY DEVICE command.  Note
@@ -152,6 +152,20 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){
 }
 #endif
 
+
+// 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(unsigned char *buffer){
+  unsigned char sum=0;
+  int i;
+  
+  for (i=0; i<512; i++)
+    sum+=buffer[i];
+
+  return sum;
+}
+
 // Reads current Device Identity info (512 bytes) into buf
 int ataReadHDIdentity (int device, struct hd_driveid *buf){
   unsigned short driveidchecksum;
@@ -191,19 +205,10 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){
   }
 #endif
   
-  if ((driveidchecksum & 0x00ff) == 0x00a5){
-    // Device identity structure contains a checksum
-    unsigned char cksum=0;
-    int i;
-    
-    for (i=0;i<sizeof(*buf);i++)
-      cksum+=parms[i+HDIO_DRIVE_CMD_HDR_SIZE];
-    
-    if (cksum)
-      checksumwarning("Drive Identity Structure");
-  }
- 
- return 0;
+  if ((driveidchecksum & 0x00ff) == 0x00a5 && checksum((unsigned char *)buf))
+    checksumwarning("Drive Identity Structure");
+  
+  return 0;
 }
 
 // Returns ATA version as an integer, and a pointer to a string
@@ -294,8 +299,6 @@ int ataIsSmartEnabled(struct hd_driveid *drive){
 
 // Reads SMART attributes into *data
 int ataReadSmartValues(int device, struct ata_smart_values *data){	
-  int i;
-  unsigned char chksum=0;
   unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE]= 
     {WIN_SMART, 0, SMART_READ_VALUES, 1, };
   
@@ -303,25 +306,20 @@ int ataReadSmartValues(int device, struct ata_smart_values *data){
     syserror("Error SMART Values Read failed");
     return -1;
   }
-  
+
+  // copy data
+  memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE,ATA_SMART_SEC_SIZE);
+
   // compute checksum
-  for (i=0;i<ATA_SMART_SEC_SIZE;i++)
-    chksum+=buf[i+HDIO_DRIVE_CMD_HDR_SIZE];
-  
-  // verify that checksum vanishes
-  if (chksum)
+  if (checksum((unsigned char *)data))
     checksumwarning("SMART Attribute Data Structure");
   
-  // copy data and return
-  memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE,ATA_SMART_SEC_SIZE);
   return 0;
 }
 
 
 // Reads the Self Test Log (log #6)
 int ataReadSelfTestLog (int device, struct ata_smart_selftestlog *data){	
-  int i;
-  unsigned char chksum=0;	
   unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE] = 
     {WIN_SMART, 0x06, SMART_READ_LOG_SECTOR, 1,};
   
@@ -330,22 +328,19 @@ int ataReadSelfTestLog (int device, struct ata_smart_selftestlog *data){
     syserror("Error SMART Error Self-Test Log Read failed");
     return -1;
   }
-  
+
+  // copy data back to the user
+  memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE); 
+
   // compute its checksum, and issue a warning if needed
-  for (i=0;i<ATA_SMART_SEC_SIZE;i++)
-    chksum+=buf[HDIO_DRIVE_CMD_HDR_SIZE+i];
-  if (chksum)
+  if (checksum((unsigned char *)data))
     checksumwarning("SMART Self-Test Log Structure");
   
-  // copy data back to the user and return
-  memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE); 
   return 0;
 }
 
 // Reads the Error Log (log #1)
 int ataReadErrorLog (int device, struct ata_smart_errorlog *data){	
-  int i;
-  unsigned char chksum=0;	
   unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE] = 
     {WIN_SMART, 0x01, SMART_READ_LOG_SECTOR, 1,};
   
@@ -355,21 +350,18 @@ int ataReadErrorLog (int device, struct ata_smart_errorlog *data){
     return -1;
   }
   
-  // compute checksum and issue warning if needed
-  for (i=0;i<ATA_SMART_SEC_SIZE;i++)
-    chksum+=buf[HDIO_DRIVE_CMD_HDR_SIZE+i];
-  if (chksum)
+  //copy data back to user
+  memcpy(data, buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE);
+  
+  // compute its checksum, and issue a warning if needed
+  if (checksum((unsigned char *)data))
     checksumwarning("SMART ATA Error Log Structure");
   
-  //copy data back to user and return
-  memcpy(data, buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE);
   return 0;
 }
 
 
 int ataReadSmartThresholds (int device, struct ata_smart_thresholds *data){
-  int i;
-  unsigned char chksum=0;	
   unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE] = 
     {WIN_SMART, 1, SMART_READ_THRESHOLDS, 1,};
   
@@ -378,15 +370,14 @@ int ataReadSmartThresholds (int device, struct ata_smart_thresholds *data){
     syserror("Error SMART Thresholds Read failed");
     return -1;
   }
+
+  // copy data back to user
+  memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE);
   
-  // compute checksum and issue warning if needed
-  for (i=0;i<ATA_SMART_SEC_SIZE;i++)
-    chksum+=buf[HDIO_DRIVE_CMD_HDR_SIZE+i];
-  if (chksum)
+  // compute its checksum, and issue a warning if needed
+  if (checksum((unsigned char *)data))
     checksumwarning("SMART Attribute Thresholds Structure");
   
-  // copy data back to user and return
-  memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE);
   return 0;
 }
 
-- 
GitLab