4 * Home page of code is: http://smartmontools.sourceforge.net
6 * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
7 * Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net>
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, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * This code was originally developed as a Senior Thesis by Michael Cornwell
21 * at the Concurrent Systems Laboratory (now part of the Storage Systems
22 * Research Center), Jack Baskin School of Engineering, University of
23 * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
37 #include "dev_ata_cmd_set.h" // for parsed_ata_device
39 const char * atacmds_cpp_cvsid
= "$Id: atacmds.cpp 3507 2012-02-11 20:16:13Z 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
60 // These Drive Identity tables are taken from hdparm 5.2, and are also
61 // given in the ATA/ATAPI specs for the IDENTIFY DEVICE command. Note
62 // that SMART was first added into the ATA/ATAPI-3 Standard with
63 // Revision 3 of the document, July 25, 1995. Look at the "Document
64 // Status" revision commands at the beginning of
65 // http://www.t13.org/Documents/UploadedDocuments/project/d2008r7b-ATA-3.pdf
67 #define NOVAL_0 0x0000
68 #define NOVAL_1 0xffff
69 /* word 81: minor version number */
70 #define MINOR_MAX 0x22
71 static const char * const minor_str
[] = { /* word 81 value: */
72 "Device does not report version", /* 0x0000 */
73 "ATA-1 X3T9.2 781D prior to revision 4", /* 0x0001 */
74 "ATA-1 published, ANSI X3.221-1994", /* 0x0002 */
75 "ATA-1 X3T9.2 781D revision 4", /* 0x0003 */
76 "ATA-2 published, ANSI X3.279-1996", /* 0x0004 */
77 "ATA-2 X3T10 948D prior to revision 2k", /* 0x0005 */
78 "ATA-3 X3T10 2008D revision 1", /* 0x0006 */ /* SMART NOT INCLUDED */
79 "ATA-2 X3T10 948D revision 2k", /* 0x0007 */
80 "ATA-3 X3T10 2008D revision 0", /* 0x0008 */
81 "ATA-2 X3T10 948D revision 3", /* 0x0009 */
82 "ATA-3 published, ANSI X3.298-199x", /* 0x000a */
83 "ATA-3 X3T10 2008D revision 6", /* 0x000b */ /* 1st VERSION WITH SMART */
84 "ATA-3 X3T13 2008D revision 7 and 7a", /* 0x000c */
85 "ATA/ATAPI-4 X3T13 1153D revision 6", /* 0x000d */
86 "ATA/ATAPI-4 T13 1153D revision 13", /* 0x000e */
87 "ATA/ATAPI-4 X3T13 1153D revision 7", /* 0x000f */
88 "ATA/ATAPI-4 T13 1153D revision 18", /* 0x0010 */
89 "ATA/ATAPI-4 T13 1153D revision 15", /* 0x0011 */
90 "ATA/ATAPI-4 published, ANSI NCITS 317-1998", /* 0x0012 */
91 "ATA/ATAPI-5 T13 1321D revision 3", /* 0x0013 */
92 "ATA/ATAPI-4 T13 1153D revision 14", /* 0x0014 */
93 "ATA/ATAPI-5 T13 1321D revision 1", /* 0x0015 */
94 "ATA/ATAPI-5 published, ANSI NCITS 340-2000", /* 0x0016 */
95 "ATA/ATAPI-4 T13 1153D revision 17", /* 0x0017 */
96 "ATA/ATAPI-6 T13 1410D revision 0", /* 0x0018 */
97 "ATA/ATAPI-6 T13 1410D revision 3a", /* 0x0019 */
98 "ATA/ATAPI-7 T13 1532D revision 1", /* 0x001a */
99 "ATA/ATAPI-6 T13 1410D revision 2", /* 0x001b */
100 "ATA/ATAPI-6 T13 1410D revision 1", /* 0x001c */
101 "ATA/ATAPI-7 published, ANSI INCITS 397-2005",/* 0x001d */
102 "ATA/ATAPI-7 T13 1532D revision 0", /* 0x001e */
103 "reserved", /* 0x001f */
104 "reserved", /* 0x0020 */
105 "ATA/ATAPI-7 T13 1532D revision 4a", /* 0x0021 */
106 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" /* 0x0022 */
109 // NOTE ATA/ATAPI-4 REV 4 was the LAST revision where the device
110 // attribute structures were NOT completely vendor specific. So any
111 // disk that is ATA/ATAPI-4 or above can not be trusted to show the
112 // vendor values in sensible format.
114 // Negative values below are because it doesn't support SMART
115 static const int actual_ver
[] = {
117 0, /* 0x0000 WARNING: */
118 1, /* 0x0001 WARNING: */
119 1, /* 0x0002 WARNING: */
120 1, /* 0x0003 WARNING: */
121 2, /* 0x0004 WARNING: This array */
122 2, /* 0x0005 WARNING: corresponds */
123 -3, /*<== */ /* 0x0006 WARNING: *exactly* */
124 2, /* 0x0007 WARNING: to the ATA/ */
125 -3, /*<== */ /* 0x0008 WARNING: ATAPI version */
126 2, /* 0x0009 WARNING: listed in */
127 3, /* 0x000a WARNING: the */
128 3, /* 0x000b WARNING: minor_str */
129 3, /* 0x000c WARNING: array */
130 4, /* 0x000d WARNING: above. */
131 4, /* 0x000e WARNING: */
132 4, /* 0x000f WARNING: If you change */
133 4, /* 0x0010 WARNING: that one, */
134 4, /* 0x0011 WARNING: change this one */
135 4, /* 0x0012 WARNING: too!!! */
136 5, /* 0x0013 WARNING: */
137 4, /* 0x0014 WARNING: */
138 5, /* 0x0015 WARNING: */
139 5, /* 0x0016 WARNING: */
140 4, /* 0x0017 WARNING: */
141 6, /* 0x0018 WARNING: */
142 6, /* 0x0019 WARNING: */
143 7, /* 0x001a WARNING: */
144 6, /* 0x001b WARNING: */
145 6, /* 0x001c WARNING: */
146 7, /* 0x001d WARNING: */
147 7, /* 0x001e WARNING: */
148 0, /* 0x001f WARNING: */
149 0, /* 0x0020 WARNING: */
150 7, /* 0x0021 WARNING: */
151 6 /* 0x0022 WARNING: */
154 // Compile time check of above array sizes
155 typedef char assert_sizeof_minor_str
[sizeof(minor_str
) /sizeof(minor_str
[0]) == MINOR_MAX
+1 ? 1 : -1];
156 typedef char assert_sizeof_actual_ver
[sizeof(actual_ver
)/sizeof(actual_ver
[0]) == MINOR_MAX
+1 ? 1 : -1];
158 // Get ID and increase flag of current pending or offline
159 // uncorrectable attribute.
160 unsigned char get_unc_attr_id(bool offline
, const ata_vendor_attr_defs
& defs
,
163 unsigned char id
= (!offline
? 197 : 198);
164 const ata_vendor_attr_defs::entry
& def
= defs
[id
];
165 if (def
.flags
& ATTRFLAG_INCREASING
)
166 increase
= true; // '-v 19[78],increasing' option
167 else if (def
.name
.empty() || (id
== 198 && def
.name
== "Offline_Scan_UNC_SectCt"))
168 increase
= false; // no or '-v 198,offlinescanuncsectorct' option
170 id
= 0; // other '-v 19[78],...' option
174 #if 0 // TODO: never used
175 // This are the meanings of the Self-test failure checkpoint byte.
176 // This is in the self-test log at offset 4 bytes into the self-test
177 // descriptor and in the SMART READ DATA structure at byte offset
178 // 371. These codes are not well documented. The meanings returned by
179 // this routine are used (at least) by Maxtor and IBM. Returns NULL if
180 // not recognized. Currently the maximum length is 15 bytes.
181 const char *SelfTestFailureCodeName(unsigned char which
){
187 return "Servo_Basic";
189 return "Servo_Random";
191 return "G-list_Scan";
193 return "Handling_Damage";
203 // Table of raw print format names
204 struct format_name_entry
207 ata_attr_raw_format format
;
210 const format_name_entry format_names
[] = {
211 {"raw8" , RAWFMT_RAW8
},
212 {"raw16" , RAWFMT_RAW16
},
213 {"raw48" , RAWFMT_RAW48
},
214 {"hex48" , RAWFMT_HEX48
},
215 {"raw64" , RAWFMT_RAW64
},
216 {"hex64" , RAWFMT_HEX64
},
217 {"raw16(raw16)" , RAWFMT_RAW16_OPT_RAW16
},
218 {"raw16(avg16)" , RAWFMT_RAW16_OPT_AVG16
},
219 {"raw24/raw24" , RAWFMT_RAW24_DIV_RAW24
},
220 {"raw24/raw32" , RAWFMT_RAW24_DIV_RAW32
},
221 {"sec2hour" , RAWFMT_SEC2HOUR
},
222 {"min2hour" , RAWFMT_MIN2HOUR
},
223 {"halfmin2hour" , RAWFMT_HALFMIN2HOUR
},
224 {"msec24hour32" , RAWFMT_MSEC24_HOUR32
},
225 {"tempminmax" , RAWFMT_TEMPMINMAX
},
226 {"temp10x" , RAWFMT_TEMP10X
},
229 const unsigned num_format_names
= sizeof(format_names
)/sizeof(format_names
[0]);
231 // Table to map old to new '-v' option arguments
232 const char * map_old_vendor_opts
[][2] = {
233 { "9,halfminutes" , "9,halfmin2hour,Power_On_Half_Minutes"},
234 { "9,minutes" , "9,min2hour,Power_On_Minutes"},
235 { "9,seconds" , "9,sec2hour,Power_On_Seconds"},
236 { "9,temp" , "9,tempminmax,Temperature_Celsius"},
237 {"192,emergencyretractcyclect" , "192,raw48,Emerg_Retract_Cycle_Ct"},
238 {"193,loadunload" , "193,raw24/raw24"},
239 {"194,10xCelsius" , "194,temp10x,Temperature_Celsius_x10"},
240 {"194,unknown" , "194,raw48,Unknown_Attribute"},
241 {"197,increasing" , "197,raw48+,Total_Pending_Sectors"}, // '+' sets flag
242 {"198,offlinescanuncsectorct" , "198,raw48,Offline_Scan_UNC_SectCt"}, // see also get_unc_attr_id() above
243 {"198,increasing" , "198,raw48+,Total_Offl_Uncorrectabl"}, // '+' sets flag
244 {"200,writeerrorcount" , "200,raw48,Write_Error_Count"},
245 {"201,detectedtacount" , "201,raw48,Detected_TA_Count"},
246 {"220,temp" , "220,raw48,Temperature_Celsius"},
249 const unsigned num_old_vendor_opts
= sizeof(map_old_vendor_opts
)/sizeof(map_old_vendor_opts
[0]);
251 // Parse vendor attribute display def (-v option).
252 // Return false on error.
253 bool parse_attribute_def(const char * opt
, ata_vendor_attr_defs
& defs
,
254 ata_vendor_def_prior priority
)
256 // Map old -> new options
258 for (i
= 0; i
< num_old_vendor_opts
; i
++) {
259 if (!strcmp(opt
, map_old_vendor_opts
[i
][0])) {
260 opt
= map_old_vendor_opts
[i
][1];
266 int len
= strlen(opt
);
267 int id
= 0, n1
= -1, n2
= -1;
268 char fmtname
[32+1], attrname
[32+1];
271 if (!( sscanf(opt
, "N,%32[^,]%n,%32[^,]%n", fmtname
, &n1
, attrname
, &n2
) >= 1
272 && (n1
== len
|| n2
== len
)))
276 // "id,format[+][,name]"
277 if (!( sscanf(opt
, "%d,%32[^,]%n,%32[^,]%n", &id
, fmtname
, &n1
, attrname
, &n2
) >= 2
278 && 1 <= id
&& id
<= 255 && (n1
== len
|| n2
== len
)))
285 // For "-v 19[78],increasing" above
286 if (fmtname
[strlen(fmtname
)-1] == '+') {
287 fmtname
[strlen(fmtname
)-1] = 0;
288 flags
= ATTRFLAG_INCREASING
;
291 // Split "format[:byteorder]"
292 char byteorder
[8+1] = "";
293 if (strchr(fmtname
, ':')) {
294 if (!( sscanf(fmtname
, "%*[^:]%n:%8[012345rvwz]%n", &n1
, byteorder
, &n2
) >= 1
295 && n2
== (int)strlen(fmtname
)))
298 if (strchr(byteorder
, 'v'))
299 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
300 if (strchr(byteorder
, 'w'))
301 flags
|= ATTRFLAG_NO_WORSTVAL
;
306 if (i
>= num_format_names
)
307 return false; // Not found
308 if (!strcmp(fmtname
, format_names
[i
].name
))
311 ata_attr_raw_format format
= format_names
[i
].format
;
313 // 64-bit formats use the normalized and worst value bytes.
314 if (!*byteorder
&& (format
== RAWFMT_RAW64
|| format
== RAWFMT_HEX64
))
315 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
318 // "N,format" -> set format for all entries
319 for (i
= 0; i
< MAX_ATTRIBUTE_NUM
; i
++) {
320 if (defs
[i
].priority
>= priority
)
323 defs
[i
].name
= attrname
;
324 defs
[i
].priority
= priority
;
325 defs
[i
].raw_format
= format
;
326 defs
[i
].flags
= flags
;
327 strcpy(defs
[i
].byteorder
, byteorder
);
330 else if (defs
[id
].priority
<= priority
) {
331 // "id,format[,name]"
333 defs
[id
].name
= attrname
;
334 defs
[id
].raw_format
= format
;
335 defs
[id
].priority
= priority
;
336 defs
[id
].flags
= flags
;
337 strcpy(defs
[id
].byteorder
, byteorder
);
344 // Return a multiline string containing a list of valid arguments for
345 // parse_attribute_def(). The strings are preceeded by tabs and followed
346 // (except for the last) by newlines.
347 std::string
create_vendor_attribute_arg_list()
351 for (i
= 0; i
< num_format_names
; i
++)
352 s
+= strprintf("%s\tN,%s[:012345rvwz][,ATTR_NAME]",
353 (i
>0 ? "\n" : ""), format_names
[i
].name
);
354 for (i
= 0; i
< num_old_vendor_opts
; i
++)
355 s
+= strprintf("\n\t%s", map_old_vendor_opts
[i
][0]);
359 // swap two bytes. Point to low address
360 void swap2(char *location
){
362 *location
=*(location
+1);
367 // swap four bytes. Point to low address
368 void swap4(char *location
){
370 *location
=*(location
+3);
376 // swap eight bytes. Points to low address
377 void swap8(char *location
){
379 *location
=*(location
+7);
382 *(location
+1)=*(location
+6);
388 // Invalidate serial number and WWN and adjust checksum in IDENTIFY data
389 static void invalidate_serno(ata_identify_device
* id
)
391 unsigned char sum
= 0;
393 for (i
= 0; i
< sizeof(id
->serial_no
); i
++) {
394 sum
+= id
->serial_no
[i
]; sum
-= id
->serial_no
[i
] = 'X';
396 unsigned char * b
= (unsigned char *)id
;
397 for (i
= 2*108; i
< 2*112; i
++) { // words108-111: WWN
398 sum
+= b
[i
]; sum
-= b
[i
] = 0x00;
402 bool must_swap
= !!isbigendian();
404 swapx(id
->words088_255
+255-88);
406 if ((id
->words088_255
[255-88] & 0x00ff) == 0x00a5)
407 id
->words088_255
[255-88] += sum
<< 8;
410 swapx(id
->words088_255
+255-88);
414 static const char * const commandstrings
[]={
417 "SMART AUTOMATIC ATTRIBUTE SAVE",
418 "SMART IMMEDIATE OFFLINE",
419 "SMART AUTO OFFLINE",
421 "SMART STATUS CHECK",
422 "SMART READ ATTRIBUTE VALUES",
423 "SMART READ ATTRIBUTE THRESHOLDS",
426 "IDENTIFY PACKET DEVICE",
429 "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT
")\n"
433 static const char * preg(const ata_register
& r
, char * buf
)
438 sprintf(buf
, "0x%02x", r
.val()); return buf
;
441 static void print_regs(const char * prefix
, const ata_in_regs
& r
, const char * suffix
= "\n")
443 char bufs
[7][4+1+13];
444 pout("%s FR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, CMD=%s%s", prefix
,
445 preg(r
.features
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
446 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
447 preg(r
.command
, bufs
[6]), suffix
);
450 static void print_regs(const char * prefix
, const ata_out_regs
& r
, const char * suffix
= "\n")
452 char bufs
[7][4+1+13];
453 pout("%sERR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, STS=%s%s", prefix
,
454 preg(r
.error
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
455 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
456 preg(r
.status
, bufs
[6]), suffix
);
459 static void prettyprint(const unsigned char *p
, const char *name
){
460 pout("\n===== [%s] DATA START (BASE-16) =====\n", name
);
461 for (int i
=0; i
<512; i
+=16, p
+=16)
462 #define P(n) (' ' <= p[n] && p[n] <= '~' ? (int)p[n] : '.')
463 // print complete line to avoid slow tty output and extra lines in syslog.
464 pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x "
465 "%02x %02x %02x %02x %02x %02x %02x %02x"
466 " |%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c|"
469 p
[ 0], p
[ 1], p
[ 2], p
[ 3], p
[ 4], p
[ 5], p
[ 6], p
[ 7],
470 p
[ 8], p
[ 9], p
[10], p
[11], p
[12], p
[13], p
[14], p
[15],
471 P( 0), P( 1), P( 2), P( 3), P( 4), P( 5), P( 6), P( 7),
472 P( 8), P( 9), P(10), P(11), P(12), P(13), P(14), P(15),
475 pout("===== [%s] DATA END (512 Bytes) =====\n\n", name
);
478 // This function provides the pretty-print reporting for SMART
479 // commands: it implements the various -r "reporting" options for ATA
481 int smartcommandhandler(ata_device
* device
, smart_command_set command
, int select
, char *data
){
482 // TODO: Rework old stuff below
483 // This conditional is true for commands that return data
484 int getsdata
=(command
==PIDENTIFY
||
487 command
==READ_THRESHOLDS
||
488 command
==READ_VALUES
||
489 command
==CHECK_POWER_MODE
);
491 int sendsdata
=(command
==WRITE_LOG
);
493 // If reporting is enabled, say what the command will be before it's executed
495 // conditional is true for commands that use parameters
496 int usesparam
=(command
==READ_LOG
||
497 command
==AUTO_OFFLINE
||
499 command
==IMMEDIATE_OFFLINE
||
502 pout("\nREPORT-IOCTL: Device=%s Command=%s", device
->get_dev_name(), commandstrings
[command
]);
504 pout(" InputParameter=%d\n", select
);
509 if ((getsdata
|| sendsdata
) && !data
){
510 pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings
[command
]);
514 // The reporting is cleaner, and we will find coding bugs faster, if
515 // the commands that failed clearly return empty (zeroed) data
518 if (command
==CHECK_POWER_MODE
)
521 memset(data
, '\0', 512);
525 // if requested, pretty-print the input data structure
526 if (ata_debugmode
> 1 && sendsdata
)
527 //pout("REPORT-IOCTL: Device=%s Command=%s\n", device->get_dev_name(), commandstrings[command]);
528 prettyprint((unsigned char *)data
, commandstrings
[command
]);
530 // now execute the command
534 // Set common register values
536 default: // SMART commands
537 in
.in_regs
.command
= ATA_SMART_CMD
;
538 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
540 case IDENTIFY
: case PIDENTIFY
: case CHECK_POWER_MODE
: // Non SMART commands
543 // Set specific values
546 in
.in_regs
.command
= ATA_IDENTIFY_DEVICE
;
547 in
.set_data_in(data
, 1);
550 in
.in_regs
.command
= ATA_IDENTIFY_PACKET_DEVICE
;
551 in
.set_data_in(data
, 1);
553 case CHECK_POWER_MODE
:
554 in
.in_regs
.command
= ATA_CHECK_POWER_MODE
;
555 in
.out_needed
.sector_count
= true; // Powermode returned here
558 in
.in_regs
.features
= ATA_SMART_READ_VALUES
;
559 in
.set_data_in(data
, 1);
561 case READ_THRESHOLDS
:
562 in
.in_regs
.features
= ATA_SMART_READ_THRESHOLDS
;
563 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
564 in
.set_data_in(data
, 1);
567 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
568 in
.in_regs
.lba_low
= select
;
569 in
.set_data_in(data
, 1);
572 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
573 in
.in_regs
.lba_low
= select
;
574 in
.set_data_out(data
, 1);
577 in
.in_regs
.features
= ATA_SMART_ENABLE
;
578 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
581 in
.in_regs
.features
= ATA_SMART_DISABLE
;
582 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
585 in
.out_needed
.lba_high
= in
.out_needed
.lba_mid
= true; // Status returned here
587 in
.in_regs
.features
= ATA_SMART_STATUS
;
590 in
.in_regs
.features
= ATA_SMART_AUTO_OFFLINE
;
591 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
594 in
.in_regs
.features
= ATA_SMART_AUTOSAVE
;
595 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
597 case IMMEDIATE_OFFLINE
:
598 in
.in_regs
.features
= ATA_SMART_IMMEDIATE_OFFLINE
;
599 in
.in_regs
.lba_low
= select
;
602 pout("Unrecognized command %d in smartcommandhandler()\n"
603 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
604 device
->set_err(ENOSYS
);
609 print_regs(" Input: ", in
.in_regs
,
610 (in
.direction
==ata_cmd_in::data_in
? " IN\n":
611 in
.direction
==ata_cmd_in::data_out
? " OUT\n":"\n"));
614 bool ok
= device
->ata_pass_through(in
, out
);
616 if (ata_debugmode
&& out
.out_regs
.is_set())
617 print_regs(" Output: ", out
.out_regs
);
619 if (ok
) switch (command
) {
623 case CHECK_POWER_MODE
:
624 if (out
.out_regs
.sector_count
.is_set()) {
625 data
[0] = out
.out_regs
.sector_count
;
629 pout("CHECK POWER MODE: incomplete response, ATA output registers missing\n");
630 device
->set_err(ENOSYS
);
635 // Cyl low and Cyl high unchanged means "Good SMART status"
636 if ((out
.out_regs
.lba_high
== SMART_CYL_HI
) &&
637 (out
.out_regs
.lba_mid
== SMART_CYL_LOW
))
639 // These values mean "Bad SMART status"
640 else if ((out
.out_regs
.lba_high
== SRET_STATUS_HI_EXCEEDED
) &&
641 (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
))
643 else if (out
.out_regs
.lba_mid
== SMART_CYL_LOW
) {
646 pout("SMART STATUS RETURN: half healthy response sequence, "
647 "probable SAT/USB truncation\n");
648 } else if (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
) {
651 pout("SMART STATUS RETURN: half unhealthy response sequence, "
652 "probable SAT/USB truncation\n");
654 else if (!out
.out_regs
.is_set()) {
655 pout("SMART STATUS RETURN: incomplete response, ATA output registers missing\n");
656 device
->set_err(ENOSYS
);
660 // We haven't gotten output that makes sense; print out some debugging info
661 pout("Error SMART Status command failed\n");
662 pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE
);
663 pout("Register values returned from SMART Status command are:\n");
664 print_regs(" ", out
.out_regs
);
665 device
->set_err(EIO
);
672 // If requested, invalidate serial number before any printing is done
673 if ((command
== IDENTIFY
|| command
== PIDENTIFY
) && !retval
&& dont_print_serial_number
)
674 invalidate_serno((ata_identify_device
*)data
);
676 // If reporting is enabled, say what output was produced by the command
678 if (device
->get_errno())
679 pout("REPORT-IOCTL: Device=%s Command=%s returned %d errno=%d [%s]\n",
680 device
->get_dev_name(), commandstrings
[command
], retval
,
681 device
->get_errno(), device
->get_errmsg());
683 pout("REPORT-IOCTL: Device=%s Command=%s returned %d\n",
684 device
->get_dev_name(), commandstrings
[command
], retval
);
686 // if requested, pretty-print the output data structure
687 if (ata_debugmode
> 1 && getsdata
) {
688 if (command
==CHECK_POWER_MODE
)
689 pout("Sector Count Register (BASE-16): %02x\n", (unsigned char)(*data
));
691 prettyprint((unsigned char *)data
, commandstrings
[command
]);
698 // Get capacity and sector sizes from IDENTIFY data
699 void ata_get_size_info(const ata_identify_device
* id
, ata_size_info
& sizes
)
701 sizes
.sectors
= sizes
.capacity
= 0;
702 sizes
.log_sector_size
= sizes
.phy_sector_size
= 0;
703 sizes
.log_sector_offset
= 0;
705 // Return if no LBA support
706 if (!(id
->words047_079
[49-47] & 0x0200))
709 // Determine 28-bit LBA capacity
710 unsigned lba28
= (unsigned)id
->words047_079
[61-47] << 16
711 | (unsigned)id
->words047_079
[60-47] ;
713 // Determine 48-bit LBA capacity if supported
715 if ((id
->command_set_2
& 0xc400) == 0x4400)
716 lba48
= (uint64_t)id
->words088_255
[103-88] << 48
717 | (uint64_t)id
->words088_255
[102-88] << 32
718 | (uint64_t)id
->words088_255
[101-88] << 16
719 | (uint64_t)id
->words088_255
[100-88] ;
721 // Return if capacity unknown (ATAPI CD/DVD)
722 if (!(lba28
|| lba48
))
725 // Determine sector sizes
726 sizes
.log_sector_size
= sizes
.phy_sector_size
= 512;
728 unsigned short word106
= id
->words088_255
[106-88];
729 if ((word106
& 0xc000) == 0x4000) {
730 // Long Logical/Physical Sectors (LLS/LPS) ?
731 if (word106
& 0x1000)
732 // Logical sector size is specified in 16-bit words
733 sizes
.log_sector_size
= sizes
.phy_sector_size
=
734 ((id
->words088_255
[118-88] << 16) | id
->words088_255
[117-88]) << 1;
736 if (word106
& 0x2000)
737 // Physical sector size is multiple of logical sector size
738 sizes
.phy_sector_size
<<= (word106
& 0x0f);
740 unsigned short word209
= id
->words088_255
[209-88];
741 if ((word209
& 0xc000) == 0x4000)
742 sizes
.log_sector_offset
= (word209
& 0x3fff) * sizes
.log_sector_size
;
745 // Some early 4KiB LLS disks (Samsung N3U-3) return bogus lba28 value
746 if (lba48
>= lba28
|| (lba48
&& sizes
.log_sector_size
> 512))
747 sizes
.sectors
= lba48
;
749 sizes
.sectors
= lba28
;
751 sizes
.capacity
= sizes
.sectors
* sizes
.log_sector_size
;
754 // This function computes the checksum of a single disk sector (512
755 // bytes). Returns zero if checksum is OK, nonzero if the checksum is
756 // incorrect. The size (512) is correct for all SMART structures.
757 unsigned char checksum(const void * data
)
759 unsigned char sum
= 0;
760 for (int i
= 0; i
< 512; i
++)
761 sum
+= ((const unsigned char *)data
)[i
];
765 // Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
767 static void swapbytes(char * out
, const char * in
, size_t n
)
769 for (size_t i
= 0; i
< n
; i
+= 2) {
775 // Copies in to out, but removes leading and trailing whitespace.
776 static void trim(char * out
, const char * in
)
778 // Find the first non-space character (maybe none).
781 for (i
= 0; in
[i
]; i
++)
782 if (!isspace((int)in
[i
])) {
788 // There are no non-space characters.
793 // Find the last non-space character.
794 for (i
= strlen(in
)-1; i
>= first
&& isspace((int)in
[i
]); i
--)
798 strncpy(out
, in
+first
, last
-first
+1);
799 out
[last
-first
+1] = '\0';
802 // Convenience function for formatting strings from ata_identify_device
803 void ata_format_id_string(char * out
, const unsigned char * in
, int n
)
805 bool must_swap
= true;
807 /* NetBSD kernel delivers IDENTIFY data in host byte order (but all else is LE) */
808 // TODO: Handle NetBSD case in os_netbsd.cpp
810 must_swap
= !must_swap
;
816 strncpy(tmp
, (const char *)in
, n
);
818 swapbytes(tmp
, (const char *)in
, n
);
823 // returns -1 if command fails or the device is in Sleep mode, else
824 // value of Sector Count register. Sector Count result values:
825 // 00h device is in Standby mode.
826 // 80h device is in Idle mode.
827 // FFh device is in Active mode or Idle mode.
829 int ataCheckPowerMode(ata_device
* device
) {
830 unsigned char result
;
832 if ((smartcommandhandler(device
, CHECK_POWER_MODE
, 0, (char *)&result
)))
835 if (result
!=0 && result
!=0x80 && result
!=0xff)
836 pout("ataCheckPowerMode(): ATA CHECK POWER MODE returned unknown Sector Count Register value %02x\n", result
);
841 // Issue a no-data ATA command with optional sector count register value
842 bool ata_nodata_command(ata_device
* device
, unsigned char command
,
843 int sector_count
/* = -1 */)
846 in
.in_regs
.command
= command
;
847 if (sector_count
>= 0)
848 in
.in_regs
.sector_count
= sector_count
;
850 return device
->ata_pass_through(in
);
853 // Issue SET FEATURES command with optional sector count register value
854 bool ata_set_features(ata_device
* device
, unsigned char features
,
855 int sector_count
/* = -1 */)
858 in
.in_regs
.command
= ATA_SET_FEATURES
;
859 in
.in_regs
.features
= features
;
860 if (sector_count
>= 0)
861 in
.in_regs
.sector_count
= sector_count
;
863 return device
->ata_pass_through(in
);
866 // Reads current Device Identity info (512 bytes) into buf. Returns 0
867 // if all OK. Returns -1 if no ATA Device identity can be
868 // established. Returns >0 if Device is ATA Packet Device (not SMART
869 // capable). The value of the integer helps identify the type of
870 // Packet device, which is useful so that the user can connect the
871 // formal device number with whatever object is inside their computer.
872 int ata_read_identity(ata_device
* device
, ata_identify_device
* buf
, bool fix_swapped_id
)
874 unsigned short *rawshort
=(unsigned short *)buf
;
875 unsigned char *rawbyte
=(unsigned char *)buf
;
877 // See if device responds either to IDENTIFY DEVICE or IDENTIFY
880 if ((smartcommandhandler(device
, IDENTIFY
, 0, (char *)buf
))){
881 if (smartcommandhandler(device
, PIDENTIFY
, 0, (char *)buf
)){
888 if (fix_swapped_id
) {
890 for (i
= 0; i
< sizeof(buf
->serial_no
)-1; i
+= 2)
891 swap2((char *)(buf
->serial_no
+i
));
892 for (i
= 0; i
< sizeof(buf
->fw_rev
)-1; i
+= 2)
893 swap2((char *)(buf
->fw_rev
+i
));
894 for (i
= 0; i
< sizeof(buf
->model
)-1; i
+= 2)
895 swap2((char *)(buf
->model
+i
));
899 // if machine is big-endian, swap byte order as needed
900 // NetBSD kernel delivers IDENTIFY data in host byte order
901 // TODO: Handle NetBSD case in os_netbsd.cpp
904 // swap various capability words that are needed
906 swap2((char *)(buf
->words047_079
+i
));
908 for (i
=80; i
<=87; i
++)
909 swap2((char *)(rawshort
+i
));
911 for (i
=0; i
<168; i
++)
912 swap2((char *)(buf
->words088_255
+i
));
916 // If there is a checksum there, validate it
917 if ((rawshort
[255] & 0x00ff) == 0x00a5 && checksum(rawbyte
))
918 checksumwarning("Drive Identity Structure");
920 // AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
921 // T13/1699-D Revision 6a (Final Draft), September 6, 2008.
922 // Sections 7.16.7 and 7.17.6:
924 // Word 0 of IDENTIFY DEVICE data:
925 // Bit 15 = 0 : ATA device
927 // Word 0 of IDENTIFY PACKET DEVICE data:
928 // Bits 15:14 = 10b : ATAPI device
929 // Bits 15:14 = 11b : Reserved
930 // Bits 12:8 : Device type (SPC-4, e.g 0x05 = CD/DVD)
932 // CF+ and CompactFlash Specification Revision 4.0, May 24, 2006.
935 // Word 0 of IDENTIFY DEVICE data:
936 // 848Ah = Signature for CompactFlash Storage Card
937 // 044Ah = Alternate value turns on ATA device while preserving all retired bits
938 // 0040h = Alternate value turns on ATA device while zeroing all retired bits
940 // Assume ATA if IDENTIFY DEVICE returns CompactFlash Signature
941 if (!packet
&& rawbyte
[1] == 0x84 && rawbyte
[0] == 0x8a)
944 // If this is a PACKET DEVICE, return device type
945 if (rawbyte
[1] & 0x80)
946 return 1+(rawbyte
[1] & 0x1f);
948 // Not a PACKET DEVICE
952 // Returns ATA version as an integer, and a pointer to a string
953 // describing which revision. Note that Revision 0 of ATA-3 does NOT
954 // support SMART. For this one case we return -3 rather than +3 as
955 // the version number. See notes above.
956 int ataVersionInfo(const char ** description
, const ata_identify_device
* drive
, unsigned short * minor
)
958 // get major and minor ATA revision numbers
959 unsigned short major
= drive
->major_rev_num
;
960 *minor
=drive
->minor_rev_num
;
962 // First check if device has ANY ATA version information in it
963 if (major
==NOVAL_0
|| major
==NOVAL_1
) {
965 return 0; // No info found
968 // The minor revision number has more information - try there first
969 if (*minor
&& (*minor
<=MINOR_MAX
)){
970 int std
= actual_ver
[*minor
];
972 *description
=minor_str
[*minor
];
977 // Try new ATA-8 ACS minor revision numbers.
978 // Table 55 of T13/2015-D Revision 4a (ACS-2), December 9, 2010.
979 // (not in actual_ver/minor_str to avoid large sparse tables)
982 case 0x0027: desc
= "ATA-8-ACS revision 3c"; break;
983 case 0x0028: desc
= "ATA-8-ACS revision 6"; break;
984 case 0x0029: desc
= "ATA-8-ACS revision 4"; break;
985 case 0x0031: desc
= "ACS-2 revision 2"; break;
986 case 0x0033: desc
= "ATA-8-ACS revision 3e"; break;
987 case 0x0039: desc
= "ATA-8-ACS revision 4c"; break;
988 case 0x0042: desc
= "ATA-8-ACS revision 3f"; break;
989 case 0x0052: desc
= "ATA-8-ACS revision 3b"; break;
990 case 0x0107: desc
= "ATA-8-ACS revision 2d"; break;
991 case 0x0110: desc
= "ACS-2 revision 3"; break;
992 default: desc
= 0; break;
999 // HDPARM has a very complicated algorithm from here on. Since SMART only
1000 // exists on ATA-3 and later standards, let's punt on this. If you don't
1001 // like it, please fix it. The code's in CVS.
1003 for (i
=15; i
>0; i
--)
1004 if (major
& (0x1<<i
))
1014 // Get World Wide Name (WWN) fields.
1015 // Return NAA field or -1 if WWN is unsupported.
1016 // Table 34 of T13/1699-D Revision 6a (ATA8-ACS), September 6, 2008.
1017 // (WWN was introduced in ATA/ATAPI-7 and is mandatory since ATA8-ACS Revision 3b)
1018 int ata_get_wwn(const ata_identify_device
* id
, unsigned & oui
, uint64_t & unique_id
)
1020 // Don't use word 84 to be compatible with some older ATA-7 disks
1021 unsigned short word087
= id
->csf_default
;
1022 if ((word087
& 0xc100) != 0x4100)
1023 return -1; // word not valid or WWN support bit 8 not set
1025 unsigned short word108
= id
->words088_255
[108-88];
1026 unsigned short word109
= id
->words088_255
[109-88];
1027 unsigned short word110
= id
->words088_255
[110-88];
1028 unsigned short word111
= id
->words088_255
[111-88];
1030 oui
= ((word108
& 0x0fff) << 12) | (word109
>> 4);
1031 unique_id
= ((uint64_t)(word109
& 0xf) << 32)
1032 | (unsigned)((word110
<< 16) | word111
);
1033 return (word108
>> 12);
1036 // returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
1037 int ataSmartSupport(const ata_identify_device
* drive
)
1039 unsigned short word82
=drive
->command_set_1
;
1040 unsigned short word83
=drive
->command_set_2
;
1042 // check if words 82/83 contain valid info
1043 if ((word83
>>14) == 0x01)
1044 // return value of SMART support bit
1045 return word82
& 0x0001;
1047 // since we can're rely on word 82, we don't know if SMART supported
1051 // returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
1052 int ataIsSmartEnabled(const ata_identify_device
* drive
)
1054 unsigned short word85
=drive
->cfs_enable_1
;
1055 unsigned short word87
=drive
->csf_default
;
1057 // check if words 85/86/87 contain valid info
1058 if ((word87
>>14) == 0x01)
1059 // return value of SMART enabled bit
1060 return word85
& 0x0001;
1062 // Since we can't rely word85, we don't know if SMART is enabled.
1067 // Reads SMART attributes into *data
1068 int ataReadSmartValues(ata_device
* device
, struct ata_smart_values
*data
){
1070 if (smartcommandhandler(device
, READ_VALUES
, 0, (char *)data
)){
1071 pout("Error SMART Values Read failed: %s\n", device
->get_errmsg());
1077 checksumwarning("SMART Attribute Data Structure");
1079 // swap endian order if needed
1082 swap2((char *)&(data
->revnumber
));
1083 swap2((char *)&(data
->total_time_to_complete_off_line
));
1084 swap2((char *)&(data
->smart_capability
));
1085 swapx(&data
->extend_test_completion_time_w
);
1086 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
1087 struct ata_smart_attribute
*x
=data
->vendor_attributes
+i
;
1088 swap2((char *)&(x
->flags
));
1096 // This corrects some quantities that are byte reversed in the SMART
1098 static void fixsamsungselftestlog(ata_smart_selftestlog
* data
)
1100 // bytes 508/509 (numbered from 0) swapped (swap of self-test index
1101 // with one byte of reserved.
1102 swap2((char *)&(data
->mostrecenttest
));
1104 // LBA low register (here called 'selftestnumber", containing
1105 // information about the TYPE of the self-test) is byte swapped with
1106 // Self-test execution status byte. These are bytes N, N+1 in the
1108 for (int i
= 0; i
< 21; i
++)
1109 swap2((char *)&(data
->selftest_struct
[i
].selftestnumber
));
1114 // Reads the Self Test Log (log #6)
1115 int ataReadSelfTestLog (ata_device
* device
, ata_smart_selftestlog
* data
,
1116 unsigned char fix_firmwarebug
)
1119 // get data from device
1120 if (smartcommandhandler(device
, READ_LOG
, 0x06, (char *)data
)){
1121 pout("Error SMART Error Self-Test Log Read failed: %s\n", device
->get_errmsg());
1125 // compute its checksum, and issue a warning if needed
1127 checksumwarning("SMART Self-Test Log Structure");
1129 // fix firmware bugs in self-test log
1130 if (fix_firmwarebug
== FIX_SAMSUNG
)
1131 fixsamsungselftestlog(data
);
1133 // swap endian order if needed
1136 swap2((char*)&(data
->revnumber
));
1137 for (i
=0; i
<21; i
++){
1138 struct ata_smart_selftestlog_struct
*x
=data
->selftest_struct
+i
;
1139 swap2((char *)&(x
->timestamp
));
1140 swap4((char *)&(x
->lbafirstfailure
));
1147 // Print checksum warning for multi sector log
1148 static void check_multi_sector_sum(const void * data
, unsigned nsectors
, const char * msg
)
1151 for (unsigned i
= 0; i
< nsectors
; i
++) {
1152 if (checksum((const unsigned char *)data
+ i
*512))
1157 checksumwarning(msg
);
1159 checksumwarning(strprintf("%s (%u/%u)", msg
, errs
, nsectors
).c_str());
1163 // Read SMART Extended Self-test Log
1164 bool ataReadExtSelfTestLog(ata_device
* device
, ata_smart_extselftestlog
* log
,
1167 if (!ataReadLogExt(device
, 0x07, 0x00, 0, log
, nsectors
))
1170 check_multi_sector_sum(log
, nsectors
, "SMART Extended Self-test Log Structure");
1172 if (isbigendian()) {
1173 swapx(&log
->log_desc_index
);
1174 for (unsigned i
= 0; i
< nsectors
; i
++) {
1175 for (unsigned j
= 0; j
< 19; j
++)
1176 swapx(&log
->log_descs
[i
].timestamp
);
1183 // Read GP Log page(s)
1184 bool ataReadLogExt(ata_device
* device
, unsigned char logaddr
,
1185 unsigned char features
, unsigned page
,
1186 void * data
, unsigned nsectors
)
1189 in
.in_regs
.command
= ATA_READ_LOG_EXT
;
1190 in
.in_regs
.features
= features
; // log specific
1191 in
.set_data_in_48bit(data
, nsectors
);
1192 in
.in_regs
.lba_low
= logaddr
;
1193 in
.in_regs
.lba_mid_16
= page
;
1195 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1196 if (nsectors
<= 1) {
1197 pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n",
1198 logaddr
, features
, page
, nsectors
, device
->get_errmsg());
1202 // Recurse to retry with single sectors,
1203 // multi-sector reads may not be supported by ioctl.
1204 for (unsigned i
= 0; i
< nsectors
; i
++) {
1205 if (!ataReadLogExt(device
, logaddr
,
1207 (char *)data
+ 512*i
, 1))
1215 // Read SMART Log page(s)
1216 bool ataReadSmartLog(ata_device
* device
, unsigned char logaddr
,
1217 void * data
, unsigned nsectors
)
1220 in
.in_regs
.command
= ATA_SMART_CMD
;
1221 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
1222 in
.set_data_in(data
, nsectors
);
1223 in
.in_regs
.lba_high
= SMART_CYL_HI
;
1224 in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
1225 in
.in_regs
.lba_low
= logaddr
;
1227 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1228 pout("ATA_SMART_READ_LOG failed: %s\n", device
->get_errmsg());
1236 // Reads the SMART or GPL Log Directory (log #0)
1237 int ataReadLogDirectory(ata_device
* device
, ata_smart_log_directory
* data
, bool gpl
)
1239 if (!gpl
) { // SMART Log directory
1240 if (smartcommandhandler(device
, READ_LOG
, 0x00, (char *)data
))
1243 else { // GP Log directory
1244 if (!ataReadLogExt(device
, 0x00, 0x00, 0, data
, 1))
1248 // swap endian order if needed
1250 swapx(&data
->logversion
);
1256 // Reads the selective self-test log (log #9)
1257 int ataReadSelectiveSelfTestLog(ata_device
* device
, struct ata_selective_self_test_log
*data
){
1259 // get data from device
1260 if (smartcommandhandler(device
, READ_LOG
, 0x09, (char *)data
)){
1261 pout("Error SMART Read Selective Self-Test Log failed: %s\n", device
->get_errmsg());
1265 // compute its checksum, and issue a warning if needed
1267 checksumwarning("SMART Selective Self-Test Log Structure");
1269 // swap endian order if needed
1272 swap2((char *)&(data
->logversion
));
1274 swap8((char *)&(data
->span
[i
].start
));
1275 swap8((char *)&(data
->span
[i
].end
));
1277 swap8((char *)&(data
->currentlba
));
1278 swap2((char *)&(data
->currentspan
));
1279 swap2((char *)&(data
->flags
));
1280 swap2((char *)&(data
->pendingtime
));
1283 if (data
->logversion
!= 1)
1284 pout("Note: selective self-test log revision number (%d) not 1 implies that no selective self-test has ever been run\n", data
->logversion
);
1289 // Writes the selective self-test log (log #9)
1290 int ataWriteSelectiveSelfTestLog(ata_device
* device
, ata_selective_selftest_args
& args
,
1291 const ata_smart_values
* sv
, uint64_t num_sectors
,
1292 const ata_selective_selftest_args
* prev_args
)
1294 // Disk size must be known
1296 pout("Disk size is unknown, unable to check selective self-test spans\n");
1301 struct ata_selective_self_test_log sstlog
, *data
=&sstlog
;
1302 unsigned char *ptr
=(unsigned char *)data
;
1303 if (ataReadSelectiveSelfTestLog(device
, data
)) {
1304 pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
1309 data
->logversion
= 1;
1311 // Host is NOT allowed to write selective self-test log if a selective
1312 // self-test is in progress.
1313 if (0<data
->currentspan
&& data
->currentspan
<6 && ((sv
->self_test_exec_status
)>>4)==15) {
1314 pout("Error SMART Selective or other Self-Test in progress.\n");
1318 // Set start/end values based on old spans for special -t select,... options
1320 for (i
= 0; i
< args
.num_spans
; i
++) {
1321 int mode
= args
.span
[i
].mode
;
1322 uint64_t start
= args
.span
[i
].start
;
1323 uint64_t end
= args
.span
[i
].end
;
1324 if (mode
== SEL_CONT
) {// redo or next dependig on last test status
1325 switch (sv
->self_test_exec_status
>> 4) {
1326 case 1: case 2: // Aborted/Interrupted by host
1327 pout("Continue Selective Self-Test: Redo last span\n");
1330 default: // All others
1331 pout("Continue Selective Self-Test: Start next span\n");
1337 if ( (mode
== SEL_REDO
|| mode
== SEL_NEXT
)
1338 && prev_args
&& i
< prev_args
->num_spans
1339 && !data
->span
[i
].start
&& !data
->span
[i
].end
) {
1340 // Some drives do not preserve the selective self-test log accross
1341 // power-cyles. If old span on drive is cleared use span provided
1342 // by caller. This is used by smartd (first span only).
1343 data
->span
[i
].start
= prev_args
->span
[i
].start
;
1344 data
->span
[i
].end
= prev_args
->span
[i
].end
;
1348 case SEL_RANGE
: // -t select,START-END
1350 case SEL_REDO
: // -t select,redo... => Redo current
1351 start
= data
->span
[i
].start
;
1352 if (end
> 0) { // -t select,redo+SIZE
1353 end
--; end
+= start
; // [oldstart, oldstart+SIZE)
1355 else // -t select,redo
1356 end
= data
->span
[i
].end
; // [oldstart, oldend]
1358 case SEL_NEXT
: // -t select,next... => Do next
1359 if (data
->span
[i
].end
== 0) {
1360 start
= end
= 0; break; // skip empty spans
1362 start
= data
->span
[i
].end
+ 1;
1363 if (start
>= num_sectors
)
1364 start
= 0; // wrap around
1365 if (end
> 0) { // -t select,next+SIZE
1366 end
--; end
+= start
; // (oldend, oldend+SIZE]
1368 else { // -t select,next
1369 uint64_t oldsize
= data
->span
[i
].end
- data
->span
[i
].start
+ 1;
1370 end
= start
+ oldsize
- 1; // (oldend, oldend+oldsize]
1371 if (end
>= num_sectors
) {
1372 // Adjust size to allow round-robin testing without future size decrease
1373 uint64_t spans
= (num_sectors
+ oldsize
-1) / oldsize
;
1374 uint64_t newsize
= (num_sectors
+ spans
-1) / spans
;
1375 uint64_t newstart
= num_sectors
- newsize
, newend
= num_sectors
- 1;
1376 pout("Span %d changed from %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors)\n",
1377 i
, start
, end
, oldsize
);
1378 pout(" to %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors) (%"PRIu64
" spans)\n",
1379 newstart
, newend
, newsize
, spans
);
1380 start
= newstart
; end
= newend
;
1385 pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode
);
1389 if (start
< num_sectors
&& num_sectors
<= end
) {
1390 if (end
!= ~(uint64_t)0) // -t select,N-max
1391 pout("Size of self-test span %d decreased according to disk size\n", i
);
1392 end
= num_sectors
- 1;
1394 if (!(start
<= end
&& end
< num_sectors
)) {
1395 pout("Invalid selective self-test span %d: %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors)\n",
1396 i
, start
, end
, num_sectors
);
1399 // Return the actual mode and range to caller.
1400 args
.span
[i
].mode
= mode
;
1401 args
.span
[i
].start
= start
;
1402 args
.span
[i
].end
= end
;
1407 memset(data
->span
+i
, 0, sizeof(struct test_span
));
1409 // Set spans for testing
1410 for (i
= 0; i
< args
.num_spans
; i
++){
1411 data
->span
[i
].start
= args
.span
[i
].start
;
1412 data
->span
[i
].end
= args
.span
[i
].end
;
1415 // host must initialize to zero before initiating selective self-test
1417 data
->currentspan
=0;
1419 // Perform off-line scan after selective test?
1420 if (args
.scan_after_select
== 1)
1422 data
->flags
&= ~SELECTIVE_FLAG_DOSCAN
;
1423 else if (args
.scan_after_select
== 2)
1425 data
->flags
|= SELECTIVE_FLAG_DOSCAN
;
1427 // Must clear active and pending flags before writing
1428 data
->flags
&= ~(SELECTIVE_FLAG_ACTIVE
);
1429 data
->flags
&= ~(SELECTIVE_FLAG_PENDING
);
1431 // modify pending time?
1432 if (args
.pending_time
)
1433 data
->pendingtime
= (unsigned short)(args
.pending_time
-1);
1435 // Set checksum to zero, then compute checksum
1437 unsigned char cksum
=0;
1438 for (i
=0; i
<512; i
++)
1442 data
->checksum
=cksum
;
1444 // swap endian order if needed
1446 swap2((char *)&(data
->logversion
));
1447 for (int b
= 0; b
< 5; b
++) {
1448 swap8((char *)&(data
->span
[b
].start
));
1449 swap8((char *)&(data
->span
[b
].end
));
1451 swap8((char *)&(data
->currentlba
));
1452 swap2((char *)&(data
->currentspan
));
1453 swap2((char *)&(data
->flags
));
1454 swap2((char *)&(data
->pendingtime
));
1457 // write new selective self-test log
1458 if (smartcommandhandler(device
, WRITE_LOG
, 0x09, (char *)data
)){
1459 pout("Error Write Selective Self-Test Log failed: %s\n", device
->get_errmsg());
1466 // This corrects some quantities that are byte reversed in the SMART
1468 static void fixsamsungerrorlog(ata_smart_errorlog
* data
)
1470 // FIXED IN SAMSUNG -25 FIRMWARE???
1471 // Device error count in bytes 452-3
1472 swap2((char *)&(data
->ata_error_count
));
1474 // FIXED IN SAMSUNG -22a FIRMWARE
1475 // step through 5 error log data structures
1476 for (int i
= 0; i
< 5; i
++){
1477 // step through 5 command data structures
1478 for (int j
= 0; j
< 5; j
++)
1479 // Command data structure 4-byte millisec timestamp. These are
1480 // bytes (N+8, N+9, N+10, N+11).
1481 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1482 // Error data structure two-byte hour life timestamp. These are
1483 // bytes (N+28, N+29).
1484 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1489 // NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
1490 static void fixsamsungerrorlog2(ata_smart_errorlog
* data
)
1492 // Device error count in bytes 452-3
1493 swap2((char *)&(data
->ata_error_count
));
1497 // Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1498 // Error Log is #2, and the Extended Comprehensive SMART Error log is
1500 int ataReadErrorLog (ata_device
* device
, ata_smart_errorlog
*data
,
1501 unsigned char fix_firmwarebug
)
1504 // get data from device
1505 if (smartcommandhandler(device
, READ_LOG
, 0x01, (char *)data
)){
1506 pout("Error SMART Error Log Read failed: %s\n", device
->get_errmsg());
1510 // compute its checksum, and issue a warning if needed
1512 checksumwarning("SMART ATA Error Log Structure");
1514 // Some disks have the byte order reversed in some SMART Summary
1515 // Error log entries
1516 if (fix_firmwarebug
== FIX_SAMSUNG
)
1517 fixsamsungerrorlog(data
);
1518 else if (fix_firmwarebug
== FIX_SAMSUNG2
)
1519 fixsamsungerrorlog2(data
);
1521 // swap endian order if needed
1525 // Device error count in bytes 452-3
1526 swap2((char *)&(data
->ata_error_count
));
1528 // step through 5 error log data structures
1529 for (i
=0; i
<5; i
++){
1530 // step through 5 command data structures
1532 // Command data structure 4-byte millisec timestamp
1533 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1534 // Error data structure life timestamp
1535 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1542 // Read Extended Comprehensive Error Log
1543 bool ataReadExtErrorLog(ata_device
* device
, ata_smart_exterrlog
* log
,
1546 if (!ataReadLogExt(device
, 0x03, 0x00, 0, log
, nsectors
))
1549 check_multi_sector_sum(log
, nsectors
, "SMART Extended Comprehensive Error Log Structure");
1551 if (isbigendian()) {
1552 swapx(&log
->device_error_count
);
1553 swapx(&log
->error_log_index
);
1555 for (unsigned i
= 0; i
< nsectors
; i
++) {
1556 for (unsigned j
= 0; j
< 4; j
++)
1557 swapx(&log
->error_logs
[i
].commands
[j
].timestamp
);
1558 swapx(&log
->error_logs
[i
].error
.timestamp
);
1566 int ataReadSmartThresholds (ata_device
* device
, struct ata_smart_thresholds_pvt
*data
){
1568 // get data from device
1569 if (smartcommandhandler(device
, READ_THRESHOLDS
, 0, (char *)data
)){
1570 pout("Error SMART Thresholds Read failed: %s\n", device
->get_errmsg());
1574 // compute its checksum, and issue a warning if needed
1576 checksumwarning("SMART Attribute Thresholds Structure");
1578 // swap endian order if needed
1580 swap2((char *)&(data
->revnumber
));
1585 int ataEnableSmart (ata_device
* device
){
1586 if (smartcommandhandler(device
, ENABLE
, 0, NULL
)){
1587 pout("Error SMART Enable failed: %s\n", device
->get_errmsg());
1593 int ataDisableSmart (ata_device
* device
){
1595 if (smartcommandhandler(device
, DISABLE
, 0, NULL
)){
1596 pout("Error SMART Disable failed: %s\n", device
->get_errmsg());
1602 int ataEnableAutoSave(ata_device
* device
){
1603 if (smartcommandhandler(device
, AUTOSAVE
, 241, NULL
)){
1604 pout("Error SMART Enable Auto-save failed: %s\n", device
->get_errmsg());
1610 int ataDisableAutoSave(ata_device
* device
){
1612 if (smartcommandhandler(device
, AUTOSAVE
, 0, NULL
)){
1613 pout("Error SMART Disable Auto-save failed: %s\n", device
->get_errmsg());
1619 // In *ALL* ATA standards the Enable/Disable AutoOffline command is
1620 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1621 // vendors still support it for backwards compatibility. IBM documents
1622 // it for some drives.
1623 int ataEnableAutoOffline (ata_device
* device
){
1625 /* timer hard coded to 4 hours */
1626 if (smartcommandhandler(device
, AUTO_OFFLINE
, 248, NULL
)){
1627 pout("Error SMART Enable Automatic Offline failed: %s\n", device
->get_errmsg());
1633 // Another Obsolete Command. See comments directly above, associated
1634 // with the corresponding Enable command.
1635 int ataDisableAutoOffline (ata_device
* device
){
1637 if (smartcommandhandler(device
, AUTO_OFFLINE
, 0, NULL
)){
1638 pout("Error SMART Disable Automatic Offline failed: %s\n", device
->get_errmsg());
1644 // If SMART is enabled, supported, and working, then this call is
1645 // guaranteed to return 1, else zero. Note that it should return 1
1646 // regardless of whether the disk's SMART status is 'healthy' or
1648 int ataDoesSmartWork(ata_device
* device
){
1649 int retval
=smartcommandhandler(device
, STATUS
, 0, NULL
);
1657 // This function uses a different interface (DRIVE_TASK) than the
1658 // other commands in this file.
1659 int ataSmartStatus2(ata_device
* device
){
1660 return smartcommandhandler(device
, STATUS_CHECK
, 0, NULL
);
1663 // This is the way to execute ALL tests: offline, short self-test,
1664 // extended self test, with and without captive mode, etc.
1665 // TODO: Move to ataprint.cpp ?
1666 int ataSmartTest(ata_device
* device
, int testtype
, bool force
,
1667 const ata_selective_selftest_args
& selargs
,
1668 const ata_smart_values
* sv
, uint64_t num_sectors
)
1670 char cmdmsg
[128]; const char *type
, *captive
;
1671 int cap
, retval
, select
=0;
1673 // Boolean, if set, says test is captive
1674 cap
=testtype
& CAPTIVE_MASK
;
1676 // Set up strings that describe the type of test
1682 if (testtype
==OFFLINE_FULL_SCAN
)
1684 else if (testtype
==SHORT_SELF_TEST
|| testtype
==SHORT_CAPTIVE_SELF_TEST
)
1685 type
="Short self-test";
1686 else if (testtype
==EXTEND_SELF_TEST
|| testtype
==EXTEND_CAPTIVE_SELF_TEST
)
1687 type
="Extended self-test";
1688 else if (testtype
==CONVEYANCE_SELF_TEST
|| testtype
==CONVEYANCE_CAPTIVE_SELF_TEST
)
1689 type
="Conveyance self-test";
1690 else if ((select
=(testtype
==SELECTIVE_SELF_TEST
|| testtype
==SELECTIVE_CAPTIVE_SELF_TEST
)))
1691 type
="Selective self-test";
1695 // Check whether another test is already running
1696 if (type
&& (sv
->self_test_exec_status
>> 4) == 0xf) {
1698 pout("Can't start self-test without aborting current test (%d0%% remaining),\n"
1699 "%srun 'smartctl -X' to abort test.\n",
1700 sv
->self_test_exec_status
& 0x0f,
1701 (!select
? "add '-t force' option to override, or " : ""));
1708 // If doing a selective self-test, first use WRITE_LOG to write the
1709 // selective self-test log.
1710 ata_selective_selftest_args selargs_io
= selargs
; // filled with info about actual spans
1711 if (select
&& (retval
= ataWriteSelectiveSelfTestLog(device
, selargs_io
, sv
, num_sectors
))) {
1713 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1717 // Print ouf message that we are sending the command to test
1718 if (testtype
==ABORT_SELF_TEST
)
1719 sprintf(cmdmsg
,"Abort SMART off-line mode self-test routine");
1721 sprintf(cmdmsg
, "SMART EXECUTE OFF-LINE IMMEDIATE subcommand 0x%02x", testtype
);
1723 sprintf(cmdmsg
,"Execute SMART %s routine immediately in %s mode",type
,captive
);
1724 pout("Sending command: \"%s\".\n",cmdmsg
);
1728 pout("SPAN STARTING_LBA ENDING_LBA\n");
1729 for (i
= 0; i
< selargs_io
.num_spans
; i
++)
1730 pout(" %d %20"PRId64
" %20"PRId64
"\n", i
,
1731 selargs_io
.span
[i
].start
,
1732 selargs_io
.span
[i
].end
);
1735 // Now send the command to test
1736 if (smartcommandhandler(device
, IMMEDIATE_OFFLINE
, testtype
, NULL
)) {
1737 if (!(cap
&& device
->get_errno() == EIO
)) {
1738 pout("Command \"%s\" failed: %s\n", cmdmsg
, device
->get_errmsg());
1743 // Since the command succeeded, tell user
1744 if (testtype
==ABORT_SELF_TEST
)
1745 pout("Self-testing aborted!\n");
1747 pout("Drive command \"%s\" successful.\n", cmdmsg
);
1749 pout("Testing has begun%s.\n", (force
? " (previous test aborted)" : ""));
1754 /* Test Time Functions */
1755 int TestTime(const ata_smart_values
*data
, int testtype
)
1758 case OFFLINE_FULL_SCAN
:
1759 return (int) data
->total_time_to_complete_off_line
;
1760 case SHORT_SELF_TEST
:
1761 case SHORT_CAPTIVE_SELF_TEST
:
1762 return (int) data
->short_test_completion_time
;
1763 case EXTEND_SELF_TEST
:
1764 case EXTEND_CAPTIVE_SELF_TEST
:
1765 if (data
->extend_test_completion_time_b
== 0xff
1766 && data
->extend_test_completion_time_w
!= 0x0000
1767 && data
->extend_test_completion_time_w
!= 0xffff)
1768 return data
->extend_test_completion_time_w
; // ATA-8
1770 return data
->extend_test_completion_time_b
;
1771 case CONVEYANCE_SELF_TEST
:
1772 case CONVEYANCE_CAPTIVE_SELF_TEST
:
1773 return (int) data
->conveyance_test_completion_time
;
1779 // This function tells you both about the ATA error log and the
1780 // self-test error log capability (introduced in ATA-5). The bit is
1781 // poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1782 // SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1783 // word 84 and 87. Top two bits must match the pattern 01. BEFORE
1784 // ATA-6 these top two bits still had to match the pattern 01, but the
1785 // remaining bits were reserved (==0).
1786 int isSmartErrorLogCapable (const ata_smart_values
* data
, const ata_identify_device
* identity
)
1788 unsigned short word84
=identity
->command_set_extension
;
1789 unsigned short word87
=identity
->csf_default
;
1790 int isata6
=identity
->major_rev_num
& (0x01<<6);
1791 int isata7
=identity
->major_rev_num
& (0x01<<7);
1793 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x01))
1796 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x01))
1799 // otherwise we'll use the poorly documented capability bit
1800 return data
->errorlog_capability
& 0x01;
1803 // See previous function. If the error log exists then the self-test
1804 // log should (must?) also exist.
1805 int isSmartTestLogCapable (const ata_smart_values
* data
, const ata_identify_device
*identity
)
1807 unsigned short word84
=identity
->command_set_extension
;
1808 unsigned short word87
=identity
->csf_default
;
1809 int isata6
=identity
->major_rev_num
& (0x01<<6);
1810 int isata7
=identity
->major_rev_num
& (0x01<<7);
1812 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x02))
1815 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x02))
1819 // otherwise we'll use the poorly documented capability bit
1820 return data
->errorlog_capability
& 0x01;
1824 int isGeneralPurposeLoggingCapable(const ata_identify_device
*identity
)
1826 unsigned short word84
=identity
->command_set_extension
;
1827 unsigned short word87
=identity
->csf_default
;
1829 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1830 // cleared to zero, the contents of word 84 contains valid support
1831 // information. If not, support information is not valid in this
1833 if ((word84
>>14) == 0x01)
1834 // If bit 5 of word 84 is set to one, the device supports the
1835 // General Purpose Logging feature set.
1836 return (word84
& (0x01 << 5));
1838 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1839 // cleared to zero, the contents of words (87:85) contain valid
1840 // information. If not, information is not valid in these words.
1841 if ((word87
>>14) == 0x01)
1842 // If bit 5 of word 87 is set to one, the device supports
1843 // the General Purpose Logging feature set.
1844 return (word87
& (0x01 << 5));
1851 // SMART self-test capability is also indicated in bit 1 of DEVICE
1852 // IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1853 // However this was only introduced in ATA-6 (but self-test log was in
1855 int isSupportExecuteOfflineImmediate(const ata_smart_values
*data
)
1857 return data
->offline_data_collection_capability
& 0x01;
1860 // Note in the ATA-5 standard, the following bit is listed as "Vendor
1861 // Specific". So it may not be reliable. The only use of this that I
1862 // have found is in IBM drives, where it is well-documented. See for
1863 // example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1864 // hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
1865 int isSupportAutomaticTimer(const ata_smart_values
* data
)
1867 return data
->offline_data_collection_capability
& 0x02;
1869 int isSupportOfflineAbort(const ata_smart_values
*data
)
1871 return data
->offline_data_collection_capability
& 0x04;
1873 int isSupportOfflineSurfaceScan(const ata_smart_values
* data
)
1875 return data
->offline_data_collection_capability
& 0x08;
1877 int isSupportSelfTest (const ata_smart_values
* data
)
1879 return data
->offline_data_collection_capability
& 0x10;
1881 int isSupportConveyanceSelfTest(const ata_smart_values
* data
)
1883 return data
->offline_data_collection_capability
& 0x20;
1885 int isSupportSelectiveSelfTest(const ata_smart_values
* data
)
1887 return data
->offline_data_collection_capability
& 0x40;
1890 // Get attribute state
1891 ata_attr_state
ata_get_attr_state(const ata_smart_attribute
& attr
,
1893 const ata_smart_threshold_entry
* thresholds
,
1894 const ata_vendor_attr_defs
& defs
,
1895 unsigned char * threshval
/* = 0 */)
1898 return ATTRSTATE_NON_EXISTING
;
1900 // Normalized values (current,worst,threshold) not valid
1901 // if specified by '-v' option.
1902 // (Some SSD disks uses these bytes to store raw value).
1903 if (defs
[attr
.id
].flags
& ATTRFLAG_NO_NORMVAL
)
1904 return ATTRSTATE_NO_NORMVAL
;
1906 // Normally threshold is at same index as attribute
1908 if (thresholds
[i
].id
!= attr
.id
) {
1909 // Find threshold id in table
1910 for (i
= 0; thresholds
[i
].id
!= attr
.id
; ) {
1911 if (++i
>= NUMBER_ATA_SMART_ATTRIBUTES
)
1912 // Threshold id missing or thresholds cannot be read
1913 return ATTRSTATE_NO_THRESHOLD
;
1916 unsigned char threshold
= thresholds
[i
].threshold
;
1918 // Return threshold if requested
1920 *threshval
= threshold
;
1922 // Don't report a failed attribute if its threshold is 0.
1923 // ATA-3 (X3T13/2008D Revision 7b) declares 0x00 as the "always passing"
1924 // threshold (Later ATA versions declare all thresholds as "obsolete").
1925 // In practice, threshold value 0 is often used for usage attributes.
1927 return ATTRSTATE_OK
;
1929 // Failed now if current value is below threshold
1930 if (attr
.current
<= threshold
)
1931 return ATTRSTATE_FAILED_NOW
;
1933 // Failed in the past if worst value is below threshold
1934 if (!(defs
[attr
.id
].flags
& ATTRFLAG_NO_WORSTVAL
) && attr
.worst
<= threshold
)
1935 return ATTRSTATE_FAILED_PAST
;
1937 return ATTRSTATE_OK
;
1940 // Get default raw value print format
1941 static ata_attr_raw_format
get_default_raw_format(unsigned char id
)
1944 case 3: // Spin-up time
1945 return RAWFMT_RAW16_OPT_AVG16
;
1947 case 5: // Reallocated sector count
1948 case 196: // Reallocated event count
1949 return RAWFMT_RAW16_OPT_RAW16
;
1951 case 190: // Temperature
1953 return RAWFMT_TEMPMINMAX
;
1956 return RAWFMT_RAW48
;
1960 // Get attribute raw value.
1961 uint64_t ata_get_attr_raw_value(const ata_smart_attribute
& attr
,
1962 const ata_vendor_attr_defs
& defs
)
1964 const ata_vendor_attr_defs::entry
& def
= defs
[attr
.id
];
1966 // Use default byteorder if not specified
1967 const char * byteorder
= def
.byteorder
;
1969 switch (def
.raw_format
) {
1972 byteorder
= "543210wv"; break;
1973 case RAWFMT_RAW24_DIV_RAW32
:
1974 case RAWFMT_MSEC24_HOUR32
:
1975 byteorder
= "r543210"; break;
1977 byteorder
= "543210"; break;
1981 // Build 64-bit value from selected bytes
1982 uint64_t rawvalue
= 0;
1983 for (int i
= 0; byteorder
[i
]; i
++) {
1985 switch (byteorder
[i
]) {
1986 case '0': b
= attr
.raw
[0]; break;
1987 case '1': b
= attr
.raw
[1]; break;
1988 case '2': b
= attr
.raw
[2]; break;
1989 case '3': b
= attr
.raw
[3]; break;
1990 case '4': b
= attr
.raw
[4]; break;
1991 case '5': b
= attr
.raw
[5]; break;
1992 case 'r': b
= attr
.reserv
; break;
1993 case 'v': b
= attr
.current
; break;
1994 case 'w': b
= attr
.worst
; break;
1995 default : b
= 0; break;
1997 rawvalue
<<= 8; rawvalue
|= b
;
2004 // Format attribute raw value.
2005 std::string
ata_format_attr_raw_value(const ata_smart_attribute
& attr
,
2006 const ata_vendor_attr_defs
& defs
)
2008 // Get 48 bit or 64 bit raw value
2009 uint64_t rawvalue
= ata_get_attr_raw_value(attr
, defs
);
2011 // Split into bytes and words
2012 unsigned char raw
[6];
2013 raw
[0] = (unsigned char) rawvalue
;
2014 raw
[1] = (unsigned char)(rawvalue
>> 8);
2015 raw
[2] = (unsigned char)(rawvalue
>> 16);
2016 raw
[3] = (unsigned char)(rawvalue
>> 24);
2017 raw
[4] = (unsigned char)(rawvalue
>> 32);
2018 raw
[5] = (unsigned char)(rawvalue
>> 40);
2020 word
[0] = raw
[0] | (raw
[1] << 8);
2021 word
[1] = raw
[2] | (raw
[3] << 8);
2022 word
[2] = raw
[4] | (raw
[5] << 8);
2025 ata_attr_raw_format format
= defs
[attr
.id
].raw_format
;
2026 if (format
== RAWFMT_DEFAULT
)
2027 format
= get_default_raw_format(attr
.id
);
2033 s
= strprintf("%d %d %d %d %d %d",
2034 raw
[5], raw
[4], raw
[3], raw
[2], raw
[1], raw
[0]);
2038 s
= strprintf("%u %u %u", word
[2], word
[1], word
[0]);
2043 s
= strprintf("%"PRIu64
, rawvalue
);
2047 s
= strprintf("0x%012"PRIx64
, rawvalue
);
2051 s
= strprintf("0x%016"PRIx64
, rawvalue
);
2054 case RAWFMT_RAW16_OPT_RAW16
:
2055 s
= strprintf("%u", word
[0]);
2056 if (word
[1] || word
[2])
2057 s
+= strprintf(" (%u, %u)", word
[2], word
[1]);
2060 case RAWFMT_RAW16_OPT_AVG16
:
2061 s
= strprintf("%u", word
[0]);
2063 s
+= strprintf(" (Average %u)", word
[1]);
2066 case RAWFMT_RAW24_DIV_RAW24
:
2067 s
= strprintf("%u/%u",
2068 (unsigned)(rawvalue
>> 24), (unsigned)(rawvalue
& 0x00ffffffULL
));
2071 case RAWFMT_RAW24_DIV_RAW32
:
2072 s
= strprintf("%u/%u",
2073 (unsigned)(rawvalue
>> 32), (unsigned)(rawvalue
& 0xffffffffULL
));
2076 case RAWFMT_MIN2HOUR
:
2079 int64_t temp
= word
[0]+(word
[1]<<16);
2080 int64_t tmp1
= temp
/60;
2081 int64_t tmp2
= temp
%60;
2082 s
= strprintf("%"PRIu64
"h+%02"PRIu64
"m", tmp1
, tmp2
);
2084 s
+= strprintf(" (%u)", word
[2]);
2088 case RAWFMT_SEC2HOUR
:
2091 int64_t hours
= rawvalue
/3600;
2092 int64_t minutes
= (rawvalue
-3600*hours
)/60;
2093 int64_t seconds
= rawvalue
%60;
2094 s
= strprintf("%"PRIu64
"h+%02"PRIu64
"m+%02"PRIu64
"s", hours
, minutes
, seconds
);
2098 case RAWFMT_HALFMIN2HOUR
:
2100 // 30-second counter
2101 int64_t hours
= rawvalue
/120;
2102 int64_t minutes
= (rawvalue
-120*hours
)/2;
2103 s
+= strprintf("%"PRIu64
"h+%02"PRIu64
"m", hours
, minutes
);
2107 case RAWFMT_MSEC24_HOUR32
:
2109 // hours + milliseconds
2110 unsigned hours
= (unsigned)(rawvalue
& 0xffffffffULL
);
2111 unsigned milliseconds
= (unsigned)(rawvalue
>> 32);
2112 unsigned seconds
= milliseconds
/ 1000;
2113 s
= strprintf("%uh+%02um+%02u.%03us",
2114 hours
, seconds
/ 60, seconds
% 60, milliseconds
% 1000);
2118 case RAWFMT_TEMPMINMAX
:
2121 // Search for possible min/max values
2122 // 00 HH 00 LL 00 TT (Hitachi/IBM)
2123 // 00 00 HH LL 00 TT (Maxtor, Samsung)
2124 // 00 00 00 HH LL TT (WDC)
2125 unsigned char lo
= 0, hi
= 0;
2127 for (int i
= 1; i
< 6; i
++) {
2135 hi
= lo
; lo
= raw
[i
];
2143 unsigned char t
= raw
[0];
2145 s
= strprintf("%d", t
);
2146 else if (cnt
== 2 && 0 < lo
&& lo
<= t
&& t
<= hi
&& hi
< 128)
2147 s
= strprintf("%d (Min/Max %d/%d)", t
, lo
, hi
);
2149 s
= strprintf("%d (%d %d %d %d %d)", t
, raw
[5], raw
[4], raw
[3], raw
[2], raw
[1]);
2153 case RAWFMT_TEMP10X
:
2154 // ten times temperature in Celsius
2155 s
= strprintf("%d.%d", word
[0]/10, word
[0]%10);
2159 s
= "?"; // Should not happen
2166 // Attribute names shouldn't be longer than 23 chars, otherwise they break the
2167 // output of smartctl.
2168 static const char * get_default_attr_name(unsigned char id
)
2172 return "Raw_Read_Error_Rate";
2174 return "Throughput_Performance";
2176 return "Spin_Up_Time";
2178 return "Start_Stop_Count";
2180 return "Reallocated_Sector_Ct";
2182 return "Read_Channel_Margin";
2184 return "Seek_Error_Rate";
2186 return "Seek_Time_Performance";
2188 return "Power_On_Hours";
2190 return "Spin_Retry_Count";
2192 return "Calibration_Retry_Count";
2194 return "Power_Cycle_Count";
2196 return "Read_Soft_Error_Rate";
2198 return "Program_Fail_Count_Chip";
2200 return "Erase_Fail_Count_Chip";
2202 return "Wear_Leveling_Count";
2204 return "Used_Rsvd_Blk_Cnt_Chip";
2206 return "Used_Rsvd_Blk_Cnt_Tot";
2208 return "Unused_Rsvd_Blk_Cnt_Tot";
2210 return "Program_Fail_Cnt_Total";
2212 return "Erase_Fail_Count_Total";
2214 return "Runtime_Bad_Block";
2216 return "End-to-End_Error";
2218 return "Reported_Uncorrect";
2220 return "Command_Timeout";
2222 return "High_Fly_Writes";
2224 // Western Digital uses this for temperature.
2225 // It's identical to Attribute 194 except that it
2226 // has a failure threshold set to correspond to the
2227 // max allowed operating temperature of the drive, which
2228 // is typically 55C. So if this attribute has failed
2229 // in the past, it indicates that the drive temp exceeded
2230 // 55C sometime in the past.
2231 return "Airflow_Temperature_Cel";
2233 return "G-Sense_Error_Rate";
2235 return "Power-Off_Retract_Count";
2237 return "Load_Cycle_Count";
2239 return "Temperature_Celsius";
2241 // Fujitsu: "ECC_On_The_Fly_Count";
2242 return "Hardware_ECC_Recovered";
2244 return "Reallocated_Event_Count";
2246 return "Current_Pending_Sector";
2248 return "Offline_Uncorrectable";
2250 return "UDMA_CRC_Error_Count";
2253 return "Multi_Zone_Error_Rate";
2255 return "Soft_Read_Error_Rate";
2257 // Fujitsu: "TA_Increase_Count"
2258 return "Data_Address_Mark_Errs";
2261 return "Run_Out_Cancel";
2262 // Maxtor: ECC Errors
2264 // Fujitsu: "Shock_Count_Write_Opern"
2265 return "Soft_ECC_Correction";
2267 // Fujitsu: "Shock_Rate_Write_Opern"
2268 return "Thermal_Asperity_Rate";
2271 return "Flying_Height";
2274 return "Spin_High_Current";
2280 return "Offline_Seek_Performnce";
2282 return "Disk_Shift";
2284 return "G-Sense_Error_Rate";
2286 return "Loaded_Hours";
2288 return "Load_Retry_Count";
2290 return "Load_Friction";
2292 return "Load_Cycle_Count";
2294 return "Load-in_Time";
2296 return "Torq-amp_Count";
2298 return "Power-off_Retract_Count";
2300 // seen in IBM DTPA-353750
2301 return "Head_Amplitude";
2303 return "Temperature_Celsius";
2305 // seen in Intel X25-E SSD
2306 return "Available_Reservd_Space";
2308 // seen in Intel X25-E SSD
2309 return "Media_Wearout_Indicator";
2311 return "Head_Flying_Hours";
2313 return "Total_LBAs_Written";
2315 return "Total_LBAs_Read";
2317 return "Read_Error_Retry_Rate";
2319 return "Free_Fall_Sensor";
2321 return "Unknown_Attribute";
2325 // Get attribute name
2326 std::string
ata_get_smart_attr_name(unsigned char id
, const ata_vendor_attr_defs
& defs
)
2328 if (!defs
[id
].name
.empty())
2329 return defs
[id
].name
;
2331 return get_default_attr_name(id
);
2334 // Find attribute index for attribute id, -1 if not found.
2335 int ata_find_attr_index(unsigned char id
, const ata_smart_values
& smartval
)
2339 for (int i
= 0; i
< NUMBER_ATA_SMART_ATTRIBUTES
; i
++) {
2340 if (smartval
.vendor_attributes
[i
].id
== id
)
2346 // Return Temperature Attribute raw value selected according to possible
2347 // non-default interpretations. If the Attribute does not exist, return 0
2348 unsigned char ata_return_temperature_value(const ata_smart_values
* data
, const ata_vendor_attr_defs
& defs
)
2350 for (int i
= 0; i
< 3; i
++) {
2351 static const unsigned char ids
[3] = {194, 9, 220};
2352 unsigned char id
= ids
[i
];
2353 const ata_attr_raw_format format
= defs
[id
].raw_format
;
2354 if (!( (id
== 194 && format
== RAWFMT_DEFAULT
)
2355 || format
== RAWFMT_TEMPMINMAX
|| format
== RAWFMT_TEMP10X
))
2357 int idx
= ata_find_attr_index(id
, *data
);
2360 uint64_t raw
= ata_get_attr_raw_value(data
->vendor_attributes
[idx
], defs
);
2362 // ignore possible min/max values in high words
2363 if (format
== RAWFMT_TEMP10X
) // -v N,temp10x
2364 temp
= ((unsigned short)raw
+ 5) / 10;
2366 temp
= (unsigned char)raw
;
2367 if (!(0 < temp
&& temp
< 128))
2371 // No valid attribute found
2377 int ataReadSCTStatus(ata_device
* device
, ata_sct_status_response
* sts
)
2379 // read SCT status via SMART log 0xe0
2380 memset(sts
, 0, sizeof(*sts
));
2381 if (smartcommandhandler(device
, READ_LOG
, 0xe0, (char *)sts
)){
2382 pout("Error Read SCT Status failed: %s\n", device
->get_errmsg());
2386 // swap endian order if needed
2388 swapx(&sts
->format_version
);
2389 swapx(&sts
->sct_version
);
2390 swapx(&sts
->sct_spec
);
2391 swapx(&sts
->ext_status_code
);
2392 swapx(&sts
->action_code
);
2393 swapx(&sts
->function_code
);
2394 swapx(&sts
->over_limit_count
);
2395 swapx(&sts
->under_limit_count
);
2398 // Check format version
2399 if (!(sts
->format_version
== 2 || sts
->format_version
== 3)) {
2400 pout("Error unknown SCT Status format version %u, should be 2 or 3.\n", sts
->format_version
);
2406 // Read SCT Temperature History Table and Status
2407 int ataReadSCTTempHist(ata_device
* device
, ata_sct_temperature_history_table
* tmh
,
2408 ata_sct_status_response
* sts
)
2410 // Check initial status
2411 if (ataReadSCTStatus(device
, sts
))
2414 // Do nothing if other SCT command is executing
2415 if (sts
->ext_status_code
== 0xffff) {
2416 pout("Another SCT command is executing, abort Read Data Table\n"
2417 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2418 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2422 ata_sct_data_table_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2423 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2424 cmd
.action_code
= 5; // Data table command
2425 cmd
.function_code
= 1; // Read table
2426 cmd
.table_id
= 2; // Temperature History Table
2428 // swap endian order if needed
2429 if (isbigendian()) {
2430 swapx(&cmd
.action_code
);
2431 swapx(&cmd
.function_code
);
2432 swapx(&cmd
.table_id
);
2435 // write command via SMART log page 0xe0
2436 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2437 pout("Error Write SCT Data Table command failed: %s\n", device
->get_errmsg());
2441 // read SCT data via SMART log page 0xe1
2442 memset(tmh
, 0, sizeof(*tmh
));
2443 if (smartcommandhandler(device
, READ_LOG
, 0xe1, (char *)tmh
)){
2444 pout("Error Read SCT Data Table failed: %s\n", device
->get_errmsg());
2448 // re-read and check SCT status
2449 if (ataReadSCTStatus(device
, sts
))
2452 if (!(sts
->ext_status_code
== 0 && sts
->action_code
== 5 && sts
->function_code
== 1)) {
2453 pout("Error unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2454 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2458 // swap endian order if needed
2460 swapx(&tmh
->format_version
);
2461 swapx(&tmh
->sampling_period
);
2462 swapx(&tmh
->interval
);
2465 // Check format version
2466 if (tmh
->format_version
!= 2) {
2467 pout("Error unknown SCT Temperature History Format Version (%u), should be 2.\n", tmh
->format_version
);
2473 // Set SCT Temperature Logging Interval
2474 int ataSetSCTTempInterval(ata_device
* device
, unsigned interval
, bool persistent
)
2476 // Check initial status
2477 ata_sct_status_response sts
;
2478 if (ataReadSCTStatus(device
, &sts
))
2481 // Do nothing if other SCT command is executing
2482 if (sts
.ext_status_code
== 0xffff) {
2483 pout("Another SCT command is executing, abort Feature Control\n"
2484 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2485 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2489 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2490 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2491 cmd
.action_code
= 4; // Feature Control command
2492 cmd
.function_code
= 1; // Set state
2493 cmd
.feature_code
= 3; // Temperature logging interval
2494 cmd
.state
= interval
;
2495 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2497 // swap endian order if needed
2498 if (isbigendian()) {
2499 swapx(&cmd
.action_code
);
2500 swapx(&cmd
.function_code
);
2501 swapx(&cmd
.feature_code
);
2503 swapx(&cmd
.option_flags
);
2506 // write command via SMART log page 0xe0
2507 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2508 pout("Error Write SCT Feature Control Command failed: %s\n", device
->get_errmsg());
2512 // re-read and check SCT status
2513 if (ataReadSCTStatus(device
, &sts
))
2516 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== 1)) {
2517 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2518 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2524 // Get/Set SCT Error Recovery Control
2525 static int ataGetSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
,
2526 bool set
, unsigned short & time_limit
)
2528 // Check initial status
2529 ata_sct_status_response sts
;
2530 if (ataReadSCTStatus(device
, &sts
))
2533 // Do nothing if other SCT command is executing
2534 if (sts
.ext_status_code
== 0xffff) {
2535 pout("Another SCT command is executing, abort Error Recovery Control\n"
2536 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2537 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2541 ata_sct_error_recovery_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2542 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2543 cmd
.action_code
= 3; // Error Recovery Control command
2544 cmd
.function_code
= (set
? 1 : 2); // 1=Set timer, 2=Get timer
2545 cmd
.selection_code
= type
; // 1=Read timer, 2=Write timer
2547 cmd
.time_limit
= time_limit
;
2549 // swap endian order if needed
2550 if (isbigendian()) {
2551 swapx(&cmd
.action_code
);
2552 swapx(&cmd
.function_code
);
2553 swapx(&cmd
.selection_code
);
2554 swapx(&cmd
.time_limit
);
2557 // write command via SMART log page 0xe0
2558 // TODO: Debug output
2560 in
.in_regs
.command
= ATA_SMART_CMD
;
2561 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
2562 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
2563 in
.in_regs
.lba_low
= 0xe0;
2564 in
.set_data_out(&cmd
, 1);
2567 // Time limit returned in ATA registers
2568 in
.out_needed
.sector_count
= in
.out_needed
.lba_low
= true;
2571 if (!device
->ata_pass_through(in
, out
)) {
2572 pout("Error Write SCT (%cet) Error Recovery Control Command failed: %s\n",
2573 (!set
? 'G' : 'S'), device
->get_errmsg());
2577 // re-read and check SCT status
2578 if (ataReadSCTStatus(device
, &sts
))
2581 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 3 && sts
.function_code
== (set
? 1 : 2))) {
2582 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2583 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2588 // Check whether registers are properly returned by ioctl()
2589 if (!(out
.out_regs
.sector_count
.is_set() && out
.out_regs
.lba_low
.is_set())) {
2590 // TODO: Output register support should be checked within each ata_pass_through()
2591 // implementation before command is issued.
2592 pout("Error SMART WRITE LOG does not return COUNT and LBA_LOW register\n");
2595 // Return value to caller
2596 time_limit
= out
.out_regs
.sector_count
| (out
.out_regs
.lba_low
<< 8);
2602 // Get SCT Error Recovery Control
2603 int ataGetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short & time_limit
)
2605 return ataGetSetSCTErrorRecoveryControltime(device
, type
, false/*get*/, time_limit
);
2608 // Set SCT Error Recovery Control
2609 int ataSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short time_limit
)
2611 return ataGetSetSCTErrorRecoveryControltime(device
, type
, true/*set*/, time_limit
);
2615 // Print one self-test log entry.
2617 // -1: self-test failed
2618 // 1: extended self-test completed without error
2620 int ataPrintSmartSelfTestEntry(unsigned testnum
, unsigned char test_type
,
2621 unsigned char test_status
,
2622 unsigned short timestamp
,
2623 uint64_t failing_lba
,
2624 bool print_error_only
, bool & print_header
)
2626 // Check status and type for return value
2628 switch (test_status
>> 4) {
2630 if ((test_type
& 0x0f) == 0x02)
2631 retval
= 1; // extended self-test completed without error
2636 retval
= -1; // self-test failed
2640 if (retval
>= 0 && print_error_only
)
2643 std::string msgtest
;
2644 switch (test_type
) {
2645 case 0x00: msgtest
= "Offline"; break;
2646 case 0x01: msgtest
= "Short offline"; break;
2647 case 0x02: msgtest
= "Extended offline"; break;
2648 case 0x03: msgtest
= "Conveyance offline"; break;
2649 case 0x04: msgtest
= "Selective offline"; break;
2650 case 0x7f: msgtest
= "Abort offline test"; break;
2651 case 0x81: msgtest
= "Short captive"; break;
2652 case 0x82: msgtest
= "Extended captive"; break;
2653 case 0x83: msgtest
= "Conveyance captive"; break;
2654 case 0x84: msgtest
= "Selective captive"; break;
2656 if ((0x40 <= test_type
&& test_type
<= 0x7e) || 0x90 <= test_type
)
2657 msgtest
= strprintf("Vendor (0x%02x)", test_type
);
2659 msgtest
= strprintf("Reserved (0x%02x)", test_type
);
2662 std::string msgstat
;
2663 switch (test_status
>> 4) {
2664 case 0x0: msgstat
= "Completed without error"; break;
2665 case 0x1: msgstat
= "Aborted by host"; break;
2666 case 0x2: msgstat
= "Interrupted (host reset)"; break;
2667 case 0x3: msgstat
= "Fatal or unknown error"; break;
2668 case 0x4: msgstat
= "Completed: unknown failure"; break;
2669 case 0x5: msgstat
= "Completed: electrical failure"; break;
2670 case 0x6: msgstat
= "Completed: servo/seek failure"; break;
2671 case 0x7: msgstat
= "Completed: read failure"; break;
2672 case 0x8: msgstat
= "Completed: handling damage??"; break;
2673 case 0xf: msgstat
= "Self-test routine in progress"; break;
2674 default: msgstat
= strprintf("Unknown status (0x%x)", test_status
>> 4);
2677 // Print header once
2679 print_header
= false;
2680 pout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2684 if (retval
< 0 && failing_lba
< 0xffffffffffffULL
)
2685 snprintf(msglba
, sizeof(msglba
), "%"PRIu64
, failing_lba
);
2687 strcpy(msglba
, "-");
2689 pout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum
,
2690 msgtest
.c_str(), msgstat
.c_str(), test_status
& 0x0f, timestamp
, msglba
);
2695 // Print Smart self-test log, used by smartctl and smartd.
2697 // bottom 8 bits: number of entries found where self-test showed an error
2698 // remaining bits: if nonzero, power on hours of last self-test where error was found
2699 int ataPrintSmartSelfTestlog(const ata_smart_selftestlog
* data
, bool allentries
,
2700 unsigned char fix_firmwarebug
)
2703 pout("SMART Self-test log structure revision number %d\n",(int)data
->revnumber
);
2704 if ((data
->revnumber
!=0x0001) && allentries
&& fix_firmwarebug
!= FIX_SAMSUNG
)
2705 pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2706 if (data
->mostrecenttest
==0){
2708 pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
2712 bool noheaderprinted
= true;
2713 int errcnt
= 0, hours
= 0, igncnt
= 0;
2714 int testno
= 0, ext_ok_testno
= -1;
2717 for (int i
= 20; i
>= 0; i
--) {
2718 // log is a circular buffer
2719 int j
= (i
+data
->mostrecenttest
)%21;
2720 const ata_smart_selftestlog_struct
* log
= data
->selftest_struct
+j
;
2722 if (nonempty(log
, sizeof(*log
))) {
2723 // count entry based on non-empty structures -- needed for
2724 // Seagate only -- other vendors don't have blank entries 'in
2728 // T13/1321D revision 1c: (Data structure Rev #1)
2730 //The failing LBA shall be the LBA of the uncorrectable sector
2731 //that caused the test to fail. If the device encountered more
2732 //than one uncorrectable sector during the test, this field
2733 //shall indicate the LBA of the first uncorrectable sector
2734 //encountered. If the test passed or the test failed for some
2735 //reason other than an uncorrectable sector, the value of this
2736 //field is undefined.
2738 // This is true in ALL ATA-5 specs
2739 uint64_t lba48
= (log
->lbafirstfailure
< 0xffffffff ? log
->lbafirstfailure
: 0xffffffffffffULL
);
2742 int state
= ataPrintSmartSelfTestEntry(testno
,
2743 log
->selftestnumber
, log
->selfteststatus
,
2744 log
->timestamp
, lba48
, !allentries
, noheaderprinted
);
2747 // Self-test showed an error
2748 if (ext_ok_testno
< 0) {
2751 // keep track of time of most recent error
2753 hours
= log
->timestamp
;
2756 // Newer successful extended self-test exits
2759 else if (state
> 0 && ext_ok_testno
< 0) {
2760 // Latest successful extended self-test
2761 ext_ok_testno
= testno
;
2767 pout("%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2768 igncnt
, igncnt
+errcnt
, ext_ok_testno
);
2770 if (!allentries
&& !noheaderprinted
)
2773 return ((hours
<< 8) | errcnt
);
2777 /////////////////////////////////////////////////////////////////////////////
2778 // Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2779 // an ATA device with same behaviour
2783 class parsed_ata_device
2784 : public /*implements*/ ata_device_with_command_set
2787 parsed_ata_device(smart_interface
* intf
, const char * dev_name
);
2789 virtual ~parsed_ata_device() throw();
2791 virtual bool is_open() const;
2793 virtual bool open();
2795 virtual bool close();
2797 virtual bool ata_identify_is_cached() const;
2800 virtual int ata_command_interface(smart_command_set command
, int select
, char * data
);
2803 // Table of parsed commands, return value, data
2804 struct parsed_ata_command
2806 smart_command_set command
;
2812 enum { max_num_commands
= 32 };
2813 parsed_ata_command m_command_table
[max_num_commands
];
2816 int m_next_replay_command
;
2817 bool m_replay_out_of_sync
;
2818 bool m_ata_identify_is_cached
;
2821 static const char * nextline(const char * s
, int & lineno
)
2823 for (s
+= strcspn(s
, "\r\n"); *s
== '\r' || *s
== '\n'; s
++) {
2824 if (*s
== '\r' && s
[1] == '\n')
2831 static int name2command(const char * s
)
2833 for (int i
= 0; i
< (int)(sizeof(commandstrings
)/sizeof(commandstrings
[0])); i
++) {
2834 if (!strcmp(s
, commandstrings
[i
]))
2840 static bool matchcpy(char * dest
, size_t size
, const char * src
, const regmatch_t
& srcmatch
)
2842 if (srcmatch
.rm_so
< 0)
2844 size_t n
= srcmatch
.rm_eo
- srcmatch
.rm_so
;
2847 memcpy(dest
, src
+ srcmatch
.rm_so
, n
);
2852 static inline int matchtoi(const char * src
, const regmatch_t
& srcmatch
, int defval
)
2854 if (srcmatch
.rm_so
< 0)
2856 return atoi(src
+ srcmatch
.rm_so
);
2859 parsed_ata_device::parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2860 : smart_device(intf
, dev_name
, "ata", ""),
2862 m_next_replay_command(0),
2863 m_replay_out_of_sync(false),
2864 m_ata_identify_is_cached(false)
2866 memset(m_command_table
, 0, sizeof(m_command_table
));
2869 parsed_ata_device::~parsed_ata_device() throw()
2874 bool parsed_ata_device::is_open() const
2876 return (m_num_commands
> 0);
2879 // Parse stdin and build command table
2880 bool parsed_ata_device::open()
2882 const char * pathname
= get_dev_name();
2883 if (strcmp(pathname
, "-"))
2884 return set_err(EINVAL
);
2885 pathname
= "<stdin>";
2887 char buffer
[64*1024];
2889 while (size
< (int)sizeof(buffer
)) {
2890 int nr
= fread(buffer
, 1, sizeof(buffer
), stdin
);
2896 return set_err(ENOENT
, "%s: Unexpected EOF", pathname
);
2897 if (size
>= (int)sizeof(buffer
))
2898 return set_err(EIO
, "%s: Buffer overflow", pathname
);
2901 // Regex to match output from "-r ataioctl,2"
2902 static const char pattern
[] = "^"
2904 "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
2906 "( InputParameter=([0-9]+))?" // (4 (5))
2908 "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2910 "[\r\n]" // EOL match necessary to match optional parts above
2912 "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2914 " *(En|Dis)abled status cached by OS, " // (11)
2918 const regular_expression
regex(pattern
, REG_EXTENDED
);
2921 const char * errmsg
= 0;
2922 int i
= -1, state
= 0, lineno
= 1;
2923 for (const char * line
= buffer
; *line
; line
= nextline(line
, lineno
)) {
2925 if (!(line
[0] == 'R' || line
[0] == '=' || line
[0] == ' '))
2927 const int nmatch
= 1+11;
2928 regmatch_t match
[nmatch
];
2929 if (!regex
.execute(line
, nmatch
, match
))
2933 if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[2])) { // "REPORT-IOCTL:... Command=%s ..."
2934 int nc
= name2command(cmdname
);
2936 errmsg
= "Unknown ATA command name"; break;
2938 if (match
[7].rm_so
< 0) { // "returned %d"
2940 if (!(state
== 0 || state
== 2)) {
2941 errmsg
= "Missing REPORT-IOCTL result"; break;
2943 if (++i
>= max_num_commands
) {
2944 errmsg
= "Too many ATA commands"; break;
2946 m_command_table
[i
].command
= (smart_command_set
)nc
;
2947 m_command_table
[i
].select
= matchtoi(line
, match
[5], 0); // "InputParameter=%d"
2952 if (!(state
== 1 && (int)m_command_table
[i
].command
== nc
)) {
2953 errmsg
= "Missing REPORT-IOCTL start"; break;
2955 m_command_table
[i
].retval
= matchtoi(line
, match
[7], -1); // "returned %d"
2956 m_command_table
[i
].errval
= matchtoi(line
, match
[9], 0); // "errno=%d"
2960 else if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[10])) { // "===== [%s] DATA START "
2961 // Start of sector hexdump
2962 int nc
= name2command(cmdname
);
2963 if (!(state
== (nc
== WRITE_LOG
? 1 : 2) && (int)m_command_table
[i
].command
== nc
)) {
2964 errmsg
= "Unexpected DATA START"; break;
2966 line
= nextline(line
, lineno
);
2967 char * data
= (char *)malloc(512);
2969 for (j
= 0; j
< 32; j
++) {
2971 unsigned u1
, u2
; int n1
= -1;
2972 if (!(sscanf(line
, "%3u-%3u: "
2973 "%2x %2x %2x %2x %2x %2x %2x %2x "
2974 "%2x %2x %2x %2x %2x %2x %2x %2x%n",
2976 b
+ 0, b
+ 1, b
+ 2, b
+ 3, b
+ 4, b
+ 5, b
+ 6, b
+ 7,
2977 b
+ 8, b
+ 9, b
+10, b
+11, b
+12, b
+13, b
+14, b
+15, &n1
) == 18
2978 && n1
>= 56 && u1
== j
*16 && u2
== j
*16+15))
2980 for (unsigned k
= 0; k
< 16; k
++)
2981 data
[j
*16+k
] = b
[k
];
2982 line
= nextline(line
, lineno
);
2986 errmsg
= "Incomplete sector hex dump"; break;
2988 m_command_table
[i
].data
= data
;
2989 if (nc
!= WRITE_LOG
)
2992 else if (match
[11].rm_so
> 0) { // "(En|Dis)abled status cached by OS"
2993 m_ata_identify_is_cached
= true;
2997 if (!(state
== 0 || state
== 2))
2998 errmsg
= "Missing REPORT-IOCTL result";
3000 if (!errmsg
&& i
< 0)
3001 errmsg
= "No information found";
3003 m_num_commands
= i
+1;
3004 m_next_replay_command
= 0;
3005 m_replay_out_of_sync
= false;
3009 return set_err(EIO
, "%s(%d): Syntax error: %s", pathname
, lineno
, errmsg
);
3014 // Report warnings and free command table
3015 bool parsed_ata_device::close()
3017 if (m_replay_out_of_sync
)
3018 pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
3019 else if (m_next_replay_command
!= 0)
3020 pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands
-m_next_replay_command
);
3022 for (int i
= 0; i
< m_num_commands
; i
++) {
3023 if (m_command_table
[i
].data
) {
3024 free(m_command_table
[i
].data
); m_command_table
[i
].data
= 0;
3028 m_next_replay_command
= 0;
3029 m_replay_out_of_sync
= false;
3034 bool parsed_ata_device::ata_identify_is_cached() const
3036 return m_ata_identify_is_cached
;
3040 // Simulate ATA command from command table
3041 int parsed_ata_device::ata_command_interface(smart_command_set command
, int select
, char * data
)
3043 // Find command, try round-robin if out of sync
3044 int i
= m_next_replay_command
;
3045 for (int j
= 0; ; j
++) {
3046 if (j
>= m_num_commands
) {
3047 pout("REPLAY-IOCTL: Warning: Command not found\n");
3051 if (m_command_table
[i
].command
== command
&& m_command_table
[i
].select
== select
)
3053 if (!m_replay_out_of_sync
) {
3054 m_replay_out_of_sync
= true;
3055 pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i
+1);
3057 if (++i
>= m_num_commands
)
3060 m_next_replay_command
= i
;
3061 if (++m_next_replay_command
>= m_num_commands
)
3062 m_next_replay_command
= 0;
3064 // Return command data
3069 case READ_THRESHOLDS
:
3071 if (m_command_table
[i
].data
)
3072 memcpy(data
, m_command_table
[i
].data
, 512);
3075 if (!(m_command_table
[i
].data
&& !memcmp(data
, m_command_table
[i
].data
, 512)))
3076 pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
3078 case CHECK_POWER_MODE
:
3079 data
[0] = (char)0xff;
3084 if (m_command_table
[i
].errval
)
3085 errno
= m_command_table
[i
].errval
;
3086 return m_command_table
[i
].retval
;
3091 ata_device
* get_parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
3093 return new parsed_ata_device(intf
, dev_name
);