4 * Home page of code is: http://www.smartmontools.org
6 * Copyright (C) 2002-11 Bruce Allen
7 * Copyright (C) 2008-17 Christian Franke
8 * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
9 * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
16 * You should have received a copy of the GNU General Public License
17 * (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
19 * This code was originally developed as a Senior Thesis by Michael Cornwell
20 * at the Concurrent Systems Laboratory (now part of the Storage Systems
21 * Research Center), Jack Baskin School of Engineering, University of
22 * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
35 #include "knowndrives.h" // get_default_attr_defs()
37 #include "dev_ata_cmd_set.h" // for parsed_ata_device
39 const char * atacmds_cpp_cvsid
= "$Id: atacmds.cpp 4582 2017-11-03 20:54:56Z chrfranke $"
42 // Print ATA debug messages?
43 unsigned char ata_debugmode
= 0;
45 // Suppress serial number?
46 // (also used in scsiprint.cpp)
47 bool dont_print_serial_number
= false;
50 #define SMART_CYL_LOW 0x4F
51 #define SMART_CYL_HI 0xC2
53 // SMART RETURN STATUS yields SMART_CYL_HI,SMART_CYL_LOW to indicate drive
54 // is healthy and SRET_STATUS_HI_EXCEEDED,SRET_STATUS_MID_EXCEEDED to
55 // indicate that a threshhold exceeded condition has been detected.
56 // Those values (byte pairs) are placed in ATA register "LBA 23:8".
57 #define SRET_STATUS_HI_EXCEEDED 0x2C
58 #define SRET_STATUS_MID_EXCEEDED 0xF4
61 // Get ID and increase flag of current pending or offline
62 // uncorrectable attribute.
63 unsigned char get_unc_attr_id(bool offline
, const ata_vendor_attr_defs
& defs
,
66 unsigned char id
= (!offline
? 197 : 198);
67 const ata_vendor_attr_defs::entry
& def
= defs
[id
];
68 if (def
.flags
& ATTRFLAG_INCREASING
)
69 increase
= true; // '-v 19[78],increasing' option
70 else if (def
.name
.empty() || (id
== 198 && def
.name
== "Offline_Scan_UNC_SectCt"))
71 increase
= false; // no or '-v 198,offlinescanuncsectorct' option
73 id
= 0; // other '-v 19[78],...' option
77 #if 0 // TODO: never used
78 // This are the meanings of the Self-test failure checkpoint byte.
79 // This is in the self-test log at offset 4 bytes into the self-test
80 // descriptor and in the SMART READ DATA structure at byte offset
81 // 371. These codes are not well documented. The meanings returned by
82 // this routine are used (at least) by Maxtor and IBM. Returns NULL if
83 // not recognized. Currently the maximum length is 15 bytes.
84 const char *SelfTestFailureCodeName(unsigned char which
){
92 return "Servo_Random";
96 return "Handling_Damage";
106 // Table of raw print format names
107 struct format_name_entry
110 ata_attr_raw_format format
;
113 const format_name_entry format_names
[] = {
114 {"raw8" , RAWFMT_RAW8
},
115 {"raw16" , RAWFMT_RAW16
},
116 {"raw48" , RAWFMT_RAW48
},
117 {"hex48" , RAWFMT_HEX48
},
118 {"raw56" , RAWFMT_RAW56
},
119 {"hex56" , RAWFMT_HEX56
},
120 {"raw64" , RAWFMT_RAW64
},
121 {"hex64" , RAWFMT_HEX64
},
122 {"raw16(raw16)" , RAWFMT_RAW16_OPT_RAW16
},
123 {"raw16(avg16)" , RAWFMT_RAW16_OPT_AVG16
},
124 {"raw24(raw8)" , RAWFMT_RAW24_OPT_RAW8
},
125 {"raw24/raw24" , RAWFMT_RAW24_DIV_RAW24
},
126 {"raw24/raw32" , RAWFMT_RAW24_DIV_RAW32
},
127 {"sec2hour" , RAWFMT_SEC2HOUR
},
128 {"min2hour" , RAWFMT_MIN2HOUR
},
129 {"halfmin2hour" , RAWFMT_HALFMIN2HOUR
},
130 {"msec24hour32" , RAWFMT_MSEC24_HOUR32
},
131 {"tempminmax" , RAWFMT_TEMPMINMAX
},
132 {"temp10x" , RAWFMT_TEMP10X
},
135 const unsigned num_format_names
= sizeof(format_names
)/sizeof(format_names
[0]);
137 // Table to map old to new '-v' option arguments
138 const char * const map_old_vendor_opts
[][2] = {
139 { "9,halfminutes" , "9,halfmin2hour,Power_On_Half_Minutes"},
140 { "9,minutes" , "9,min2hour,Power_On_Minutes"},
141 { "9,seconds" , "9,sec2hour,Power_On_Seconds"},
142 { "9,temp" , "9,tempminmax,Temperature_Celsius"},
143 {"192,emergencyretractcyclect" , "192,raw48,Emerg_Retract_Cycle_Ct"},
144 {"193,loadunload" , "193,raw24/raw24"},
145 {"194,10xCelsius" , "194,temp10x,Temperature_Celsius_x10"},
146 {"194,unknown" , "194,raw48,Unknown_Attribute"},
147 {"197,increasing" , "197,raw48+,Total_Pending_Sectors"}, // '+' sets flag
148 {"198,offlinescanuncsectorct" , "198,raw48,Offline_Scan_UNC_SectCt"}, // see also get_unc_attr_id() above
149 {"198,increasing" , "198,raw48+,Total_Offl_Uncorrectabl"}, // '+' sets flag
150 {"200,writeerrorcount" , "200,raw48,Write_Error_Count"},
151 {"201,detectedtacount" , "201,raw48,Detected_TA_Count"},
152 {"220,temp" , "220,tempminmax,Temperature_Celsius"},
155 const unsigned num_old_vendor_opts
= sizeof(map_old_vendor_opts
)/sizeof(map_old_vendor_opts
[0]);
157 // Parse vendor attribute display def (-v option).
158 // Return false on error.
159 bool parse_attribute_def(const char * opt
, ata_vendor_attr_defs
& defs
,
160 ata_vendor_def_prior priority
)
162 // Map old -> new options
164 for (i
= 0; i
< num_old_vendor_opts
; i
++) {
165 if (!strcmp(opt
, map_old_vendor_opts
[i
][0])) {
166 opt
= map_old_vendor_opts
[i
][1];
172 int len
= strlen(opt
);
173 int id
= 0, n1
= -1, n2
= -1;
174 char fmtname
[32+1], attrname
[32+1], hddssd
[3+1];
175 attrname
[0] = hddssd
[0] = 0;
179 if (!( sscanf(opt
, "N,%32[^,]%n,%32[^,]%n", fmtname
, &n1
, attrname
, &n2
) >= 1
180 && (n1
== len
|| n2
== len
)))
184 // "id,format[+][,name[,HDD|SSD]]"
186 if (!( sscanf(opt
, "%d,%32[^,]%n,%32[^,]%n,%3[DHS]%n",
187 &id
, fmtname
, &n1
, attrname
, &n2
, hddssd
, &n3
) >= 2
188 && 1 <= id
&& id
<= 255
189 && ( n1
== len
|| n2
== len
190 // ",HDD|SSD" for DEFAULT settings only
191 || (n3
== len
&& priority
== PRIOR_DEFAULT
))))
196 // For "-v 19[78],increasing" above
197 if (fmtname
[strlen(fmtname
)-1] == '+') {
198 fmtname
[strlen(fmtname
)-1] = 0;
199 flags
= ATTRFLAG_INCREASING
;
202 // Split "format[:byteorder]"
203 char byteorder
[8+1] = "";
204 if (strchr(fmtname
, ':')) {
205 if (priority
== PRIOR_DEFAULT
)
206 // TODO: Allow Byteorder in DEFAULT entry
209 if (!( sscanf(fmtname
, "%*[^:]%n:%8[012345rvwz]%n", &n1
, byteorder
, &n2
) >= 1
210 && n2
== (int)strlen(fmtname
)))
213 if (strchr(byteorder
, 'v'))
214 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
215 if (strchr(byteorder
, 'w'))
216 flags
|= ATTRFLAG_NO_WORSTVAL
;
221 if (i
>= num_format_names
)
222 return false; // Not found
223 if (!strcmp(fmtname
, format_names
[i
].name
))
226 ata_attr_raw_format format
= format_names
[i
].format
;
228 // 64-bit formats use the normalized and worst value bytes.
229 if (!*byteorder
&& (format
== RAWFMT_RAW64
|| format
== RAWFMT_HEX64
))
230 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
232 // ",HDD|SSD" suffix for DEFAULT settings
234 if (!strcmp(hddssd
, "HDD"))
235 flags
|= ATTRFLAG_HDD_ONLY
;
236 else if (!strcmp(hddssd
, "SSD"))
237 flags
|= ATTRFLAG_SSD_ONLY
;
243 // "N,format" -> set format for all entries
244 for (i
= 0; i
< MAX_ATTRIBUTE_NUM
; i
++) {
245 if (defs
[i
].priority
>= priority
)
248 defs
[i
].name
= attrname
;
249 defs
[i
].priority
= priority
;
250 defs
[i
].raw_format
= format
;
251 defs
[i
].flags
= flags
;
252 snprintf(defs
[i
].byteorder
, sizeof(defs
[i
].byteorder
), "%s", byteorder
);
255 else if (defs
[id
].priority
<= priority
) {
256 // "id,format[,name]"
258 defs
[id
].name
= attrname
;
259 defs
[id
].raw_format
= format
;
260 defs
[id
].priority
= priority
;
261 defs
[id
].flags
= flags
;
262 snprintf(defs
[id
].byteorder
, sizeof(defs
[id
].byteorder
), "%s", byteorder
);
269 // Return a multiline string containing a list of valid arguments for
270 // parse_attribute_def(). The strings are preceeded by tabs and followed
271 // (except for the last) by newlines.
272 std::string
create_vendor_attribute_arg_list()
276 for (i
= 0; i
< num_format_names
; i
++)
277 s
+= strprintf("%s\tN,%s[:012345rvwz][,ATTR_NAME]",
278 (i
>0 ? "\n" : ""), format_names
[i
].name
);
279 for (i
= 0; i
< num_old_vendor_opts
; i
++)
280 s
+= strprintf("\n\t%s", map_old_vendor_opts
[i
][0]);
285 // Parse firmwarebug def (-F option).
286 // Return false on error.
287 bool parse_firmwarebug_def(const char * opt
, firmwarebug_defs
& firmwarebugs
)
289 if (!strcmp(opt
, "none"))
290 firmwarebugs
.set(BUG_NONE
);
291 else if (!strcmp(opt
, "nologdir"))
292 firmwarebugs
.set(BUG_NOLOGDIR
);
293 else if (!strcmp(opt
, "samsung"))
294 firmwarebugs
.set(BUG_SAMSUNG
);
295 else if (!strcmp(opt
, "samsung2"))
296 firmwarebugs
.set(BUG_SAMSUNG2
);
297 else if (!strcmp(opt
, "samsung3"))
298 firmwarebugs
.set(BUG_SAMSUNG3
);
299 else if (!strcmp(opt
, "xerrorlba"))
300 firmwarebugs
.set(BUG_XERRORLBA
);
306 // Return a string of valid argument words for parse_firmwarebug_def()
307 const char * get_valid_firmwarebug_args()
309 return "none, nologdir, samsung, samsung2, samsung3, xerrorlba";
313 // swap two bytes. Point to low address
314 void swap2(char *location
){
316 *location
=*(location
+1);
321 // swap four bytes. Point to low address
322 void swap4(char *location
){
324 *location
=*(location
+3);
330 // swap eight bytes. Points to low address
331 void swap8(char *location
){
333 *location
=*(location
+7);
336 *(location
+1)=*(location
+6);
342 // When using the overloaded swapx() function with member of packed ATA structs,
343 // it is required to pass a possibly unaligned pointer as argument.
344 // Clang++ 4.0 prints -Waddress-of-packed-member warning in this case.
345 // The SWAPV() macro below is a replacement which prevents the use of such pointers.
346 template <typename T
>
347 static T
get_swapx_val(T x
)
348 { swapx(&x
); return x
; }
350 #define SWAPV(x) ((x) = get_swapx_val(x))
352 // Invalidate serial number and WWN and adjust checksum in IDENTIFY data
353 static void invalidate_serno(ata_identify_device
* id
)
355 unsigned char sum
= 0;
357 for (i
= 0; i
< sizeof(id
->serial_no
); i
++) {
358 sum
+= id
->serial_no
[i
]; sum
-= id
->serial_no
[i
] = 'X';
360 unsigned char * b
= (unsigned char *)id
;
361 for (i
= 2*108; i
< 2*112; i
++) { // words108-111: WWN
362 sum
+= b
[i
]; sum
-= b
[i
] = 0x00;
366 bool must_swap
= !!isbigendian();
368 SWAPV(id
->words088_255
[255-88]);
370 if ((id
->words088_255
[255-88] & 0x00ff) == 0x00a5)
371 id
->words088_255
[255-88] += sum
<< 8;
374 SWAPV(id
->words088_255
[255-88]);
378 static const char * const commandstrings
[]={
381 "SMART AUTOMATIC ATTRIBUTE SAVE",
382 "SMART IMMEDIATE OFFLINE",
383 "SMART AUTO OFFLINE",
385 "SMART STATUS CHECK",
386 "SMART READ ATTRIBUTE VALUES",
387 "SMART READ ATTRIBUTE THRESHOLDS",
390 "IDENTIFY PACKET DEVICE",
393 "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT
")\n"
397 static const char * preg(const ata_register
& r
, char (& buf
)[8])
402 snprintf(buf
, sizeof(buf
), "0x%02x", r
.val());
406 static void print_regs(const char * prefix
, const ata_in_regs
& r
, const char * suffix
= "\n")
409 pout("%s FR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, CMD=%s%s", prefix
,
410 preg(r
.features
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
411 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
412 preg(r
.command
, bufs
[6]), suffix
);
415 static void print_regs(const char * prefix
, const ata_out_regs
& r
, const char * suffix
= "\n")
418 pout("%sERR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, STS=%s%s", prefix
,
419 preg(r
.error
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
420 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
421 preg(r
.status
, bufs
[6]), suffix
);
424 static void prettyprint(const unsigned char *p
, const char *name
){
425 pout("\n===== [%s] DATA START (BASE-16) =====\n", name
);
426 for (int i
=0; i
<512; i
+=16, p
+=16)
427 #define P(n) (' ' <= p[n] && p[n] <= '~' ? (int)p[n] : '.')
428 // print complete line to avoid slow tty output and extra lines in syslog.
429 pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x "
430 "%02x %02x %02x %02x %02x %02x %02x %02x"
431 " |%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c|"
434 p
[ 0], p
[ 1], p
[ 2], p
[ 3], p
[ 4], p
[ 5], p
[ 6], p
[ 7],
435 p
[ 8], p
[ 9], p
[10], p
[11], p
[12], p
[13], p
[14], p
[15],
436 P( 0), P( 1), P( 2), P( 3), P( 4), P( 5), P( 6), P( 7),
437 P( 8), P( 9), P(10), P(11), P(12), P(13), P(14), P(15),
440 pout("===== [%s] DATA END (512 Bytes) =====\n\n", name
);
443 // This function provides the pretty-print reporting for SMART
444 // commands: it implements the various -r "reporting" options for ATA
446 int smartcommandhandler(ata_device
* device
, smart_command_set command
, int select
, char *data
){
447 // TODO: Rework old stuff below
448 // This conditional is true for commands that return data
449 int getsdata
=(command
==PIDENTIFY
||
452 command
==READ_THRESHOLDS
||
453 command
==READ_VALUES
||
454 command
==CHECK_POWER_MODE
);
456 int sendsdata
=(command
==WRITE_LOG
);
458 // If reporting is enabled, say what the command will be before it's executed
460 // conditional is true for commands that use parameters
461 int usesparam
=(command
==READ_LOG
||
462 command
==AUTO_OFFLINE
||
464 command
==IMMEDIATE_OFFLINE
||
467 pout("\nREPORT-IOCTL: Device=%s Command=%s", device
->get_dev_name(), commandstrings
[command
]);
469 pout(" InputParameter=%d\n", select
);
474 if ((getsdata
|| sendsdata
) && !data
){
475 pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings
[command
]);
479 // The reporting is cleaner, and we will find coding bugs faster, if
480 // the commands that failed clearly return empty (zeroed) data
483 if (command
==CHECK_POWER_MODE
)
486 memset(data
, '\0', 512);
490 // if requested, pretty-print the input data structure
491 if (ata_debugmode
> 1 && sendsdata
)
492 //pout("REPORT-IOCTL: Device=%s Command=%s\n", device->get_dev_name(), commandstrings[command]);
493 prettyprint((unsigned char *)data
, commandstrings
[command
]);
495 // now execute the command
499 // Set common register values
501 default: // SMART commands
502 in
.in_regs
.command
= ATA_SMART_CMD
;
503 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
505 case IDENTIFY
: case PIDENTIFY
: case CHECK_POWER_MODE
: // Non SMART commands
508 // Set specific values
511 in
.in_regs
.command
= ATA_IDENTIFY_DEVICE
;
512 in
.set_data_in(data
, 1);
515 in
.in_regs
.command
= ATA_IDENTIFY_PACKET_DEVICE
;
516 in
.set_data_in(data
, 1);
518 case CHECK_POWER_MODE
:
519 in
.in_regs
.command
= ATA_CHECK_POWER_MODE
;
520 in
.out_needed
.sector_count
= true; // Powermode returned here
523 in
.in_regs
.features
= ATA_SMART_READ_VALUES
;
524 in
.set_data_in(data
, 1);
526 case READ_THRESHOLDS
:
527 in
.in_regs
.features
= ATA_SMART_READ_THRESHOLDS
;
528 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
529 in
.set_data_in(data
, 1);
532 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
533 in
.in_regs
.lba_low
= select
;
534 in
.set_data_in(data
, 1);
537 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
538 in
.in_regs
.lba_low
= select
;
539 in
.set_data_out(data
, 1);
542 in
.in_regs
.features
= ATA_SMART_ENABLE
;
543 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
546 in
.in_regs
.features
= ATA_SMART_DISABLE
;
547 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
550 in
.out_needed
.lba_high
= in
.out_needed
.lba_mid
= true; // Status returned here
553 in
.in_regs
.features
= ATA_SMART_STATUS
;
556 in
.in_regs
.features
= ATA_SMART_AUTO_OFFLINE
;
557 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
560 in
.in_regs
.features
= ATA_SMART_AUTOSAVE
;
561 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
563 case IMMEDIATE_OFFLINE
:
564 in
.in_regs
.features
= ATA_SMART_IMMEDIATE_OFFLINE
;
565 in
.in_regs
.lba_low
= select
;
568 pout("Unrecognized command %d in smartcommandhandler()\n"
569 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
570 device
->set_err(ENOSYS
);
575 print_regs(" Input: ", in
.in_regs
,
576 (in
.direction
==ata_cmd_in::data_in
? " IN\n":
577 in
.direction
==ata_cmd_in::data_out
? " OUT\n":"\n"));
581 int64_t start_usec
= -1;
583 start_usec
= smi()->get_timer_usec();
585 bool ok
= device
->ata_pass_through(in
, out
);
587 if (start_usec
>= 0) {
588 int64_t duration_usec
= smi()->get_timer_usec() - start_usec
;
589 if (duration_usec
>= 500)
590 pout(" [Duration: %.3fs]\n", duration_usec
/ 1000000.0);
593 if (ata_debugmode
&& out
.out_regs
.is_set())
594 print_regs(" Output: ", out
.out_regs
);
596 if (ok
) switch (command
) {
600 case CHECK_POWER_MODE
:
601 if (out
.out_regs
.sector_count
.is_set()) {
602 data
[0] = out
.out_regs
.sector_count
;
606 pout("CHECK POWER MODE: incomplete response, ATA output registers missing\n");
607 device
->set_err(ENOSYS
);
612 // Cyl low and Cyl high unchanged means "Good SMART status"
613 if ((out
.out_regs
.lba_high
== SMART_CYL_HI
) &&
614 (out
.out_regs
.lba_mid
== SMART_CYL_LOW
))
616 // These values mean "Bad SMART status"
617 else if ((out
.out_regs
.lba_high
== SRET_STATUS_HI_EXCEEDED
) &&
618 (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
))
620 else if (out
.out_regs
.lba_mid
== SMART_CYL_LOW
) {
623 pout("SMART STATUS RETURN: half healthy response sequence, "
624 "probable SAT/USB truncation\n");
625 } else if (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
) {
628 pout("SMART STATUS RETURN: half unhealthy response sequence, "
629 "probable SAT/USB truncation\n");
631 else if (!out
.out_regs
.is_set()) {
632 device
->set_err(ENOSYS
, "Incomplete response, ATA output registers missing");
636 // We haven't gotten output that makes sense; print out some debugging info
637 pout("SMART Status command failed\n");
638 pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE
);
639 pout("Register values returned from SMART Status command are:\n");
640 print_regs(" ", out
.out_regs
);
641 device
->set_err(ENOSYS
, "Invalid ATA output register values");
648 // If requested, invalidate serial number before any printing is done
649 if ((command
== IDENTIFY
|| command
== PIDENTIFY
) && !retval
&& dont_print_serial_number
)
650 invalidate_serno( reinterpret_cast<ata_identify_device
*>(data
) );
652 // If reporting is enabled, say what output was produced by the command
654 if (device
->get_errno())
655 pout("REPORT-IOCTL: Device=%s Command=%s returned %d errno=%d [%s]\n",
656 device
->get_dev_name(), commandstrings
[command
], retval
,
657 device
->get_errno(), device
->get_errmsg());
659 pout("REPORT-IOCTL: Device=%s Command=%s returned %d\n",
660 device
->get_dev_name(), commandstrings
[command
], retval
);
662 // if requested, pretty-print the output data structure
663 if (ata_debugmode
> 1 && getsdata
) {
664 if (command
==CHECK_POWER_MODE
)
665 pout("Sector Count Register (BASE-16): %02x\n", (unsigned char)(*data
));
667 prettyprint((unsigned char *)data
, commandstrings
[command
]);
674 // Get capacity and sector sizes from IDENTIFY data
675 void ata_get_size_info(const ata_identify_device
* id
, ata_size_info
& sizes
)
677 sizes
.sectors
= sizes
.capacity
= 0;
678 sizes
.log_sector_size
= sizes
.phy_sector_size
= 0;
679 sizes
.log_sector_offset
= 0;
681 // Return if no LBA support
682 if (!(id
->words047_079
[49-47] & 0x0200))
685 // Determine 28-bit LBA capacity
686 unsigned lba28
= (unsigned)id
->words047_079
[61-47] << 16
687 | (unsigned)id
->words047_079
[60-47] ;
689 // Determine 48-bit LBA capacity if supported
691 if ((id
->command_set_2
& 0xc400) == 0x4400)
692 lba48
= (uint64_t)id
->words088_255
[103-88] << 48
693 | (uint64_t)id
->words088_255
[102-88] << 32
694 | (uint64_t)id
->words088_255
[101-88] << 16
695 | (uint64_t)id
->words088_255
[100-88] ;
697 // Return if capacity unknown (ATAPI CD/DVD)
698 if (!(lba28
|| lba48
))
701 // Determine sector sizes
702 sizes
.log_sector_size
= sizes
.phy_sector_size
= 512;
704 unsigned short word106
= id
->words088_255
[106-88];
705 if ((word106
& 0xc000) == 0x4000) {
706 // Long Logical/Physical Sectors (LLS/LPS) ?
707 if (word106
& 0x1000)
708 // Logical sector size is specified in 16-bit words
709 sizes
.log_sector_size
= sizes
.phy_sector_size
=
710 ((id
->words088_255
[118-88] << 16) | id
->words088_255
[117-88]) << 1;
712 if (word106
& 0x2000)
713 // Physical sector size is multiple of logical sector size
714 sizes
.phy_sector_size
<<= (word106
& 0x0f);
716 unsigned short word209
= id
->words088_255
[209-88];
717 if ((word209
& 0xc000) == 0x4000)
718 sizes
.log_sector_offset
= (word209
& 0x3fff) * sizes
.log_sector_size
;
721 // Some early 4KiB LLS disks (Samsung N3U-3) return bogus lba28 value
722 if (lba48
>= lba28
|| (lba48
&& sizes
.log_sector_size
> 512))
723 sizes
.sectors
= lba48
;
725 sizes
.sectors
= lba28
;
727 sizes
.capacity
= sizes
.sectors
* sizes
.log_sector_size
;
730 // This function computes the checksum of a single disk sector (512
731 // bytes). Returns zero if checksum is OK, nonzero if the checksum is
732 // incorrect. The size (512) is correct for all SMART structures.
733 unsigned char checksum(const void * data
)
735 unsigned char sum
= 0;
736 for (int i
= 0; i
< 512; i
++)
737 sum
+= ((const unsigned char *)data
)[i
];
741 // Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
743 static void swapbytes(char * out
, const char * in
, size_t n
)
745 for (size_t i
= 0; i
< n
; i
+= 2) {
751 // Copies in to out, but removes leading and trailing whitespace.
752 static void trim(char * out
, const char * in
)
754 // Find the first non-space character (maybe none).
757 for (i
= 0; in
[i
]; i
++)
758 if (!isspace((int)in
[i
])) {
764 // There are no non-space characters.
769 // Find the last non-space character.
770 for (i
= strlen(in
)-1; i
>= first
&& isspace((int)in
[i
]); i
--)
774 strncpy(out
, in
+first
, last
-first
+1);
775 out
[last
-first
+1] = '\0';
778 // Convenience function for formatting strings from ata_identify_device
779 void ata_format_id_string(char * out
, const unsigned char * in
, int n
)
781 bool must_swap
= true;
783 /* NetBSD kernel delivers IDENTIFY data in host byte order (but all else is LE) */
784 // TODO: Handle NetBSD case in os_netbsd.cpp
786 must_swap
= !must_swap
;
792 strncpy(tmp
, (const char *)in
, n
);
794 swapbytes(tmp
, (const char *)in
, n
);
799 // returns -1 if command fails or the device is in Sleep mode, else
800 // value of Sector Count register. Sector Count result values:
801 // 00h device is in Standby mode.
802 // 80h device is in Idle mode.
803 // FFh device is in Active mode or Idle mode.
805 int ataCheckPowerMode(ata_device
* device
) {
806 unsigned char result
;
808 if ((smartcommandhandler(device
, CHECK_POWER_MODE
, 0, (char *)&result
)))
814 // Issue a no-data ATA command with optional sector count register value
815 bool ata_nodata_command(ata_device
* device
, unsigned char command
,
816 int sector_count
/* = -1 */)
819 in
.in_regs
.command
= command
;
820 if (sector_count
>= 0)
821 in
.in_regs
.sector_count
= sector_count
;
823 return device
->ata_pass_through(in
);
826 // Issue SET FEATURES command with optional sector count register value
827 bool ata_set_features(ata_device
* device
, unsigned char features
,
828 int sector_count
/* = -1 */)
831 in
.in_regs
.command
= ATA_SET_FEATURES
;
832 in
.in_regs
.features
= features
;
833 if (sector_count
>= 0)
834 in
.in_regs
.sector_count
= sector_count
;
836 return device
->ata_pass_through(in
);
839 // Reads current Device Identity info (512 bytes) into buf. Returns 0
840 // if all OK. Returns -1 if no ATA Device identity can be
841 // established. Returns >0 if Device is ATA Packet Device (not SMART
842 // capable). The value of the integer helps identify the type of
843 // Packet device, which is useful so that the user can connect the
844 // formal device number with whatever object is inside their computer.
845 int ata_read_identity(ata_device
* device
, ata_identify_device
* buf
, bool fix_swapped_id
,
846 unsigned char * raw_buf
/* = 0 */)
848 unsigned short *rawshort
=(unsigned short *)buf
;
849 unsigned char *rawbyte
=(unsigned char *)buf
;
851 // See if device responds either to IDENTIFY DEVICE or IDENTIFY
854 if ((smartcommandhandler(device
, IDENTIFY
, 0, (char *)buf
))){
855 if (smartcommandhandler(device
, PIDENTIFY
, 0, (char *)buf
)){
861 if (fix_swapped_id
) {
864 for (i
= 0; i
< sizeof(buf
->serial_no
)-1; i
+= 2)
865 swap2((char *)(buf
->serial_no
+i
));
866 for (i
= 0; i
< sizeof(buf
->fw_rev
)-1; i
+= 2)
867 swap2((char *)(buf
->fw_rev
+i
));
868 for (i
= 0; i
< sizeof(buf
->model
)-1; i
+= 2)
869 swap2((char *)(buf
->model
+i
));
872 // If requested, save raw data before endianness adjustments
874 memcpy(raw_buf
, buf
, sizeof(*buf
));
877 // if machine is big-endian, swap byte order as needed
878 // NetBSD kernel delivers IDENTIFY data in host byte order
879 // TODO: Handle NetBSD case in os_netbsd.cpp
881 // swap various capability words that are needed
884 swap2((char *)(buf
->words047_079
+i
));
885 for (i
=80; i
<=87; i
++)
886 swap2((char *)(rawshort
+i
));
887 for (i
=0; i
<168; i
++)
888 swap2((char *)(buf
->words088_255
+i
));
892 // If there is a checksum there, validate it
893 if ((rawshort
[255] & 0x00ff) == 0x00a5 && checksum(rawbyte
))
894 checksumwarning("Drive Identity Structure");
896 // AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
897 // T13/1699-D Revision 6a (Final Draft), September 6, 2008.
898 // Sections 7.16.7 and 7.17.6:
900 // Word 0 of IDENTIFY DEVICE data:
901 // Bit 15 = 0 : ATA device
903 // Word 0 of IDENTIFY PACKET DEVICE data:
904 // Bits 15:14 = 10b : ATAPI device
905 // Bits 15:14 = 11b : Reserved
906 // Bits 12:8 : Device type (SPC-4, e.g 0x05 = CD/DVD)
908 // CF+ and CompactFlash Specification Revision 4.0, May 24, 2006.
911 // Word 0 of IDENTIFY DEVICE data:
912 // 848Ah = Signature for CompactFlash Storage Card
913 // 044Ah = Alternate value turns on ATA device while preserving all retired bits
914 // 0040h = Alternate value turns on ATA device while zeroing all retired bits
916 // Assume ATA if IDENTIFY DEVICE returns CompactFlash Signature
917 if (!packet
&& rawbyte
[1] == 0x84 && rawbyte
[0] == 0x8a)
920 // If this is a PACKET DEVICE, return device type
921 if (rawbyte
[1] & 0x80)
922 return 1+(rawbyte
[1] & 0x1f);
924 // Not a PACKET DEVICE
928 // Get World Wide Name (WWN) fields.
929 // Return NAA field or -1 if WWN is unsupported.
930 // Table 34 of T13/1699-D Revision 6a (ATA8-ACS), September 6, 2008.
931 // (WWN was introduced in ATA/ATAPI-7 and is mandatory since ATA8-ACS Revision 3b)
932 int ata_get_wwn(const ata_identify_device
* id
, unsigned & oui
, uint64_t & unique_id
)
934 // Don't use word 84 to be compatible with some older ATA-7 disks
935 unsigned short word087
= id
->csf_default
;
936 if ((word087
& 0xc100) != 0x4100)
937 return -1; // word not valid or WWN support bit 8 not set
939 unsigned short word108
= id
->words088_255
[108-88];
940 unsigned short word109
= id
->words088_255
[109-88];
941 unsigned short word110
= id
->words088_255
[110-88];
942 unsigned short word111
= id
->words088_255
[111-88];
944 oui
= ((word108
& 0x0fff) << 12) | (word109
>> 4);
945 unique_id
= ((uint64_t)(word109
& 0xf) << 32)
946 | (unsigned)((word110
<< 16) | word111
);
947 return (word108
>> 12);
950 // Get nominal media rotation rate.
951 // Returns: 0 = not reported, 1 = SSD, >1 = HDD rpm, < 0 = -(Unknown value)
952 int ata_get_rotation_rate(const ata_identify_device
* id
)
954 // Table 37 of T13/1699-D (ATA8-ACS) Revision 6a, September 6, 2008
955 // Table A.31 of T13/2161-D (ACS-3) Revision 3b, August 25, 2012
956 unsigned short word217
= id
->words088_255
[217-88];
957 if (word217
== 0x0000 || word217
== 0xffff)
959 else if (word217
== 0x0001)
961 else if (word217
> 0x0400)
964 return -(int)word217
;
967 // returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
968 int ataSmartSupport(const ata_identify_device
* drive
)
970 unsigned short word82
=drive
->command_set_1
;
971 unsigned short word83
=drive
->command_set_2
;
973 // check if words 82/83 contain valid info
974 if ((word83
>>14) == 0x01)
975 // return value of SMART support bit
976 return word82
& 0x0001;
978 // since we can're rely on word 82, we don't know if SMART supported
982 // returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
983 int ataIsSmartEnabled(const ata_identify_device
* drive
)
985 unsigned short word85
=drive
->cfs_enable_1
;
986 unsigned short word87
=drive
->csf_default
;
988 // check if words 85/86/87 contain valid info
989 if ((word87
>>14) == 0x01)
990 // return value of SMART enabled bit
991 return word85
& 0x0001;
993 // Since we can't rely word85, we don't know if SMART is enabled.
998 // Reads SMART attributes into *data
999 int ataReadSmartValues(ata_device
* device
, struct ata_smart_values
*data
){
1001 if (smartcommandhandler(device
, READ_VALUES
, 0, (char *)data
)){
1007 checksumwarning("SMART Attribute Data Structure");
1009 // swap endian order if needed
1012 swap2((char *)&(data
->revnumber
));
1013 swap2((char *)&(data
->total_time_to_complete_off_line
));
1014 swap2((char *)&(data
->smart_capability
));
1015 SWAPV(data
->extend_test_completion_time_w
);
1016 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
1017 struct ata_smart_attribute
*x
=data
->vendor_attributes
+i
;
1018 swap2((char *)&(x
->flags
));
1026 // This corrects some quantities that are byte reversed in the SMART
1028 static void fixsamsungselftestlog(ata_smart_selftestlog
* data
)
1030 // bytes 508/509 (numbered from 0) swapped (swap of self-test index
1031 // with one byte of reserved.
1032 swap2((char *)&(data
->mostrecenttest
));
1034 // LBA low register (here called 'selftestnumber", containing
1035 // information about the TYPE of the self-test) is byte swapped with
1036 // Self-test execution status byte. These are bytes N, N+1 in the
1038 for (int i
= 0; i
< 21; i
++)
1039 swap2((char *)&(data
->selftest_struct
[i
].selftestnumber
));
1044 // Reads the Self Test Log (log #6)
1045 int ataReadSelfTestLog (ata_device
* device
, ata_smart_selftestlog
* data
,
1046 firmwarebug_defs firmwarebugs
)
1049 // get data from device
1050 if (smartcommandhandler(device
, READ_LOG
, 0x06, (char *)data
)){
1054 // compute its checksum, and issue a warning if needed
1056 checksumwarning("SMART Self-Test Log Structure");
1058 // fix firmware bugs in self-test log
1059 if (firmwarebugs
.is_set(BUG_SAMSUNG
))
1060 fixsamsungselftestlog(data
);
1062 // swap endian order if needed
1065 swap2((char*)&(data
->revnumber
));
1066 for (i
=0; i
<21; i
++){
1067 struct ata_smart_selftestlog_struct
*x
=data
->selftest_struct
+i
;
1068 swap2((char *)&(x
->timestamp
));
1069 swap4((char *)&(x
->lbafirstfailure
));
1076 // Print checksum warning for multi sector log
1077 static void check_multi_sector_sum(const void * data
, unsigned nsectors
, const char * msg
)
1080 for (unsigned i
= 0; i
< nsectors
; i
++) {
1081 if (checksum((const unsigned char *)data
+ i
*512))
1086 checksumwarning(msg
);
1088 checksumwarning(strprintf("%s (%u/%u)", msg
, errs
, nsectors
).c_str());
1092 // Read SMART Extended Self-test Log
1093 bool ataReadExtSelfTestLog(ata_device
* device
, ata_smart_extselftestlog
* log
,
1096 if (!ataReadLogExt(device
, 0x07, 0x00, 0, log
, nsectors
))
1099 check_multi_sector_sum(log
, nsectors
, "SMART Extended Self-test Log Structure");
1101 if (isbigendian()) {
1102 SWAPV(log
->log_desc_index
);
1103 for (unsigned i
= 0; i
< nsectors
; i
++) {
1104 for (unsigned j
= 0; j
< 19; j
++)
1105 SWAPV(log
->log_descs
[i
].timestamp
);
1111 // Write GP Log page(s)
1112 bool ataWriteLogExt(ata_device
* device
, unsigned char logaddr
,
1113 unsigned page
, void * data
, unsigned nsectors
)
1116 in
.in_regs
.command
= ATA_WRITE_LOG_EXT
;
1117 in
.set_data_out(data
, nsectors
);
1118 in
.in_regs
.lba_low
= logaddr
;
1119 in
.in_regs
.lba_mid_16
= page
;
1120 in
.set_data_out(data
, nsectors
);
1123 if (!device
->ata_pass_through(in
, out
)) { // TODO: Debug output
1124 if (nsectors
<= 1) {
1125 pout("ATA_WRITE_LOG_EXT (addr=0x%02x, page=%u, n=%u) failed: %s\n",
1126 logaddr
, page
, nsectors
, device
->get_errmsg());
1130 // Recurse to retry with single sectors,
1131 // multi-sector reads may not be supported by ioctl.
1132 for (unsigned i
= 0; i
< nsectors
; i
++) {
1133 if (!ataWriteLogExt(device
, logaddr
, page
+ i
,
1134 (char *)data
+ 512*i
, 1))
1142 // Read GP Log page(s)
1143 bool ataReadLogExt(ata_device
* device
, unsigned char logaddr
,
1144 unsigned char features
, unsigned page
,
1145 void * data
, unsigned nsectors
)
1148 in
.in_regs
.command
= ATA_READ_LOG_EXT
;
1149 in
.in_regs
.features
= features
; // log specific
1150 in
.set_data_in_48bit(data
, nsectors
);
1151 in
.in_regs
.lba_low
= logaddr
;
1152 in
.in_regs
.lba_mid_16
= page
;
1154 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1155 if (nsectors
<= 1) {
1156 pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n",
1157 logaddr
, features
, page
, nsectors
, device
->get_errmsg());
1161 // Recurse to retry with single sectors,
1162 // multi-sector reads may not be supported by ioctl.
1163 for (unsigned i
= 0; i
< nsectors
; i
++) {
1164 if (!ataReadLogExt(device
, logaddr
,
1166 (char *)data
+ 512*i
, 1))
1174 // Read SMART Log page(s)
1175 bool ataReadSmartLog(ata_device
* device
, unsigned char logaddr
,
1176 void * data
, unsigned nsectors
)
1179 in
.in_regs
.command
= ATA_SMART_CMD
;
1180 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
1181 in
.set_data_in(data
, nsectors
);
1182 in
.in_regs
.lba_high
= SMART_CYL_HI
;
1183 in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
1184 in
.in_regs
.lba_low
= logaddr
;
1186 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1187 pout("ATA_SMART_READ_LOG failed: %s\n", device
->get_errmsg());
1195 // Reads the SMART or GPL Log Directory (log #0)
1196 int ataReadLogDirectory(ata_device
* device
, ata_smart_log_directory
* data
, bool gpl
)
1198 if (!gpl
) { // SMART Log directory
1199 if (smartcommandhandler(device
, READ_LOG
, 0x00, (char *)data
))
1202 else { // GP Log directory
1203 if (!ataReadLogExt(device
, 0x00, 0x00, 0, data
, 1))
1207 // swap endian order if needed
1209 SWAPV(data
->logversion
);
1215 // Reads the selective self-test log (log #9)
1216 int ataReadSelectiveSelfTestLog(ata_device
* device
, struct ata_selective_self_test_log
*data
){
1218 // get data from device
1219 if (smartcommandhandler(device
, READ_LOG
, 0x09, (char *)data
)){
1223 // compute its checksum, and issue a warning if needed
1225 checksumwarning("SMART Selective Self-Test Log Structure");
1227 // swap endian order if needed
1230 swap2((char *)&(data
->logversion
));
1232 swap8((char *)&(data
->span
[i
].start
));
1233 swap8((char *)&(data
->span
[i
].end
));
1235 swap8((char *)&(data
->currentlba
));
1236 swap2((char *)&(data
->currentspan
));
1237 swap2((char *)&(data
->flags
));
1238 swap2((char *)&(data
->pendingtime
));
1244 // Writes the selective self-test log (log #9)
1245 int ataWriteSelectiveSelfTestLog(ata_device
* device
, ata_selective_selftest_args
& args
,
1246 const ata_smart_values
* sv
, uint64_t num_sectors
,
1247 const ata_selective_selftest_args
* prev_args
)
1249 // Disk size must be known
1251 pout("Disk size is unknown, unable to check selective self-test spans\n");
1256 struct ata_selective_self_test_log sstlog
, *data
=&sstlog
;
1257 unsigned char *ptr
=(unsigned char *)data
;
1258 if (ataReadSelectiveSelfTestLog(device
, data
)) {
1259 pout("SMART Read Selective Self-test Log failed: %s\n", device
->get_errmsg());
1260 pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
1265 data
->logversion
= 1;
1267 // Host is NOT allowed to write selective self-test log if a selective
1268 // self-test is in progress.
1269 if (0<data
->currentspan
&& data
->currentspan
<6 && ((sv
->self_test_exec_status
)>>4)==15) {
1270 pout("SMART Selective or other Self-test in progress\n");
1274 // Set start/end values based on old spans for special -t select,... options
1276 for (i
= 0; i
< args
.num_spans
; i
++) {
1277 int mode
= args
.span
[i
].mode
;
1278 uint64_t start
= args
.span
[i
].start
;
1279 uint64_t end
= args
.span
[i
].end
;
1280 if (mode
== SEL_CONT
) {// redo or next dependig on last test status
1281 switch (sv
->self_test_exec_status
>> 4) {
1282 case 1: case 2: // Aborted/Interrupted by host
1283 pout("Continue Selective Self-Test: Redo last span\n");
1286 default: // All others
1287 pout("Continue Selective Self-Test: Start next span\n");
1293 if ( (mode
== SEL_REDO
|| mode
== SEL_NEXT
)
1294 && prev_args
&& i
< prev_args
->num_spans
1295 && !data
->span
[i
].start
&& !data
->span
[i
].end
) {
1296 // Some drives do not preserve the selective self-test log accross
1297 // power-cyles. If old span on drive is cleared use span provided
1298 // by caller. This is used by smartd (first span only).
1299 data
->span
[i
].start
= prev_args
->span
[i
].start
;
1300 data
->span
[i
].end
= prev_args
->span
[i
].end
;
1304 case SEL_RANGE
: // -t select,START-END
1306 case SEL_REDO
: // -t select,redo... => Redo current
1307 start
= data
->span
[i
].start
;
1308 if (end
> 0) { // -t select,redo+SIZE
1309 end
--; end
+= start
; // [oldstart, oldstart+SIZE)
1311 else // -t select,redo
1312 end
= data
->span
[i
].end
; // [oldstart, oldend]
1314 case SEL_NEXT
: // -t select,next... => Do next
1315 if (data
->span
[i
].end
== 0) {
1316 start
= end
= 0; break; // skip empty spans
1318 start
= data
->span
[i
].end
+ 1;
1319 if (start
>= num_sectors
)
1320 start
= 0; // wrap around
1321 if (end
> 0) { // -t select,next+SIZE
1322 end
--; end
+= start
; // (oldend, oldend+SIZE]
1324 else { // -t select,next
1325 uint64_t oldsize
= data
->span
[i
].end
- data
->span
[i
].start
+ 1;
1326 end
= start
+ oldsize
- 1; // (oldend, oldend+oldsize]
1327 if (end
>= num_sectors
) {
1328 // Adjust size to allow round-robin testing without future size decrease
1329 uint64_t spans
= (num_sectors
+ oldsize
-1) / oldsize
;
1330 uint64_t newsize
= (num_sectors
+ spans
-1) / spans
;
1331 uint64_t newstart
= num_sectors
- newsize
, newend
= num_sectors
- 1;
1332 pout("Span %d changed from %" PRIu64
"-%" PRIu64
" (%" PRIu64
" sectors)\n",
1333 i
, start
, end
, oldsize
);
1334 pout(" to %" PRIu64
"-%" PRIu64
" (%" PRIu64
" sectors) (%" PRIu64
" spans)\n",
1335 newstart
, newend
, newsize
, spans
);
1336 start
= newstart
; end
= newend
;
1341 pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode
);
1345 if (start
< num_sectors
&& num_sectors
<= end
) {
1346 if (end
!= ~(uint64_t)0) // -t select,N-max
1347 pout("Size of self-test span %d decreased according to disk size\n", i
);
1348 end
= num_sectors
- 1;
1350 if (!(start
<= end
&& end
< num_sectors
)) {
1351 pout("Invalid selective self-test span %d: %" PRIu64
"-%" PRIu64
" (%" PRIu64
" sectors)\n",
1352 i
, start
, end
, num_sectors
);
1355 // Return the actual mode and range to caller.
1356 args
.span
[i
].mode
= mode
;
1357 args
.span
[i
].start
= start
;
1358 args
.span
[i
].end
= end
;
1363 memset(data
->span
+i
, 0, sizeof(struct test_span
));
1365 // Set spans for testing
1366 for (i
= 0; i
< args
.num_spans
; i
++){
1367 data
->span
[i
].start
= args
.span
[i
].start
;
1368 data
->span
[i
].end
= args
.span
[i
].end
;
1371 // host must initialize to zero before initiating selective self-test
1373 data
->currentspan
=0;
1375 // Perform off-line scan after selective test?
1376 if (args
.scan_after_select
== 1)
1378 data
->flags
&= ~SELECTIVE_FLAG_DOSCAN
;
1379 else if (args
.scan_after_select
== 2)
1381 data
->flags
|= SELECTIVE_FLAG_DOSCAN
;
1383 // Must clear active and pending flags before writing
1384 data
->flags
&= ~(SELECTIVE_FLAG_ACTIVE
);
1385 data
->flags
&= ~(SELECTIVE_FLAG_PENDING
);
1387 // modify pending time?
1388 if (args
.pending_time
)
1389 data
->pendingtime
= (unsigned short)(args
.pending_time
-1);
1391 // Set checksum to zero, then compute checksum
1393 unsigned char cksum
=0;
1394 for (i
=0; i
<512; i
++)
1398 data
->checksum
=cksum
;
1400 // swap endian order if needed
1402 swap2((char *)&(data
->logversion
));
1403 for (int b
= 0; b
< 5; b
++) {
1404 swap8((char *)&(data
->span
[b
].start
));
1405 swap8((char *)&(data
->span
[b
].end
));
1407 swap8((char *)&(data
->currentlba
));
1408 swap2((char *)&(data
->currentspan
));
1409 swap2((char *)&(data
->flags
));
1410 swap2((char *)&(data
->pendingtime
));
1413 // write new selective self-test log
1414 if (smartcommandhandler(device
, WRITE_LOG
, 0x09, (char *)data
)){
1415 pout("Write Selective Self-test Log failed: %s\n", device
->get_errmsg());
1422 // This corrects some quantities that are byte reversed in the SMART
1424 static void fixsamsungerrorlog(ata_smart_errorlog
* data
)
1426 // FIXED IN SAMSUNG -25 FIRMWARE???
1427 // Device error count in bytes 452-3
1428 swap2((char *)&(data
->ata_error_count
));
1430 // FIXED IN SAMSUNG -22a FIRMWARE
1431 // step through 5 error log data structures
1432 for (int i
= 0; i
< 5; i
++){
1433 // step through 5 command data structures
1434 for (int j
= 0; j
< 5; j
++)
1435 // Command data structure 4-byte millisec timestamp. These are
1436 // bytes (N+8, N+9, N+10, N+11).
1437 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1438 // Error data structure two-byte hour life timestamp. These are
1439 // bytes (N+28, N+29).
1440 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1445 // NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
1446 static void fixsamsungerrorlog2(ata_smart_errorlog
* data
)
1448 // Device error count in bytes 452-3
1449 swap2((char *)&(data
->ata_error_count
));
1453 // Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1454 // Error Log is #2, and the Extended Comprehensive SMART Error log is
1456 int ataReadErrorLog (ata_device
* device
, ata_smart_errorlog
*data
,
1457 firmwarebug_defs firmwarebugs
)
1460 // get data from device
1461 if (smartcommandhandler(device
, READ_LOG
, 0x01, (char *)data
)){
1465 // compute its checksum, and issue a warning if needed
1467 checksumwarning("SMART ATA Error Log Structure");
1469 // Some disks have the byte order reversed in some SMART Summary
1470 // Error log entries
1471 if (firmwarebugs
.is_set(BUG_SAMSUNG
))
1472 fixsamsungerrorlog(data
);
1473 else if (firmwarebugs
.is_set(BUG_SAMSUNG2
))
1474 fixsamsungerrorlog2(data
);
1476 // swap endian order if needed
1480 // Device error count in bytes 452-3
1481 swap2((char *)&(data
->ata_error_count
));
1483 // step through 5 error log data structures
1484 for (i
=0; i
<5; i
++){
1485 // step through 5 command data structures
1487 // Command data structure 4-byte millisec timestamp
1488 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1489 // Error data structure life timestamp
1490 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1498 // Fix LBA byte ordering of Extended Comprehensive Error Log
1499 // if little endian instead of ATA register ordering is provided
1501 static inline void fix_exterrlog_lba_cmd(T
& cmd
)
1504 cmd
.lba_mid_register_hi
= org
.lba_high_register
;
1505 cmd
.lba_low_register_hi
= org
.lba_mid_register_hi
;
1506 cmd
.lba_high_register
= org
.lba_mid_register
;
1507 cmd
.lba_mid_register
= org
.lba_low_register_hi
;
1510 static void fix_exterrlog_lba(ata_smart_exterrlog
* log
, unsigned nsectors
)
1512 for (unsigned i
= 0; i
< nsectors
; i
++) {
1513 for (int ei
= 0; ei
< 4; ei
++) {
1514 ata_smart_exterrlog_error_log
& entry
= log
[i
].error_logs
[ei
];
1515 fix_exterrlog_lba_cmd(entry
.error
);
1516 for (int ci
= 0; ci
< 5; ci
++)
1517 fix_exterrlog_lba_cmd(entry
.commands
[ci
]);
1522 // Read Extended Comprehensive Error Log
1523 bool ataReadExtErrorLog(ata_device
* device
, ata_smart_exterrlog
* log
,
1524 unsigned page
, unsigned nsectors
, firmwarebug_defs firmwarebugs
)
1526 if (!ataReadLogExt(device
, 0x03, 0x00, page
, log
, nsectors
))
1529 check_multi_sector_sum(log
, nsectors
, "SMART Extended Comprehensive Error Log Structure");
1531 if (isbigendian()) {
1532 SWAPV(log
->device_error_count
);
1533 SWAPV(log
->error_log_index
);
1534 for (unsigned i
= 0; i
< nsectors
; i
++) {
1535 for (unsigned j
= 0; j
< 4; j
++) {
1536 for (unsigned k
= 0; k
< 5; k
++)
1537 SWAPV(log
[i
].error_logs
[j
].commands
[k
].timestamp
);
1538 SWAPV(log
[i
].error_logs
[j
].error
.timestamp
);
1543 if (firmwarebugs
.is_set(BUG_XERRORLBA
))
1544 fix_exterrlog_lba(log
, nsectors
);
1550 int ataReadSmartThresholds (ata_device
* device
, struct ata_smart_thresholds_pvt
*data
){
1552 // get data from device
1553 if (smartcommandhandler(device
, READ_THRESHOLDS
, 0, (char *)data
)){
1557 // compute its checksum, and issue a warning if needed
1559 checksumwarning("SMART Attribute Thresholds Structure");
1561 // swap endian order if needed
1563 swap2((char *)&(data
->revnumber
));
1568 int ataEnableSmart (ata_device
* device
){
1569 if (smartcommandhandler(device
, ENABLE
, 0, NULL
)){
1575 int ataDisableSmart (ata_device
* device
){
1577 if (smartcommandhandler(device
, DISABLE
, 0, NULL
)){
1583 int ataEnableAutoSave(ata_device
* device
){
1584 if (smartcommandhandler(device
, AUTOSAVE
, 241, NULL
)){
1590 int ataDisableAutoSave(ata_device
* device
){
1592 if (smartcommandhandler(device
, AUTOSAVE
, 0, NULL
)){
1598 // In *ALL* ATA standards the Enable/Disable AutoOffline command is
1599 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1600 // vendors still support it for backwards compatibility. IBM documents
1601 // it for some drives.
1602 int ataEnableAutoOffline (ata_device
* device
){
1604 /* timer hard coded to 4 hours */
1605 if (smartcommandhandler(device
, AUTO_OFFLINE
, 248, NULL
)){
1611 // Another Obsolete Command. See comments directly above, associated
1612 // with the corresponding Enable command.
1613 int ataDisableAutoOffline (ata_device
* device
){
1615 if (smartcommandhandler(device
, AUTO_OFFLINE
, 0, NULL
)){
1621 // If SMART is enabled, supported, and working, then this call is
1622 // guaranteed to return 1, else zero. Note that it should return 1
1623 // regardless of whether the disk's SMART status is 'healthy' or
1625 int ataDoesSmartWork(ata_device
* device
){
1626 int retval
=smartcommandhandler(device
, STATUS
, 0, NULL
);
1634 // This function uses a different interface (DRIVE_TASK) than the
1635 // other commands in this file.
1636 int ataSmartStatus2(ata_device
* device
){
1637 return smartcommandhandler(device
, STATUS_CHECK
, 0, NULL
);
1640 // This is the way to execute ALL tests: offline, short self-test,
1641 // extended self test, with and without captive mode, etc.
1642 // TODO: Move to ataprint.cpp ?
1643 int ataSmartTest(ata_device
* device
, int testtype
, bool force
,
1644 const ata_selective_selftest_args
& selargs
,
1645 const ata_smart_values
* sv
, uint64_t num_sectors
)
1647 char cmdmsg
[128]; const char *type
, *captive
;
1648 int cap
, retval
, select
=0;
1650 // Boolean, if set, says test is captive
1651 cap
=testtype
& CAPTIVE_MASK
;
1653 // Set up strings that describe the type of test
1659 if (testtype
==OFFLINE_FULL_SCAN
)
1661 else if (testtype
==SHORT_SELF_TEST
|| testtype
==SHORT_CAPTIVE_SELF_TEST
)
1662 type
="Short self-test";
1663 else if (testtype
==EXTEND_SELF_TEST
|| testtype
==EXTEND_CAPTIVE_SELF_TEST
)
1664 type
="Extended self-test";
1665 else if (testtype
==CONVEYANCE_SELF_TEST
|| testtype
==CONVEYANCE_CAPTIVE_SELF_TEST
)
1666 type
="Conveyance self-test";
1667 else if ((select
=(testtype
==SELECTIVE_SELF_TEST
|| testtype
==SELECTIVE_CAPTIVE_SELF_TEST
)))
1668 type
="Selective self-test";
1672 // Check whether another test is already running
1673 if (type
&& (sv
->self_test_exec_status
>> 4) == 0xf) {
1675 pout("Can't start self-test without aborting current test (%d0%% remaining),\n"
1676 "%srun 'smartctl -X' to abort test.\n",
1677 sv
->self_test_exec_status
& 0x0f,
1678 (!select
? "add '-t force' option to override, or " : ""));
1685 // If doing a selective self-test, first use WRITE_LOG to write the
1686 // selective self-test log.
1687 ata_selective_selftest_args selargs_io
= selargs
; // filled with info about actual spans
1688 if (select
&& (retval
= ataWriteSelectiveSelfTestLog(device
, selargs_io
, sv
, num_sectors
))) {
1690 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1694 // Print ouf message that we are sending the command to test
1695 if (testtype
==ABORT_SELF_TEST
)
1696 snprintf(cmdmsg
, sizeof(cmdmsg
), "Abort SMART off-line mode self-test routine");
1698 snprintf(cmdmsg
, sizeof(cmdmsg
), "SMART EXECUTE OFF-LINE IMMEDIATE subcommand 0x%02x", testtype
);
1700 snprintf(cmdmsg
, sizeof(cmdmsg
), "Execute SMART %s routine immediately in %s mode", type
, captive
);
1701 pout("Sending command: \"%s\".\n",cmdmsg
);
1705 pout("SPAN STARTING_LBA ENDING_LBA\n");
1706 for (i
= 0; i
< selargs_io
.num_spans
; i
++)
1707 pout(" %d %20" PRId64
" %20" PRId64
"\n", i
,
1708 selargs_io
.span
[i
].start
,
1709 selargs_io
.span
[i
].end
);
1712 // Now send the command to test
1713 if (smartcommandhandler(device
, IMMEDIATE_OFFLINE
, testtype
, NULL
)) {
1714 if (!(cap
&& device
->get_errno() == EIO
)) {
1715 pout("Command \"%s\" failed: %s\n", cmdmsg
, device
->get_errmsg());
1720 // Since the command succeeded, tell user
1721 if (testtype
==ABORT_SELF_TEST
)
1722 pout("Self-testing aborted!\n");
1724 pout("Drive command \"%s\" successful.\n", cmdmsg
);
1726 pout("Testing has begun%s.\n", (force
? " (previous test aborted)" : ""));
1731 /* Test Time Functions */
1732 int TestTime(const ata_smart_values
*data
, int testtype
)
1735 case OFFLINE_FULL_SCAN
:
1736 return (int) data
->total_time_to_complete_off_line
;
1737 case SHORT_SELF_TEST
:
1738 case SHORT_CAPTIVE_SELF_TEST
:
1739 return (int) data
->short_test_completion_time
;
1740 case EXTEND_SELF_TEST
:
1741 case EXTEND_CAPTIVE_SELF_TEST
:
1742 if (data
->extend_test_completion_time_b
== 0xff
1743 && data
->extend_test_completion_time_w
!= 0x0000
1744 && data
->extend_test_completion_time_w
!= 0xffff)
1745 return data
->extend_test_completion_time_w
; // ATA-8
1747 return data
->extend_test_completion_time_b
;
1748 case CONVEYANCE_SELF_TEST
:
1749 case CONVEYANCE_CAPTIVE_SELF_TEST
:
1750 return (int) data
->conveyance_test_completion_time
;
1756 // This function tells you both about the ATA error log and the
1757 // self-test error log capability (introduced in ATA-5). The bit is
1758 // poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1759 // SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1760 // word 84 and 87. Top two bits must match the pattern 01. BEFORE
1761 // ATA-6 these top two bits still had to match the pattern 01, but the
1762 // remaining bits were reserved (==0).
1763 int isSmartErrorLogCapable (const ata_smart_values
* data
, const ata_identify_device
* identity
)
1765 unsigned short word84
=identity
->command_set_extension
;
1766 unsigned short word87
=identity
->csf_default
;
1767 int isata6
=identity
->major_rev_num
& (0x01<<6);
1768 int isata7
=identity
->major_rev_num
& (0x01<<7);
1770 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x01))
1773 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x01))
1776 // otherwise we'll use the poorly documented capability bit
1777 return data
->errorlog_capability
& 0x01;
1780 // See previous function. If the error log exists then the self-test
1781 // log should (must?) also exist.
1782 int isSmartTestLogCapable (const ata_smart_values
* data
, const ata_identify_device
*identity
)
1784 unsigned short word84
=identity
->command_set_extension
;
1785 unsigned short word87
=identity
->csf_default
;
1786 int isata6
=identity
->major_rev_num
& (0x01<<6);
1787 int isata7
=identity
->major_rev_num
& (0x01<<7);
1789 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x02))
1792 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x02))
1796 // otherwise we'll use the poorly documented capability bit
1797 return data
->errorlog_capability
& 0x01;
1801 int isGeneralPurposeLoggingCapable(const ata_identify_device
*identity
)
1803 unsigned short word84
=identity
->command_set_extension
;
1804 unsigned short word87
=identity
->csf_default
;
1806 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1807 // cleared to zero, the contents of word 84 contains valid support
1808 // information. If not, support information is not valid in this
1810 if ((word84
>>14) == 0x01)
1811 // If bit 5 of word 84 is set to one, the device supports the
1812 // General Purpose Logging feature set.
1813 return (word84
& (0x01 << 5));
1815 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1816 // cleared to zero, the contents of words (87:85) contain valid
1817 // information. If not, information is not valid in these words.
1818 if ((word87
>>14) == 0x01)
1819 // If bit 5 of word 87 is set to one, the device supports
1820 // the General Purpose Logging feature set.
1821 return (word87
& (0x01 << 5));
1828 // SMART self-test capability is also indicated in bit 1 of DEVICE
1829 // IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1830 // However this was only introduced in ATA-6 (but self-test log was in
1832 int isSupportExecuteOfflineImmediate(const ata_smart_values
*data
)
1834 return data
->offline_data_collection_capability
& 0x01;
1837 // Note in the ATA-5 standard, the following bit is listed as "Vendor
1838 // Specific". So it may not be reliable. The only use of this that I
1839 // have found is in IBM drives, where it is well-documented. See for
1840 // example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1841 // hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
1842 int isSupportAutomaticTimer(const ata_smart_values
* data
)
1844 return data
->offline_data_collection_capability
& 0x02;
1846 int isSupportOfflineAbort(const ata_smart_values
*data
)
1848 return data
->offline_data_collection_capability
& 0x04;
1850 int isSupportOfflineSurfaceScan(const ata_smart_values
* data
)
1852 return data
->offline_data_collection_capability
& 0x08;
1854 int isSupportSelfTest (const ata_smart_values
* data
)
1856 return data
->offline_data_collection_capability
& 0x10;
1858 int isSupportConveyanceSelfTest(const ata_smart_values
* data
)
1860 return data
->offline_data_collection_capability
& 0x20;
1862 int isSupportSelectiveSelfTest(const ata_smart_values
* data
)
1864 return data
->offline_data_collection_capability
& 0x40;
1867 // Get attribute state
1868 ata_attr_state
ata_get_attr_state(const ata_smart_attribute
& attr
,
1870 const ata_smart_threshold_entry
* thresholds
,
1871 const ata_vendor_attr_defs
& defs
,
1872 unsigned char * threshval
/* = 0 */)
1875 return ATTRSTATE_NON_EXISTING
;
1877 // Normalized values (current,worst,threshold) not valid
1878 // if specified by '-v' option.
1879 // (Some SSD disks uses these bytes to store raw value).
1880 if (defs
[attr
.id
].flags
& ATTRFLAG_NO_NORMVAL
)
1881 return ATTRSTATE_NO_NORMVAL
;
1883 // Normally threshold is at same index as attribute
1885 if (thresholds
[i
].id
!= attr
.id
) {
1886 // Find threshold id in table
1887 for (i
= 0; thresholds
[i
].id
!= attr
.id
; ) {
1888 if (++i
>= NUMBER_ATA_SMART_ATTRIBUTES
)
1889 // Threshold id missing or thresholds cannot be read
1890 return ATTRSTATE_NO_THRESHOLD
;
1893 unsigned char threshold
= thresholds
[i
].threshold
;
1895 // Return threshold if requested
1897 *threshval
= threshold
;
1899 // Don't report a failed attribute if its threshold is 0.
1900 // ATA-3 (X3T13/2008D Revision 7b) declares 0x00 as the "always passing"
1901 // threshold (Later ATA versions declare all thresholds as "obsolete").
1902 // In practice, threshold value 0 is often used for usage attributes.
1904 return ATTRSTATE_OK
;
1906 // Failed now if current value is below threshold
1907 if (attr
.current
<= threshold
)
1908 return ATTRSTATE_FAILED_NOW
;
1910 // Failed in the past if worst value is below threshold
1911 if (!(defs
[attr
.id
].flags
& ATTRFLAG_NO_WORSTVAL
) && attr
.worst
<= threshold
)
1912 return ATTRSTATE_FAILED_PAST
;
1914 return ATTRSTATE_OK
;
1917 // Get attribute raw value.
1918 uint64_t ata_get_attr_raw_value(const ata_smart_attribute
& attr
,
1919 const ata_vendor_attr_defs
& defs
)
1921 const ata_vendor_attr_defs::entry
& def
= defs
[attr
.id
];
1922 // TODO: Allow Byteorder in DEFAULT entry
1924 // Use default byteorder if not specified
1925 const char * byteorder
= def
.byteorder
;
1927 switch (def
.raw_format
) {
1930 byteorder
= "543210wv"; break;
1933 case RAWFMT_RAW24_DIV_RAW32
:
1934 case RAWFMT_MSEC24_HOUR32
:
1935 byteorder
= "r543210"; break;
1937 byteorder
= "543210"; break;
1941 // Build 64-bit value from selected bytes
1942 uint64_t rawvalue
= 0;
1943 for (int i
= 0; byteorder
[i
]; i
++) {
1945 switch (byteorder
[i
]) {
1946 case '0': b
= attr
.raw
[0]; break;
1947 case '1': b
= attr
.raw
[1]; break;
1948 case '2': b
= attr
.raw
[2]; break;
1949 case '3': b
= attr
.raw
[3]; break;
1950 case '4': b
= attr
.raw
[4]; break;
1951 case '5': b
= attr
.raw
[5]; break;
1952 case 'r': b
= attr
.reserv
; break;
1953 case 'v': b
= attr
.current
; break;
1954 case 'w': b
= attr
.worst
; break;
1955 default : b
= 0; break;
1957 rawvalue
<<= 8; rawvalue
|= b
;
1963 // Helper functions for RAWFMT_TEMPMINMAX
1964 static inline int check_temp_word(unsigned word
)
1967 return 0x11; // >= 0, signed byte or word
1969 return 0x01; // < 0, signed byte
1971 return 0x10; // < 0, signed word
1975 static bool check_temp_range(int t
, unsigned char ut1
, unsigned char ut2
,
1978 int t1
= (signed char)ut1
, t2
= (signed char)ut2
;
1980 int tx
= t1
; t1
= t2
; t2
= tx
;
1983 if ( -60 <= t1
&& t1
<= t
&& t
<= t2
&& t2
<= 120
1984 && !(t1
== -1 && t2
<= 0) ) {
1991 // Format attribute raw value.
1992 std::string
ata_format_attr_raw_value(const ata_smart_attribute
& attr
,
1993 const ata_vendor_attr_defs
& defs
)
1995 // Get 48 bit or 64 bit raw value
1996 uint64_t rawvalue
= ata_get_attr_raw_value(attr
, defs
);
1998 // Split into bytes and words
1999 unsigned char raw
[6];
2000 raw
[0] = (unsigned char) rawvalue
;
2001 raw
[1] = (unsigned char)(rawvalue
>> 8);
2002 raw
[2] = (unsigned char)(rawvalue
>> 16);
2003 raw
[3] = (unsigned char)(rawvalue
>> 24);
2004 raw
[4] = (unsigned char)(rawvalue
>> 32);
2005 raw
[5] = (unsigned char)(rawvalue
>> 40);
2007 word
[0] = raw
[0] | (raw
[1] << 8);
2008 word
[1] = raw
[2] | (raw
[3] << 8);
2009 word
[2] = raw
[4] | (raw
[5] << 8);
2012 ata_attr_raw_format format
= defs
[attr
.id
].raw_format
;
2013 if (format
== RAWFMT_DEFAULT
) {
2014 // Get format from DEFAULT entry
2015 format
= get_default_attr_defs()[attr
.id
].raw_format
;
2016 if (format
== RAWFMT_DEFAULT
)
2017 // Unknown Attribute
2018 format
= RAWFMT_RAW48
;
2025 s
= strprintf("%d %d %d %d %d %d",
2026 raw
[5], raw
[4], raw
[3], raw
[2], raw
[1], raw
[0]);
2030 s
= strprintf("%u %u %u", word
[2], word
[1], word
[0]);
2036 s
= strprintf("%" PRIu64
, rawvalue
);
2040 s
= strprintf("0x%012" PRIx64
, rawvalue
);
2044 s
= strprintf("0x%014" PRIx64
, rawvalue
);
2048 s
= strprintf("0x%016" PRIx64
, rawvalue
);
2051 case RAWFMT_RAW16_OPT_RAW16
:
2052 s
= strprintf("%u", word
[0]);
2053 if (word
[1] || word
[2])
2054 s
+= strprintf(" (%u %u)", word
[2], word
[1]);
2057 case RAWFMT_RAW16_OPT_AVG16
:
2058 s
= strprintf("%u", word
[0]);
2060 s
+= strprintf(" (Average %u)", word
[1]);
2063 case RAWFMT_RAW24_OPT_RAW8
:
2064 s
= strprintf("%u", (unsigned)(rawvalue
& 0x00ffffffULL
));
2065 if (raw
[3] || raw
[4] || raw
[5])
2066 s
+= strprintf(" (%d %d %d)", raw
[5], raw
[4], raw
[3]);
2069 case RAWFMT_RAW24_DIV_RAW24
:
2070 s
= strprintf("%u/%u",
2071 (unsigned)(rawvalue
>> 24), (unsigned)(rawvalue
& 0x00ffffffULL
));
2074 case RAWFMT_RAW24_DIV_RAW32
:
2075 s
= strprintf("%u/%u",
2076 (unsigned)(rawvalue
>> 32), (unsigned)(rawvalue
& 0xffffffffULL
));
2079 case RAWFMT_MIN2HOUR
:
2082 int64_t temp
= word
[0]+(word
[1]<<16);
2083 int64_t tmp1
= temp
/60;
2084 int64_t tmp2
= temp
%60;
2085 s
= strprintf("%" PRIu64
"h+%02" PRIu64
"m", tmp1
, tmp2
);
2087 s
+= strprintf(" (%u)", word
[2]);
2091 case RAWFMT_SEC2HOUR
:
2094 int64_t hours
= rawvalue
/3600;
2095 int64_t minutes
= (rawvalue
-3600*hours
)/60;
2096 int64_t seconds
= rawvalue
%60;
2097 s
= strprintf("%" PRIu64
"h+%02" PRIu64
"m+%02" PRIu64
"s", hours
, minutes
, seconds
);
2101 case RAWFMT_HALFMIN2HOUR
:
2103 // 30-second counter
2104 int64_t hours
= rawvalue
/120;
2105 int64_t minutes
= (rawvalue
-120*hours
)/2;
2106 s
+= strprintf("%" PRIu64
"h+%02" PRIu64
"m", hours
, minutes
);
2110 case RAWFMT_MSEC24_HOUR32
:
2112 // hours + milliseconds
2113 unsigned hours
= (unsigned)(rawvalue
& 0xffffffffULL
);
2114 unsigned milliseconds
= (unsigned)(rawvalue
>> 32);
2115 unsigned seconds
= milliseconds
/ 1000;
2116 s
= strprintf("%uh+%02um+%02u.%03us",
2117 hours
, seconds
/ 60, seconds
% 60, milliseconds
% 1000);
2121 case RAWFMT_TEMPMINMAX
:
2124 // Search for possible min/max values
2125 // [5][4][3][2][1][0] raw[]
2126 // [ 2 ] [ 1 ] [ 0 ] word[]
2127 // xx HH xx LL xx TT (Hitachi/HGST)
2128 // xx LL xx HH xx TT (Kingston SSDs)
2129 // 00 00 HH LL xx TT (Maxtor, Samsung, Seagate, Toshiba)
2130 // 00 00 00 HH LL TT (WDC)
2131 // CC CC HH LL xx TT (WDC, CCCC=over temperature count)
2132 // (xx = 00/ff, possibly sign extension of lower byte)
2134 int t
= (signed char)raw
[0];
2138 int ctw0
= check_temp_word(word
[0]);
2140 if (!word
[1] && ctw0
)
2141 // 00 00 00 00 xx TT
2143 else if (ctw0
&& check_temp_range(t
, raw
[2], raw
[3], lo
, hi
))
2144 // 00 00 HL LH xx TT
2146 else if (!raw
[3] && check_temp_range(t
, raw
[1], raw
[2], lo
, hi
))
2147 // 00 00 00 HL LH TT
2153 if ( (ctw0
& check_temp_word(word
[1]) & check_temp_word(word
[2])) != 0x00
2154 && check_temp_range(t
, raw
[2], raw
[4], lo
, hi
) )
2155 // xx HL xx LH xx TT
2157 else if ( word
[2] < 0x7fff
2158 && check_temp_range(t
, raw
[2], raw
[3], lo
, hi
)
2160 // CC CC HL LH xx TT
2170 s
= strprintf("%d", t
);
2172 case 1: case 2: case 3:
2173 s
= strprintf("%d (Min/Max %d/%d)", t
, lo
, hi
);
2176 s
= strprintf("%d (Min/Max %d/%d #%d)", t
, lo
, hi
, word
[2]);
2179 s
= strprintf("%d (%d %d %d %d %d)", raw
[0], raw
[5], raw
[4], raw
[3], raw
[2], raw
[1]);
2185 case RAWFMT_TEMP10X
:
2186 // ten times temperature in Celsius
2187 s
= strprintf("%d.%d", word
[0]/10, word
[0]%10);
2191 s
= "?"; // Should not happen
2198 // Get attribute name
2199 std::string
ata_get_smart_attr_name(unsigned char id
, const ata_vendor_attr_defs
& defs
,
2202 if (!defs
[id
].name
.empty())
2203 return defs
[id
].name
;
2205 const ata_vendor_attr_defs::entry
& def
= get_default_attr_defs()[id
];
2206 if (def
.name
.empty())
2207 return "Unknown_Attribute";
2208 else if ((def
.flags
& ATTRFLAG_HDD_ONLY
) && rpm
== 1)
2209 return "Unknown_SSD_Attribute";
2210 else if ((def
.flags
& ATTRFLAG_SSD_ONLY
) && rpm
> 1)
2211 return "Unknown_HDD_Attribute";
2217 // Find attribute index for attribute id, -1 if not found.
2218 int ata_find_attr_index(unsigned char id
, const ata_smart_values
& smartval
)
2222 for (int i
= 0; i
< NUMBER_ATA_SMART_ATTRIBUTES
; i
++) {
2223 if (smartval
.vendor_attributes
[i
].id
== id
)
2229 // Return Temperature Attribute raw value selected according to possible
2230 // non-default interpretations. If the Attribute does not exist, return 0
2231 unsigned char ata_return_temperature_value(const ata_smart_values
* data
, const ata_vendor_attr_defs
& defs
)
2233 for (int i
= 0; i
< 4; i
++) {
2234 static const unsigned char ids
[4] = {194, 190, 9, 220};
2235 unsigned char id
= ids
[i
];
2236 const ata_attr_raw_format format
= defs
[id
].raw_format
;
2237 if (!( ((id
== 194 || id
== 190) && format
== RAWFMT_DEFAULT
)
2238 || format
== RAWFMT_TEMPMINMAX
|| format
== RAWFMT_TEMP10X
))
2240 int idx
= ata_find_attr_index(id
, *data
);
2243 uint64_t raw
= ata_get_attr_raw_value(data
->vendor_attributes
[idx
], defs
);
2245 // ignore possible min/max values in high words
2246 if (format
== RAWFMT_TEMP10X
) // -v N,temp10x
2247 temp
= ((unsigned short)raw
+ 5) / 10;
2249 temp
= (unsigned char)raw
;
2250 if (!(0 < temp
&& temp
< 128))
2254 // No valid attribute found
2260 int ataReadSCTStatus(ata_device
* device
, ata_sct_status_response
* sts
)
2262 // read SCT status via SMART log 0xe0
2263 memset(sts
, 0, sizeof(*sts
));
2264 if (smartcommandhandler(device
, READ_LOG
, 0xe0, (char *)sts
)){
2265 pout("Read SCT Status failed: %s\n", device
->get_errmsg());
2269 // swap endian order if needed
2271 SWAPV(sts
->format_version
);
2272 SWAPV(sts
->sct_version
);
2273 SWAPV(sts
->sct_spec
);
2274 SWAPV(sts
->ext_status_code
);
2275 SWAPV(sts
->action_code
);
2276 SWAPV(sts
->function_code
);
2277 SWAPV(sts
->over_limit_count
);
2278 SWAPV(sts
->under_limit_count
);
2279 SWAPV(sts
->smart_status
);
2280 SWAPV(sts
->min_erc_time
);
2283 // Check format version
2284 if (!(sts
->format_version
== 2 || sts
->format_version
== 3)) {
2285 pout("Unknown SCT Status format version %u, should be 2 or 3.\n", sts
->format_version
);
2291 // Read SCT Temperature History Table
2292 int ataReadSCTTempHist(ata_device
* device
, ata_sct_temperature_history_table
* tmh
,
2293 ata_sct_status_response
* sts
)
2295 // Initial SCT status must be provided by caller
2297 // Do nothing if other SCT command is executing
2298 if (sts
->ext_status_code
== 0xffff) {
2299 pout("Another SCT command is executing, abort Read Data Table\n"
2300 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2301 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2305 ata_sct_data_table_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2306 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2307 cmd
.action_code
= 5; // Data table command
2308 cmd
.function_code
= 1; // Read table
2309 cmd
.table_id
= 2; // Temperature History Table
2311 // swap endian order if needed
2312 if (isbigendian()) {
2313 SWAPV(cmd
.action_code
);
2314 SWAPV(cmd
.function_code
);
2315 SWAPV(cmd
.table_id
);
2318 // write command via SMART log page 0xe0
2319 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2320 pout("Write SCT Data Table failed: %s\n", device
->get_errmsg());
2324 // read SCT data via SMART log page 0xe1
2325 memset(tmh
, 0, sizeof(*tmh
));
2326 if (smartcommandhandler(device
, READ_LOG
, 0xe1, (char *)tmh
)){
2327 pout("Read SCT Data Table failed: %s\n", device
->get_errmsg());
2331 // re-read and check SCT status
2332 if (ataReadSCTStatus(device
, sts
))
2335 if (!(sts
->ext_status_code
== 0 && sts
->action_code
== 5 && sts
->function_code
== 1)) {
2336 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2337 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2341 // swap endian order if needed
2343 SWAPV(tmh
->format_version
);
2344 SWAPV(tmh
->sampling_period
);
2345 SWAPV(tmh
->interval
);
2346 SWAPV(tmh
->cb_index
);
2347 SWAPV(tmh
->cb_size
);
2352 // Common function for Get/Set SCT Feature Control:
2353 // Write Cache, Write Cache Reordering, etc.
2354 static int ataGetSetSCTFeatureControl(ata_device
* device
, unsigned short feature_code
,
2355 unsigned short state
, bool persistent
, bool set
)
2357 // Check initial status
2358 ata_sct_status_response sts
;
2359 if (ataReadSCTStatus(device
, &sts
))
2362 // Do nothing if other SCT command is executing
2363 if (sts
.ext_status_code
== 0xffff) {
2364 pout("Another SCT command is executing, abort Feature Control\n"
2365 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2366 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2370 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2371 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2372 cmd
.action_code
= 4; // Feature Control command
2373 cmd
.function_code
= (set
? 1 : 2); // 1=Set, 2=Get
2374 cmd
.feature_code
= feature_code
;
2376 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2378 // swap endian order if needed
2379 if (isbigendian()) {
2380 SWAPV(cmd
.action_code
);
2381 SWAPV(cmd
.function_code
);
2382 SWAPV(cmd
.feature_code
);
2384 SWAPV(cmd
.option_flags
);
2387 // write command via SMART log page 0xe0
2388 // TODO: Debug output
2390 in
.in_regs
.command
= ATA_SMART_CMD
;
2391 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
2392 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
2393 in
.in_regs
.lba_low
= 0xe0;
2394 in
.set_data_out(&cmd
, 1);
2397 // Time limit returned in ATA registers
2398 in
.out_needed
.sector_count
= in
.out_needed
.lba_low
= true;
2401 if (!device
->ata_pass_through(in
, out
)) {
2402 pout("Write SCT (%cet) Feature Control Command failed: %s\n",
2403 (!set
? 'G' : 'S'), device
->get_errmsg());
2406 state
= out
.out_regs
.sector_count
| (out
.out_regs
.lba_low
<< 8);
2408 // re-read and check SCT status
2409 if (ataReadSCTStatus(device
, &sts
))
2412 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== (set
? 1 : 2))) {
2413 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2414 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2420 // Get/Set Write Cache Reordering
2421 int ataGetSetSCTWriteCacheReordering(ata_device
* device
, bool enable
, bool persistent
, bool set
)
2423 return ataGetSetSCTFeatureControl(device
, 2 /* Enable/Disable Write Cache Reordering */,
2424 (enable
? 1 : 2), persistent
, set
);
2427 // Get/Set Write Cache (force enable, force disable,
2428 int ataGetSetSCTWriteCache(ata_device
* device
, unsigned short state
, bool persistent
, bool set
)
2430 return ataGetSetSCTFeatureControl(device
, 1 /* Enable/Disable Write Cache */,
2431 state
, persistent
, set
);
2434 // Set SCT Temperature Logging Interval
2435 int ataSetSCTTempInterval(ata_device
* device
, unsigned interval
, bool persistent
)
2437 // Check initial status
2438 ata_sct_status_response sts
;
2439 if (ataReadSCTStatus(device
, &sts
))
2442 // Do nothing if other SCT command is executing
2443 if (sts
.ext_status_code
== 0xffff) {
2444 pout("Another SCT command is executing, abort Feature Control\n"
2445 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2446 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2450 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2451 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2452 cmd
.action_code
= 4; // Feature Control command
2453 cmd
.function_code
= 1; // Set state
2454 cmd
.feature_code
= 3; // Temperature logging interval
2455 cmd
.state
= interval
;
2456 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2458 // swap endian order if needed
2459 if (isbigendian()) {
2460 SWAPV(cmd
.action_code
);
2461 SWAPV(cmd
.function_code
);
2462 SWAPV(cmd
.feature_code
);
2464 SWAPV(cmd
.option_flags
);
2467 // write command via SMART log page 0xe0
2468 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2469 pout("Write SCT Feature Control Command failed: %s\n", device
->get_errmsg());
2473 // re-read and check SCT status
2474 if (ataReadSCTStatus(device
, &sts
))
2477 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== 1)) {
2478 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2479 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2485 // Get/Set SCT Error Recovery Control
2486 static int ataGetSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
,
2487 bool set
, unsigned short & time_limit
)
2489 // Check initial status
2490 ata_sct_status_response sts
;
2491 if (ataReadSCTStatus(device
, &sts
))
2494 // Do nothing if other SCT command is executing
2495 if (sts
.ext_status_code
== 0xffff) {
2496 pout("Another SCT command is executing, abort Error Recovery Control\n"
2497 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2498 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2502 ata_sct_error_recovery_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2503 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2504 cmd
.action_code
= 3; // Error Recovery Control command
2505 cmd
.function_code
= (set
? 1 : 2); // 1=Set timer, 2=Get timer
2506 cmd
.selection_code
= type
; // 1=Read timer, 2=Write timer
2508 cmd
.time_limit
= time_limit
;
2510 // swap endian order if needed
2511 if (isbigendian()) {
2512 SWAPV(cmd
.action_code
);
2513 SWAPV(cmd
.function_code
);
2514 SWAPV(cmd
.selection_code
);
2515 SWAPV(cmd
.time_limit
);
2518 // write command via SMART log page 0xe0
2519 // TODO: Debug output
2521 in
.in_regs
.command
= ATA_SMART_CMD
;
2522 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
2523 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
2524 in
.in_regs
.lba_low
= 0xe0;
2525 in
.set_data_out(&cmd
, 1);
2528 // Time limit returned in ATA registers
2529 in
.out_needed
.sector_count
= in
.out_needed
.lba_low
= true;
2532 if (!device
->ata_pass_through(in
, out
)) {
2533 pout("Write SCT (%cet) Error Recovery Control Command failed: %s\n",
2534 (!set
? 'G' : 'S'), device
->get_errmsg());
2538 // re-read and check SCT status
2539 if (ataReadSCTStatus(device
, &sts
))
2542 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 3 && sts
.function_code
== (set
? 1 : 2))) {
2543 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2544 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2549 // Check whether registers are properly returned by ioctl()
2550 if (!(out
.out_regs
.sector_count
.is_set() && out
.out_regs
.lba_low
.is_set())) {
2551 // TODO: Output register support should be checked within each ata_pass_through()
2552 // implementation before command is issued.
2553 pout("SMART WRITE LOG does not return COUNT and LBA_LOW register\n");
2556 if ( out
.out_regs
.sector_count
== in
.in_regs
.sector_count
2557 && out
.out_regs
.lba_low
== in
.in_regs
.lba_low
) {
2558 // 0xe001 (5734.5s) - this is most likely a broken ATA pass-through implementation
2559 pout("SMART WRITE LOG returns COUNT and LBA_LOW register unchanged\n");
2563 // Return value to caller
2564 time_limit
= out
.out_regs
.sector_count
| (out
.out_regs
.lba_low
<< 8);
2570 // Get SCT Error Recovery Control
2571 int ataGetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short & time_limit
)
2573 return ataGetSetSCTErrorRecoveryControltime(device
, type
, false/*get*/, time_limit
);
2576 // Set SCT Error Recovery Control
2577 int ataSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short time_limit
)
2579 return ataGetSetSCTErrorRecoveryControltime(device
, type
, true/*set*/, time_limit
);
2583 // Print one self-test log entry.
2585 // -1: self-test failed
2586 // 1: extended self-test completed without error
2588 int ataPrintSmartSelfTestEntry(unsigned testnum
, unsigned char test_type
,
2589 unsigned char test_status
,
2590 unsigned short timestamp
,
2591 uint64_t failing_lba
,
2592 bool print_error_only
, bool & print_header
)
2594 // Check status and type for return value
2596 switch (test_status
>> 4) {
2598 if ((test_type
& 0x0f) == 0x02)
2599 retval
= 1; // extended self-test completed without error
2604 retval
= -1; // self-test failed
2608 if (retval
>= 0 && print_error_only
)
2611 std::string msgtest
;
2612 switch (test_type
) {
2613 case 0x00: msgtest
= "Offline"; break;
2614 case 0x01: msgtest
= "Short offline"; break;
2615 case 0x02: msgtest
= "Extended offline"; break;
2616 case 0x03: msgtest
= "Conveyance offline"; break;
2617 case 0x04: msgtest
= "Selective offline"; break;
2618 case 0x7f: msgtest
= "Abort offline test"; break;
2619 case 0x81: msgtest
= "Short captive"; break;
2620 case 0x82: msgtest
= "Extended captive"; break;
2621 case 0x83: msgtest
= "Conveyance captive"; break;
2622 case 0x84: msgtest
= "Selective captive"; break;
2624 if ((0x40 <= test_type
&& test_type
<= 0x7e) || 0x90 <= test_type
)
2625 msgtest
= strprintf("Vendor (0x%02x)", test_type
);
2627 msgtest
= strprintf("Reserved (0x%02x)", test_type
);
2630 std::string msgstat
;
2631 switch (test_status
>> 4) {
2632 case 0x0: msgstat
= "Completed without error"; break;
2633 case 0x1: msgstat
= "Aborted by host"; break;
2634 case 0x2: msgstat
= "Interrupted (host reset)"; break;
2635 case 0x3: msgstat
= "Fatal or unknown error"; break;
2636 case 0x4: msgstat
= "Completed: unknown failure"; break;
2637 case 0x5: msgstat
= "Completed: electrical failure"; break;
2638 case 0x6: msgstat
= "Completed: servo/seek failure"; break;
2639 case 0x7: msgstat
= "Completed: read failure"; break;
2640 case 0x8: msgstat
= "Completed: handling damage??"; break;
2641 case 0xf: msgstat
= "Self-test routine in progress"; break;
2642 default: msgstat
= strprintf("Unknown status (0x%x)", test_status
>> 4);
2645 // Print header once
2647 print_header
= false;
2648 pout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2652 if (retval
< 0 && failing_lba
< 0xffffffffffffULL
)
2653 snprintf(msglba
, sizeof(msglba
), "%" PRIu64
, failing_lba
);
2655 msglba
[0] = '-'; msglba
[1] = 0;
2658 pout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum
,
2659 msgtest
.c_str(), msgstat
.c_str(), test_status
& 0x0f, timestamp
, msglba
);
2664 // Print Smart self-test log, used by smartctl and smartd.
2666 // bottom 8 bits: number of entries found where self-test showed an error
2667 // remaining bits: if nonzero, power on hours of last self-test where error was found
2668 int ataPrintSmartSelfTestlog(const ata_smart_selftestlog
* data
, bool allentries
,
2669 firmwarebug_defs firmwarebugs
)
2672 pout("SMART Self-test log structure revision number %d\n",(int)data
->revnumber
);
2673 if (data
->revnumber
!= 0x0001 && allentries
&& !firmwarebugs
.is_set(BUG_SAMSUNG
))
2674 pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2675 if (data
->mostrecenttest
==0){
2677 pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n");
2681 bool noheaderprinted
= true;
2682 int errcnt
= 0, hours
= 0, igncnt
= 0;
2683 int testno
= 0, ext_ok_testno
= -1;
2686 for (int i
= 20; i
>= 0; i
--) {
2687 // log is a circular buffer
2688 int j
= (i
+data
->mostrecenttest
)%21;
2689 const ata_smart_selftestlog_struct
* log
= data
->selftest_struct
+j
;
2691 if (nonempty(log
, sizeof(*log
))) {
2692 // count entry based on non-empty structures -- needed for
2693 // Seagate only -- other vendors don't have blank entries 'in
2697 // T13/1321D revision 1c: (Data structure Rev #1)
2699 //The failing LBA shall be the LBA of the uncorrectable sector
2700 //that caused the test to fail. If the device encountered more
2701 //than one uncorrectable sector during the test, this field
2702 //shall indicate the LBA of the first uncorrectable sector
2703 //encountered. If the test passed or the test failed for some
2704 //reason other than an uncorrectable sector, the value of this
2705 //field is undefined.
2707 // This is true in ALL ATA-5 specs
2708 uint64_t lba48
= (log
->lbafirstfailure
< 0xffffffff ? log
->lbafirstfailure
: 0xffffffffffffULL
);
2711 int state
= ataPrintSmartSelfTestEntry(testno
,
2712 log
->selftestnumber
, log
->selfteststatus
,
2713 log
->timestamp
, lba48
, !allentries
, noheaderprinted
);
2716 // Self-test showed an error
2717 if (ext_ok_testno
< 0) {
2720 // keep track of time of most recent error
2722 hours
= log
->timestamp
;
2725 // Newer successful extended self-test exits
2728 else if (state
> 0 && ext_ok_testno
< 0) {
2729 // Latest successful extended self-test
2730 ext_ok_testno
= testno
;
2736 pout("%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2737 igncnt
, igncnt
+errcnt
, ext_ok_testno
);
2739 if (!allentries
&& !noheaderprinted
)
2742 return ((hours
<< 8) | errcnt
);
2746 /////////////////////////////////////////////////////////////////////////////
2747 // Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2748 // an ATA device with same behaviour
2752 class parsed_ata_device
2753 : public /*implements*/ ata_device_with_command_set
2756 parsed_ata_device(smart_interface
* intf
, const char * dev_name
);
2758 virtual ~parsed_ata_device() throw();
2760 virtual bool is_open() const;
2762 virtual bool open();
2764 virtual bool close();
2766 virtual bool ata_identify_is_cached() const;
2769 virtual int ata_command_interface(smart_command_set command
, int select
, char * data
);
2772 // Table of parsed commands, return value, data
2773 struct parsed_ata_command
2775 smart_command_set command
;
2781 enum { max_num_commands
= 32 };
2782 parsed_ata_command m_command_table
[max_num_commands
];
2785 int m_next_replay_command
;
2786 bool m_replay_out_of_sync
;
2787 bool m_ata_identify_is_cached
;
2790 static const char * nextline(const char * s
, int & lineno
)
2792 for (s
+= strcspn(s
, "\r\n"); *s
== '\r' || *s
== '\n'; s
++) {
2793 if (*s
== '\r' && s
[1] == '\n')
2800 static int name2command(const char * s
)
2802 for (int i
= 0; i
< (int)(sizeof(commandstrings
)/sizeof(commandstrings
[0])); i
++) {
2803 if (!strcmp(s
, commandstrings
[i
]))
2809 static bool matchcpy(char * dest
, size_t size
, const char * src
, const regmatch_t
& srcmatch
)
2811 if (srcmatch
.rm_so
< 0)
2813 size_t n
= srcmatch
.rm_eo
- srcmatch
.rm_so
;
2816 memcpy(dest
, src
+ srcmatch
.rm_so
, n
);
2821 static inline int matchtoi(const char * src
, const regmatch_t
& srcmatch
, int defval
)
2823 if (srcmatch
.rm_so
< 0)
2825 return atoi(src
+ srcmatch
.rm_so
);
2828 parsed_ata_device::parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2829 : smart_device(intf
, dev_name
, "ata", ""),
2831 m_next_replay_command(0),
2832 m_replay_out_of_sync(false),
2833 m_ata_identify_is_cached(false)
2835 memset(m_command_table
, 0, sizeof(m_command_table
));
2838 parsed_ata_device::~parsed_ata_device() throw()
2843 bool parsed_ata_device::is_open() const
2845 return (m_num_commands
> 0);
2848 // Parse stdin and build command table
2849 bool parsed_ata_device::open()
2851 const char * pathname
= get_dev_name();
2852 if (strcmp(pathname
, "-"))
2853 return set_err(EINVAL
);
2854 pathname
= "<stdin>";
2856 char buffer
[64*1024];
2858 while (size
< (int)sizeof(buffer
)) {
2859 int nr
= fread(buffer
, 1, sizeof(buffer
), stdin
);
2865 return set_err(ENOENT
, "%s: Unexpected EOF", pathname
);
2866 if (size
>= (int)sizeof(buffer
))
2867 return set_err(EIO
, "%s: Buffer overflow", pathname
);
2870 // Regex to match output from "-r ataioctl,2"
2871 static const char pattern
[] = "^"
2873 "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
2875 "( InputParameter=([0-9]+))?" // (4 (5))
2877 "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2879 "[\r\n]" // EOL match necessary to match optional parts above
2881 "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2883 " *(En|Dis)abled status cached by OS, " // (11)
2887 const regular_expression
regex(pattern
, REG_EXTENDED
);
2890 const char * errmsg
= 0;
2891 int i
= -1, state
= 0, lineno
= 1;
2892 for (const char * line
= buffer
; *line
; line
= nextline(line
, lineno
)) {
2894 if (!(line
[0] == 'R' || line
[0] == '=' || line
[0] == ' '))
2896 const int nmatch
= 1+11;
2897 regmatch_t match
[nmatch
];
2898 if (!regex
.execute(line
, nmatch
, match
))
2902 if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[2])) { // "REPORT-IOCTL:... Command=%s ..."
2903 int nc
= name2command(cmdname
);
2905 errmsg
= "Unknown ATA command name"; break;
2907 if (match
[7].rm_so
< 0) { // "returned %d"
2909 if (!(state
== 0 || state
== 2)) {
2910 errmsg
= "Missing REPORT-IOCTL result"; break;
2912 if (++i
>= max_num_commands
) {
2913 errmsg
= "Too many ATA commands"; break;
2915 m_command_table
[i
].command
= (smart_command_set
)nc
;
2916 m_command_table
[i
].select
= matchtoi(line
, match
[5], 0); // "InputParameter=%d"
2921 if (!(state
== 1 && (int)m_command_table
[i
].command
== nc
)) {
2922 errmsg
= "Missing REPORT-IOCTL start"; break;
2924 m_command_table
[i
].retval
= matchtoi(line
, match
[7], -1); // "returned %d"
2925 m_command_table
[i
].errval
= matchtoi(line
, match
[9], 0); // "errno=%d"
2929 else if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[10])) { // "===== [%s] DATA START "
2930 // Start of sector hexdump
2931 int nc
= name2command(cmdname
);
2932 if (!(state
== (nc
== WRITE_LOG
? 1 : 2) && (int)m_command_table
[i
].command
== nc
)) {
2933 errmsg
= "Unexpected DATA START"; break;
2935 line
= nextline(line
, lineno
);
2936 char * data
= (char *)malloc(512);
2938 for (j
= 0; j
< 32; j
++) {
2940 unsigned u1
, u2
; int n1
= -1;
2941 if (!(sscanf(line
, "%3u-%3u: "
2942 "%2x %2x %2x %2x %2x %2x %2x %2x "
2943 "%2x %2x %2x %2x %2x %2x %2x %2x%n",
2945 b
+ 0, b
+ 1, b
+ 2, b
+ 3, b
+ 4, b
+ 5, b
+ 6, b
+ 7,
2946 b
+ 8, b
+ 9, b
+10, b
+11, b
+12, b
+13, b
+14, b
+15, &n1
) == 18
2947 && n1
>= 56 && u1
== j
*16 && u2
== j
*16+15))
2949 for (unsigned k
= 0; k
< 16; k
++)
2950 data
[j
*16+k
] = b
[k
];
2951 line
= nextline(line
, lineno
);
2955 errmsg
= "Incomplete sector hex dump"; break;
2957 m_command_table
[i
].data
= data
;
2958 if (nc
!= WRITE_LOG
)
2961 else if (match
[11].rm_so
> 0) { // "(En|Dis)abled status cached by OS"
2962 m_ata_identify_is_cached
= true;
2966 if (!(state
== 0 || state
== 2))
2967 errmsg
= "Missing REPORT-IOCTL result";
2969 if (!errmsg
&& i
< 0)
2970 errmsg
= "No information found";
2972 m_num_commands
= i
+1;
2973 m_next_replay_command
= 0;
2974 m_replay_out_of_sync
= false;
2978 return set_err(EIO
, "%s(%d): Syntax error: %s", pathname
, lineno
, errmsg
);
2983 // Report warnings and free command table
2984 bool parsed_ata_device::close()
2986 if (m_replay_out_of_sync
)
2987 pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
2988 else if (m_next_replay_command
!= 0)
2989 pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands
-m_next_replay_command
);
2991 for (int i
= 0; i
< m_num_commands
; i
++) {
2992 if (m_command_table
[i
].data
) {
2993 free(m_command_table
[i
].data
); m_command_table
[i
].data
= 0;
2997 m_next_replay_command
= 0;
2998 m_replay_out_of_sync
= false;
3003 bool parsed_ata_device::ata_identify_is_cached() const
3005 return m_ata_identify_is_cached
;
3009 // Simulate ATA command from command table
3010 int parsed_ata_device::ata_command_interface(smart_command_set command
, int select
, char * data
)
3012 // Find command, try round-robin if out of sync
3013 int i
= m_next_replay_command
;
3014 for (int j
= 0; ; j
++) {
3015 if (j
>= m_num_commands
) {
3016 pout("REPLAY-IOCTL: Warning: Command not found\n");
3020 if (m_command_table
[i
].command
== command
&& m_command_table
[i
].select
== select
)
3022 if (!m_replay_out_of_sync
) {
3023 m_replay_out_of_sync
= true;
3024 pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i
+1);
3026 if (++i
>= m_num_commands
)
3029 m_next_replay_command
= i
;
3030 if (++m_next_replay_command
>= m_num_commands
)
3031 m_next_replay_command
= 0;
3033 // Return command data
3038 case READ_THRESHOLDS
:
3040 if (m_command_table
[i
].data
)
3041 memcpy(data
, m_command_table
[i
].data
, 512);
3044 if (!(m_command_table
[i
].data
&& !memcmp(data
, m_command_table
[i
].data
, 512)))
3045 pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
3047 case CHECK_POWER_MODE
:
3048 data
[0] = (char)0xff;
3053 if (m_command_table
[i
].errval
)
3054 errno
= m_command_table
[i
].errval
;
3055 return m_command_table
[i
].retval
;
3060 ata_device
* get_parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
3062 return new parsed_ata_device(intf
, dev_name
);