305 lines
11 KiB
C++
305 lines
11 KiB
C++
#ifndef _ARCLIBS_H
|
|
#define _ARCLIBS_H
|
|
|
|
/********************************************************/
|
|
/*
|
|
/* Data Structures & Function prototypes for S.M.A.R.T
|
|
/*
|
|
/********************************************************/
|
|
|
|
#include "arclib.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
|
|
#pragma pack(1)
|
|
|
|
|
|
#define MAX_DATA_LENGTH 512
|
|
#define SHORT_SELF_TEST 1
|
|
#define EXTENDED_SELF_TEST 2
|
|
|
|
/*
|
|
Attribute ID Numbers
|
|
Any non-zero value in the Attribute ID Number indicates an active attribute. The device supports the
|
|
following Attribute ID Numbers.
|
|
|
|
ID Attribute Name
|
|
=============================================
|
|
199 Ultra DMA CRC Error Count
|
|
198 Off-line Scan Uncorrectable Sector Count
|
|
197 Current Pending Sector Count
|
|
196 Reallocation Event Count
|
|
194 Temperature
|
|
193 Load Cycle Count
|
|
192 Power-off Retract Count
|
|
12 Device Power Cycle Count
|
|
10 Spin Retry Count
|
|
9 Power-on Hours Count
|
|
8 Seek Time Performance
|
|
7 Seek Error Rate
|
|
5 Reallocated Sector Count
|
|
4 Start/Stop Count
|
|
3 Spin Up Time
|
|
2 Throughput Performance
|
|
1 Raw Read Error Rate
|
|
0 Indicates that this entry in the data structure is not used
|
|
|
|
|
|
Status Flag definitions
|
|
Bit Definition
|
|
0 Pre-failure/advisory bit
|
|
0 An attribute value less than or equal to its corresponding attribute threshold indicates an
|
|
advisory condition where the usage or age of the device has exceeded its intended
|
|
design life period.
|
|
1 An attribute value less than or equal to its corresponding attribute threshold indicates a
|
|
pre-Failure condition where imminent loss of data is being predicted.
|
|
1 On-line Collective bit
|
|
0 The attribute value is updated only during Off-line testing.
|
|
1 The attribute value is updated during On-line testing or during both On-line and Off-line
|
|
testing.
|
|
2 - 5 Vendor specific
|
|
6 - 15 Reserved (0)
|
|
|
|
*/
|
|
|
|
|
|
/*
|
|
The following defines the 12 bytes that make up the information for each Attribute entry in the Device
|
|
Attribute Data Structure.
|
|
*/
|
|
typedef struct _DEVICE_ATTR_DATA // Individual Attribute Data Structure
|
|
{
|
|
BYTE id; // 0x00, Attribute ID Number (01h to FFh)
|
|
BYTE status[2]; // 0x01, Status flags
|
|
BYTE value; // 0x03, Attribute Value (valid values from 01h to FDh)
|
|
BYTE vendor_spec[8]; // 0x04, Vendor Specific
|
|
}sDEVICE_ATTR_DATA, *pDEVICE_ATTR_DATA; // total 12 bytes
|
|
|
|
/*
|
|
The following defines the 512 bytes that make up the Attribute Value information. This data structure is
|
|
accessed by the host in its entirety using the SMART Read Attribute Values subcommand. All multibyte
|
|
fields shown in these data structures are in byte ordering, that is, the least significant byte occupies the
|
|
lowest numbered byte address location in the field.
|
|
*/
|
|
typedef struct _SMART_ATTR_DATA // Device Attributes Data Structure
|
|
{
|
|
BYTE rev_num[2]; // 0x00 Data Structure Revision Number
|
|
sDEVICE_ATTR_DATA device_attr_data[30]; // 0x02 Device Attribute, from 1st~30th
|
|
BYTE dc_status; // 0x16A, Off¡Vline data collection status
|
|
BYTE st_status; // 0x16B, Self¡Vtest execution status
|
|
BYTE total_time_for_dc[2]; // 0x16C, Total time in seconds to complete off¡Vline data collection activity
|
|
BYTE vendor_spec1; // 0x16E, Vendor specific
|
|
BYTE dc_capability; // 0x16F, Off¡Vline data collection capability
|
|
BYTE smart_cap[2]; // 0x170, SMART capability
|
|
BYTE smart_error_log_cap; // 0x172, SMART device error logging capability
|
|
BYTE st_failure_check_point; // 0x173, Self¡Vtest failure check point
|
|
BYTE short_st_completion_time; // 0x174, Short self¡Vtest completion time in minutes
|
|
BYTE extended_st_completion_time; // 0x175, Extended self¡Vtest completion time in minutes
|
|
BYTE reserved[12]; // 0x176, Reserved
|
|
BYTE vendor_spec2[125]; // 0x182, Vendor specific
|
|
BYTE checksum; // 0x1FF, Data structure checksum
|
|
|
|
}sSMART_ATTR_DATA, *pSMART_ATTR_DATA; // total 512 bytes
|
|
|
|
/*
|
|
The following defines the 12 bytes that make up the information for each Threshold entry in the Device
|
|
Attribute Thresholds Data Structure. Attribute entries in the Individual Threshold Data Structure is in the
|
|
same order and correspond to the entries in the Individual Attribute Data Structure.
|
|
*/
|
|
typedef struct _DEVICE_ATTR_THRE_DATA // Individual Thresholds Data Structure
|
|
{
|
|
BYTE id; // 0x00, Attribute ID Number (01h to FFh)
|
|
BYTE threshold; // 0x01, Attribute Threshold
|
|
BYTE reserved[10]; // 0x02, Reserved (00h)
|
|
}sDEVICE_ATTR_THRE_DATA, *pDEVICE_ATTR_THRE_DATA; // total 12 bytes
|
|
|
|
/*
|
|
The following defines the 512 bytes that make up the Attribute Threshold information. This data structure
|
|
is accessed by the host in its entirety using the SMART Read Attribute Thresholds. All multibyte fields
|
|
shown in these data structures are in byte ordering, that is, the least significant byte occupies the lowest
|
|
numbered byte address location in the field.
|
|
The sequence of active Attribute Thresholds will appear in the same order as their corresponding
|
|
Attribute Values.
|
|
*/
|
|
typedef struct _SMART_ATTR_THRE_DATA // Device Attribute Thresholds Data Structure
|
|
{
|
|
BYTE rev_num[2]; // 0x00, Data Structure Revision Number
|
|
sDEVICE_ATTR_THRE_DATA device_attr_data[30]; // 0x02, Device Attribute, from 1st~30th
|
|
BYTE reserved[18]; // 0x16A, Reserved
|
|
BYTE vendor_spec[131]; // 0x17C, Vendor specific
|
|
BYTE checksum; // 0x1FF, Data structure checksum
|
|
}sSMART_ATTR_THRE_DATA, *pSMART_ATTR_THRE_THRE_DATA; // total 512 bytes
|
|
|
|
|
|
/*
|
|
Command data structure
|
|
Data format of each command data structure is shown below.
|
|
*/
|
|
typedef struct _COMMAND_DATA
|
|
{
|
|
BYTE dev_control_reg; // 0x00, Device Control register
|
|
BYTE features_reg; // 0x01, Features register
|
|
BYTE sector_count_reg; // 0x02, Sector count register
|
|
BYTE sector_number_reg; // 0x03, Sector number register
|
|
BYTE cylinder_low_reg; // 0x04, Cylinder Low register
|
|
BYTE cylinder_high_reg; // 0x05, Cylinder High register
|
|
BYTE head_reg; // 0x06, Device/Head register
|
|
BYTE command_reg; // 0x07, Command register
|
|
BYTE time_stamp[4]; // 0x08, Timestamp(ms from Power On)
|
|
}sCOMMAND_DATA, *pCOMMAND_DATA; // total 12 bytes
|
|
|
|
/*
|
|
Error data structure:
|
|
Data format of error data structure is shown below.
|
|
The state field contains a value indicating the device state when the command was issued to the device.
|
|
xBh-xFh Vendor specific
|
|
x5h-xAh Reserved
|
|
x4h SMART Off-line or Self-test
|
|
x3h Active/Idle
|
|
x2h Standby
|
|
x1h Sleep
|
|
x0h Unknown
|
|
Value
|
|
*/
|
|
|
|
typedef struct _ERROR_DATA
|
|
{
|
|
BYTE reserved; // 0x00, Reserved
|
|
BYTE error_reg; // 0x01, Error register
|
|
BYTE sector_count_reg; // 0x02, Sector count register
|
|
BYTE sector_number_reg; // 0x03, Sector number register
|
|
BYTE cylinder_low_reg; // 0x04, Cylinder Low register
|
|
BYTE cylinder_high_reg; // 0x05, Cylinder High register
|
|
BYTE head_reg; // 0x06, Device/Head register
|
|
BYTE status_reg; // 0x07, Status register
|
|
BYTE extended_error_data[19]; //0x08, Extended error data (vendor specific)
|
|
BYTE state; // 0x1B, State
|
|
BYTE life_timestamp[2]; // 0x1C Life timestamp (hours)
|
|
}sERROR_DATA, *pERROR_DATA; // total 30 bytes
|
|
|
|
|
|
/*
|
|
Error log data structure
|
|
Data format of error data structure is shown below.
|
|
*/
|
|
typedef struct _ERROR_LOG_DATA
|
|
{
|
|
sCOMMAND_DATA command_data[5]; // 0x00, Command data structure, from 1~5
|
|
sERROR_DATA error_data; // 0x3C, Error data structure
|
|
}sERROR_LOG_DATA, *pERROR_LOG_DATA; // total 90 bytes
|
|
|
|
|
|
/*
|
|
The following figure defines the 512 bytes that make up the SMART error log sector. All multibyte fields
|
|
shown in these data structures are in byte ordering.
|
|
*/
|
|
typedef struct _SMART_ERROR_LOG_SECTOR
|
|
{
|
|
BYTE version; // 0x00, SMART error log version
|
|
BYTE pointer; // 0x01, Error log pointer
|
|
sERROR_LOG_DATA log_data[5]; // 0x02, 1st~5th error log data structure
|
|
BYTE device_error_count[2]; // 0x1C4, Device error count
|
|
BYTE reserved[57]; // 0x1C6, Reserved
|
|
BYTE checksum; // 0x1FF, Data structure checksum
|
|
|
|
}sSMART_ERROR_LOG_SECTOR, *pSMART_ERROR_LOG_SECTOR; // total 512 bytes
|
|
|
|
|
|
/*
|
|
The data structure contains the descriptor of Self-test that the device has performed. Each descriptor is
|
|
24 bytes long and the self-test data structure is capable of containing up to 21 descriptors.
|
|
After 21 descriptors have been recorded, the oldest descriptor will be overwritten with a new descriptor.
|
|
The self-test log pointer points to the most recent descriptor. When there is no descriptor, the value is 0.
|
|
When there is descriptor(s) the value is 1 through 21.
|
|
*/
|
|
typedef struct _SELF_TEST_LOG_DESCRIPTOR
|
|
{
|
|
BYTE number; // 0x00, Self-test number
|
|
BYTE exe_status; // 0x01, Self-test execution status
|
|
BYTE life_time[2]; // 0x02, Life time power on hours
|
|
BYTE st_failure_check_point; // 0x04, Self-test failure check point
|
|
BYTE lba_of_first_failure[4];// 0x05, LBA of first failure
|
|
BYTE vendor_spec[15]; // 0x06, Vendor specific
|
|
|
|
}sSELF_TEST_LOG_DESCRIPTOR, *pSELF_TEST_LOG_DESCRIPTOR; // total 24 bytes
|
|
|
|
|
|
/*
|
|
Self-test log data structure
|
|
The following figure defines the 512 bytes that make up the Self-test log sector. All multibyte fields shown
|
|
in these data structures are in byte ordering.
|
|
*/
|
|
|
|
typedef struct _SELF_TEST_LOG_DATA
|
|
{
|
|
BYTE reversion[2]; // 0x00, Data structure revision
|
|
sSELF_TEST_LOG_DESCRIPTOR descriptor[21]; // 0x02, descriptors
|
|
BYTE vendor_spec[2]; // 0x1FA, Vendor specific
|
|
BYTE pointer; // 0x1FC, Self-test log pointer
|
|
BYTE reserved[2]; // 0x1FD, Reserved
|
|
BYTE checksum; // 0x1FF, Data structure checksum
|
|
}sSELF_TEST_LOG_DATA, *pSELF_TEST_LOG_DATA; // total 512 bytes
|
|
|
|
|
|
#ifdef _WIN32
|
|
class ARCLIB_API CArclibSMART : public CArclib
|
|
{
|
|
#else
|
|
class CArclibSMART : public CArclib
|
|
{
|
|
#endif
|
|
public:
|
|
|
|
// (O): Implemented
|
|
// (X): Not Implemented
|
|
enum
|
|
{
|
|
R_SMART_DATA = 0, // (O)Read smart data
|
|
R_THLD_DATA, // (O)Read threshold data
|
|
ED_AUTOSAVE, // (X)Enable/disable autosave
|
|
S_ATTR, // (X)Save attribute
|
|
EXE_OFFLINE, // (O)Execute offline
|
|
R_LOG, // (X)Read log
|
|
W_LOG, // (X)Write log
|
|
RESERVED1,
|
|
E_SMART, // (O)Enable SMART
|
|
D_SMART, // (O)Disable SMART
|
|
RET_SMART_STATUS, // (X)Return SMART status
|
|
ED_AUTO_OFFLINE, // (X)Enable/Disable automatic offline
|
|
RESERVED2,
|
|
RESERVED3,
|
|
RESERVED4,
|
|
RESERVED5,
|
|
RW_TEST, // (O)Read/Write test
|
|
STOP_RW_TEST, // (O)Stop Read/Write test
|
|
CHECK_RW_RESULT, // (O)Check Read/Write Result
|
|
RESERVED6
|
|
};
|
|
|
|
//################################################################################################
|
|
// Function: ArcExeSMART
|
|
// Parameters: (i) cmd: the commands listed above
|
|
// (i) drv: drive# where the SMART command is being executed
|
|
// (i) params: The options for EXE_OFFLINE, RW_TEST only.
|
|
// for EXE_OFFLINE: value SHORT_SELF_TEST indicates short self-test
|
|
// value EXTENDED_SELF_TEST indicates extended self-test
|
|
// for RW_TEST: percentage of RW_TEST
|
|
// (o) data: The option for R_SMART_DATA, R_THLD_DATA, CHECK_RW_RESULT only.
|
|
// the SMART data returned from the drive that indicates by drv,
|
|
// the memory allocation of 'data' is the responsibility of the
|
|
// calling thread, and it's size should be >= 512 bytes
|
|
//################################################################################################
|
|
ARC_STATUS ArcExeSMART(int cmd, BYTE drv, BYTE params, PBYTE data);
|
|
};
|
|
|
|
#pragma pack()
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|