13#define __STDC_FORMAT_MACROS 1
39 if (
regular_expression(
"^ST[0-9]{3,5}[A-Z]{2}[A-Z0-9]{3,5}(-.*)?$").full_match(model)) {
58 const size_t FARM_PAGE_SIZE = 16384;
59 const size_t FARM_ATTRIBUTE_SIZE = 8;
60 const size_t FARM_MAX_PAGES = 6;
61 const size_t FARM_SECTOR_SIZE = FARM_PAGE_SIZE * FARM_MAX_PAGES / nsectors;
62 const unsigned FARM_SECTORS_PER_PAGE = nsectors / FARM_MAX_PAGES;
63 const size_t FARM_CURRENT_PAGE_DATA_SIZE[FARM_MAX_PAGES] = {
71 unsigned numSectorsToRead = (
sizeof(
ataFarmHeader) / FARM_SECTOR_SIZE) + 1;
73 for (
unsigned page = 0; page < FARM_MAX_PAGES; page++) {
75 uint8_t pageBuffer[FARM_PAGE_SIZE] = { };
77 uint64_t currentFarmLogPage[FARM_PAGE_SIZE / FARM_ATTRIBUTE_SIZE] = { };
79 bool readSuccessful =
ataReadLogExt(device, 0xA6, 0, page * FARM_SECTORS_PER_PAGE, pageBuffer, numSectorsToRead);
80 if (!readSuccessful) {
81 jerr(
"Read FARM Log page %u failed\n\n", page);
85 for (
unsigned pageOffset = 0; pageOffset < FARM_CURRENT_PAGE_DATA_SIZE[page]; pageOffset += FARM_ATTRIBUTE_SIZE) {
86 uint64_t currentMetric = 0;
88 for (
unsigned byteOffset = 0; byteOffset < FARM_ATTRIBUTE_SIZE - 1; byteOffset++) {
89 currentMetric |= (uint64_t)(pageBuffer[pageOffset + byteOffset] |
90 (pageBuffer[pageOffset + byteOffset + 1] << 8)) << (byteOffset * 8);
93 if (currentMetric >> 56 == 0xC0) {
94 currentMetric &= 0x00FFFFFFFFFFFFFFULL;
99 if (page == 0 && pageOffset == 0) {
100 if (currentMetric != 0x00004641524D4552) {
101 jerr(
"FARM log header is invalid (log signature=%" PRIu64
")\n\n", currentMetric);
106 currentFarmLogPage[pageOffset / FARM_ATTRIBUTE_SIZE] = currentMetric;
112 memcpy(&farmLog.
header, currentFarmLogPage,
sizeof(farmLog.
header));
124 memcpy(&farmLog.
error, currentFarmLogPage,
sizeof(farmLog.
error));
150 return (0 == memcmp(
scsi_vendor,
"SEAGATE", strlen(
"SEAGATE")));
166 const size_t FARM_ATTRIBUTE_SIZE = 8;
169 jerr(
"Read FARM Log page failed\n\n");
172 bool isParameterHeader =
true;
179 uint64_t currentParameter[
sizeof(
gBuf) / FARM_ATTRIBUTE_SIZE] = { };
181 unsigned currentMetricIndex = 0;
183 unsigned currentParameterOffset = 0;
188 pageOffset += FARM_ATTRIBUTE_SIZE) {
190 if (isParameterHeader) {
229 currentParameterOffset +=
sizeof(
scsiFarmByHead) * ((0x2A - 0x10) + (0x36 - 0x30) + (currentParameterHeader.
parameterCode - 0x40));
231 currentParameterOffset +=
sizeof(
scsiFarmByHead) * ((0x2A - 0x10) + (0x36 - 0x30) + (0x4F - 0x40));
270 memcpy(
reinterpret_cast<char*
>(&farmLog) + currentParameterOffset,
271 ¤tParameterHeader,
276 isParameterHeader =
false;
277 currentMetricIndex = 0;
279 uint64_t currentMetric = 0;
281 for (
unsigned byteOffset = 0; byteOffset < FARM_ATTRIBUTE_SIZE; byteOffset++) {
282 currentMetric |= (uint64_t)(
gBuf[pageOffset + byteOffset]) << ((7 - byteOffset) * 8);
285 if (currentMetric >> 56 == 0xC0) {
286 currentMetric &= 0x00FFFFFFFFFFFFFFULL;
289 if (currentMetric != 0x00004641524D4552) {
290 jerr(
"FARM log header is invalid (log signature=%" PRIu64
")\n\n", currentMetric);
295 }
else if (currentParameterHeader.
parameterLength <= currentMetricIndex * FARM_ATTRIBUTE_SIZE) {
297 isParameterHeader =
true;
298 pageOffset -= FARM_ATTRIBUTE_SIZE;
307 currentParameter[currentMetricIndex] = currentMetric;
308 currentMetricIndex++;
bool ataReadLogExt(ata_device *device, unsigned char logaddr, unsigned char features, unsigned page, void *data, unsigned nsectors)
void ata_format_id_string(char *out, const unsigned char *in, int n)
Wrapper class for POSIX regex(3) or std::regex Supports copy & assignment and is compatible with STL ...
bool scsiReadFarmLog(scsi_device *device, scsiFarmLog &farmLog)
bool scsiIsSeagate(char *scsi_vendor)
bool ataIsSeagate(const ata_identify_device &drive, const drive_settings *dbentry)
bool ataReadFarmLog(ata_device *device, ataFarmLog &farmLog, unsigned nsectors)
int scsiLogSense(scsi_device *device, int pagenum, int subpagenum, uint8_t *pBuf, int bufLen, int known_resp_len)
#define SEAGATE_FARM_LPAGE
#define SEAGATE_FARM_CURRENT_L_SPAGE
static char scsi_vendor[8+1]
#define LOG_RESP_LONG_LEN
void void void void jerr(const char *fmt,...) __attribute_format_printf(1
ataFarmErrorStatistics error
ataFarmReliabilityStatistics reliability
ataFarmWorkloadStatistics workload
ataFarmEnvironmentStatistics environment
ataFarmDriveInformation driveInformation
scsiFarmPageHeader pageHeader
bool str_starts_with(const char *str, const char *prefix)