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 3528 2012-03-25 17:13:47Z 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 {"raw56" , RAWFMT_RAW56
},
216 {"hex56" , RAWFMT_HEX56
},
217 {"raw64" , RAWFMT_RAW64
},
218 {"hex64" , RAWFMT_HEX64
},
219 {"raw16(raw16)" , RAWFMT_RAW16_OPT_RAW16
},
220 {"raw16(avg16)" , RAWFMT_RAW16_OPT_AVG16
},
221 {"raw24(raw8)" , RAWFMT_RAW24_OPT_RAW8
},
222 {"raw24/raw24" , RAWFMT_RAW24_DIV_RAW24
},
223 {"raw24/raw32" , RAWFMT_RAW24_DIV_RAW32
},
224 {"sec2hour" , RAWFMT_SEC2HOUR
},
225 {"min2hour" , RAWFMT_MIN2HOUR
},
226 {"halfmin2hour" , RAWFMT_HALFMIN2HOUR
},
227 {"msec24hour32" , RAWFMT_MSEC24_HOUR32
},
228 {"tempminmax" , RAWFMT_TEMPMINMAX
},
229 {"temp10x" , RAWFMT_TEMP10X
},
232 const unsigned num_format_names
= sizeof(format_names
)/sizeof(format_names
[0]);
234 // Table to map old to new '-v' option arguments
235 const char * map_old_vendor_opts
[][2] = {
236 { "9,halfminutes" , "9,halfmin2hour,Power_On_Half_Minutes"},
237 { "9,minutes" , "9,min2hour,Power_On_Minutes"},
238 { "9,seconds" , "9,sec2hour,Power_On_Seconds"},
239 { "9,temp" , "9,tempminmax,Temperature_Celsius"},
240 {"192,emergencyretractcyclect" , "192,raw48,Emerg_Retract_Cycle_Ct"},
241 {"193,loadunload" , "193,raw24/raw24"},
242 {"194,10xCelsius" , "194,temp10x,Temperature_Celsius_x10"},
243 {"194,unknown" , "194,raw48,Unknown_Attribute"},
244 {"197,increasing" , "197,raw48+,Total_Pending_Sectors"}, // '+' sets flag
245 {"198,offlinescanuncsectorct" , "198,raw48,Offline_Scan_UNC_SectCt"}, // see also get_unc_attr_id() above
246 {"198,increasing" , "198,raw48+,Total_Offl_Uncorrectabl"}, // '+' sets flag
247 {"200,writeerrorcount" , "200,raw48,Write_Error_Count"},
248 {"201,detectedtacount" , "201,raw48,Detected_TA_Count"},
249 {"220,temp" , "220,raw48,Temperature_Celsius"},
252 const unsigned num_old_vendor_opts
= sizeof(map_old_vendor_opts
)/sizeof(map_old_vendor_opts
[0]);
254 // Parse vendor attribute display def (-v option).
255 // Return false on error.
256 bool parse_attribute_def(const char * opt
, ata_vendor_attr_defs
& defs
,
257 ata_vendor_def_prior priority
)
259 // Map old -> new options
261 for (i
= 0; i
< num_old_vendor_opts
; i
++) {
262 if (!strcmp(opt
, map_old_vendor_opts
[i
][0])) {
263 opt
= map_old_vendor_opts
[i
][1];
269 int len
= strlen(opt
);
270 int id
= 0, n1
= -1, n2
= -1;
271 char fmtname
[32+1], attrname
[32+1];
274 if (!( sscanf(opt
, "N,%32[^,]%n,%32[^,]%n", fmtname
, &n1
, attrname
, &n2
) >= 1
275 && (n1
== len
|| n2
== len
)))
279 // "id,format[+][,name]"
280 if (!( sscanf(opt
, "%d,%32[^,]%n,%32[^,]%n", &id
, fmtname
, &n1
, attrname
, &n2
) >= 2
281 && 1 <= id
&& id
<= 255 && (n1
== len
|| n2
== len
)))
288 // For "-v 19[78],increasing" above
289 if (fmtname
[strlen(fmtname
)-1] == '+') {
290 fmtname
[strlen(fmtname
)-1] = 0;
291 flags
= ATTRFLAG_INCREASING
;
294 // Split "format[:byteorder]"
295 char byteorder
[8+1] = "";
296 if (strchr(fmtname
, ':')) {
297 if (!( sscanf(fmtname
, "%*[^:]%n:%8[012345rvwz]%n", &n1
, byteorder
, &n2
) >= 1
298 && n2
== (int)strlen(fmtname
)))
301 if (strchr(byteorder
, 'v'))
302 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
303 if (strchr(byteorder
, 'w'))
304 flags
|= ATTRFLAG_NO_WORSTVAL
;
309 if (i
>= num_format_names
)
310 return false; // Not found
311 if (!strcmp(fmtname
, format_names
[i
].name
))
314 ata_attr_raw_format format
= format_names
[i
].format
;
316 // 64-bit formats use the normalized and worst value bytes.
317 if (!*byteorder
&& (format
== RAWFMT_RAW64
|| format
== RAWFMT_HEX64
))
318 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
321 // "N,format" -> set format for all entries
322 for (i
= 0; i
< MAX_ATTRIBUTE_NUM
; i
++) {
323 if (defs
[i
].priority
>= priority
)
326 defs
[i
].name
= attrname
;
327 defs
[i
].priority
= priority
;
328 defs
[i
].raw_format
= format
;
329 defs
[i
].flags
= flags
;
330 strcpy(defs
[i
].byteorder
, byteorder
);
333 else if (defs
[id
].priority
<= priority
) {
334 // "id,format[,name]"
336 defs
[id
].name
= attrname
;
337 defs
[id
].raw_format
= format
;
338 defs
[id
].priority
= priority
;
339 defs
[id
].flags
= flags
;
340 strcpy(defs
[id
].byteorder
, byteorder
);
347 // Return a multiline string containing a list of valid arguments for
348 // parse_attribute_def(). The strings are preceeded by tabs and followed
349 // (except for the last) by newlines.
350 std::string
create_vendor_attribute_arg_list()
354 for (i
= 0; i
< num_format_names
; i
++)
355 s
+= strprintf("%s\tN,%s[:012345rvwz][,ATTR_NAME]",
356 (i
>0 ? "\n" : ""), format_names
[i
].name
);
357 for (i
= 0; i
< num_old_vendor_opts
; i
++)
358 s
+= strprintf("\n\t%s", map_old_vendor_opts
[i
][0]);
362 // swap two bytes. Point to low address
363 void swap2(char *location
){
365 *location
=*(location
+1);
370 // swap four bytes. Point to low address
371 void swap4(char *location
){
373 *location
=*(location
+3);
379 // swap eight bytes. Points to low address
380 void swap8(char *location
){
382 *location
=*(location
+7);
385 *(location
+1)=*(location
+6);
391 // Invalidate serial number and WWN and adjust checksum in IDENTIFY data
392 static void invalidate_serno(ata_identify_device
* id
)
394 unsigned char sum
= 0;
396 for (i
= 0; i
< sizeof(id
->serial_no
); i
++) {
397 sum
+= id
->serial_no
[i
]; sum
-= id
->serial_no
[i
] = 'X';
399 unsigned char * b
= (unsigned char *)id
;
400 for (i
= 2*108; i
< 2*112; i
++) { // words108-111: WWN
401 sum
+= b
[i
]; sum
-= b
[i
] = 0x00;
405 bool must_swap
= !!isbigendian();
407 swapx(id
->words088_255
+255-88);
409 if ((id
->words088_255
[255-88] & 0x00ff) == 0x00a5)
410 id
->words088_255
[255-88] += sum
<< 8;
413 swapx(id
->words088_255
+255-88);
417 static const char * const commandstrings
[]={
420 "SMART AUTOMATIC ATTRIBUTE SAVE",
421 "SMART IMMEDIATE OFFLINE",
422 "SMART AUTO OFFLINE",
424 "SMART STATUS CHECK",
425 "SMART READ ATTRIBUTE VALUES",
426 "SMART READ ATTRIBUTE THRESHOLDS",
429 "IDENTIFY PACKET DEVICE",
432 "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT
")\n"
436 static const char * preg(const ata_register
& r
, char * buf
)
441 sprintf(buf
, "0x%02x", r
.val()); return buf
;
444 static void print_regs(const char * prefix
, const ata_in_regs
& r
, const char * suffix
= "\n")
446 char bufs
[7][4+1+13];
447 pout("%s FR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, CMD=%s%s", prefix
,
448 preg(r
.features
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
449 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
450 preg(r
.command
, bufs
[6]), suffix
);
453 static void print_regs(const char * prefix
, const ata_out_regs
& r
, const char * suffix
= "\n")
455 char bufs
[7][4+1+13];
456 pout("%sERR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, STS=%s%s", prefix
,
457 preg(r
.error
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
458 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
459 preg(r
.status
, bufs
[6]), suffix
);
462 static void prettyprint(const unsigned char *p
, const char *name
){
463 pout("\n===== [%s] DATA START (BASE-16) =====\n", name
);
464 for (int i
=0; i
<512; i
+=16, p
+=16)
465 #define P(n) (' ' <= p[n] && p[n] <= '~' ? (int)p[n] : '.')
466 // print complete line to avoid slow tty output and extra lines in syslog.
467 pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x "
468 "%02x %02x %02x %02x %02x %02x %02x %02x"
469 " |%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c|"
472 p
[ 0], p
[ 1], p
[ 2], p
[ 3], p
[ 4], p
[ 5], p
[ 6], p
[ 7],
473 p
[ 8], p
[ 9], p
[10], p
[11], p
[12], p
[13], p
[14], p
[15],
474 P( 0), P( 1), P( 2), P( 3), P( 4), P( 5), P( 6), P( 7),
475 P( 8), P( 9), P(10), P(11), P(12), P(13), P(14), P(15),
478 pout("===== [%s] DATA END (512 Bytes) =====\n\n", name
);
481 // This function provides the pretty-print reporting for SMART
482 // commands: it implements the various -r "reporting" options for ATA
484 int smartcommandhandler(ata_device
* device
, smart_command_set command
, int select
, char *data
){
485 // TODO: Rework old stuff below
486 // This conditional is true for commands that return data
487 int getsdata
=(command
==PIDENTIFY
||
490 command
==READ_THRESHOLDS
||
491 command
==READ_VALUES
||
492 command
==CHECK_POWER_MODE
);
494 int sendsdata
=(command
==WRITE_LOG
);
496 // If reporting is enabled, say what the command will be before it's executed
498 // conditional is true for commands that use parameters
499 int usesparam
=(command
==READ_LOG
||
500 command
==AUTO_OFFLINE
||
502 command
==IMMEDIATE_OFFLINE
||
505 pout("\nREPORT-IOCTL: Device=%s Command=%s", device
->get_dev_name(), commandstrings
[command
]);
507 pout(" InputParameter=%d\n", select
);
512 if ((getsdata
|| sendsdata
) && !data
){
513 pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings
[command
]);
517 // The reporting is cleaner, and we will find coding bugs faster, if
518 // the commands that failed clearly return empty (zeroed) data
521 if (command
==CHECK_POWER_MODE
)
524 memset(data
, '\0', 512);
528 // if requested, pretty-print the input data structure
529 if (ata_debugmode
> 1 && sendsdata
)
530 //pout("REPORT-IOCTL: Device=%s Command=%s\n", device->get_dev_name(), commandstrings[command]);
531 prettyprint((unsigned char *)data
, commandstrings
[command
]);
533 // now execute the command
537 // Set common register values
539 default: // SMART commands
540 in
.in_regs
.command
= ATA_SMART_CMD
;
541 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
543 case IDENTIFY
: case PIDENTIFY
: case CHECK_POWER_MODE
: // Non SMART commands
546 // Set specific values
549 in
.in_regs
.command
= ATA_IDENTIFY_DEVICE
;
550 in
.set_data_in(data
, 1);
553 in
.in_regs
.command
= ATA_IDENTIFY_PACKET_DEVICE
;
554 in
.set_data_in(data
, 1);
556 case CHECK_POWER_MODE
:
557 in
.in_regs
.command
= ATA_CHECK_POWER_MODE
;
558 in
.out_needed
.sector_count
= true; // Powermode returned here
561 in
.in_regs
.features
= ATA_SMART_READ_VALUES
;
562 in
.set_data_in(data
, 1);
564 case READ_THRESHOLDS
:
565 in
.in_regs
.features
= ATA_SMART_READ_THRESHOLDS
;
566 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
567 in
.set_data_in(data
, 1);
570 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
571 in
.in_regs
.lba_low
= select
;
572 in
.set_data_in(data
, 1);
575 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
576 in
.in_regs
.lba_low
= select
;
577 in
.set_data_out(data
, 1);
580 in
.in_regs
.features
= ATA_SMART_ENABLE
;
581 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
584 in
.in_regs
.features
= ATA_SMART_DISABLE
;
585 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
588 in
.out_needed
.lba_high
= in
.out_needed
.lba_mid
= true; // Status returned here
590 in
.in_regs
.features
= ATA_SMART_STATUS
;
593 in
.in_regs
.features
= ATA_SMART_AUTO_OFFLINE
;
594 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
597 in
.in_regs
.features
= ATA_SMART_AUTOSAVE
;
598 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
600 case IMMEDIATE_OFFLINE
:
601 in
.in_regs
.features
= ATA_SMART_IMMEDIATE_OFFLINE
;
602 in
.in_regs
.lba_low
= select
;
605 pout("Unrecognized command %d in smartcommandhandler()\n"
606 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
607 device
->set_err(ENOSYS
);
612 print_regs(" Input: ", in
.in_regs
,
613 (in
.direction
==ata_cmd_in::data_in
? " IN\n":
614 in
.direction
==ata_cmd_in::data_out
? " OUT\n":"\n"));
618 int64_t start_usec
= -1;
620 start_usec
= smi()->get_timer_usec();
622 bool ok
= device
->ata_pass_through(in
, out
);
624 if (start_usec
>= 0) {
625 int64_t duration_usec
= smi()->get_timer_usec() - start_usec
;
626 if (duration_usec
>= 500)
627 pout(" [Duration: %.3fs]\n", duration_usec
/ 1000000.0);
630 if (ata_debugmode
&& out
.out_regs
.is_set())
631 print_regs(" Output: ", out
.out_regs
);
633 if (ok
) switch (command
) {
637 case CHECK_POWER_MODE
:
638 if (out
.out_regs
.sector_count
.is_set()) {
639 data
[0] = out
.out_regs
.sector_count
;
643 pout("CHECK POWER MODE: incomplete response, ATA output registers missing\n");
644 device
->set_err(ENOSYS
);
649 // Cyl low and Cyl high unchanged means "Good SMART status"
650 if ((out
.out_regs
.lba_high
== SMART_CYL_HI
) &&
651 (out
.out_regs
.lba_mid
== SMART_CYL_LOW
))
653 // These values mean "Bad SMART status"
654 else if ((out
.out_regs
.lba_high
== SRET_STATUS_HI_EXCEEDED
) &&
655 (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
))
657 else if (out
.out_regs
.lba_mid
== SMART_CYL_LOW
) {
660 pout("SMART STATUS RETURN: half healthy response sequence, "
661 "probable SAT/USB truncation\n");
662 } else if (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
) {
665 pout("SMART STATUS RETURN: half unhealthy response sequence, "
666 "probable SAT/USB truncation\n");
668 else if (!out
.out_regs
.is_set()) {
669 pout("SMART STATUS RETURN: incomplete response, ATA output registers missing\n");
670 device
->set_err(ENOSYS
);
674 // We haven't gotten output that makes sense; print out some debugging info
675 pout("Error SMART Status command failed\n");
676 pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE
);
677 pout("Register values returned from SMART Status command are:\n");
678 print_regs(" ", out
.out_regs
);
679 device
->set_err(EIO
);
686 // If requested, invalidate serial number before any printing is done
687 if ((command
== IDENTIFY
|| command
== PIDENTIFY
) && !retval
&& dont_print_serial_number
)
688 invalidate_serno((ata_identify_device
*)data
);
690 // If reporting is enabled, say what output was produced by the command
692 if (device
->get_errno())
693 pout("REPORT-IOCTL: Device=%s Command=%s returned %d errno=%d [%s]\n",
694 device
->get_dev_name(), commandstrings
[command
], retval
,
695 device
->get_errno(), device
->get_errmsg());
697 pout("REPORT-IOCTL: Device=%s Command=%s returned %d\n",
698 device
->get_dev_name(), commandstrings
[command
], retval
);
700 // if requested, pretty-print the output data structure
701 if (ata_debugmode
> 1 && getsdata
) {
702 if (command
==CHECK_POWER_MODE
)
703 pout("Sector Count Register (BASE-16): %02x\n", (unsigned char)(*data
));
705 prettyprint((unsigned char *)data
, commandstrings
[command
]);
712 // Get capacity and sector sizes from IDENTIFY data
713 void ata_get_size_info(const ata_identify_device
* id
, ata_size_info
& sizes
)
715 sizes
.sectors
= sizes
.capacity
= 0;
716 sizes
.log_sector_size
= sizes
.phy_sector_size
= 0;
717 sizes
.log_sector_offset
= 0;
719 // Return if no LBA support
720 if (!(id
->words047_079
[49-47] & 0x0200))
723 // Determine 28-bit LBA capacity
724 unsigned lba28
= (unsigned)id
->words047_079
[61-47] << 16
725 | (unsigned)id
->words047_079
[60-47] ;
727 // Determine 48-bit LBA capacity if supported
729 if ((id
->command_set_2
& 0xc400) == 0x4400)
730 lba48
= (uint64_t)id
->words088_255
[103-88] << 48
731 | (uint64_t)id
->words088_255
[102-88] << 32
732 | (uint64_t)id
->words088_255
[101-88] << 16
733 | (uint64_t)id
->words088_255
[100-88] ;
735 // Return if capacity unknown (ATAPI CD/DVD)
736 if (!(lba28
|| lba48
))
739 // Determine sector sizes
740 sizes
.log_sector_size
= sizes
.phy_sector_size
= 512;
742 unsigned short word106
= id
->words088_255
[106-88];
743 if ((word106
& 0xc000) == 0x4000) {
744 // Long Logical/Physical Sectors (LLS/LPS) ?
745 if (word106
& 0x1000)
746 // Logical sector size is specified in 16-bit words
747 sizes
.log_sector_size
= sizes
.phy_sector_size
=
748 ((id
->words088_255
[118-88] << 16) | id
->words088_255
[117-88]) << 1;
750 if (word106
& 0x2000)
751 // Physical sector size is multiple of logical sector size
752 sizes
.phy_sector_size
<<= (word106
& 0x0f);
754 unsigned short word209
= id
->words088_255
[209-88];
755 if ((word209
& 0xc000) == 0x4000)
756 sizes
.log_sector_offset
= (word209
& 0x3fff) * sizes
.log_sector_size
;
759 // Some early 4KiB LLS disks (Samsung N3U-3) return bogus lba28 value
760 if (lba48
>= lba28
|| (lba48
&& sizes
.log_sector_size
> 512))
761 sizes
.sectors
= lba48
;
763 sizes
.sectors
= lba28
;
765 sizes
.capacity
= sizes
.sectors
* sizes
.log_sector_size
;
768 // This function computes the checksum of a single disk sector (512
769 // bytes). Returns zero if checksum is OK, nonzero if the checksum is
770 // incorrect. The size (512) is correct for all SMART structures.
771 unsigned char checksum(const void * data
)
773 unsigned char sum
= 0;
774 for (int i
= 0; i
< 512; i
++)
775 sum
+= ((const unsigned char *)data
)[i
];
779 // Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
781 static void swapbytes(char * out
, const char * in
, size_t n
)
783 for (size_t i
= 0; i
< n
; i
+= 2) {
789 // Copies in to out, but removes leading and trailing whitespace.
790 static void trim(char * out
, const char * in
)
792 // Find the first non-space character (maybe none).
795 for (i
= 0; in
[i
]; i
++)
796 if (!isspace((int)in
[i
])) {
802 // There are no non-space characters.
807 // Find the last non-space character.
808 for (i
= strlen(in
)-1; i
>= first
&& isspace((int)in
[i
]); i
--)
812 strncpy(out
, in
+first
, last
-first
+1);
813 out
[last
-first
+1] = '\0';
816 // Convenience function for formatting strings from ata_identify_device
817 void ata_format_id_string(char * out
, const unsigned char * in
, int n
)
819 bool must_swap
= true;
821 /* NetBSD kernel delivers IDENTIFY data in host byte order (but all else is LE) */
822 // TODO: Handle NetBSD case in os_netbsd.cpp
824 must_swap
= !must_swap
;
830 strncpy(tmp
, (const char *)in
, n
);
832 swapbytes(tmp
, (const char *)in
, n
);
837 // returns -1 if command fails or the device is in Sleep mode, else
838 // value of Sector Count register. Sector Count result values:
839 // 00h device is in Standby mode.
840 // 80h device is in Idle mode.
841 // FFh device is in Active mode or Idle mode.
843 int ataCheckPowerMode(ata_device
* device
) {
844 unsigned char result
;
846 if ((smartcommandhandler(device
, CHECK_POWER_MODE
, 0, (char *)&result
)))
849 if (result
!=0 && result
!=0x80 && result
!=0xff)
850 pout("ataCheckPowerMode(): ATA CHECK POWER MODE returned unknown Sector Count Register value %02x\n", result
);
855 // Issue a no-data ATA command with optional sector count register value
856 bool ata_nodata_command(ata_device
* device
, unsigned char command
,
857 int sector_count
/* = -1 */)
860 in
.in_regs
.command
= command
;
861 if (sector_count
>= 0)
862 in
.in_regs
.sector_count
= sector_count
;
864 return device
->ata_pass_through(in
);
867 // Issue SET FEATURES command with optional sector count register value
868 bool ata_set_features(ata_device
* device
, unsigned char features
,
869 int sector_count
/* = -1 */)
872 in
.in_regs
.command
= ATA_SET_FEATURES
;
873 in
.in_regs
.features
= features
;
874 if (sector_count
>= 0)
875 in
.in_regs
.sector_count
= sector_count
;
877 return device
->ata_pass_through(in
);
880 // Reads current Device Identity info (512 bytes) into buf. Returns 0
881 // if all OK. Returns -1 if no ATA Device identity can be
882 // established. Returns >0 if Device is ATA Packet Device (not SMART
883 // capable). The value of the integer helps identify the type of
884 // Packet device, which is useful so that the user can connect the
885 // formal device number with whatever object is inside their computer.
886 int ata_read_identity(ata_device
* device
, ata_identify_device
* buf
, bool fix_swapped_id
)
888 unsigned short *rawshort
=(unsigned short *)buf
;
889 unsigned char *rawbyte
=(unsigned char *)buf
;
891 // See if device responds either to IDENTIFY DEVICE or IDENTIFY
894 if ((smartcommandhandler(device
, IDENTIFY
, 0, (char *)buf
))){
895 if (smartcommandhandler(device
, PIDENTIFY
, 0, (char *)buf
)){
902 if (fix_swapped_id
) {
904 for (i
= 0; i
< sizeof(buf
->serial_no
)-1; i
+= 2)
905 swap2((char *)(buf
->serial_no
+i
));
906 for (i
= 0; i
< sizeof(buf
->fw_rev
)-1; i
+= 2)
907 swap2((char *)(buf
->fw_rev
+i
));
908 for (i
= 0; i
< sizeof(buf
->model
)-1; i
+= 2)
909 swap2((char *)(buf
->model
+i
));
913 // if machine is big-endian, swap byte order as needed
914 // NetBSD kernel delivers IDENTIFY data in host byte order
915 // TODO: Handle NetBSD case in os_netbsd.cpp
918 // swap various capability words that are needed
920 swap2((char *)(buf
->words047_079
+i
));
922 for (i
=80; i
<=87; i
++)
923 swap2((char *)(rawshort
+i
));
925 for (i
=0; i
<168; i
++)
926 swap2((char *)(buf
->words088_255
+i
));
930 // If there is a checksum there, validate it
931 if ((rawshort
[255] & 0x00ff) == 0x00a5 && checksum(rawbyte
))
932 checksumwarning("Drive Identity Structure");
934 // AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
935 // T13/1699-D Revision 6a (Final Draft), September 6, 2008.
936 // Sections 7.16.7 and 7.17.6:
938 // Word 0 of IDENTIFY DEVICE data:
939 // Bit 15 = 0 : ATA device
941 // Word 0 of IDENTIFY PACKET DEVICE data:
942 // Bits 15:14 = 10b : ATAPI device
943 // Bits 15:14 = 11b : Reserved
944 // Bits 12:8 : Device type (SPC-4, e.g 0x05 = CD/DVD)
946 // CF+ and CompactFlash Specification Revision 4.0, May 24, 2006.
949 // Word 0 of IDENTIFY DEVICE data:
950 // 848Ah = Signature for CompactFlash Storage Card
951 // 044Ah = Alternate value turns on ATA device while preserving all retired bits
952 // 0040h = Alternate value turns on ATA device while zeroing all retired bits
954 // Assume ATA if IDENTIFY DEVICE returns CompactFlash Signature
955 if (!packet
&& rawbyte
[1] == 0x84 && rawbyte
[0] == 0x8a)
958 // If this is a PACKET DEVICE, return device type
959 if (rawbyte
[1] & 0x80)
960 return 1+(rawbyte
[1] & 0x1f);
962 // Not a PACKET DEVICE
966 // Returns ATA version as an integer, and a pointer to a string
967 // describing which revision. Note that Revision 0 of ATA-3 does NOT
968 // support SMART. For this one case we return -3 rather than +3 as
969 // the version number. See notes above.
970 int ataVersionInfo(const char ** description
, const ata_identify_device
* drive
, unsigned short * minor
)
972 // get major and minor ATA revision numbers
973 unsigned short major
= drive
->major_rev_num
;
974 *minor
=drive
->minor_rev_num
;
976 // First check if device has ANY ATA version information in it
977 if (major
==NOVAL_0
|| major
==NOVAL_1
) {
979 return 0; // No info found
982 // The minor revision number has more information - try there first
983 if (*minor
&& (*minor
<=MINOR_MAX
)){
984 int std
= actual_ver
[*minor
];
986 *description
=minor_str
[*minor
];
991 // Try new ATA-8 ACS minor revision numbers.
992 // Table 55 of T13/2015-D Revision 4a (ACS-2), December 9, 2010.
993 // (not in actual_ver/minor_str to avoid large sparse tables)
996 case 0x0027: desc
= "ATA-8-ACS revision 3c"; break;
997 case 0x0028: desc
= "ATA-8-ACS revision 6"; break;
998 case 0x0029: desc
= "ATA-8-ACS revision 4"; break;
999 case 0x0031: desc
= "ACS-2 revision 2"; break;
1000 case 0x0033: desc
= "ATA-8-ACS revision 3e"; break;
1001 case 0x0039: desc
= "ATA-8-ACS revision 4c"; break;
1002 case 0x0042: desc
= "ATA-8-ACS revision 3f"; break;
1003 case 0x0052: desc
= "ATA-8-ACS revision 3b"; break;
1004 case 0x0107: desc
= "ATA-8-ACS revision 2d"; break;
1005 case 0x0110: desc
= "ACS-2 revision 3"; break;
1006 default: desc
= 0; break;
1009 *description
= desc
;
1013 // HDPARM has a very complicated algorithm from here on. Since SMART only
1014 // exists on ATA-3 and later standards, let's punt on this. If you don't
1015 // like it, please fix it. The code's in CVS.
1017 for (i
=15; i
>0; i
--)
1018 if (major
& (0x1<<i
))
1028 // Get World Wide Name (WWN) fields.
1029 // Return NAA field or -1 if WWN is unsupported.
1030 // Table 34 of T13/1699-D Revision 6a (ATA8-ACS), September 6, 2008.
1031 // (WWN was introduced in ATA/ATAPI-7 and is mandatory since ATA8-ACS Revision 3b)
1032 int ata_get_wwn(const ata_identify_device
* id
, unsigned & oui
, uint64_t & unique_id
)
1034 // Don't use word 84 to be compatible with some older ATA-7 disks
1035 unsigned short word087
= id
->csf_default
;
1036 if ((word087
& 0xc100) != 0x4100)
1037 return -1; // word not valid or WWN support bit 8 not set
1039 unsigned short word108
= id
->words088_255
[108-88];
1040 unsigned short word109
= id
->words088_255
[109-88];
1041 unsigned short word110
= id
->words088_255
[110-88];
1042 unsigned short word111
= id
->words088_255
[111-88];
1044 oui
= ((word108
& 0x0fff) << 12) | (word109
>> 4);
1045 unique_id
= ((uint64_t)(word109
& 0xf) << 32)
1046 | (unsigned)((word110
<< 16) | word111
);
1047 return (word108
>> 12);
1050 // returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
1051 int ataSmartSupport(const ata_identify_device
* drive
)
1053 unsigned short word82
=drive
->command_set_1
;
1054 unsigned short word83
=drive
->command_set_2
;
1056 // check if words 82/83 contain valid info
1057 if ((word83
>>14) == 0x01)
1058 // return value of SMART support bit
1059 return word82
& 0x0001;
1061 // since we can're rely on word 82, we don't know if SMART supported
1065 // returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
1066 int ataIsSmartEnabled(const ata_identify_device
* drive
)
1068 unsigned short word85
=drive
->cfs_enable_1
;
1069 unsigned short word87
=drive
->csf_default
;
1071 // check if words 85/86/87 contain valid info
1072 if ((word87
>>14) == 0x01)
1073 // return value of SMART enabled bit
1074 return word85
& 0x0001;
1076 // Since we can't rely word85, we don't know if SMART is enabled.
1081 // Reads SMART attributes into *data
1082 int ataReadSmartValues(ata_device
* device
, struct ata_smart_values
*data
){
1084 if (smartcommandhandler(device
, READ_VALUES
, 0, (char *)data
)){
1085 pout("Error SMART Values Read failed: %s\n", device
->get_errmsg());
1091 checksumwarning("SMART Attribute Data Structure");
1093 // swap endian order if needed
1096 swap2((char *)&(data
->revnumber
));
1097 swap2((char *)&(data
->total_time_to_complete_off_line
));
1098 swap2((char *)&(data
->smart_capability
));
1099 swapx(&data
->extend_test_completion_time_w
);
1100 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
1101 struct ata_smart_attribute
*x
=data
->vendor_attributes
+i
;
1102 swap2((char *)&(x
->flags
));
1110 // This corrects some quantities that are byte reversed in the SMART
1112 static void fixsamsungselftestlog(ata_smart_selftestlog
* data
)
1114 // bytes 508/509 (numbered from 0) swapped (swap of self-test index
1115 // with one byte of reserved.
1116 swap2((char *)&(data
->mostrecenttest
));
1118 // LBA low register (here called 'selftestnumber", containing
1119 // information about the TYPE of the self-test) is byte swapped with
1120 // Self-test execution status byte. These are bytes N, N+1 in the
1122 for (int i
= 0; i
< 21; i
++)
1123 swap2((char *)&(data
->selftest_struct
[i
].selftestnumber
));
1128 // Reads the Self Test Log (log #6)
1129 int ataReadSelfTestLog (ata_device
* device
, ata_smart_selftestlog
* data
,
1130 unsigned char fix_firmwarebug
)
1133 // get data from device
1134 if (smartcommandhandler(device
, READ_LOG
, 0x06, (char *)data
)){
1135 pout("Error SMART Error Self-Test Log Read failed: %s\n", device
->get_errmsg());
1139 // compute its checksum, and issue a warning if needed
1141 checksumwarning("SMART Self-Test Log Structure");
1143 // fix firmware bugs in self-test log
1144 if (fix_firmwarebug
== FIX_SAMSUNG
)
1145 fixsamsungselftestlog(data
);
1147 // swap endian order if needed
1150 swap2((char*)&(data
->revnumber
));
1151 for (i
=0; i
<21; i
++){
1152 struct ata_smart_selftestlog_struct
*x
=data
->selftest_struct
+i
;
1153 swap2((char *)&(x
->timestamp
));
1154 swap4((char *)&(x
->lbafirstfailure
));
1161 // Print checksum warning for multi sector log
1162 static void check_multi_sector_sum(const void * data
, unsigned nsectors
, const char * msg
)
1165 for (unsigned i
= 0; i
< nsectors
; i
++) {
1166 if (checksum((const unsigned char *)data
+ i
*512))
1171 checksumwarning(msg
);
1173 checksumwarning(strprintf("%s (%u/%u)", msg
, errs
, nsectors
).c_str());
1177 // Read SMART Extended Self-test Log
1178 bool ataReadExtSelfTestLog(ata_device
* device
, ata_smart_extselftestlog
* log
,
1181 if (!ataReadLogExt(device
, 0x07, 0x00, 0, log
, nsectors
))
1184 check_multi_sector_sum(log
, nsectors
, "SMART Extended Self-test Log Structure");
1186 if (isbigendian()) {
1187 swapx(&log
->log_desc_index
);
1188 for (unsigned i
= 0; i
< nsectors
; i
++) {
1189 for (unsigned j
= 0; j
< 19; j
++)
1190 swapx(&log
->log_descs
[i
].timestamp
);
1197 // Read GP Log page(s)
1198 bool ataReadLogExt(ata_device
* device
, unsigned char logaddr
,
1199 unsigned char features
, unsigned page
,
1200 void * data
, unsigned nsectors
)
1203 in
.in_regs
.command
= ATA_READ_LOG_EXT
;
1204 in
.in_regs
.features
= features
; // log specific
1205 in
.set_data_in_48bit(data
, nsectors
);
1206 in
.in_regs
.lba_low
= logaddr
;
1207 in
.in_regs
.lba_mid_16
= page
;
1209 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1210 if (nsectors
<= 1) {
1211 pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n",
1212 logaddr
, features
, page
, nsectors
, device
->get_errmsg());
1216 // Recurse to retry with single sectors,
1217 // multi-sector reads may not be supported by ioctl.
1218 for (unsigned i
= 0; i
< nsectors
; i
++) {
1219 if (!ataReadLogExt(device
, logaddr
,
1221 (char *)data
+ 512*i
, 1))
1229 // Read SMART Log page(s)
1230 bool ataReadSmartLog(ata_device
* device
, unsigned char logaddr
,
1231 void * data
, unsigned nsectors
)
1234 in
.in_regs
.command
= ATA_SMART_CMD
;
1235 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
1236 in
.set_data_in(data
, nsectors
);
1237 in
.in_regs
.lba_high
= SMART_CYL_HI
;
1238 in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
1239 in
.in_regs
.lba_low
= logaddr
;
1241 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1242 pout("ATA_SMART_READ_LOG failed: %s\n", device
->get_errmsg());
1250 // Reads the SMART or GPL Log Directory (log #0)
1251 int ataReadLogDirectory(ata_device
* device
, ata_smart_log_directory
* data
, bool gpl
)
1253 if (!gpl
) { // SMART Log directory
1254 if (smartcommandhandler(device
, READ_LOG
, 0x00, (char *)data
))
1257 else { // GP Log directory
1258 if (!ataReadLogExt(device
, 0x00, 0x00, 0, data
, 1))
1262 // swap endian order if needed
1264 swapx(&data
->logversion
);
1270 // Reads the selective self-test log (log #9)
1271 int ataReadSelectiveSelfTestLog(ata_device
* device
, struct ata_selective_self_test_log
*data
){
1273 // get data from device
1274 if (smartcommandhandler(device
, READ_LOG
, 0x09, (char *)data
)){
1275 pout("Error SMART Read Selective Self-Test Log failed: %s\n", device
->get_errmsg());
1279 // compute its checksum, and issue a warning if needed
1281 checksumwarning("SMART Selective Self-Test Log Structure");
1283 // swap endian order if needed
1286 swap2((char *)&(data
->logversion
));
1288 swap8((char *)&(data
->span
[i
].start
));
1289 swap8((char *)&(data
->span
[i
].end
));
1291 swap8((char *)&(data
->currentlba
));
1292 swap2((char *)&(data
->currentspan
));
1293 swap2((char *)&(data
->flags
));
1294 swap2((char *)&(data
->pendingtime
));
1297 if (data
->logversion
!= 1)
1298 pout("Note: selective self-test log revision number (%d) not 1 implies that no selective self-test has ever been run\n", data
->logversion
);
1303 // Writes the selective self-test log (log #9)
1304 int ataWriteSelectiveSelfTestLog(ata_device
* device
, ata_selective_selftest_args
& args
,
1305 const ata_smart_values
* sv
, uint64_t num_sectors
,
1306 const ata_selective_selftest_args
* prev_args
)
1308 // Disk size must be known
1310 pout("Disk size is unknown, unable to check selective self-test spans\n");
1315 struct ata_selective_self_test_log sstlog
, *data
=&sstlog
;
1316 unsigned char *ptr
=(unsigned char *)data
;
1317 if (ataReadSelectiveSelfTestLog(device
, data
)) {
1318 pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
1323 data
->logversion
= 1;
1325 // Host is NOT allowed to write selective self-test log if a selective
1326 // self-test is in progress.
1327 if (0<data
->currentspan
&& data
->currentspan
<6 && ((sv
->self_test_exec_status
)>>4)==15) {
1328 pout("Error SMART Selective or other Self-Test in progress.\n");
1332 // Set start/end values based on old spans for special -t select,... options
1334 for (i
= 0; i
< args
.num_spans
; i
++) {
1335 int mode
= args
.span
[i
].mode
;
1336 uint64_t start
= args
.span
[i
].start
;
1337 uint64_t end
= args
.span
[i
].end
;
1338 if (mode
== SEL_CONT
) {// redo or next dependig on last test status
1339 switch (sv
->self_test_exec_status
>> 4) {
1340 case 1: case 2: // Aborted/Interrupted by host
1341 pout("Continue Selective Self-Test: Redo last span\n");
1344 default: // All others
1345 pout("Continue Selective Self-Test: Start next span\n");
1351 if ( (mode
== SEL_REDO
|| mode
== SEL_NEXT
)
1352 && prev_args
&& i
< prev_args
->num_spans
1353 && !data
->span
[i
].start
&& !data
->span
[i
].end
) {
1354 // Some drives do not preserve the selective self-test log accross
1355 // power-cyles. If old span on drive is cleared use span provided
1356 // by caller. This is used by smartd (first span only).
1357 data
->span
[i
].start
= prev_args
->span
[i
].start
;
1358 data
->span
[i
].end
= prev_args
->span
[i
].end
;
1362 case SEL_RANGE
: // -t select,START-END
1364 case SEL_REDO
: // -t select,redo... => Redo current
1365 start
= data
->span
[i
].start
;
1366 if (end
> 0) { // -t select,redo+SIZE
1367 end
--; end
+= start
; // [oldstart, oldstart+SIZE)
1369 else // -t select,redo
1370 end
= data
->span
[i
].end
; // [oldstart, oldend]
1372 case SEL_NEXT
: // -t select,next... => Do next
1373 if (data
->span
[i
].end
== 0) {
1374 start
= end
= 0; break; // skip empty spans
1376 start
= data
->span
[i
].end
+ 1;
1377 if (start
>= num_sectors
)
1378 start
= 0; // wrap around
1379 if (end
> 0) { // -t select,next+SIZE
1380 end
--; end
+= start
; // (oldend, oldend+SIZE]
1382 else { // -t select,next
1383 uint64_t oldsize
= data
->span
[i
].end
- data
->span
[i
].start
+ 1;
1384 end
= start
+ oldsize
- 1; // (oldend, oldend+oldsize]
1385 if (end
>= num_sectors
) {
1386 // Adjust size to allow round-robin testing without future size decrease
1387 uint64_t spans
= (num_sectors
+ oldsize
-1) / oldsize
;
1388 uint64_t newsize
= (num_sectors
+ spans
-1) / spans
;
1389 uint64_t newstart
= num_sectors
- newsize
, newend
= num_sectors
- 1;
1390 pout("Span %d changed from %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors)\n",
1391 i
, start
, end
, oldsize
);
1392 pout(" to %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors) (%"PRIu64
" spans)\n",
1393 newstart
, newend
, newsize
, spans
);
1394 start
= newstart
; end
= newend
;
1399 pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode
);
1403 if (start
< num_sectors
&& num_sectors
<= end
) {
1404 if (end
!= ~(uint64_t)0) // -t select,N-max
1405 pout("Size of self-test span %d decreased according to disk size\n", i
);
1406 end
= num_sectors
- 1;
1408 if (!(start
<= end
&& end
< num_sectors
)) {
1409 pout("Invalid selective self-test span %d: %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors)\n",
1410 i
, start
, end
, num_sectors
);
1413 // Return the actual mode and range to caller.
1414 args
.span
[i
].mode
= mode
;
1415 args
.span
[i
].start
= start
;
1416 args
.span
[i
].end
= end
;
1421 memset(data
->span
+i
, 0, sizeof(struct test_span
));
1423 // Set spans for testing
1424 for (i
= 0; i
< args
.num_spans
; i
++){
1425 data
->span
[i
].start
= args
.span
[i
].start
;
1426 data
->span
[i
].end
= args
.span
[i
].end
;
1429 // host must initialize to zero before initiating selective self-test
1431 data
->currentspan
=0;
1433 // Perform off-line scan after selective test?
1434 if (args
.scan_after_select
== 1)
1436 data
->flags
&= ~SELECTIVE_FLAG_DOSCAN
;
1437 else if (args
.scan_after_select
== 2)
1439 data
->flags
|= SELECTIVE_FLAG_DOSCAN
;
1441 // Must clear active and pending flags before writing
1442 data
->flags
&= ~(SELECTIVE_FLAG_ACTIVE
);
1443 data
->flags
&= ~(SELECTIVE_FLAG_PENDING
);
1445 // modify pending time?
1446 if (args
.pending_time
)
1447 data
->pendingtime
= (unsigned short)(args
.pending_time
-1);
1449 // Set checksum to zero, then compute checksum
1451 unsigned char cksum
=0;
1452 for (i
=0; i
<512; i
++)
1456 data
->checksum
=cksum
;
1458 // swap endian order if needed
1460 swap2((char *)&(data
->logversion
));
1461 for (int b
= 0; b
< 5; b
++) {
1462 swap8((char *)&(data
->span
[b
].start
));
1463 swap8((char *)&(data
->span
[b
].end
));
1465 swap8((char *)&(data
->currentlba
));
1466 swap2((char *)&(data
->currentspan
));
1467 swap2((char *)&(data
->flags
));
1468 swap2((char *)&(data
->pendingtime
));
1471 // write new selective self-test log
1472 if (smartcommandhandler(device
, WRITE_LOG
, 0x09, (char *)data
)){
1473 pout("Error Write Selective Self-Test Log failed: %s\n", device
->get_errmsg());
1480 // This corrects some quantities that are byte reversed in the SMART
1482 static void fixsamsungerrorlog(ata_smart_errorlog
* data
)
1484 // FIXED IN SAMSUNG -25 FIRMWARE???
1485 // Device error count in bytes 452-3
1486 swap2((char *)&(data
->ata_error_count
));
1488 // FIXED IN SAMSUNG -22a FIRMWARE
1489 // step through 5 error log data structures
1490 for (int i
= 0; i
< 5; i
++){
1491 // step through 5 command data structures
1492 for (int j
= 0; j
< 5; j
++)
1493 // Command data structure 4-byte millisec timestamp. These are
1494 // bytes (N+8, N+9, N+10, N+11).
1495 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1496 // Error data structure two-byte hour life timestamp. These are
1497 // bytes (N+28, N+29).
1498 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1503 // NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
1504 static void fixsamsungerrorlog2(ata_smart_errorlog
* data
)
1506 // Device error count in bytes 452-3
1507 swap2((char *)&(data
->ata_error_count
));
1511 // Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1512 // Error Log is #2, and the Extended Comprehensive SMART Error log is
1514 int ataReadErrorLog (ata_device
* device
, ata_smart_errorlog
*data
,
1515 unsigned char fix_firmwarebug
)
1518 // get data from device
1519 if (smartcommandhandler(device
, READ_LOG
, 0x01, (char *)data
)){
1520 pout("Error SMART Error Log Read failed: %s\n", device
->get_errmsg());
1524 // compute its checksum, and issue a warning if needed
1526 checksumwarning("SMART ATA Error Log Structure");
1528 // Some disks have the byte order reversed in some SMART Summary
1529 // Error log entries
1530 if (fix_firmwarebug
== FIX_SAMSUNG
)
1531 fixsamsungerrorlog(data
);
1532 else if (fix_firmwarebug
== FIX_SAMSUNG2
)
1533 fixsamsungerrorlog2(data
);
1535 // swap endian order if needed
1539 // Device error count in bytes 452-3
1540 swap2((char *)&(data
->ata_error_count
));
1542 // step through 5 error log data structures
1543 for (i
=0; i
<5; i
++){
1544 // step through 5 command data structures
1546 // Command data structure 4-byte millisec timestamp
1547 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1548 // Error data structure life timestamp
1549 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1556 // Read Extended Comprehensive Error Log
1557 bool ataReadExtErrorLog(ata_device
* device
, ata_smart_exterrlog
* log
,
1560 if (!ataReadLogExt(device
, 0x03, 0x00, 0, log
, nsectors
))
1563 check_multi_sector_sum(log
, nsectors
, "SMART Extended Comprehensive Error Log Structure");
1565 if (isbigendian()) {
1566 swapx(&log
->device_error_count
);
1567 swapx(&log
->error_log_index
);
1569 for (unsigned i
= 0; i
< nsectors
; i
++) {
1570 for (unsigned j
= 0; j
< 4; j
++)
1571 swapx(&log
->error_logs
[i
].commands
[j
].timestamp
);
1572 swapx(&log
->error_logs
[i
].error
.timestamp
);
1580 int ataReadSmartThresholds (ata_device
* device
, struct ata_smart_thresholds_pvt
*data
){
1582 // get data from device
1583 if (smartcommandhandler(device
, READ_THRESHOLDS
, 0, (char *)data
)){
1584 pout("Error SMART Thresholds Read failed: %s\n", device
->get_errmsg());
1588 // compute its checksum, and issue a warning if needed
1590 checksumwarning("SMART Attribute Thresholds Structure");
1592 // swap endian order if needed
1594 swap2((char *)&(data
->revnumber
));
1599 int ataEnableSmart (ata_device
* device
){
1600 if (smartcommandhandler(device
, ENABLE
, 0, NULL
)){
1601 pout("Error SMART Enable failed: %s\n", device
->get_errmsg());
1607 int ataDisableSmart (ata_device
* device
){
1609 if (smartcommandhandler(device
, DISABLE
, 0, NULL
)){
1610 pout("Error SMART Disable failed: %s\n", device
->get_errmsg());
1616 int ataEnableAutoSave(ata_device
* device
){
1617 if (smartcommandhandler(device
, AUTOSAVE
, 241, NULL
)){
1618 pout("Error SMART Enable Auto-save failed: %s\n", device
->get_errmsg());
1624 int ataDisableAutoSave(ata_device
* device
){
1626 if (smartcommandhandler(device
, AUTOSAVE
, 0, NULL
)){
1627 pout("Error SMART Disable Auto-save failed: %s\n", device
->get_errmsg());
1633 // In *ALL* ATA standards the Enable/Disable AutoOffline command is
1634 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1635 // vendors still support it for backwards compatibility. IBM documents
1636 // it for some drives.
1637 int ataEnableAutoOffline (ata_device
* device
){
1639 /* timer hard coded to 4 hours */
1640 if (smartcommandhandler(device
, AUTO_OFFLINE
, 248, NULL
)){
1641 pout("Error SMART Enable Automatic Offline failed: %s\n", device
->get_errmsg());
1647 // Another Obsolete Command. See comments directly above, associated
1648 // with the corresponding Enable command.
1649 int ataDisableAutoOffline (ata_device
* device
){
1651 if (smartcommandhandler(device
, AUTO_OFFLINE
, 0, NULL
)){
1652 pout("Error SMART Disable Automatic Offline failed: %s\n", device
->get_errmsg());
1658 // If SMART is enabled, supported, and working, then this call is
1659 // guaranteed to return 1, else zero. Note that it should return 1
1660 // regardless of whether the disk's SMART status is 'healthy' or
1662 int ataDoesSmartWork(ata_device
* device
){
1663 int retval
=smartcommandhandler(device
, STATUS
, 0, NULL
);
1671 // This function uses a different interface (DRIVE_TASK) than the
1672 // other commands in this file.
1673 int ataSmartStatus2(ata_device
* device
){
1674 return smartcommandhandler(device
, STATUS_CHECK
, 0, NULL
);
1677 // This is the way to execute ALL tests: offline, short self-test,
1678 // extended self test, with and without captive mode, etc.
1679 // TODO: Move to ataprint.cpp ?
1680 int ataSmartTest(ata_device
* device
, int testtype
, bool force
,
1681 const ata_selective_selftest_args
& selargs
,
1682 const ata_smart_values
* sv
, uint64_t num_sectors
)
1684 char cmdmsg
[128]; const char *type
, *captive
;
1685 int cap
, retval
, select
=0;
1687 // Boolean, if set, says test is captive
1688 cap
=testtype
& CAPTIVE_MASK
;
1690 // Set up strings that describe the type of test
1696 if (testtype
==OFFLINE_FULL_SCAN
)
1698 else if (testtype
==SHORT_SELF_TEST
|| testtype
==SHORT_CAPTIVE_SELF_TEST
)
1699 type
="Short self-test";
1700 else if (testtype
==EXTEND_SELF_TEST
|| testtype
==EXTEND_CAPTIVE_SELF_TEST
)
1701 type
="Extended self-test";
1702 else if (testtype
==CONVEYANCE_SELF_TEST
|| testtype
==CONVEYANCE_CAPTIVE_SELF_TEST
)
1703 type
="Conveyance self-test";
1704 else if ((select
=(testtype
==SELECTIVE_SELF_TEST
|| testtype
==SELECTIVE_CAPTIVE_SELF_TEST
)))
1705 type
="Selective self-test";
1709 // Check whether another test is already running
1710 if (type
&& (sv
->self_test_exec_status
>> 4) == 0xf) {
1712 pout("Can't start self-test without aborting current test (%d0%% remaining),\n"
1713 "%srun 'smartctl -X' to abort test.\n",
1714 sv
->self_test_exec_status
& 0x0f,
1715 (!select
? "add '-t force' option to override, or " : ""));
1722 // If doing a selective self-test, first use WRITE_LOG to write the
1723 // selective self-test log.
1724 ata_selective_selftest_args selargs_io
= selargs
; // filled with info about actual spans
1725 if (select
&& (retval
= ataWriteSelectiveSelfTestLog(device
, selargs_io
, sv
, num_sectors
))) {
1727 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1731 // Print ouf message that we are sending the command to test
1732 if (testtype
==ABORT_SELF_TEST
)
1733 sprintf(cmdmsg
,"Abort SMART off-line mode self-test routine");
1735 sprintf(cmdmsg
, "SMART EXECUTE OFF-LINE IMMEDIATE subcommand 0x%02x", testtype
);
1737 sprintf(cmdmsg
,"Execute SMART %s routine immediately in %s mode",type
,captive
);
1738 pout("Sending command: \"%s\".\n",cmdmsg
);
1742 pout("SPAN STARTING_LBA ENDING_LBA\n");
1743 for (i
= 0; i
< selargs_io
.num_spans
; i
++)
1744 pout(" %d %20"PRId64
" %20"PRId64
"\n", i
,
1745 selargs_io
.span
[i
].start
,
1746 selargs_io
.span
[i
].end
);
1749 // Now send the command to test
1750 if (smartcommandhandler(device
, IMMEDIATE_OFFLINE
, testtype
, NULL
)) {
1751 if (!(cap
&& device
->get_errno() == EIO
)) {
1752 pout("Command \"%s\" failed: %s\n", cmdmsg
, device
->get_errmsg());
1757 // Since the command succeeded, tell user
1758 if (testtype
==ABORT_SELF_TEST
)
1759 pout("Self-testing aborted!\n");
1761 pout("Drive command \"%s\" successful.\n", cmdmsg
);
1763 pout("Testing has begun%s.\n", (force
? " (previous test aborted)" : ""));
1768 /* Test Time Functions */
1769 int TestTime(const ata_smart_values
*data
, int testtype
)
1772 case OFFLINE_FULL_SCAN
:
1773 return (int) data
->total_time_to_complete_off_line
;
1774 case SHORT_SELF_TEST
:
1775 case SHORT_CAPTIVE_SELF_TEST
:
1776 return (int) data
->short_test_completion_time
;
1777 case EXTEND_SELF_TEST
:
1778 case EXTEND_CAPTIVE_SELF_TEST
:
1779 if (data
->extend_test_completion_time_b
== 0xff
1780 && data
->extend_test_completion_time_w
!= 0x0000
1781 && data
->extend_test_completion_time_w
!= 0xffff)
1782 return data
->extend_test_completion_time_w
; // ATA-8
1784 return data
->extend_test_completion_time_b
;
1785 case CONVEYANCE_SELF_TEST
:
1786 case CONVEYANCE_CAPTIVE_SELF_TEST
:
1787 return (int) data
->conveyance_test_completion_time
;
1793 // This function tells you both about the ATA error log and the
1794 // self-test error log capability (introduced in ATA-5). The bit is
1795 // poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1796 // SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1797 // word 84 and 87. Top two bits must match the pattern 01. BEFORE
1798 // ATA-6 these top two bits still had to match the pattern 01, but the
1799 // remaining bits were reserved (==0).
1800 int isSmartErrorLogCapable (const ata_smart_values
* data
, const ata_identify_device
* identity
)
1802 unsigned short word84
=identity
->command_set_extension
;
1803 unsigned short word87
=identity
->csf_default
;
1804 int isata6
=identity
->major_rev_num
& (0x01<<6);
1805 int isata7
=identity
->major_rev_num
& (0x01<<7);
1807 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x01))
1810 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x01))
1813 // otherwise we'll use the poorly documented capability bit
1814 return data
->errorlog_capability
& 0x01;
1817 // See previous function. If the error log exists then the self-test
1818 // log should (must?) also exist.
1819 int isSmartTestLogCapable (const ata_smart_values
* data
, const ata_identify_device
*identity
)
1821 unsigned short word84
=identity
->command_set_extension
;
1822 unsigned short word87
=identity
->csf_default
;
1823 int isata6
=identity
->major_rev_num
& (0x01<<6);
1824 int isata7
=identity
->major_rev_num
& (0x01<<7);
1826 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x02))
1829 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x02))
1833 // otherwise we'll use the poorly documented capability bit
1834 return data
->errorlog_capability
& 0x01;
1838 int isGeneralPurposeLoggingCapable(const ata_identify_device
*identity
)
1840 unsigned short word84
=identity
->command_set_extension
;
1841 unsigned short word87
=identity
->csf_default
;
1843 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1844 // cleared to zero, the contents of word 84 contains valid support
1845 // information. If not, support information is not valid in this
1847 if ((word84
>>14) == 0x01)
1848 // If bit 5 of word 84 is set to one, the device supports the
1849 // General Purpose Logging feature set.
1850 return (word84
& (0x01 << 5));
1852 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1853 // cleared to zero, the contents of words (87:85) contain valid
1854 // information. If not, information is not valid in these words.
1855 if ((word87
>>14) == 0x01)
1856 // If bit 5 of word 87 is set to one, the device supports
1857 // the General Purpose Logging feature set.
1858 return (word87
& (0x01 << 5));
1865 // SMART self-test capability is also indicated in bit 1 of DEVICE
1866 // IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1867 // However this was only introduced in ATA-6 (but self-test log was in
1869 int isSupportExecuteOfflineImmediate(const ata_smart_values
*data
)
1871 return data
->offline_data_collection_capability
& 0x01;
1874 // Note in the ATA-5 standard, the following bit is listed as "Vendor
1875 // Specific". So it may not be reliable. The only use of this that I
1876 // have found is in IBM drives, where it is well-documented. See for
1877 // example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1878 // hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
1879 int isSupportAutomaticTimer(const ata_smart_values
* data
)
1881 return data
->offline_data_collection_capability
& 0x02;
1883 int isSupportOfflineAbort(const ata_smart_values
*data
)
1885 return data
->offline_data_collection_capability
& 0x04;
1887 int isSupportOfflineSurfaceScan(const ata_smart_values
* data
)
1889 return data
->offline_data_collection_capability
& 0x08;
1891 int isSupportSelfTest (const ata_smart_values
* data
)
1893 return data
->offline_data_collection_capability
& 0x10;
1895 int isSupportConveyanceSelfTest(const ata_smart_values
* data
)
1897 return data
->offline_data_collection_capability
& 0x20;
1899 int isSupportSelectiveSelfTest(const ata_smart_values
* data
)
1901 return data
->offline_data_collection_capability
& 0x40;
1904 // Get attribute state
1905 ata_attr_state
ata_get_attr_state(const ata_smart_attribute
& attr
,
1907 const ata_smart_threshold_entry
* thresholds
,
1908 const ata_vendor_attr_defs
& defs
,
1909 unsigned char * threshval
/* = 0 */)
1912 return ATTRSTATE_NON_EXISTING
;
1914 // Normalized values (current,worst,threshold) not valid
1915 // if specified by '-v' option.
1916 // (Some SSD disks uses these bytes to store raw value).
1917 if (defs
[attr
.id
].flags
& ATTRFLAG_NO_NORMVAL
)
1918 return ATTRSTATE_NO_NORMVAL
;
1920 // Normally threshold is at same index as attribute
1922 if (thresholds
[i
].id
!= attr
.id
) {
1923 // Find threshold id in table
1924 for (i
= 0; thresholds
[i
].id
!= attr
.id
; ) {
1925 if (++i
>= NUMBER_ATA_SMART_ATTRIBUTES
)
1926 // Threshold id missing or thresholds cannot be read
1927 return ATTRSTATE_NO_THRESHOLD
;
1930 unsigned char threshold
= thresholds
[i
].threshold
;
1932 // Return threshold if requested
1934 *threshval
= threshold
;
1936 // Don't report a failed attribute if its threshold is 0.
1937 // ATA-3 (X3T13/2008D Revision 7b) declares 0x00 as the "always passing"
1938 // threshold (Later ATA versions declare all thresholds as "obsolete").
1939 // In practice, threshold value 0 is often used for usage attributes.
1941 return ATTRSTATE_OK
;
1943 // Failed now if current value is below threshold
1944 if (attr
.current
<= threshold
)
1945 return ATTRSTATE_FAILED_NOW
;
1947 // Failed in the past if worst value is below threshold
1948 if (!(defs
[attr
.id
].flags
& ATTRFLAG_NO_WORSTVAL
) && attr
.worst
<= threshold
)
1949 return ATTRSTATE_FAILED_PAST
;
1951 return ATTRSTATE_OK
;
1954 // Get default raw value print format
1955 static ata_attr_raw_format
get_default_raw_format(unsigned char id
)
1958 case 3: // Spin-up time
1959 return RAWFMT_RAW16_OPT_AVG16
;
1961 case 5: // Reallocated sector count
1962 case 196: // Reallocated event count
1963 return RAWFMT_RAW16_OPT_RAW16
;
1965 case 9: // Power on hours
1966 return RAWFMT_RAW24_OPT_RAW8
;
1968 case 190: // Temperature
1970 return RAWFMT_TEMPMINMAX
;
1973 return RAWFMT_RAW48
;
1977 // Get attribute raw value.
1978 uint64_t ata_get_attr_raw_value(const ata_smart_attribute
& attr
,
1979 const ata_vendor_attr_defs
& defs
)
1981 const ata_vendor_attr_defs::entry
& def
= defs
[attr
.id
];
1983 // Use default byteorder if not specified
1984 const char * byteorder
= def
.byteorder
;
1986 switch (def
.raw_format
) {
1989 byteorder
= "543210wv"; break;
1992 case RAWFMT_RAW24_DIV_RAW32
:
1993 case RAWFMT_MSEC24_HOUR32
:
1994 byteorder
= "r543210"; break;
1996 byteorder
= "543210"; break;
2000 // Build 64-bit value from selected bytes
2001 uint64_t rawvalue
= 0;
2002 for (int i
= 0; byteorder
[i
]; i
++) {
2004 switch (byteorder
[i
]) {
2005 case '0': b
= attr
.raw
[0]; break;
2006 case '1': b
= attr
.raw
[1]; break;
2007 case '2': b
= attr
.raw
[2]; break;
2008 case '3': b
= attr
.raw
[3]; break;
2009 case '4': b
= attr
.raw
[4]; break;
2010 case '5': b
= attr
.raw
[5]; break;
2011 case 'r': b
= attr
.reserv
; break;
2012 case 'v': b
= attr
.current
; break;
2013 case 'w': b
= attr
.worst
; break;
2014 default : b
= 0; break;
2016 rawvalue
<<= 8; rawvalue
|= b
;
2023 // Format attribute raw value.
2024 std::string
ata_format_attr_raw_value(const ata_smart_attribute
& attr
,
2025 const ata_vendor_attr_defs
& defs
)
2027 // Get 48 bit or 64 bit raw value
2028 uint64_t rawvalue
= ata_get_attr_raw_value(attr
, defs
);
2030 // Split into bytes and words
2031 unsigned char raw
[6];
2032 raw
[0] = (unsigned char) rawvalue
;
2033 raw
[1] = (unsigned char)(rawvalue
>> 8);
2034 raw
[2] = (unsigned char)(rawvalue
>> 16);
2035 raw
[3] = (unsigned char)(rawvalue
>> 24);
2036 raw
[4] = (unsigned char)(rawvalue
>> 32);
2037 raw
[5] = (unsigned char)(rawvalue
>> 40);
2039 word
[0] = raw
[0] | (raw
[1] << 8);
2040 word
[1] = raw
[2] | (raw
[3] << 8);
2041 word
[2] = raw
[4] | (raw
[5] << 8);
2044 ata_attr_raw_format format
= defs
[attr
.id
].raw_format
;
2045 if (format
== RAWFMT_DEFAULT
)
2046 format
= get_default_raw_format(attr
.id
);
2052 s
= strprintf("%d %d %d %d %d %d",
2053 raw
[5], raw
[4], raw
[3], raw
[2], raw
[1], raw
[0]);
2057 s
= strprintf("%u %u %u", word
[2], word
[1], word
[0]);
2063 s
= strprintf("%"PRIu64
, rawvalue
);
2067 s
= strprintf("0x%012"PRIx64
, rawvalue
);
2071 s
= strprintf("0x%014"PRIx64
, rawvalue
);
2075 s
= strprintf("0x%016"PRIx64
, rawvalue
);
2078 case RAWFMT_RAW16_OPT_RAW16
:
2079 s
= strprintf("%u", word
[0]);
2080 if (word
[1] || word
[2])
2081 s
+= strprintf(" (%u %u)", word
[2], word
[1]);
2084 case RAWFMT_RAW16_OPT_AVG16
:
2085 s
= strprintf("%u", word
[0]);
2087 s
+= strprintf(" (Average %u)", word
[1]);
2090 case RAWFMT_RAW24_OPT_RAW8
:
2091 s
= strprintf("%u", (unsigned)(rawvalue
& 0x00ffffffULL
));
2092 if (raw
[3] || raw
[4] || raw
[5])
2093 s
+= strprintf(" (%d %d %d)", raw
[5], raw
[4], raw
[3]);
2096 case RAWFMT_RAW24_DIV_RAW24
:
2097 s
= strprintf("%u/%u",
2098 (unsigned)(rawvalue
>> 24), (unsigned)(rawvalue
& 0x00ffffffULL
));
2101 case RAWFMT_RAW24_DIV_RAW32
:
2102 s
= strprintf("%u/%u",
2103 (unsigned)(rawvalue
>> 32), (unsigned)(rawvalue
& 0xffffffffULL
));
2106 case RAWFMT_MIN2HOUR
:
2109 int64_t temp
= word
[0]+(word
[1]<<16);
2110 int64_t tmp1
= temp
/60;
2111 int64_t tmp2
= temp
%60;
2112 s
= strprintf("%"PRIu64
"h+%02"PRIu64
"m", tmp1
, tmp2
);
2114 s
+= strprintf(" (%u)", word
[2]);
2118 case RAWFMT_SEC2HOUR
:
2121 int64_t hours
= rawvalue
/3600;
2122 int64_t minutes
= (rawvalue
-3600*hours
)/60;
2123 int64_t seconds
= rawvalue
%60;
2124 s
= strprintf("%"PRIu64
"h+%02"PRIu64
"m+%02"PRIu64
"s", hours
, minutes
, seconds
);
2128 case RAWFMT_HALFMIN2HOUR
:
2130 // 30-second counter
2131 int64_t hours
= rawvalue
/120;
2132 int64_t minutes
= (rawvalue
-120*hours
)/2;
2133 s
+= strprintf("%"PRIu64
"h+%02"PRIu64
"m", hours
, minutes
);
2137 case RAWFMT_MSEC24_HOUR32
:
2139 // hours + milliseconds
2140 unsigned hours
= (unsigned)(rawvalue
& 0xffffffffULL
);
2141 unsigned milliseconds
= (unsigned)(rawvalue
>> 32);
2142 unsigned seconds
= milliseconds
/ 1000;
2143 s
= strprintf("%uh+%02um+%02u.%03us",
2144 hours
, seconds
/ 60, seconds
% 60, milliseconds
% 1000);
2148 case RAWFMT_TEMPMINMAX
:
2151 // Search for possible min/max values
2152 // 00 HH 00 LL 00 TT (Hitachi/IBM)
2153 // 00 00 HH LL 00 TT (Maxtor, Samsung)
2154 // 00 00 00 HH LL TT (WDC)
2155 unsigned char lo
= 0, hi
= 0;
2157 for (int i
= 1; i
< 6; i
++) {
2165 hi
= lo
; lo
= raw
[i
];
2173 unsigned char t
= raw
[0];
2175 s
= strprintf("%d", t
);
2176 else if (cnt
== 2 && 0 < lo
&& lo
<= t
&& t
<= hi
&& hi
< 128)
2177 s
= strprintf("%d (Min/Max %d/%d)", t
, lo
, hi
);
2179 s
= strprintf("%d (%d %d %d %d %d)", t
, raw
[5], raw
[4], raw
[3], raw
[2], raw
[1]);
2183 case RAWFMT_TEMP10X
:
2184 // ten times temperature in Celsius
2185 s
= strprintf("%d.%d", word
[0]/10, word
[0]%10);
2189 s
= "?"; // Should not happen
2196 // Attribute names shouldn't be longer than 23 chars, otherwise they break the
2197 // output of smartctl.
2198 static const char * get_default_attr_name(unsigned char id
)
2202 return "Raw_Read_Error_Rate";
2204 return "Throughput_Performance";
2206 return "Spin_Up_Time";
2208 return "Start_Stop_Count";
2210 return "Reallocated_Sector_Ct";
2212 return "Read_Channel_Margin";
2214 return "Seek_Error_Rate";
2216 return "Seek_Time_Performance";
2218 return "Power_On_Hours";
2220 return "Spin_Retry_Count";
2222 return "Calibration_Retry_Count";
2224 return "Power_Cycle_Count";
2226 return "Read_Soft_Error_Rate";
2228 return "Program_Fail_Count_Chip";
2230 return "Erase_Fail_Count_Chip";
2232 return "Wear_Leveling_Count";
2234 return "Used_Rsvd_Blk_Cnt_Chip";
2236 return "Used_Rsvd_Blk_Cnt_Tot";
2238 return "Unused_Rsvd_Blk_Cnt_Tot";
2240 return "Program_Fail_Cnt_Total";
2242 return "Erase_Fail_Count_Total";
2244 return "Runtime_Bad_Block";
2246 return "End-to-End_Error";
2248 return "Reported_Uncorrect";
2250 return "Command_Timeout";
2252 return "High_Fly_Writes";
2254 // Western Digital uses this for temperature.
2255 // It's identical to Attribute 194 except that it
2256 // has a failure threshold set to correspond to the
2257 // max allowed operating temperature of the drive, which
2258 // is typically 55C. So if this attribute has failed
2259 // in the past, it indicates that the drive temp exceeded
2260 // 55C sometime in the past.
2261 return "Airflow_Temperature_Cel";
2263 return "G-Sense_Error_Rate";
2265 return "Power-Off_Retract_Count";
2267 return "Load_Cycle_Count";
2269 return "Temperature_Celsius";
2271 // Fujitsu: "ECC_On_The_Fly_Count";
2272 return "Hardware_ECC_Recovered";
2274 return "Reallocated_Event_Count";
2276 return "Current_Pending_Sector";
2278 return "Offline_Uncorrectable";
2280 return "UDMA_CRC_Error_Count";
2283 return "Multi_Zone_Error_Rate";
2285 return "Soft_Read_Error_Rate";
2287 // Fujitsu: "TA_Increase_Count"
2288 return "Data_Address_Mark_Errs";
2291 return "Run_Out_Cancel";
2292 // Maxtor: ECC Errors
2294 // Fujitsu: "Shock_Count_Write_Opern"
2295 return "Soft_ECC_Correction";
2297 // Fujitsu: "Shock_Rate_Write_Opern"
2298 return "Thermal_Asperity_Rate";
2301 return "Flying_Height";
2304 return "Spin_High_Current";
2310 return "Offline_Seek_Performnce";
2312 return "Disk_Shift";
2314 return "G-Sense_Error_Rate";
2316 return "Loaded_Hours";
2318 return "Load_Retry_Count";
2320 return "Load_Friction";
2322 return "Load_Cycle_Count";
2324 return "Load-in_Time";
2326 return "Torq-amp_Count";
2328 return "Power-off_Retract_Count";
2330 // seen in IBM DTPA-353750
2331 return "Head_Amplitude";
2333 return "Temperature_Celsius";
2335 // seen in Intel X25-E SSD
2336 return "Available_Reservd_Space";
2338 // seen in Intel X25-E SSD
2339 return "Media_Wearout_Indicator";
2341 return "Head_Flying_Hours";
2343 return "Total_LBAs_Written";
2345 return "Total_LBAs_Read";
2347 return "Read_Error_Retry_Rate";
2349 return "Free_Fall_Sensor";
2351 return "Unknown_Attribute";
2355 // Get attribute name
2356 std::string
ata_get_smart_attr_name(unsigned char id
, const ata_vendor_attr_defs
& defs
)
2358 if (!defs
[id
].name
.empty())
2359 return defs
[id
].name
;
2361 return get_default_attr_name(id
);
2364 // Find attribute index for attribute id, -1 if not found.
2365 int ata_find_attr_index(unsigned char id
, const ata_smart_values
& smartval
)
2369 for (int i
= 0; i
< NUMBER_ATA_SMART_ATTRIBUTES
; i
++) {
2370 if (smartval
.vendor_attributes
[i
].id
== id
)
2376 // Return Temperature Attribute raw value selected according to possible
2377 // non-default interpretations. If the Attribute does not exist, return 0
2378 unsigned char ata_return_temperature_value(const ata_smart_values
* data
, const ata_vendor_attr_defs
& defs
)
2380 for (int i
= 0; i
< 3; i
++) {
2381 static const unsigned char ids
[3] = {194, 9, 220};
2382 unsigned char id
= ids
[i
];
2383 const ata_attr_raw_format format
= defs
[id
].raw_format
;
2384 if (!( (id
== 194 && format
== RAWFMT_DEFAULT
)
2385 || format
== RAWFMT_TEMPMINMAX
|| format
== RAWFMT_TEMP10X
))
2387 int idx
= ata_find_attr_index(id
, *data
);
2390 uint64_t raw
= ata_get_attr_raw_value(data
->vendor_attributes
[idx
], defs
);
2392 // ignore possible min/max values in high words
2393 if (format
== RAWFMT_TEMP10X
) // -v N,temp10x
2394 temp
= ((unsigned short)raw
+ 5) / 10;
2396 temp
= (unsigned char)raw
;
2397 if (!(0 < temp
&& temp
< 128))
2401 // No valid attribute found
2407 int ataReadSCTStatus(ata_device
* device
, ata_sct_status_response
* sts
)
2409 // read SCT status via SMART log 0xe0
2410 memset(sts
, 0, sizeof(*sts
));
2411 if (smartcommandhandler(device
, READ_LOG
, 0xe0, (char *)sts
)){
2412 pout("Error Read SCT Status failed: %s\n", device
->get_errmsg());
2416 // swap endian order if needed
2418 swapx(&sts
->format_version
);
2419 swapx(&sts
->sct_version
);
2420 swapx(&sts
->sct_spec
);
2421 swapx(&sts
->ext_status_code
);
2422 swapx(&sts
->action_code
);
2423 swapx(&sts
->function_code
);
2424 swapx(&sts
->over_limit_count
);
2425 swapx(&sts
->under_limit_count
);
2428 // Check format version
2429 if (!(sts
->format_version
== 2 || sts
->format_version
== 3)) {
2430 pout("Error unknown SCT Status format version %u, should be 2 or 3.\n", sts
->format_version
);
2436 // Read SCT Temperature History Table and Status
2437 int ataReadSCTTempHist(ata_device
* device
, ata_sct_temperature_history_table
* tmh
,
2438 ata_sct_status_response
* sts
)
2440 // Check initial status
2441 if (ataReadSCTStatus(device
, sts
))
2444 // Do nothing if other SCT command is executing
2445 if (sts
->ext_status_code
== 0xffff) {
2446 pout("Another SCT command is executing, abort Read Data Table\n"
2447 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2448 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2452 ata_sct_data_table_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2453 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2454 cmd
.action_code
= 5; // Data table command
2455 cmd
.function_code
= 1; // Read table
2456 cmd
.table_id
= 2; // Temperature History Table
2458 // swap endian order if needed
2459 if (isbigendian()) {
2460 swapx(&cmd
.action_code
);
2461 swapx(&cmd
.function_code
);
2462 swapx(&cmd
.table_id
);
2465 // write command via SMART log page 0xe0
2466 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2467 pout("Error Write SCT Data Table command failed: %s\n", device
->get_errmsg());
2471 // read SCT data via SMART log page 0xe1
2472 memset(tmh
, 0, sizeof(*tmh
));
2473 if (smartcommandhandler(device
, READ_LOG
, 0xe1, (char *)tmh
)){
2474 pout("Error Read SCT Data Table failed: %s\n", device
->get_errmsg());
2478 // re-read and check SCT status
2479 if (ataReadSCTStatus(device
, sts
))
2482 if (!(sts
->ext_status_code
== 0 && sts
->action_code
== 5 && sts
->function_code
== 1)) {
2483 pout("Error unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2484 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2488 // swap endian order if needed
2490 swapx(&tmh
->format_version
);
2491 swapx(&tmh
->sampling_period
);
2492 swapx(&tmh
->interval
);
2495 // Check format version
2496 if (tmh
->format_version
!= 2) {
2497 pout("Error unknown SCT Temperature History Format Version (%u), should be 2.\n", tmh
->format_version
);
2503 // Set SCT Temperature Logging Interval
2504 int ataSetSCTTempInterval(ata_device
* device
, unsigned interval
, bool persistent
)
2506 // Check initial status
2507 ata_sct_status_response sts
;
2508 if (ataReadSCTStatus(device
, &sts
))
2511 // Do nothing if other SCT command is executing
2512 if (sts
.ext_status_code
== 0xffff) {
2513 pout("Another SCT command is executing, abort Feature Control\n"
2514 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2515 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2519 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2520 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2521 cmd
.action_code
= 4; // Feature Control command
2522 cmd
.function_code
= 1; // Set state
2523 cmd
.feature_code
= 3; // Temperature logging interval
2524 cmd
.state
= interval
;
2525 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2527 // swap endian order if needed
2528 if (isbigendian()) {
2529 swapx(&cmd
.action_code
);
2530 swapx(&cmd
.function_code
);
2531 swapx(&cmd
.feature_code
);
2533 swapx(&cmd
.option_flags
);
2536 // write command via SMART log page 0xe0
2537 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2538 pout("Error Write SCT Feature Control Command failed: %s\n", device
->get_errmsg());
2542 // re-read and check SCT status
2543 if (ataReadSCTStatus(device
, &sts
))
2546 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== 1)) {
2547 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2548 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2554 // Get/Set SCT Error Recovery Control
2555 static int ataGetSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
,
2556 bool set
, unsigned short & time_limit
)
2558 // Check initial status
2559 ata_sct_status_response sts
;
2560 if (ataReadSCTStatus(device
, &sts
))
2563 // Do nothing if other SCT command is executing
2564 if (sts
.ext_status_code
== 0xffff) {
2565 pout("Another SCT command is executing, abort Error Recovery Control\n"
2566 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2567 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2571 ata_sct_error_recovery_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2572 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2573 cmd
.action_code
= 3; // Error Recovery Control command
2574 cmd
.function_code
= (set
? 1 : 2); // 1=Set timer, 2=Get timer
2575 cmd
.selection_code
= type
; // 1=Read timer, 2=Write timer
2577 cmd
.time_limit
= time_limit
;
2579 // swap endian order if needed
2580 if (isbigendian()) {
2581 swapx(&cmd
.action_code
);
2582 swapx(&cmd
.function_code
);
2583 swapx(&cmd
.selection_code
);
2584 swapx(&cmd
.time_limit
);
2587 // write command via SMART log page 0xe0
2588 // TODO: Debug output
2590 in
.in_regs
.command
= ATA_SMART_CMD
;
2591 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
2592 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
2593 in
.in_regs
.lba_low
= 0xe0;
2594 in
.set_data_out(&cmd
, 1);
2597 // Time limit returned in ATA registers
2598 in
.out_needed
.sector_count
= in
.out_needed
.lba_low
= true;
2601 if (!device
->ata_pass_through(in
, out
)) {
2602 pout("Error Write SCT (%cet) Error Recovery Control Command failed: %s\n",
2603 (!set
? 'G' : 'S'), device
->get_errmsg());
2607 // re-read and check SCT status
2608 if (ataReadSCTStatus(device
, &sts
))
2611 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 3 && sts
.function_code
== (set
? 1 : 2))) {
2612 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2613 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2618 // Check whether registers are properly returned by ioctl()
2619 if (!(out
.out_regs
.sector_count
.is_set() && out
.out_regs
.lba_low
.is_set())) {
2620 // TODO: Output register support should be checked within each ata_pass_through()
2621 // implementation before command is issued.
2622 pout("Error SMART WRITE LOG does not return COUNT and LBA_LOW register\n");
2625 // Return value to caller
2626 time_limit
= out
.out_regs
.sector_count
| (out
.out_regs
.lba_low
<< 8);
2632 // Get SCT Error Recovery Control
2633 int ataGetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short & time_limit
)
2635 return ataGetSetSCTErrorRecoveryControltime(device
, type
, false/*get*/, time_limit
);
2638 // Set SCT Error Recovery Control
2639 int ataSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short time_limit
)
2641 return ataGetSetSCTErrorRecoveryControltime(device
, type
, true/*set*/, time_limit
);
2645 // Print one self-test log entry.
2647 // -1: self-test failed
2648 // 1: extended self-test completed without error
2650 int ataPrintSmartSelfTestEntry(unsigned testnum
, unsigned char test_type
,
2651 unsigned char test_status
,
2652 unsigned short timestamp
,
2653 uint64_t failing_lba
,
2654 bool print_error_only
, bool & print_header
)
2656 // Check status and type for return value
2658 switch (test_status
>> 4) {
2660 if ((test_type
& 0x0f) == 0x02)
2661 retval
= 1; // extended self-test completed without error
2666 retval
= -1; // self-test failed
2670 if (retval
>= 0 && print_error_only
)
2673 std::string msgtest
;
2674 switch (test_type
) {
2675 case 0x00: msgtest
= "Offline"; break;
2676 case 0x01: msgtest
= "Short offline"; break;
2677 case 0x02: msgtest
= "Extended offline"; break;
2678 case 0x03: msgtest
= "Conveyance offline"; break;
2679 case 0x04: msgtest
= "Selective offline"; break;
2680 case 0x7f: msgtest
= "Abort offline test"; break;
2681 case 0x81: msgtest
= "Short captive"; break;
2682 case 0x82: msgtest
= "Extended captive"; break;
2683 case 0x83: msgtest
= "Conveyance captive"; break;
2684 case 0x84: msgtest
= "Selective captive"; break;
2686 if ((0x40 <= test_type
&& test_type
<= 0x7e) || 0x90 <= test_type
)
2687 msgtest
= strprintf("Vendor (0x%02x)", test_type
);
2689 msgtest
= strprintf("Reserved (0x%02x)", test_type
);
2692 std::string msgstat
;
2693 switch (test_status
>> 4) {
2694 case 0x0: msgstat
= "Completed without error"; break;
2695 case 0x1: msgstat
= "Aborted by host"; break;
2696 case 0x2: msgstat
= "Interrupted (host reset)"; break;
2697 case 0x3: msgstat
= "Fatal or unknown error"; break;
2698 case 0x4: msgstat
= "Completed: unknown failure"; break;
2699 case 0x5: msgstat
= "Completed: electrical failure"; break;
2700 case 0x6: msgstat
= "Completed: servo/seek failure"; break;
2701 case 0x7: msgstat
= "Completed: read failure"; break;
2702 case 0x8: msgstat
= "Completed: handling damage??"; break;
2703 case 0xf: msgstat
= "Self-test routine in progress"; break;
2704 default: msgstat
= strprintf("Unknown status (0x%x)", test_status
>> 4);
2707 // Print header once
2709 print_header
= false;
2710 pout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2714 if (retval
< 0 && failing_lba
< 0xffffffffffffULL
)
2715 snprintf(msglba
, sizeof(msglba
), "%"PRIu64
, failing_lba
);
2717 strcpy(msglba
, "-");
2719 pout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum
,
2720 msgtest
.c_str(), msgstat
.c_str(), test_status
& 0x0f, timestamp
, msglba
);
2725 // Print Smart self-test log, used by smartctl and smartd.
2727 // bottom 8 bits: number of entries found where self-test showed an error
2728 // remaining bits: if nonzero, power on hours of last self-test where error was found
2729 int ataPrintSmartSelfTestlog(const ata_smart_selftestlog
* data
, bool allentries
,
2730 unsigned char fix_firmwarebug
)
2733 pout("SMART Self-test log structure revision number %d\n",(int)data
->revnumber
);
2734 if ((data
->revnumber
!=0x0001) && allentries
&& fix_firmwarebug
!= FIX_SAMSUNG
)
2735 pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2736 if (data
->mostrecenttest
==0){
2738 pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
2742 bool noheaderprinted
= true;
2743 int errcnt
= 0, hours
= 0, igncnt
= 0;
2744 int testno
= 0, ext_ok_testno
= -1;
2747 for (int i
= 20; i
>= 0; i
--) {
2748 // log is a circular buffer
2749 int j
= (i
+data
->mostrecenttest
)%21;
2750 const ata_smart_selftestlog_struct
* log
= data
->selftest_struct
+j
;
2752 if (nonempty(log
, sizeof(*log
))) {
2753 // count entry based on non-empty structures -- needed for
2754 // Seagate only -- other vendors don't have blank entries 'in
2758 // T13/1321D revision 1c: (Data structure Rev #1)
2760 //The failing LBA shall be the LBA of the uncorrectable sector
2761 //that caused the test to fail. If the device encountered more
2762 //than one uncorrectable sector during the test, this field
2763 //shall indicate the LBA of the first uncorrectable sector
2764 //encountered. If the test passed or the test failed for some
2765 //reason other than an uncorrectable sector, the value of this
2766 //field is undefined.
2768 // This is true in ALL ATA-5 specs
2769 uint64_t lba48
= (log
->lbafirstfailure
< 0xffffffff ? log
->lbafirstfailure
: 0xffffffffffffULL
);
2772 int state
= ataPrintSmartSelfTestEntry(testno
,
2773 log
->selftestnumber
, log
->selfteststatus
,
2774 log
->timestamp
, lba48
, !allentries
, noheaderprinted
);
2777 // Self-test showed an error
2778 if (ext_ok_testno
< 0) {
2781 // keep track of time of most recent error
2783 hours
= log
->timestamp
;
2786 // Newer successful extended self-test exits
2789 else if (state
> 0 && ext_ok_testno
< 0) {
2790 // Latest successful extended self-test
2791 ext_ok_testno
= testno
;
2797 pout("%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2798 igncnt
, igncnt
+errcnt
, ext_ok_testno
);
2800 if (!allentries
&& !noheaderprinted
)
2803 return ((hours
<< 8) | errcnt
);
2807 /////////////////////////////////////////////////////////////////////////////
2808 // Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2809 // an ATA device with same behaviour
2813 class parsed_ata_device
2814 : public /*implements*/ ata_device_with_command_set
2817 parsed_ata_device(smart_interface
* intf
, const char * dev_name
);
2819 virtual ~parsed_ata_device() throw();
2821 virtual bool is_open() const;
2823 virtual bool open();
2825 virtual bool close();
2827 virtual bool ata_identify_is_cached() const;
2830 virtual int ata_command_interface(smart_command_set command
, int select
, char * data
);
2833 // Table of parsed commands, return value, data
2834 struct parsed_ata_command
2836 smart_command_set command
;
2842 enum { max_num_commands
= 32 };
2843 parsed_ata_command m_command_table
[max_num_commands
];
2846 int m_next_replay_command
;
2847 bool m_replay_out_of_sync
;
2848 bool m_ata_identify_is_cached
;
2851 static const char * nextline(const char * s
, int & lineno
)
2853 for (s
+= strcspn(s
, "\r\n"); *s
== '\r' || *s
== '\n'; s
++) {
2854 if (*s
== '\r' && s
[1] == '\n')
2861 static int name2command(const char * s
)
2863 for (int i
= 0; i
< (int)(sizeof(commandstrings
)/sizeof(commandstrings
[0])); i
++) {
2864 if (!strcmp(s
, commandstrings
[i
]))
2870 static bool matchcpy(char * dest
, size_t size
, const char * src
, const regmatch_t
& srcmatch
)
2872 if (srcmatch
.rm_so
< 0)
2874 size_t n
= srcmatch
.rm_eo
- srcmatch
.rm_so
;
2877 memcpy(dest
, src
+ srcmatch
.rm_so
, n
);
2882 static inline int matchtoi(const char * src
, const regmatch_t
& srcmatch
, int defval
)
2884 if (srcmatch
.rm_so
< 0)
2886 return atoi(src
+ srcmatch
.rm_so
);
2889 parsed_ata_device::parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2890 : smart_device(intf
, dev_name
, "ata", ""),
2892 m_next_replay_command(0),
2893 m_replay_out_of_sync(false),
2894 m_ata_identify_is_cached(false)
2896 memset(m_command_table
, 0, sizeof(m_command_table
));
2899 parsed_ata_device::~parsed_ata_device() throw()
2904 bool parsed_ata_device::is_open() const
2906 return (m_num_commands
> 0);
2909 // Parse stdin and build command table
2910 bool parsed_ata_device::open()
2912 const char * pathname
= get_dev_name();
2913 if (strcmp(pathname
, "-"))
2914 return set_err(EINVAL
);
2915 pathname
= "<stdin>";
2917 char buffer
[64*1024];
2919 while (size
< (int)sizeof(buffer
)) {
2920 int nr
= fread(buffer
, 1, sizeof(buffer
), stdin
);
2926 return set_err(ENOENT
, "%s: Unexpected EOF", pathname
);
2927 if (size
>= (int)sizeof(buffer
))
2928 return set_err(EIO
, "%s: Buffer overflow", pathname
);
2931 // Regex to match output from "-r ataioctl,2"
2932 static const char pattern
[] = "^"
2934 "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
2936 "( InputParameter=([0-9]+))?" // (4 (5))
2938 "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2940 "[\r\n]" // EOL match necessary to match optional parts above
2942 "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2944 " *(En|Dis)abled status cached by OS, " // (11)
2948 const regular_expression
regex(pattern
, REG_EXTENDED
);
2951 const char * errmsg
= 0;
2952 int i
= -1, state
= 0, lineno
= 1;
2953 for (const char * line
= buffer
; *line
; line
= nextline(line
, lineno
)) {
2955 if (!(line
[0] == 'R' || line
[0] == '=' || line
[0] == ' '))
2957 const int nmatch
= 1+11;
2958 regmatch_t match
[nmatch
];
2959 if (!regex
.execute(line
, nmatch
, match
))
2963 if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[2])) { // "REPORT-IOCTL:... Command=%s ..."
2964 int nc
= name2command(cmdname
);
2966 errmsg
= "Unknown ATA command name"; break;
2968 if (match
[7].rm_so
< 0) { // "returned %d"
2970 if (!(state
== 0 || state
== 2)) {
2971 errmsg
= "Missing REPORT-IOCTL result"; break;
2973 if (++i
>= max_num_commands
) {
2974 errmsg
= "Too many ATA commands"; break;
2976 m_command_table
[i
].command
= (smart_command_set
)nc
;
2977 m_command_table
[i
].select
= matchtoi(line
, match
[5], 0); // "InputParameter=%d"
2982 if (!(state
== 1 && (int)m_command_table
[i
].command
== nc
)) {
2983 errmsg
= "Missing REPORT-IOCTL start"; break;
2985 m_command_table
[i
].retval
= matchtoi(line
, match
[7], -1); // "returned %d"
2986 m_command_table
[i
].errval
= matchtoi(line
, match
[9], 0); // "errno=%d"
2990 else if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[10])) { // "===== [%s] DATA START "
2991 // Start of sector hexdump
2992 int nc
= name2command(cmdname
);
2993 if (!(state
== (nc
== WRITE_LOG
? 1 : 2) && (int)m_command_table
[i
].command
== nc
)) {
2994 errmsg
= "Unexpected DATA START"; break;
2996 line
= nextline(line
, lineno
);
2997 char * data
= (char *)malloc(512);
2999 for (j
= 0; j
< 32; j
++) {
3001 unsigned u1
, u2
; int n1
= -1;
3002 if (!(sscanf(line
, "%3u-%3u: "
3003 "%2x %2x %2x %2x %2x %2x %2x %2x "
3004 "%2x %2x %2x %2x %2x %2x %2x %2x%n",
3006 b
+ 0, b
+ 1, b
+ 2, b
+ 3, b
+ 4, b
+ 5, b
+ 6, b
+ 7,
3007 b
+ 8, b
+ 9, b
+10, b
+11, b
+12, b
+13, b
+14, b
+15, &n1
) == 18
3008 && n1
>= 56 && u1
== j
*16 && u2
== j
*16+15))
3010 for (unsigned k
= 0; k
< 16; k
++)
3011 data
[j
*16+k
] = b
[k
];
3012 line
= nextline(line
, lineno
);
3016 errmsg
= "Incomplete sector hex dump"; break;
3018 m_command_table
[i
].data
= data
;
3019 if (nc
!= WRITE_LOG
)
3022 else if (match
[11].rm_so
> 0) { // "(En|Dis)abled status cached by OS"
3023 m_ata_identify_is_cached
= true;
3027 if (!(state
== 0 || state
== 2))
3028 errmsg
= "Missing REPORT-IOCTL result";
3030 if (!errmsg
&& i
< 0)
3031 errmsg
= "No information found";
3033 m_num_commands
= i
+1;
3034 m_next_replay_command
= 0;
3035 m_replay_out_of_sync
= false;
3039 return set_err(EIO
, "%s(%d): Syntax error: %s", pathname
, lineno
, errmsg
);
3044 // Report warnings and free command table
3045 bool parsed_ata_device::close()
3047 if (m_replay_out_of_sync
)
3048 pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
3049 else if (m_next_replay_command
!= 0)
3050 pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands
-m_next_replay_command
);
3052 for (int i
= 0; i
< m_num_commands
; i
++) {
3053 if (m_command_table
[i
].data
) {
3054 free(m_command_table
[i
].data
); m_command_table
[i
].data
= 0;
3058 m_next_replay_command
= 0;
3059 m_replay_out_of_sync
= false;
3064 bool parsed_ata_device::ata_identify_is_cached() const
3066 return m_ata_identify_is_cached
;
3070 // Simulate ATA command from command table
3071 int parsed_ata_device::ata_command_interface(smart_command_set command
, int select
, char * data
)
3073 // Find command, try round-robin if out of sync
3074 int i
= m_next_replay_command
;
3075 for (int j
= 0; ; j
++) {
3076 if (j
>= m_num_commands
) {
3077 pout("REPLAY-IOCTL: Warning: Command not found\n");
3081 if (m_command_table
[i
].command
== command
&& m_command_table
[i
].select
== select
)
3083 if (!m_replay_out_of_sync
) {
3084 m_replay_out_of_sync
= true;
3085 pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i
+1);
3087 if (++i
>= m_num_commands
)
3090 m_next_replay_command
= i
;
3091 if (++m_next_replay_command
>= m_num_commands
)
3092 m_next_replay_command
= 0;
3094 // Return command data
3099 case READ_THRESHOLDS
:
3101 if (m_command_table
[i
].data
)
3102 memcpy(data
, m_command_table
[i
].data
, 512);
3105 if (!(m_command_table
[i
].data
&& !memcmp(data
, m_command_table
[i
].data
, 512)))
3106 pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
3108 case CHECK_POWER_MODE
:
3109 data
[0] = (char)0xff;
3114 if (m_command_table
[i
].errval
)
3115 errno
= m_command_table
[i
].errval
;
3116 return m_command_table
[i
].retval
;
3121 ata_device
* get_parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
3123 return new parsed_ata_device(intf
, dev_name
);