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-11 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 3345 2011-05-25 20:50:02Z 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) (isprint((int)(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 // Reads current Device Identity info (512 bytes) into buf. Returns 0
842 // if all OK. Returns -1 if no ATA Device identity can be
843 // established. Returns >0 if Device is ATA Packet Device (not SMART
844 // capable). The value of the integer helps identify the type of
845 // Packet device, which is useful so that the user can connect the
846 // formal device number with whatever object is inside their computer.
847 int ata_read_identity(ata_device
* device
, ata_identify_device
* buf
, bool fix_swapped_id
)
849 unsigned short *rawshort
=(unsigned short *)buf
;
850 unsigned char *rawbyte
=(unsigned char *)buf
;
852 // See if device responds either to IDENTIFY DEVICE or IDENTIFY
855 if ((smartcommandhandler(device
, IDENTIFY
, 0, (char *)buf
))){
856 if (smartcommandhandler(device
, PIDENTIFY
, 0, (char *)buf
)){
863 if (fix_swapped_id
) {
865 for (i
= 0; i
< sizeof(buf
->serial_no
)-1; i
+= 2)
866 swap2((char *)(buf
->serial_no
+i
));
867 for (i
= 0; i
< sizeof(buf
->fw_rev
)-1; i
+= 2)
868 swap2((char *)(buf
->fw_rev
+i
));
869 for (i
= 0; i
< sizeof(buf
->model
)-1; i
+= 2)
870 swap2((char *)(buf
->model
+i
));
874 // if machine is big-endian, swap byte order as needed
875 // NetBSD kernel delivers IDENTIFY data in host byte order
876 // TODO: Handle NetBSD case in os_netbsd.cpp
879 // swap various capability words that are needed
881 swap2((char *)(buf
->words047_079
+i
));
883 for (i
=80; i
<=87; i
++)
884 swap2((char *)(rawshort
+i
));
886 for (i
=0; i
<168; i
++)
887 swap2((char *)(buf
->words088_255
+i
));
891 // If there is a checksum there, validate it
892 if ((rawshort
[255] & 0x00ff) == 0x00a5 && checksum(rawbyte
))
893 checksumwarning("Drive Identity Structure");
895 // AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
896 // T13/1699-D Revision 6a (Final Draft), September 6, 2008.
897 // Sections 7.16.7 and 7.17.6:
899 // Word 0 of IDENTIFY DEVICE data:
900 // Bit 15 = 0 : ATA device
902 // Word 0 of IDENTIFY PACKET DEVICE data:
903 // Bits 15:14 = 10b : ATAPI device
904 // Bits 15:14 = 11b : Reserved
905 // Bits 12:8 : Device type (SPC-4, e.g 0x05 = CD/DVD)
907 // CF+ and CompactFlash Specification Revision 4.0, May 24, 2006.
910 // Word 0 of IDENTIFY DEVICE data:
911 // 848Ah = Signature for CompactFlash Storage Card
912 // 044Ah = Alternate value turns on ATA device while preserving all retired bits
913 // 0040h = Alternate value turns on ATA device while zeroing all retired bits
915 // Assume ATA if IDENTIFY DEVICE returns CompactFlash Signature
916 if (!packet
&& rawbyte
[1] == 0x84 && rawbyte
[0] == 0x8a)
919 // If this is a PACKET DEVICE, return device type
920 if (rawbyte
[1] & 0x80)
921 return 1+(rawbyte
[1] & 0x1f);
923 // Not a PACKET DEVICE
927 // Returns ATA version as an integer, and a pointer to a string
928 // describing which revision. Note that Revision 0 of ATA-3 does NOT
929 // support SMART. For this one case we return -3 rather than +3 as
930 // the version number. See notes above.
931 int ataVersionInfo(const char ** description
, const ata_identify_device
* drive
, unsigned short * minor
)
933 // get major and minor ATA revision numbers
934 unsigned short major
= drive
->major_rev_num
;
935 *minor
=drive
->minor_rev_num
;
937 // First check if device has ANY ATA version information in it
938 if (major
==NOVAL_0
|| major
==NOVAL_1
) {
940 return 0; // No info found
943 // The minor revision number has more information - try there first
944 if (*minor
&& (*minor
<=MINOR_MAX
)){
945 int std
= actual_ver
[*minor
];
947 *description
=minor_str
[*minor
];
952 // Try new ATA-8 ACS minor revision numbers.
953 // Table 55 of T13/2015-D Revision 4a (ACS-2), December 9, 2010.
954 // (not in actual_ver/minor_str to avoid large sparse tables)
957 case 0x0027: desc
= "ATA-8-ACS revision 3c"; break;
958 case 0x0028: desc
= "ATA-8-ACS revision 6"; break;
959 case 0x0029: desc
= "ATA-8-ACS revision 4"; break;
960 case 0x0031: desc
= "ACS-2 revision 2"; break;
961 case 0x0033: desc
= "ATA-8-ACS revision 3e"; break;
962 case 0x0039: desc
= "ATA-8-ACS revision 4c"; break;
963 case 0x0042: desc
= "ATA-8-ACS revision 3f"; break;
964 case 0x0052: desc
= "ATA-8-ACS revision 3b"; break;
965 case 0x0107: desc
= "ATA-8-ACS revision 2d"; break;
966 case 0x0110: desc
= "ACS-2 revision 3"; break;
967 default: desc
= 0; break;
974 // HDPARM has a very complicated algorithm from here on. Since SMART only
975 // exists on ATA-3 and later standards, let's punt on this. If you don't
976 // like it, please fix it. The code's in CVS.
979 if (major
& (0x1<<i
))
989 // Get World Wide Name (WWN) fields.
990 // Return NAA field or -1 if WWN is unsupported.
991 // Table 34 of T13/1699-D Revision 6a (ATA8-ACS), September 6, 2008.
992 // (WWN was introduced in ATA/ATAPI-7 and is mandatory since ATA8-ACS Revision 3b)
993 int ata_get_wwn(const ata_identify_device
* id
, unsigned & oui
, uint64_t & unique_id
)
995 // Don't use word 84 to be compatible with some older ATA-7 disks
996 unsigned short word087
= id
->csf_default
;
997 if ((word087
& 0xc100) != 0x4100)
998 return -1; // word not valid or WWN support bit 8 not set
1000 unsigned short word108
= id
->words088_255
[108-88];
1001 unsigned short word109
= id
->words088_255
[109-88];
1002 unsigned short word110
= id
->words088_255
[110-88];
1003 unsigned short word111
= id
->words088_255
[111-88];
1005 oui
= ((word108
& 0x0fff) << 12) | (word109
>> 4);
1006 unique_id
= ((uint64_t)(word109
& 0xf) << 32)
1007 | (unsigned)((word110
<< 16) | word111
);
1008 return (word108
>> 12);
1011 // returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
1012 int ataSmartSupport(const ata_identify_device
* drive
)
1014 unsigned short word82
=drive
->command_set_1
;
1015 unsigned short word83
=drive
->command_set_2
;
1017 // check if words 82/83 contain valid info
1018 if ((word83
>>14) == 0x01)
1019 // return value of SMART support bit
1020 return word82
& 0x0001;
1022 // since we can're rely on word 82, we don't know if SMART supported
1026 // returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
1027 int ataIsSmartEnabled(const ata_identify_device
* drive
)
1029 unsigned short word85
=drive
->cfs_enable_1
;
1030 unsigned short word87
=drive
->csf_default
;
1032 // check if words 85/86/87 contain valid info
1033 if ((word87
>>14) == 0x01)
1034 // return value of SMART enabled bit
1035 return word85
& 0x0001;
1037 // Since we can't rely word85, we don't know if SMART is enabled.
1042 // Reads SMART attributes into *data
1043 int ataReadSmartValues(ata_device
* device
, struct ata_smart_values
*data
){
1045 if (smartcommandhandler(device
, READ_VALUES
, 0, (char *)data
)){
1046 pout("Error SMART Values Read failed: %s\n", device
->get_errmsg());
1052 checksumwarning("SMART Attribute Data Structure");
1054 // swap endian order if needed
1057 swap2((char *)&(data
->revnumber
));
1058 swap2((char *)&(data
->total_time_to_complete_off_line
));
1059 swap2((char *)&(data
->smart_capability
));
1060 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
1061 struct ata_smart_attribute
*x
=data
->vendor_attributes
+i
;
1062 swap2((char *)&(x
->flags
));
1070 // This corrects some quantities that are byte reversed in the SMART
1072 static void fixsamsungselftestlog(ata_smart_selftestlog
* data
)
1074 // bytes 508/509 (numbered from 0) swapped (swap of self-test index
1075 // with one byte of reserved.
1076 swap2((char *)&(data
->mostrecenttest
));
1078 // LBA low register (here called 'selftestnumber", containing
1079 // information about the TYPE of the self-test) is byte swapped with
1080 // Self-test execution status byte. These are bytes N, N+1 in the
1082 for (int i
= 0; i
< 21; i
++)
1083 swap2((char *)&(data
->selftest_struct
[i
].selftestnumber
));
1088 // Reads the Self Test Log (log #6)
1089 int ataReadSelfTestLog (ata_device
* device
, ata_smart_selftestlog
* data
,
1090 unsigned char fix_firmwarebug
)
1093 // get data from device
1094 if (smartcommandhandler(device
, READ_LOG
, 0x06, (char *)data
)){
1095 pout("Error SMART Error Self-Test Log Read failed: %s\n", device
->get_errmsg());
1099 // compute its checksum, and issue a warning if needed
1101 checksumwarning("SMART Self-Test Log Structure");
1103 // fix firmware bugs in self-test log
1104 if (fix_firmwarebug
== FIX_SAMSUNG
)
1105 fixsamsungselftestlog(data
);
1107 // swap endian order if needed
1110 swap2((char*)&(data
->revnumber
));
1111 for (i
=0; i
<21; i
++){
1112 struct ata_smart_selftestlog_struct
*x
=data
->selftest_struct
+i
;
1113 swap2((char *)&(x
->timestamp
));
1114 swap4((char *)&(x
->lbafirstfailure
));
1121 // Print checksum warning for multi sector log
1122 static void check_multi_sector_sum(const void * data
, unsigned nsectors
, const char * msg
)
1125 for (unsigned i
= 0; i
< nsectors
; i
++) {
1126 if (checksum((const unsigned char *)data
+ i
*512))
1131 checksumwarning(msg
);
1133 checksumwarning(strprintf("%s (%u/%u)", msg
, errs
, nsectors
).c_str());
1137 // Read SMART Extended Self-test Log
1138 bool ataReadExtSelfTestLog(ata_device
* device
, ata_smart_extselftestlog
* log
,
1141 if (!ataReadLogExt(device
, 0x07, 0x00, 0, log
, nsectors
))
1144 check_multi_sector_sum(log
, nsectors
, "SMART Extended Self-test Log Structure");
1146 if (isbigendian()) {
1147 swapx(&log
->log_desc_index
);
1148 for (unsigned i
= 0; i
< nsectors
; i
++) {
1149 for (unsigned j
= 0; j
< 19; j
++)
1150 swapx(&log
->log_descs
[i
].timestamp
);
1157 // Read GP Log page(s)
1158 bool ataReadLogExt(ata_device
* device
, unsigned char logaddr
,
1159 unsigned char features
, unsigned page
,
1160 void * data
, unsigned nsectors
)
1163 in
.in_regs
.command
= ATA_READ_LOG_EXT
;
1164 in
.in_regs
.features
= features
; // log specific
1165 in
.set_data_in_48bit(data
, nsectors
);
1166 in
.in_regs
.lba_low
= logaddr
;
1167 in
.in_regs
.lba_mid_16
= page
;
1169 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1170 if (nsectors
<= 1) {
1171 pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n",
1172 logaddr
, features
, page
, nsectors
, device
->get_errmsg());
1176 // Recurse to retry with single sectors,
1177 // multi-sector reads may not be supported by ioctl.
1178 for (unsigned i
= 0; i
< nsectors
; i
++) {
1179 if (!ataReadLogExt(device
, logaddr
,
1181 (char *)data
+ 512*i
, 1))
1189 // Read SMART Log page(s)
1190 bool ataReadSmartLog(ata_device
* device
, unsigned char logaddr
,
1191 void * data
, unsigned nsectors
)
1194 in
.in_regs
.command
= ATA_SMART_CMD
;
1195 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
1196 in
.set_data_in(data
, nsectors
);
1197 in
.in_regs
.lba_high
= SMART_CYL_HI
;
1198 in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
1199 in
.in_regs
.lba_low
= logaddr
;
1201 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1202 pout("ATA_SMART_READ_LOG failed: %s\n", device
->get_errmsg());
1210 // Reads the SMART or GPL Log Directory (log #0)
1211 int ataReadLogDirectory(ata_device
* device
, ata_smart_log_directory
* data
, bool gpl
)
1213 if (!gpl
) { // SMART Log directory
1214 if (smartcommandhandler(device
, READ_LOG
, 0x00, (char *)data
))
1217 else { // GP Log directory
1218 if (!ataReadLogExt(device
, 0x00, 0x00, 0, data
, 1))
1222 // swap endian order if needed
1224 swapx(&data
->logversion
);
1230 // Reads the selective self-test log (log #9)
1231 int ataReadSelectiveSelfTestLog(ata_device
* device
, struct ata_selective_self_test_log
*data
){
1233 // get data from device
1234 if (smartcommandhandler(device
, READ_LOG
, 0x09, (char *)data
)){
1235 pout("Error SMART Read Selective Self-Test Log failed: %s\n", device
->get_errmsg());
1239 // compute its checksum, and issue a warning if needed
1241 checksumwarning("SMART Selective Self-Test Log Structure");
1243 // swap endian order if needed
1246 swap2((char *)&(data
->logversion
));
1248 swap8((char *)&(data
->span
[i
].start
));
1249 swap8((char *)&(data
->span
[i
].end
));
1251 swap8((char *)&(data
->currentlba
));
1252 swap2((char *)&(data
->currentspan
));
1253 swap2((char *)&(data
->flags
));
1254 swap2((char *)&(data
->pendingtime
));
1257 if (data
->logversion
!= 1)
1258 pout("Note: selective self-test log revision number (%d) not 1 implies that no selective self-test has ever been run\n", data
->logversion
);
1263 // Writes the selective self-test log (log #9)
1264 int ataWriteSelectiveSelfTestLog(ata_device
* device
, ata_selective_selftest_args
& args
,
1265 const ata_smart_values
* sv
, uint64_t num_sectors
,
1266 const ata_selective_selftest_args
* prev_args
)
1268 // Disk size must be known
1270 pout("Disk size is unknown, unable to check selective self-test spans\n");
1275 struct ata_selective_self_test_log sstlog
, *data
=&sstlog
;
1276 unsigned char *ptr
=(unsigned char *)data
;
1277 if (ataReadSelectiveSelfTestLog(device
, data
)) {
1278 pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
1283 data
->logversion
= 1;
1285 // Host is NOT allowed to write selective self-test log if a selective
1286 // self-test is in progress.
1287 if (0<data
->currentspan
&& data
->currentspan
<6 && ((sv
->self_test_exec_status
)>>4)==15) {
1288 pout("Error SMART Selective or other Self-Test in progress.\n");
1292 // Set start/end values based on old spans for special -t select,... options
1294 for (i
= 0; i
< args
.num_spans
; i
++) {
1295 int mode
= args
.span
[i
].mode
;
1296 uint64_t start
= args
.span
[i
].start
;
1297 uint64_t end
= args
.span
[i
].end
;
1298 if (mode
== SEL_CONT
) {// redo or next dependig on last test status
1299 switch (sv
->self_test_exec_status
>> 4) {
1300 case 1: case 2: // Aborted/Interrupted by host
1301 pout("Continue Selective Self-Test: Redo last span\n");
1304 default: // All others
1305 pout("Continue Selective Self-Test: Start next span\n");
1311 if ( (mode
== SEL_REDO
|| mode
== SEL_NEXT
)
1312 && prev_args
&& i
< prev_args
->num_spans
1313 && !data
->span
[i
].start
&& !data
->span
[i
].end
) {
1314 // Some drives do not preserve the selective self-test log accross
1315 // power-cyles. If old span on drive is cleared use span provided
1316 // by caller. This is used by smartd (first span only).
1317 data
->span
[i
].start
= prev_args
->span
[i
].start
;
1318 data
->span
[i
].end
= prev_args
->span
[i
].end
;
1322 case SEL_RANGE
: // -t select,START-END
1324 case SEL_REDO
: // -t select,redo... => Redo current
1325 start
= data
->span
[i
].start
;
1326 if (end
> 0) { // -t select,redo+SIZE
1327 end
--; end
+= start
; // [oldstart, oldstart+SIZE)
1329 else // -t select,redo
1330 end
= data
->span
[i
].end
; // [oldstart, oldend]
1332 case SEL_NEXT
: // -t select,next... => Do next
1333 if (data
->span
[i
].end
== 0) {
1334 start
= end
= 0; break; // skip empty spans
1336 start
= data
->span
[i
].end
+ 1;
1337 if (start
>= num_sectors
)
1338 start
= 0; // wrap around
1339 if (end
> 0) { // -t select,next+SIZE
1340 end
--; end
+= start
; // (oldend, oldend+SIZE]
1342 else { // -t select,next
1343 uint64_t oldsize
= data
->span
[i
].end
- data
->span
[i
].start
+ 1;
1344 end
= start
+ oldsize
- 1; // (oldend, oldend+oldsize]
1345 if (end
>= num_sectors
) {
1346 // Adjust size to allow round-robin testing without future size decrease
1347 uint64_t spans
= (num_sectors
+ oldsize
-1) / oldsize
;
1348 uint64_t newsize
= (num_sectors
+ spans
-1) / spans
;
1349 uint64_t newstart
= num_sectors
- newsize
, newend
= num_sectors
- 1;
1350 pout("Span %d changed from %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors)\n",
1351 i
, start
, end
, oldsize
);
1352 pout(" to %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors) (%"PRIu64
" spans)\n",
1353 newstart
, newend
, newsize
, spans
);
1354 start
= newstart
; end
= newend
;
1359 pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode
);
1363 if (start
< num_sectors
&& num_sectors
<= end
) {
1364 if (end
!= ~(uint64_t)0) // -t select,N-max
1365 pout("Size of self-test span %d decreased according to disk size\n", i
);
1366 end
= num_sectors
- 1;
1368 if (!(start
<= end
&& end
< num_sectors
)) {
1369 pout("Invalid selective self-test span %d: %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors)\n",
1370 i
, start
, end
, num_sectors
);
1373 // Return the actual mode and range to caller.
1374 args
.span
[i
].mode
= mode
;
1375 args
.span
[i
].start
= start
;
1376 args
.span
[i
].end
= end
;
1381 memset(data
->span
+i
, 0, sizeof(struct test_span
));
1383 // Set spans for testing
1384 for (i
= 0; i
< args
.num_spans
; i
++){
1385 data
->span
[i
].start
= args
.span
[i
].start
;
1386 data
->span
[i
].end
= args
.span
[i
].end
;
1389 // host must initialize to zero before initiating selective self-test
1391 data
->currentspan
=0;
1393 // Perform off-line scan after selective test?
1394 if (args
.scan_after_select
== 1)
1396 data
->flags
&= ~SELECTIVE_FLAG_DOSCAN
;
1397 else if (args
.scan_after_select
== 2)
1399 data
->flags
|= SELECTIVE_FLAG_DOSCAN
;
1401 // Must clear active and pending flags before writing
1402 data
->flags
&= ~(SELECTIVE_FLAG_ACTIVE
);
1403 data
->flags
&= ~(SELECTIVE_FLAG_PENDING
);
1405 // modify pending time?
1406 if (args
.pending_time
)
1407 data
->pendingtime
= (unsigned short)(args
.pending_time
-1);
1409 // Set checksum to zero, then compute checksum
1411 unsigned char cksum
=0;
1412 for (i
=0; i
<512; i
++)
1416 data
->checksum
=cksum
;
1418 // swap endian order if needed
1420 swap2((char *)&(data
->logversion
));
1421 for (int b
= 0; b
< 5; b
++) {
1422 swap8((char *)&(data
->span
[b
].start
));
1423 swap8((char *)&(data
->span
[b
].end
));
1425 swap8((char *)&(data
->currentlba
));
1426 swap2((char *)&(data
->currentspan
));
1427 swap2((char *)&(data
->flags
));
1428 swap2((char *)&(data
->pendingtime
));
1431 // write new selective self-test log
1432 if (smartcommandhandler(device
, WRITE_LOG
, 0x09, (char *)data
)){
1433 pout("Error Write Selective Self-Test Log failed: %s\n", device
->get_errmsg());
1440 // This corrects some quantities that are byte reversed in the SMART
1442 static void fixsamsungerrorlog(ata_smart_errorlog
* data
)
1444 // FIXED IN SAMSUNG -25 FIRMWARE???
1445 // Device error count in bytes 452-3
1446 swap2((char *)&(data
->ata_error_count
));
1448 // FIXED IN SAMSUNG -22a FIRMWARE
1449 // step through 5 error log data structures
1450 for (int i
= 0; i
< 5; i
++){
1451 // step through 5 command data structures
1452 for (int j
= 0; j
< 5; j
++)
1453 // Command data structure 4-byte millisec timestamp. These are
1454 // bytes (N+8, N+9, N+10, N+11).
1455 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1456 // Error data structure two-byte hour life timestamp. These are
1457 // bytes (N+28, N+29).
1458 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1463 // NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
1464 static void fixsamsungerrorlog2(ata_smart_errorlog
* data
)
1466 // Device error count in bytes 452-3
1467 swap2((char *)&(data
->ata_error_count
));
1471 // Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1472 // Error Log is #2, and the Extended Comprehensive SMART Error log is
1474 int ataReadErrorLog (ata_device
* device
, ata_smart_errorlog
*data
,
1475 unsigned char fix_firmwarebug
)
1478 // get data from device
1479 if (smartcommandhandler(device
, READ_LOG
, 0x01, (char *)data
)){
1480 pout("Error SMART Error Log Read failed: %s\n", device
->get_errmsg());
1484 // compute its checksum, and issue a warning if needed
1486 checksumwarning("SMART ATA Error Log Structure");
1488 // Some disks have the byte order reversed in some SMART Summary
1489 // Error log entries
1490 if (fix_firmwarebug
== FIX_SAMSUNG
)
1491 fixsamsungerrorlog(data
);
1492 else if (fix_firmwarebug
== FIX_SAMSUNG2
)
1493 fixsamsungerrorlog2(data
);
1495 // swap endian order if needed
1499 // Device error count in bytes 452-3
1500 swap2((char *)&(data
->ata_error_count
));
1502 // step through 5 error log data structures
1503 for (i
=0; i
<5; i
++){
1504 // step through 5 command data structures
1506 // Command data structure 4-byte millisec timestamp
1507 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1508 // Error data structure life timestamp
1509 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1516 // Read Extended Comprehensive Error Log
1517 bool ataReadExtErrorLog(ata_device
* device
, ata_smart_exterrlog
* log
,
1520 if (!ataReadLogExt(device
, 0x03, 0x00, 0, log
, nsectors
))
1523 check_multi_sector_sum(log
, nsectors
, "SMART Extended Comprehensive Error Log Structure");
1525 if (isbigendian()) {
1526 swapx(&log
->device_error_count
);
1527 swapx(&log
->error_log_index
);
1529 for (unsigned i
= 0; i
< nsectors
; i
++) {
1530 for (unsigned j
= 0; j
< 4; j
++)
1531 swapx(&log
->error_logs
[i
].commands
[j
].timestamp
);
1532 swapx(&log
->error_logs
[i
].error
.timestamp
);
1540 int ataReadSmartThresholds (ata_device
* device
, struct ata_smart_thresholds_pvt
*data
){
1542 // get data from device
1543 if (smartcommandhandler(device
, READ_THRESHOLDS
, 0, (char *)data
)){
1544 pout("Error SMART Thresholds Read failed: %s\n", device
->get_errmsg());
1548 // compute its checksum, and issue a warning if needed
1550 checksumwarning("SMART Attribute Thresholds Structure");
1552 // swap endian order if needed
1554 swap2((char *)&(data
->revnumber
));
1559 int ataEnableSmart (ata_device
* device
){
1560 if (smartcommandhandler(device
, ENABLE
, 0, NULL
)){
1561 pout("Error SMART Enable failed: %s\n", device
->get_errmsg());
1567 int ataDisableSmart (ata_device
* device
){
1569 if (smartcommandhandler(device
, DISABLE
, 0, NULL
)){
1570 pout("Error SMART Disable failed: %s\n", device
->get_errmsg());
1576 int ataEnableAutoSave(ata_device
* device
){
1577 if (smartcommandhandler(device
, AUTOSAVE
, 241, NULL
)){
1578 pout("Error SMART Enable Auto-save failed: %s\n", device
->get_errmsg());
1584 int ataDisableAutoSave(ata_device
* device
){
1586 if (smartcommandhandler(device
, AUTOSAVE
, 0, NULL
)){
1587 pout("Error SMART Disable Auto-save failed: %s\n", device
->get_errmsg());
1593 // In *ALL* ATA standards the Enable/Disable AutoOffline command is
1594 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1595 // vendors still support it for backwards compatibility. IBM documents
1596 // it for some drives.
1597 int ataEnableAutoOffline (ata_device
* device
){
1599 /* timer hard coded to 4 hours */
1600 if (smartcommandhandler(device
, AUTO_OFFLINE
, 248, NULL
)){
1601 pout("Error SMART Enable Automatic Offline failed: %s\n", device
->get_errmsg());
1607 // Another Obsolete Command. See comments directly above, associated
1608 // with the corresponding Enable command.
1609 int ataDisableAutoOffline (ata_device
* device
){
1611 if (smartcommandhandler(device
, AUTO_OFFLINE
, 0, NULL
)){
1612 pout("Error SMART Disable Automatic Offline failed: %s\n", device
->get_errmsg());
1618 // If SMART is enabled, supported, and working, then this call is
1619 // guaranteed to return 1, else zero. Note that it should return 1
1620 // regardless of whether the disk's SMART status is 'healthy' or
1622 int ataDoesSmartWork(ata_device
* device
){
1623 int retval
=smartcommandhandler(device
, STATUS
, 0, NULL
);
1631 // This function uses a different interface (DRIVE_TASK) than the
1632 // other commands in this file.
1633 int ataSmartStatus2(ata_device
* device
){
1634 return smartcommandhandler(device
, STATUS_CHECK
, 0, NULL
);
1637 // This is the way to execute ALL tests: offline, short self-test,
1638 // extended self test, with and without captive mode, etc.
1639 // TODO: Move to ataprint.cpp ?
1640 int ataSmartTest(ata_device
* device
, int testtype
, const ata_selective_selftest_args
& selargs
,
1641 const ata_smart_values
* sv
, uint64_t num_sectors
)
1643 char cmdmsg
[128]; const char *type
, *captive
;
1644 int cap
, retval
, select
=0;
1646 // Boolean, if set, says test is captive
1647 cap
=testtype
& CAPTIVE_MASK
;
1649 // Set up strings that describe the type of test
1655 if (testtype
==OFFLINE_FULL_SCAN
)
1657 else if (testtype
==SHORT_SELF_TEST
|| testtype
==SHORT_CAPTIVE_SELF_TEST
)
1658 type
="Short self-test";
1659 else if (testtype
==EXTEND_SELF_TEST
|| testtype
==EXTEND_CAPTIVE_SELF_TEST
)
1660 type
="Extended self-test";
1661 else if (testtype
==CONVEYANCE_SELF_TEST
|| testtype
==CONVEYANCE_CAPTIVE_SELF_TEST
)
1662 type
="Conveyance self-test";
1663 else if ((select
=(testtype
==SELECTIVE_SELF_TEST
|| testtype
==SELECTIVE_CAPTIVE_SELF_TEST
)))
1664 type
="Selective self-test";
1668 // If doing a selective self-test, first use WRITE_LOG to write the
1669 // selective self-test log.
1670 ata_selective_selftest_args selargs_io
= selargs
; // filled with info about actual spans
1671 if (select
&& (retval
= ataWriteSelectiveSelfTestLog(device
, selargs_io
, sv
, num_sectors
))) {
1673 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1677 // Print ouf message that we are sending the command to test
1678 if (testtype
==ABORT_SELF_TEST
)
1679 sprintf(cmdmsg
,"Abort SMART off-line mode self-test routine");
1681 sprintf(cmdmsg
, "SMART EXECUTE OFF-LINE IMMEDIATE subcommand 0x%02x", testtype
);
1683 sprintf(cmdmsg
,"Execute SMART %s routine immediately in %s mode",type
,captive
);
1684 pout("Sending command: \"%s\".\n",cmdmsg
);
1688 pout("SPAN STARTING_LBA ENDING_LBA\n");
1689 for (i
= 0; i
< selargs_io
.num_spans
; i
++)
1690 pout(" %d %20"PRId64
" %20"PRId64
"\n", i
,
1691 selargs_io
.span
[i
].start
,
1692 selargs_io
.span
[i
].end
);
1695 // Now send the command to test
1696 if (smartcommandhandler(device
, IMMEDIATE_OFFLINE
, testtype
, NULL
)) {
1697 if (!(cap
&& device
->get_errno() == EIO
)) {
1698 pout("Command \"%s\" failed: %s\n", cmdmsg
, device
->get_errmsg());
1703 // Since the command succeeded, tell user
1704 if (testtype
==ABORT_SELF_TEST
)
1705 pout("Self-testing aborted!\n");
1707 pout("Drive command \"%s\" successful.\n", cmdmsg
);
1709 pout("Testing has begun.\n");
1714 /* Test Time Functions */
1715 int TestTime(const ata_smart_values
*data
, int testtype
)
1718 case OFFLINE_FULL_SCAN
:
1719 return (int) data
->total_time_to_complete_off_line
;
1720 case SHORT_SELF_TEST
:
1721 case SHORT_CAPTIVE_SELF_TEST
:
1722 return (int) data
->short_test_completion_time
;
1723 case EXTEND_SELF_TEST
:
1724 case EXTEND_CAPTIVE_SELF_TEST
:
1725 return (int) data
->extend_test_completion_time
;
1726 case CONVEYANCE_SELF_TEST
:
1727 case CONVEYANCE_CAPTIVE_SELF_TEST
:
1728 return (int) data
->conveyance_test_completion_time
;
1734 // This function tells you both about the ATA error log and the
1735 // self-test error log capability (introduced in ATA-5). The bit is
1736 // poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1737 // SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1738 // word 84 and 87. Top two bits must match the pattern 01. BEFORE
1739 // ATA-6 these top two bits still had to match the pattern 01, but the
1740 // remaining bits were reserved (==0).
1741 int isSmartErrorLogCapable (const ata_smart_values
* data
, const ata_identify_device
* identity
)
1743 unsigned short word84
=identity
->command_set_extension
;
1744 unsigned short word87
=identity
->csf_default
;
1745 int isata6
=identity
->major_rev_num
& (0x01<<6);
1746 int isata7
=identity
->major_rev_num
& (0x01<<7);
1748 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x01))
1751 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x01))
1754 // otherwise we'll use the poorly documented capability bit
1755 return data
->errorlog_capability
& 0x01;
1758 // See previous function. If the error log exists then the self-test
1759 // log should (must?) also exist.
1760 int isSmartTestLogCapable (const ata_smart_values
* data
, const ata_identify_device
*identity
)
1762 unsigned short word84
=identity
->command_set_extension
;
1763 unsigned short word87
=identity
->csf_default
;
1764 int isata6
=identity
->major_rev_num
& (0x01<<6);
1765 int isata7
=identity
->major_rev_num
& (0x01<<7);
1767 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x02))
1770 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x02))
1774 // otherwise we'll use the poorly documented capability bit
1775 return data
->errorlog_capability
& 0x01;
1779 int isGeneralPurposeLoggingCapable(const ata_identify_device
*identity
)
1781 unsigned short word84
=identity
->command_set_extension
;
1782 unsigned short word87
=identity
->csf_default
;
1784 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1785 // cleared to zero, the contents of word 84 contains valid support
1786 // information. If not, support information is not valid in this
1788 if ((word84
>>14) == 0x01)
1789 // If bit 5 of word 84 is set to one, the device supports the
1790 // General Purpose Logging feature set.
1791 return (word84
& (0x01 << 5));
1793 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1794 // cleared to zero, the contents of words (87:85) contain valid
1795 // information. If not, information is not valid in these words.
1796 if ((word87
>>14) == 0x01)
1797 // If bit 5 of word 87 is set to one, the device supports
1798 // the General Purpose Logging feature set.
1799 return (word87
& (0x01 << 5));
1806 // SMART self-test capability is also indicated in bit 1 of DEVICE
1807 // IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1808 // However this was only introduced in ATA-6 (but self-test log was in
1810 int isSupportExecuteOfflineImmediate(const ata_smart_values
*data
)
1812 return data
->offline_data_collection_capability
& 0x01;
1815 // Note in the ATA-5 standard, the following bit is listed as "Vendor
1816 // Specific". So it may not be reliable. The only use of this that I
1817 // have found is in IBM drives, where it is well-documented. See for
1818 // example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1819 // hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
1820 int isSupportAutomaticTimer(const ata_smart_values
* data
)
1822 return data
->offline_data_collection_capability
& 0x02;
1824 int isSupportOfflineAbort(const ata_smart_values
*data
)
1826 return data
->offline_data_collection_capability
& 0x04;
1828 int isSupportOfflineSurfaceScan(const ata_smart_values
* data
)
1830 return data
->offline_data_collection_capability
& 0x08;
1832 int isSupportSelfTest (const ata_smart_values
* data
)
1834 return data
->offline_data_collection_capability
& 0x10;
1836 int isSupportConveyanceSelfTest(const ata_smart_values
* data
)
1838 return data
->offline_data_collection_capability
& 0x20;
1840 int isSupportSelectiveSelfTest(const ata_smart_values
* data
)
1842 return data
->offline_data_collection_capability
& 0x40;
1845 // Get attribute state
1846 ata_attr_state
ata_get_attr_state(const ata_smart_attribute
& attr
,
1848 const ata_smart_threshold_entry
* thresholds
,
1849 const ata_vendor_attr_defs
& defs
,
1850 unsigned char * threshval
/* = 0 */)
1853 return ATTRSTATE_NON_EXISTING
;
1855 // Normalized values (current,worst,threshold) not valid
1856 // if specified by '-v' option.
1857 // (Some SSD disks uses these bytes to store raw value).
1858 if (defs
[attr
.id
].flags
& ATTRFLAG_NO_NORMVAL
)
1859 return ATTRSTATE_NO_NORMVAL
;
1861 // Normally threshold is at same index as attribute
1863 if (thresholds
[i
].id
!= attr
.id
) {
1864 // Find threshold id in table
1865 for (i
= 0; thresholds
[i
].id
!= attr
.id
; ) {
1866 if (++i
>= NUMBER_ATA_SMART_ATTRIBUTES
)
1867 // Threshold id missing or thresholds cannot be read
1868 return ATTRSTATE_NO_THRESHOLD
;
1871 unsigned char threshold
= thresholds
[i
].threshold
;
1873 // Return threshold if requested
1875 *threshval
= threshold
;
1877 // Don't report a failed attribute if its threshold is 0.
1878 // ATA-3 (X3T13/2008D Revision 7b) declares 0x00 as the "always passing"
1879 // threshold (Later ATA versions declare all thresholds as "obsolete").
1880 // In practice, threshold value 0 is often used for usage attributes.
1882 return ATTRSTATE_OK
;
1884 // Failed now if current value is below threshold
1885 if (attr
.current
<= threshold
)
1886 return ATTRSTATE_FAILED_NOW
;
1888 // Failed in the past if worst value is below threshold
1889 if (!(defs
[attr
.id
].flags
& ATTRFLAG_NO_WORSTVAL
) && attr
.worst
<= threshold
)
1890 return ATTRSTATE_FAILED_PAST
;
1892 return ATTRSTATE_OK
;
1895 // Get default raw value print format
1896 static ata_attr_raw_format
get_default_raw_format(unsigned char id
)
1899 case 3: // Spin-up time
1900 return RAWFMT_RAW16_OPT_AVG16
;
1902 case 5: // Reallocated sector count
1903 case 196: // Reallocated event count
1904 return RAWFMT_RAW16_OPT_RAW16
;
1906 case 190: // Temperature
1908 return RAWFMT_TEMPMINMAX
;
1911 return RAWFMT_RAW48
;
1915 // Get attribute raw value.
1916 uint64_t ata_get_attr_raw_value(const ata_smart_attribute
& attr
,
1917 const ata_vendor_attr_defs
& defs
)
1919 const ata_vendor_attr_defs::entry
& def
= defs
[attr
.id
];
1921 // Use default byteorder if not specified
1922 const char * byteorder
= def
.byteorder
;
1924 switch (def
.raw_format
) {
1927 byteorder
= "543210wv"; break;
1928 case RAWFMT_RAW24_DIV_RAW32
:
1929 case RAWFMT_MSEC24_HOUR32
:
1930 byteorder
= "r543210"; break;
1932 byteorder
= "543210"; break;
1936 // Build 64-bit value from selected bytes
1937 uint64_t rawvalue
= 0;
1938 for (int i
= 0; byteorder
[i
]; i
++) {
1940 switch (byteorder
[i
]) {
1941 case '0': b
= attr
.raw
[0]; break;
1942 case '1': b
= attr
.raw
[1]; break;
1943 case '2': b
= attr
.raw
[2]; break;
1944 case '3': b
= attr
.raw
[3]; break;
1945 case '4': b
= attr
.raw
[4]; break;
1946 case '5': b
= attr
.raw
[5]; break;
1947 case 'r': b
= attr
.reserv
; break;
1948 case 'v': b
= attr
.current
; break;
1949 case 'w': b
= attr
.worst
; break;
1950 default : b
= 0; break;
1952 rawvalue
<<= 8; rawvalue
|= b
;
1959 // Format attribute raw value.
1960 std::string
ata_format_attr_raw_value(const ata_smart_attribute
& attr
,
1961 const ata_vendor_attr_defs
& defs
)
1963 // Get 48 bit or 64 bit raw value
1964 uint64_t rawvalue
= ata_get_attr_raw_value(attr
, defs
);
1966 // Split into bytes and words
1967 unsigned char raw
[6];
1968 raw
[0] = (unsigned char) rawvalue
;
1969 raw
[1] = (unsigned char)(rawvalue
>> 8);
1970 raw
[2] = (unsigned char)(rawvalue
>> 16);
1971 raw
[3] = (unsigned char)(rawvalue
>> 24);
1972 raw
[4] = (unsigned char)(rawvalue
>> 32);
1973 raw
[5] = (unsigned char)(rawvalue
>> 40);
1975 word
[0] = raw
[0] | (raw
[1] << 8);
1976 word
[1] = raw
[2] | (raw
[3] << 8);
1977 word
[2] = raw
[4] | (raw
[5] << 8);
1980 ata_attr_raw_format format
= defs
[attr
.id
].raw_format
;
1981 if (format
== RAWFMT_DEFAULT
)
1982 format
= get_default_raw_format(attr
.id
);
1988 s
= strprintf("%d %d %d %d %d %d",
1989 raw
[5], raw
[4], raw
[3], raw
[2], raw
[1], raw
[0]);
1993 s
= strprintf("%u %u %u", word
[2], word
[1], word
[0]);
1998 s
= strprintf("%"PRIu64
, rawvalue
);
2002 s
= strprintf("0x%012"PRIx64
, rawvalue
);
2006 s
= strprintf("0x%016"PRIx64
, rawvalue
);
2009 case RAWFMT_RAW16_OPT_RAW16
:
2010 s
= strprintf("%u", word
[0]);
2011 if (word
[1] || word
[2])
2012 s
+= strprintf(" (%u, %u)", word
[2], word
[1]);
2015 case RAWFMT_RAW16_OPT_AVG16
:
2016 s
= strprintf("%u", word
[0]);
2018 s
+= strprintf(" (Average %u)", word
[1]);
2021 case RAWFMT_RAW24_DIV_RAW24
:
2022 s
= strprintf("%u/%u",
2023 (unsigned)(rawvalue
>> 24), (unsigned)(rawvalue
& 0x00ffffffULL
));
2026 case RAWFMT_RAW24_DIV_RAW32
:
2027 s
= strprintf("%u/%u",
2028 (unsigned)(rawvalue
>> 32), (unsigned)(rawvalue
& 0xffffffffULL
));
2031 case RAWFMT_MIN2HOUR
:
2034 int64_t temp
= word
[0]+(word
[1]<<16);
2035 int64_t tmp1
= temp
/60;
2036 int64_t tmp2
= temp
%60;
2037 s
= strprintf("%"PRIu64
"h+%02"PRIu64
"m", tmp1
, tmp2
);
2039 s
+= strprintf(" (%u)", word
[2]);
2043 case RAWFMT_SEC2HOUR
:
2046 int64_t hours
= rawvalue
/3600;
2047 int64_t minutes
= (rawvalue
-3600*hours
)/60;
2048 int64_t seconds
= rawvalue
%60;
2049 s
= strprintf("%"PRIu64
"h+%02"PRIu64
"m+%02"PRIu64
"s", hours
, minutes
, seconds
);
2053 case RAWFMT_HALFMIN2HOUR
:
2055 // 30-second counter
2056 int64_t hours
= rawvalue
/120;
2057 int64_t minutes
= (rawvalue
-120*hours
)/2;
2058 s
+= strprintf("%"PRIu64
"h+%02"PRIu64
"m", hours
, minutes
);
2062 case RAWFMT_MSEC24_HOUR32
:
2064 // hours + milliseconds
2065 unsigned hours
= (unsigned)(rawvalue
& 0xffffffffULL
);
2066 unsigned milliseconds
= (unsigned)(rawvalue
>> 32);
2067 unsigned seconds
= milliseconds
/ 1000;
2068 s
= strprintf("%uh+%02um+%02u.%03us",
2069 hours
, seconds
/ 60, seconds
% 60, milliseconds
% 1000);
2073 case RAWFMT_TEMPMINMAX
:
2075 s
= strprintf("%u", word
[0]);
2076 if (word
[1] || word
[2]) {
2077 unsigned lo
= ~0, hi
= ~0;
2079 // 00 HH 00 LL 00 TT (IBM)
2080 hi
= word
[2]; lo
= word
[1];
2082 else if (!word
[2]) {
2083 // 00 00 HH LL 00 TT (Maxtor)
2084 hi
= raw
[3]; lo
= raw
[2];
2087 unsigned t
= lo
; lo
= hi
; hi
= t
;
2089 if (lo
<= word
[0] && word
[0] <= hi
)
2090 s
+= strprintf(" (Min/Max %u/%u)", lo
, hi
);
2092 s
+= strprintf(" (%d %d %d %d)", raw
[5], raw
[4], raw
[3], raw
[2]);
2096 case RAWFMT_TEMP10X
:
2097 // ten times temperature in Celsius
2098 s
= strprintf("%d.%d", word
[0]/10, word
[0]%10);
2102 s
= "?"; // Should not happen
2109 // Attribute names shouldn't be longer than 23 chars, otherwise they break the
2110 // output of smartctl.
2111 static const char * get_default_attr_name(unsigned char id
)
2115 return "Raw_Read_Error_Rate";
2117 return "Throughput_Performance";
2119 return "Spin_Up_Time";
2121 return "Start_Stop_Count";
2123 return "Reallocated_Sector_Ct";
2125 return "Read_Channel_Margin";
2127 return "Seek_Error_Rate";
2129 return "Seek_Time_Performance";
2131 return "Power_On_Hours";
2133 return "Spin_Retry_Count";
2135 return "Calibration_Retry_Count";
2137 return "Power_Cycle_Count";
2139 return "Read_Soft_Error_Rate";
2141 return "Program_Fail_Count_Chip";
2143 return "Erase_Fail_Count_Chip";
2145 return "Wear_Leveling_Count";
2147 return "Used_Rsvd_Blk_Cnt_Chip";
2149 return "Used_Rsvd_Blk_Cnt_Tot";
2151 return "Unused_Rsvd_Blk_Cnt_Tot";
2153 return "Program_Fail_Cnt_Total";
2155 return "Erase_Fail_Count_Total";
2157 return "Runtime_Bad_Block";
2159 return "End-to-End_Error";
2161 return "Reported_Uncorrect";
2163 return "Command_Timeout";
2165 return "High_Fly_Writes";
2167 // Western Digital uses this for temperature.
2168 // It's identical to Attribute 194 except that it
2169 // has a failure threshold set to correspond to the
2170 // max allowed operating temperature of the drive, which
2171 // is typically 55C. So if this attribute has failed
2172 // in the past, it indicates that the drive temp exceeded
2173 // 55C sometime in the past.
2174 return "Airflow_Temperature_Cel";
2176 return "G-Sense_Error_Rate";
2178 return "Power-Off_Retract_Count";
2180 return "Load_Cycle_Count";
2182 return "Temperature_Celsius";
2184 // Fujitsu: "ECC_On_The_Fly_Count";
2185 return "Hardware_ECC_Recovered";
2187 return "Reallocated_Event_Count";
2189 return "Current_Pending_Sector";
2191 return "Offline_Uncorrectable";
2193 return "UDMA_CRC_Error_Count";
2196 return "Multi_Zone_Error_Rate";
2198 return "Soft_Read_Error_Rate";
2200 // Fujitsu: "TA_Increase_Count"
2201 return "Data_Address_Mark_Errs";
2204 return "Run_Out_Cancel";
2205 // Maxtor: ECC Errors
2207 // Fujitsu: "Shock_Count_Write_Opern"
2208 return "Soft_ECC_Correction";
2210 // Fujitsu: "Shock_Rate_Write_Opern"
2211 return "Thermal_Asperity_Rate";
2214 return "Flying_Height";
2217 return "Spin_High_Current";
2223 return "Offline_Seek_Performnce";
2225 return "Disk_Shift";
2227 return "G-Sense_Error_Rate";
2229 return "Loaded_Hours";
2231 return "Load_Retry_Count";
2233 return "Load_Friction";
2235 return "Load_Cycle_Count";
2237 return "Load-in_Time";
2239 return "Torq-amp_Count";
2241 return "Power-off_Retract_Count";
2243 // seen in IBM DTPA-353750
2244 return "Head_Amplitude";
2246 return "Temperature_Celsius";
2248 // seen in Intel X25-E SSD
2249 return "Available_Reservd_Space";
2251 // seen in Intel X25-E SSD
2252 return "Media_Wearout_Indicator";
2254 return "Head_Flying_Hours";
2256 return "Total_LBAs_Written";
2258 return "Total_LBAs_Read";
2260 return "Read_Error_Retry_Rate";
2262 return "Free_Fall_Sensor";
2264 return "Unknown_Attribute";
2268 // Get attribute name
2269 std::string
ata_get_smart_attr_name(unsigned char id
, const ata_vendor_attr_defs
& defs
)
2271 if (!defs
[id
].name
.empty())
2272 return defs
[id
].name
;
2274 return get_default_attr_name(id
);
2277 // Find attribute index for attribute id, -1 if not found.
2278 int ata_find_attr_index(unsigned char id
, const ata_smart_values
& smartval
)
2282 for (int i
= 0; i
< NUMBER_ATA_SMART_ATTRIBUTES
; i
++) {
2283 if (smartval
.vendor_attributes
[i
].id
== id
)
2289 // Return Temperature Attribute raw value selected according to possible
2290 // non-default interpretations. If the Attribute does not exist, return 0
2291 unsigned char ata_return_temperature_value(const ata_smart_values
* data
, const ata_vendor_attr_defs
& defs
)
2293 for (int i
= 0; i
< 3; i
++) {
2294 static const unsigned char ids
[3] = {194, 9, 220};
2295 unsigned char id
= ids
[i
];
2296 const ata_attr_raw_format format
= defs
[id
].raw_format
;
2297 if (!( (id
== 194 && format
== RAWFMT_DEFAULT
)
2298 || format
== RAWFMT_TEMPMINMAX
|| format
== RAWFMT_TEMP10X
))
2300 int idx
= ata_find_attr_index(id
, *data
);
2303 uint64_t raw
= ata_get_attr_raw_value(data
->vendor_attributes
[idx
], defs
);
2304 unsigned temp
= (unsigned short)raw
; // ignore possible min/max values in high words
2305 if (format
== RAWFMT_TEMP10X
) // -v N,temp10x
2306 temp
= (temp
+5) / 10;
2307 if (!(0 < temp
&& temp
<= 255))
2311 // No valid attribute found
2317 int ataReadSCTStatus(ata_device
* device
, ata_sct_status_response
* sts
)
2319 // read SCT status via SMART log 0xe0
2320 memset(sts
, 0, sizeof(*sts
));
2321 if (smartcommandhandler(device
, READ_LOG
, 0xe0, (char *)sts
)){
2322 pout("Error Read SCT Status failed: %s\n", device
->get_errmsg());
2326 // swap endian order if needed
2328 swapx(&sts
->format_version
);
2329 swapx(&sts
->sct_version
);
2330 swapx(&sts
->sct_spec
);
2331 swapx(&sts
->ext_status_code
);
2332 swapx(&sts
->action_code
);
2333 swapx(&sts
->function_code
);
2334 swapx(&sts
->over_limit_count
);
2335 swapx(&sts
->under_limit_count
);
2338 // Check format version
2339 if (!(sts
->format_version
== 2 || sts
->format_version
== 3)) {
2340 pout("Error unknown SCT Status format version %u, should be 2 or 3.\n", sts
->format_version
);
2346 // Read SCT Temperature History Table and Status
2347 int ataReadSCTTempHist(ata_device
* device
, ata_sct_temperature_history_table
* tmh
,
2348 ata_sct_status_response
* sts
)
2350 // Check initial status
2351 if (ataReadSCTStatus(device
, sts
))
2354 // Do nothing if other SCT command is executing
2355 if (sts
->ext_status_code
== 0xffff) {
2356 pout("Another SCT command is executing, abort Read Data Table\n"
2357 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2358 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2362 ata_sct_data_table_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2363 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2364 cmd
.action_code
= 5; // Data table command
2365 cmd
.function_code
= 1; // Read table
2366 cmd
.table_id
= 2; // Temperature History Table
2368 // swap endian order if needed
2369 if (isbigendian()) {
2370 swapx(&cmd
.action_code
);
2371 swapx(&cmd
.function_code
);
2372 swapx(&cmd
.table_id
);
2375 // write command via SMART log page 0xe0
2376 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2377 pout("Error Write SCT Data Table command failed: %s\n", device
->get_errmsg());
2381 // read SCT data via SMART log page 0xe1
2382 memset(tmh
, 0, sizeof(*tmh
));
2383 if (smartcommandhandler(device
, READ_LOG
, 0xe1, (char *)tmh
)){
2384 pout("Error Read SCT Data Table failed: %s\n", device
->get_errmsg());
2388 // re-read and check SCT status
2389 if (ataReadSCTStatus(device
, sts
))
2392 if (!(sts
->ext_status_code
== 0 && sts
->action_code
== 5 && sts
->function_code
== 1)) {
2393 pout("Error unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2394 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2398 // swap endian order if needed
2400 swapx(&tmh
->format_version
);
2401 swapx(&tmh
->sampling_period
);
2402 swapx(&tmh
->interval
);
2405 // Check format version
2406 if (tmh
->format_version
!= 2) {
2407 pout("Error unknown SCT Temperature History Format Version (%u), should be 2.\n", tmh
->format_version
);
2413 // Set SCT Temperature Logging Interval
2414 int ataSetSCTTempInterval(ata_device
* device
, unsigned interval
, bool persistent
)
2416 // Check initial status
2417 ata_sct_status_response sts
;
2418 if (ataReadSCTStatus(device
, &sts
))
2421 // Do nothing if other SCT command is executing
2422 if (sts
.ext_status_code
== 0xffff) {
2423 pout("Another SCT command is executing, abort Feature Control\n"
2424 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2425 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2429 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2430 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2431 cmd
.action_code
= 4; // Feature Control command
2432 cmd
.function_code
= 1; // Set state
2433 cmd
.feature_code
= 3; // Temperature logging interval
2434 cmd
.state
= interval
;
2435 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2437 // swap endian order if needed
2438 if (isbigendian()) {
2439 swapx(&cmd
.action_code
);
2440 swapx(&cmd
.function_code
);
2441 swapx(&cmd
.feature_code
);
2443 swapx(&cmd
.option_flags
);
2446 // write command via SMART log page 0xe0
2447 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2448 pout("Error Write SCT Feature Control Command failed: %s\n", device
->get_errmsg());
2452 // re-read and check SCT status
2453 if (ataReadSCTStatus(device
, &sts
))
2456 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== 1)) {
2457 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2458 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2464 // Get/Set SCT Error Recovery Control
2465 static int ataGetSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
,
2466 bool set
, unsigned short & time_limit
)
2468 // Check initial status
2469 ata_sct_status_response sts
;
2470 if (ataReadSCTStatus(device
, &sts
))
2473 // Do nothing if other SCT command is executing
2474 if (sts
.ext_status_code
== 0xffff) {
2475 pout("Another SCT command is executing, abort Error Recovery Control\n"
2476 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2477 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2481 ata_sct_error_recovery_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2482 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2483 cmd
.action_code
= 3; // Error Recovery Control command
2484 cmd
.function_code
= (set
? 1 : 2); // 1=Set timer, 2=Get timer
2485 cmd
.selection_code
= type
; // 1=Read timer, 2=Write timer
2487 cmd
.time_limit
= time_limit
;
2489 // swap endian order if needed
2490 if (isbigendian()) {
2491 swapx(&cmd
.action_code
);
2492 swapx(&cmd
.function_code
);
2493 swapx(&cmd
.selection_code
);
2494 swapx(&cmd
.time_limit
);
2497 // write command via SMART log page 0xe0
2498 // TODO: Debug output
2500 in
.in_regs
.command
= ATA_SMART_CMD
;
2501 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
2502 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
2503 in
.in_regs
.lba_low
= 0xe0;
2504 in
.set_data_out(&cmd
, 1);
2507 // Time limit returned in ATA registers
2508 in
.out_needed
.sector_count
= in
.out_needed
.lba_low
= true;
2511 if (!device
->ata_pass_through(in
, out
)) {
2512 pout("Error Write SCT (%cet) Error Recovery Control Command failed: %s\n",
2513 (!set
? 'G' : 'S'), device
->get_errmsg());
2517 // re-read and check SCT status
2518 if (ataReadSCTStatus(device
, &sts
))
2521 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 3 && sts
.function_code
== (set
? 1 : 2))) {
2522 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2523 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2528 // Check whether registers are properly returned by ioctl()
2529 if (!(out
.out_regs
.sector_count
.is_set() && out
.out_regs
.lba_low
.is_set())) {
2530 // TODO: Output register support should be checked within each ata_pass_through()
2531 // implementation before command is issued.
2532 pout("Error SMART WRITE LOG does not return COUNT and LBA_LOW register\n");
2535 // Return value to caller
2536 time_limit
= out
.out_regs
.sector_count
| (out
.out_regs
.lba_low
<< 8);
2542 // Get SCT Error Recovery Control
2543 int ataGetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short & time_limit
)
2545 return ataGetSetSCTErrorRecoveryControltime(device
, type
, false/*get*/, time_limit
);
2548 // Set SCT Error Recovery Control
2549 int ataSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short time_limit
)
2551 return ataGetSetSCTErrorRecoveryControltime(device
, type
, true/*set*/, time_limit
);
2555 // Print one self-test log entry.
2557 // -1: self-test failed
2558 // 1: extended self-test completed without error
2560 int ataPrintSmartSelfTestEntry(unsigned testnum
, unsigned char test_type
,
2561 unsigned char test_status
,
2562 unsigned short timestamp
,
2563 uint64_t failing_lba
,
2564 bool print_error_only
, bool & print_header
)
2566 // Check status and type for return value
2568 switch (test_status
>> 4) {
2570 if ((test_type
& 0x0f) == 0x02)
2571 retval
= 1; // extended self-test completed without error
2576 retval
= -1; // self-test failed
2580 if (retval
>= 0 && print_error_only
)
2583 std::string msgtest
;
2584 switch (test_type
) {
2585 case 0x00: msgtest
= "Offline"; break;
2586 case 0x01: msgtest
= "Short offline"; break;
2587 case 0x02: msgtest
= "Extended offline"; break;
2588 case 0x03: msgtest
= "Conveyance offline"; break;
2589 case 0x04: msgtest
= "Selective offline"; break;
2590 case 0x7f: msgtest
= "Abort offline test"; break;
2591 case 0x81: msgtest
= "Short captive"; break;
2592 case 0x82: msgtest
= "Extended captive"; break;
2593 case 0x83: msgtest
= "Conveyance captive"; break;
2594 case 0x84: msgtest
= "Selective captive"; break;
2596 if ((0x40 <= test_type
&& test_type
<= 0x7e) || 0x90 <= test_type
)
2597 msgtest
= strprintf("Vendor (0x%02x)", test_type
);
2599 msgtest
= strprintf("Reserved (0x%02x)", test_type
);
2602 std::string msgstat
;
2603 switch (test_status
>> 4) {
2604 case 0x0: msgstat
= "Completed without error"; break;
2605 case 0x1: msgstat
= "Aborted by host"; break;
2606 case 0x2: msgstat
= "Interrupted (host reset)"; break;
2607 case 0x3: msgstat
= "Fatal or unknown error"; break;
2608 case 0x4: msgstat
= "Completed: unknown failure"; break;
2609 case 0x5: msgstat
= "Completed: electrical failure"; break;
2610 case 0x6: msgstat
= "Completed: servo/seek failure"; break;
2611 case 0x7: msgstat
= "Completed: read failure"; break;
2612 case 0x8: msgstat
= "Completed: handling damage??"; break;
2613 case 0xf: msgstat
= "Self-test routine in progress"; break;
2614 default: msgstat
= strprintf("Unknown status (0x%x)", test_status
>> 4);
2617 // Print header once
2619 print_header
= false;
2620 pout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2624 if (retval
< 0 && failing_lba
< 0xffffffffffffULL
)
2625 snprintf(msglba
, sizeof(msglba
), "%"PRIu64
, failing_lba
);
2627 strcpy(msglba
, "-");
2629 pout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum
,
2630 msgtest
.c_str(), msgstat
.c_str(), test_status
& 0x0f, timestamp
, msglba
);
2635 // Print Smart self-test log, used by smartctl and smartd.
2637 // bottom 8 bits: number of entries found where self-test showed an error
2638 // remaining bits: if nonzero, power on hours of last self-test where error was found
2639 int ataPrintSmartSelfTestlog(const ata_smart_selftestlog
* data
, bool allentries
,
2640 unsigned char fix_firmwarebug
)
2643 pout("SMART Self-test log structure revision number %d\n",(int)data
->revnumber
);
2644 if ((data
->revnumber
!=0x0001) && allentries
&& fix_firmwarebug
!= FIX_SAMSUNG
)
2645 pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2646 if (data
->mostrecenttest
==0){
2648 pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
2652 bool noheaderprinted
= true;
2653 int errcnt
= 0, hours
= 0, igncnt
= 0;
2654 int testno
= 0, ext_ok_testno
= -1;
2657 for (int i
= 20; i
>= 0; i
--) {
2658 // log is a circular buffer
2659 int j
= (i
+data
->mostrecenttest
)%21;
2660 const ata_smart_selftestlog_struct
* log
= data
->selftest_struct
+j
;
2662 if (nonempty(log
, sizeof(*log
))) {
2663 // count entry based on non-empty structures -- needed for
2664 // Seagate only -- other vendors don't have blank entries 'in
2668 // T13/1321D revision 1c: (Data structure Rev #1)
2670 //The failing LBA shall be the LBA of the uncorrectable sector
2671 //that caused the test to fail. If the device encountered more
2672 //than one uncorrectable sector during the test, this field
2673 //shall indicate the LBA of the first uncorrectable sector
2674 //encountered. If the test passed or the test failed for some
2675 //reason other than an uncorrectable sector, the value of this
2676 //field is undefined.
2678 // This is true in ALL ATA-5 specs
2679 uint64_t lba48
= (log
->lbafirstfailure
< 0xffffffff ? log
->lbafirstfailure
: 0xffffffffffffULL
);
2682 int state
= ataPrintSmartSelfTestEntry(testno
,
2683 log
->selftestnumber
, log
->selfteststatus
,
2684 log
->timestamp
, lba48
, !allentries
, noheaderprinted
);
2687 // Self-test showed an error
2688 if (ext_ok_testno
< 0) {
2691 // keep track of time of most recent error
2693 hours
= log
->timestamp
;
2696 // Newer successful extended self-test exits
2699 else if (state
> 0 && ext_ok_testno
< 0) {
2700 // Latest successful extended self-test
2701 ext_ok_testno
= testno
;
2707 pout("%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2708 igncnt
, igncnt
+errcnt
, ext_ok_testno
);
2710 if (!allentries
&& !noheaderprinted
)
2713 return ((hours
<< 8) | errcnt
);
2717 /////////////////////////////////////////////////////////////////////////////
2718 // Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2719 // an ATA device with same behaviour
2723 class parsed_ata_device
2724 : public /*implements*/ ata_device_with_command_set
2727 parsed_ata_device(smart_interface
* intf
, const char * dev_name
);
2729 virtual ~parsed_ata_device() throw();
2731 virtual bool is_open() const;
2733 virtual bool open();
2735 virtual bool close();
2737 virtual bool ata_identify_is_cached() const;
2740 virtual int ata_command_interface(smart_command_set command
, int select
, char * data
);
2743 // Table of parsed commands, return value, data
2744 struct parsed_ata_command
2746 smart_command_set command
;
2752 enum { max_num_commands
= 32 };
2753 parsed_ata_command m_command_table
[max_num_commands
];
2756 int m_next_replay_command
;
2757 bool m_replay_out_of_sync
;
2758 bool m_ata_identify_is_cached
;
2761 static const char * nextline(const char * s
, int & lineno
)
2763 for (s
+= strcspn(s
, "\r\n"); *s
== '\r' || *s
== '\n'; s
++) {
2764 if (*s
== '\r' && s
[1] == '\n')
2771 static int name2command(const char * s
)
2773 for (int i
= 0; i
< (int)(sizeof(commandstrings
)/sizeof(commandstrings
[0])); i
++) {
2774 if (!strcmp(s
, commandstrings
[i
]))
2780 static bool matchcpy(char * dest
, size_t size
, const char * src
, const regmatch_t
& srcmatch
)
2782 if (srcmatch
.rm_so
< 0)
2784 size_t n
= srcmatch
.rm_eo
- srcmatch
.rm_so
;
2787 memcpy(dest
, src
+ srcmatch
.rm_so
, n
);
2792 static inline int matchtoi(const char * src
, const regmatch_t
& srcmatch
, int defval
)
2794 if (srcmatch
.rm_so
< 0)
2796 return atoi(src
+ srcmatch
.rm_so
);
2799 parsed_ata_device::parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2800 : smart_device(intf
, dev_name
, "ata", ""),
2802 m_next_replay_command(0),
2803 m_replay_out_of_sync(false),
2804 m_ata_identify_is_cached(false)
2806 memset(m_command_table
, 0, sizeof(m_command_table
));
2809 parsed_ata_device::~parsed_ata_device() throw()
2814 bool parsed_ata_device::is_open() const
2816 return (m_num_commands
> 0);
2819 // Parse stdin and build command table
2820 bool parsed_ata_device::open()
2822 const char * pathname
= get_dev_name();
2823 if (strcmp(pathname
, "-"))
2824 return set_err(EINVAL
);
2825 pathname
= "<stdin>";
2827 char buffer
[64*1024];
2829 while (size
< (int)sizeof(buffer
)) {
2830 int nr
= fread(buffer
, 1, sizeof(buffer
), stdin
);
2836 return set_err(ENOENT
, "%s: Unexpected EOF", pathname
);
2837 if (size
>= (int)sizeof(buffer
))
2838 return set_err(EIO
, "%s: Buffer overflow", pathname
);
2841 // Regex to match output from "-r ataioctl,2"
2842 static const char pattern
[] = "^"
2844 "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
2846 "( InputParameter=([0-9]+))?" // (4 (5))
2848 "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2850 "[\r\n]" // EOL match necessary to match optional parts above
2852 "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2854 " *(En|Dis)abled status cached by OS, " // (11)
2858 const regular_expression
regex(pattern
, REG_EXTENDED
);
2861 const char * errmsg
= 0;
2862 int i
= -1, state
= 0, lineno
= 1;
2863 for (const char * line
= buffer
; *line
; line
= nextline(line
, lineno
)) {
2865 if (!(line
[0] == 'R' || line
[0] == '=' || line
[0] == ' '))
2867 const int nmatch
= 1+11;
2868 regmatch_t match
[nmatch
];
2869 if (!regex
.execute(line
, nmatch
, match
))
2873 if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[2])) { // "REPORT-IOCTL:... Command=%s ..."
2874 int nc
= name2command(cmdname
);
2876 errmsg
= "Unknown ATA command name"; break;
2878 if (match
[7].rm_so
< 0) { // "returned %d"
2880 if (!(state
== 0 || state
== 2)) {
2881 errmsg
= "Missing REPORT-IOCTL result"; break;
2883 if (++i
>= max_num_commands
) {
2884 errmsg
= "Too many ATA commands"; break;
2886 m_command_table
[i
].command
= (smart_command_set
)nc
;
2887 m_command_table
[i
].select
= matchtoi(line
, match
[5], 0); // "InputParameter=%d"
2892 if (!(state
== 1 && (int)m_command_table
[i
].command
== nc
)) {
2893 errmsg
= "Missing REPORT-IOCTL start"; break;
2895 m_command_table
[i
].retval
= matchtoi(line
, match
[7], -1); // "returned %d"
2896 m_command_table
[i
].errval
= matchtoi(line
, match
[9], 0); // "errno=%d"
2900 else if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[10])) { // "===== [%s] DATA START "
2901 // Start of sector hexdump
2902 int nc
= name2command(cmdname
);
2903 if (!(state
== (nc
== WRITE_LOG
? 1 : 2) && (int)m_command_table
[i
].command
== nc
)) {
2904 errmsg
= "Unexpected DATA START"; break;
2906 line
= nextline(line
, lineno
);
2907 char * data
= (char *)malloc(512);
2909 for (j
= 0; j
< 32; j
++) {
2911 unsigned u1
, u2
; int n1
= -1;
2912 if (!(sscanf(line
, "%3u-%3u: "
2913 "%2x %2x %2x %2x %2x %2x %2x %2x "
2914 "%2x %2x %2x %2x %2x %2x %2x %2x%n",
2916 b
+ 0, b
+ 1, b
+ 2, b
+ 3, b
+ 4, b
+ 5, b
+ 6, b
+ 7,
2917 b
+ 8, b
+ 9, b
+10, b
+11, b
+12, b
+13, b
+14, b
+15, &n1
) == 18
2918 && n1
>= 56 && u1
== j
*16 && u2
== j
*16+15))
2920 for (unsigned k
= 0; k
< 16; k
++)
2921 data
[j
*16+k
] = b
[k
];
2922 line
= nextline(line
, lineno
);
2926 errmsg
= "Incomplete sector hex dump"; break;
2928 m_command_table
[i
].data
= data
;
2929 if (nc
!= WRITE_LOG
)
2932 else if (match
[11].rm_so
> 0) { // "(En|Dis)abled status cached by OS"
2933 m_ata_identify_is_cached
= true;
2937 if (!(state
== 0 || state
== 2))
2938 errmsg
= "Missing REPORT-IOCTL result";
2940 if (!errmsg
&& i
< 0)
2941 errmsg
= "No information found";
2943 m_num_commands
= i
+1;
2944 m_next_replay_command
= 0;
2945 m_replay_out_of_sync
= false;
2949 return set_err(EIO
, "%s(%d): Syntax error: %s", pathname
, lineno
, errmsg
);
2954 // Report warnings and free command table
2955 bool parsed_ata_device::close()
2957 if (m_replay_out_of_sync
)
2958 pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
2959 else if (m_next_replay_command
!= 0)
2960 pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands
-m_next_replay_command
);
2962 for (int i
= 0; i
< m_num_commands
; i
++) {
2963 if (m_command_table
[i
].data
) {
2964 free(m_command_table
[i
].data
); m_command_table
[i
].data
= 0;
2968 m_next_replay_command
= 0;
2969 m_replay_out_of_sync
= false;
2974 bool parsed_ata_device::ata_identify_is_cached() const
2976 return m_ata_identify_is_cached
;
2980 // Simulate ATA command from command table
2981 int parsed_ata_device::ata_command_interface(smart_command_set command
, int select
, char * data
)
2983 // Find command, try round-robin if out of sync
2984 int i
= m_next_replay_command
;
2985 for (int j
= 0; ; j
++) {
2986 if (j
>= m_num_commands
) {
2987 pout("REPLAY-IOCTL: Warning: Command not found\n");
2991 if (m_command_table
[i
].command
== command
&& m_command_table
[i
].select
== select
)
2993 if (!m_replay_out_of_sync
) {
2994 m_replay_out_of_sync
= true;
2995 pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i
+1);
2997 if (++i
>= m_num_commands
)
3000 m_next_replay_command
= i
;
3001 if (++m_next_replay_command
>= m_num_commands
)
3002 m_next_replay_command
= 0;
3004 // Return command data
3009 case READ_THRESHOLDS
:
3011 if (m_command_table
[i
].data
)
3012 memcpy(data
, m_command_table
[i
].data
, 512);
3015 if (!(m_command_table
[i
].data
&& !memcmp(data
, m_command_table
[i
].data
, 512)))
3016 pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
3018 case CHECK_POWER_MODE
:
3019 data
[0] = (char)0xff;
3024 if (m_command_table
[i
].errval
)
3025 errno
= m_command_table
[i
].errval
;
3026 return m_command_table
[i
].retval
;
3031 ata_device
* get_parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
3033 return new parsed_ata_device(intf
, dev_name
);