Skip to content
Snippets Groups Projects
Commit 2619efab authored by ballen4705's avatar ballen4705
Browse files

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
parent 33467166
No related branches found
No related tags found
No related merge requests found
CHANGELOG for smartmontools 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> Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
...@@ -32,6 +32,9 @@ NOTES FOR FUTURE RELEASES: see TODO file. ...@@ -32,6 +32,9 @@ NOTES FOR FUTURE RELEASES: see TODO file.
CURRENT RELEASE (see VERSION file in this directory): 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 smartmontools-5.0.49
[PW] smartd --debugmode changed to --debug [PW] smartd --debugmode changed to --debug
......
49 50
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "atacmds.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 // 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 // given in the ATA/ATAPI specs for the IDENTIFY DEVICE command. Note
...@@ -152,6 +152,20 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){ ...@@ -152,6 +152,20 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){
} }
#endif #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 // Reads current Device Identity info (512 bytes) into buf
int ataReadHDIdentity (int device, struct hd_driveid *buf){ int ataReadHDIdentity (int device, struct hd_driveid *buf){
unsigned short driveidchecksum; unsigned short driveidchecksum;
...@@ -191,17 +205,8 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){ ...@@ -191,17 +205,8 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){
} }
#endif #endif
if ((driveidchecksum & 0x00ff) == 0x00a5){ if ((driveidchecksum & 0x00ff) == 0x00a5 && checksum((unsigned char *)buf))
// 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"); checksumwarning("Drive Identity Structure");
}
return 0; return 0;
} }
...@@ -294,8 +299,6 @@ int ataIsSmartEnabled(struct hd_driveid *drive){ ...@@ -294,8 +299,6 @@ int ataIsSmartEnabled(struct hd_driveid *drive){
// Reads SMART attributes into *data // Reads SMART attributes into *data
int ataReadSmartValues(int device, struct ata_smart_values *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]= unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE]=
{WIN_SMART, 0, SMART_READ_VALUES, 1, }; {WIN_SMART, 0, SMART_READ_VALUES, 1, };
...@@ -304,24 +307,19 @@ int ataReadSmartValues(int device, struct ata_smart_values *data){ ...@@ -304,24 +307,19 @@ int ataReadSmartValues(int device, struct ata_smart_values *data){
return -1; return -1;
} }
// compute checksum // copy data
for (i=0;i<ATA_SMART_SEC_SIZE;i++) memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE,ATA_SMART_SEC_SIZE);
chksum+=buf[i+HDIO_DRIVE_CMD_HDR_SIZE];
// verify that checksum vanishes // compute checksum
if (chksum) if (checksum((unsigned char *)data))
checksumwarning("SMART Attribute Data Structure"); checksumwarning("SMART Attribute Data Structure");
// copy data and return
memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE,ATA_SMART_SEC_SIZE);
return 0; return 0;
} }
// Reads the Self Test Log (log #6) // Reads the Self Test Log (log #6)
int ataReadSelfTestLog (int device, struct ata_smart_selftestlog *data){ 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] = unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE] =
{WIN_SMART, 0x06, SMART_READ_LOG_SECTOR, 1,}; {WIN_SMART, 0x06, SMART_READ_LOG_SECTOR, 1,};
...@@ -331,21 +329,18 @@ int ataReadSelfTestLog (int device, struct ata_smart_selftestlog *data){ ...@@ -331,21 +329,18 @@ int ataReadSelfTestLog (int device, struct ata_smart_selftestlog *data){
return -1; 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 // compute its checksum, and issue a warning if needed
for (i=0;i<ATA_SMART_SEC_SIZE;i++) if (checksum((unsigned char *)data))
chksum+=buf[HDIO_DRIVE_CMD_HDR_SIZE+i];
if (chksum)
checksumwarning("SMART Self-Test Log Structure"); 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; return 0;
} }
// Reads the Error Log (log #1) // Reads the Error Log (log #1)
int ataReadErrorLog (int device, struct ata_smart_errorlog *data){ 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] = unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE] =
{WIN_SMART, 0x01, SMART_READ_LOG_SECTOR, 1,}; {WIN_SMART, 0x01, SMART_READ_LOG_SECTOR, 1,};
...@@ -355,21 +350,18 @@ int ataReadErrorLog (int device, struct ata_smart_errorlog *data){ ...@@ -355,21 +350,18 @@ int ataReadErrorLog (int device, struct ata_smart_errorlog *data){
return -1; return -1;
} }
// compute checksum and issue warning if needed //copy data back to user
for (i=0;i<ATA_SMART_SEC_SIZE;i++) memcpy(data, buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE);
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 ATA Error Log Structure"); 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; return 0;
} }
int ataReadSmartThresholds (int device, struct ata_smart_thresholds *data){ 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] = unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE] =
{WIN_SMART, 1, SMART_READ_THRESHOLDS, 1,}; {WIN_SMART, 1, SMART_READ_THRESHOLDS, 1,};
...@@ -379,14 +371,13 @@ int ataReadSmartThresholds (int device, struct ata_smart_thresholds *data){ ...@@ -379,14 +371,13 @@ int ataReadSmartThresholds (int device, struct ata_smart_thresholds *data){
return -1; return -1;
} }
// compute checksum and issue warning if needed // copy data back to user
for (i=0;i<ATA_SMART_SEC_SIZE;i++) memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE);
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"); 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; return 0;
} }
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "atacmds.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 // 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 // given in the ATA/ATAPI specs for the IDENTIFY DEVICE command. Note
...@@ -152,6 +152,20 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){ ...@@ -152,6 +152,20 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){
} }
#endif #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 // Reads current Device Identity info (512 bytes) into buf
int ataReadHDIdentity (int device, struct hd_driveid *buf){ int ataReadHDIdentity (int device, struct hd_driveid *buf){
unsigned short driveidchecksum; unsigned short driveidchecksum;
...@@ -191,17 +205,8 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){ ...@@ -191,17 +205,8 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){
} }
#endif #endif
if ((driveidchecksum & 0x00ff) == 0x00a5){ if ((driveidchecksum & 0x00ff) == 0x00a5 && checksum((unsigned char *)buf))
// 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"); checksumwarning("Drive Identity Structure");
}
return 0; return 0;
} }
...@@ -294,8 +299,6 @@ int ataIsSmartEnabled(struct hd_driveid *drive){ ...@@ -294,8 +299,6 @@ int ataIsSmartEnabled(struct hd_driveid *drive){
// Reads SMART attributes into *data // Reads SMART attributes into *data
int ataReadSmartValues(int device, struct ata_smart_values *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]= unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE]=
{WIN_SMART, 0, SMART_READ_VALUES, 1, }; {WIN_SMART, 0, SMART_READ_VALUES, 1, };
...@@ -304,24 +307,19 @@ int ataReadSmartValues(int device, struct ata_smart_values *data){ ...@@ -304,24 +307,19 @@ int ataReadSmartValues(int device, struct ata_smart_values *data){
return -1; return -1;
} }
// compute checksum // copy data
for (i=0;i<ATA_SMART_SEC_SIZE;i++) memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE,ATA_SMART_SEC_SIZE);
chksum+=buf[i+HDIO_DRIVE_CMD_HDR_SIZE];
// verify that checksum vanishes // compute checksum
if (chksum) if (checksum((unsigned char *)data))
checksumwarning("SMART Attribute Data Structure"); checksumwarning("SMART Attribute Data Structure");
// copy data and return
memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE,ATA_SMART_SEC_SIZE);
return 0; return 0;
} }
// Reads the Self Test Log (log #6) // Reads the Self Test Log (log #6)
int ataReadSelfTestLog (int device, struct ata_smart_selftestlog *data){ 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] = unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE] =
{WIN_SMART, 0x06, SMART_READ_LOG_SECTOR, 1,}; {WIN_SMART, 0x06, SMART_READ_LOG_SECTOR, 1,};
...@@ -331,21 +329,18 @@ int ataReadSelfTestLog (int device, struct ata_smart_selftestlog *data){ ...@@ -331,21 +329,18 @@ int ataReadSelfTestLog (int device, struct ata_smart_selftestlog *data){
return -1; 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 // compute its checksum, and issue a warning if needed
for (i=0;i<ATA_SMART_SEC_SIZE;i++) if (checksum((unsigned char *)data))
chksum+=buf[HDIO_DRIVE_CMD_HDR_SIZE+i];
if (chksum)
checksumwarning("SMART Self-Test Log Structure"); 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; return 0;
} }
// Reads the Error Log (log #1) // Reads the Error Log (log #1)
int ataReadErrorLog (int device, struct ata_smart_errorlog *data){ 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] = unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE] =
{WIN_SMART, 0x01, SMART_READ_LOG_SECTOR, 1,}; {WIN_SMART, 0x01, SMART_READ_LOG_SECTOR, 1,};
...@@ -355,21 +350,18 @@ int ataReadErrorLog (int device, struct ata_smart_errorlog *data){ ...@@ -355,21 +350,18 @@ int ataReadErrorLog (int device, struct ata_smart_errorlog *data){
return -1; return -1;
} }
// compute checksum and issue warning if needed //copy data back to user
for (i=0;i<ATA_SMART_SEC_SIZE;i++) memcpy(data, buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE);
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 ATA Error Log Structure"); 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; return 0;
} }
int ataReadSmartThresholds (int device, struct ata_smart_thresholds *data){ 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] = unsigned char buf[HDIO_DRIVE_CMD_HDR_SIZE+ATA_SMART_SEC_SIZE] =
{WIN_SMART, 1, SMART_READ_THRESHOLDS, 1,}; {WIN_SMART, 1, SMART_READ_THRESHOLDS, 1,};
...@@ -379,14 +371,13 @@ int ataReadSmartThresholds (int device, struct ata_smart_thresholds *data){ ...@@ -379,14 +371,13 @@ int ataReadSmartThresholds (int device, struct ata_smart_thresholds *data){
return -1; return -1;
} }
// compute checksum and issue warning if needed // copy data back to user
for (i=0;i<ATA_SMART_SEC_SIZE;i++) memcpy(data,buf+HDIO_DRIVE_CMD_HDR_SIZE, ATA_SMART_SEC_SIZE);
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"); 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; return 0;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment