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 3288 2011-03-09 18:40:36Z 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 adjust checksum in IDENTIFY data
389 static void invalidate_serno(ata_identify_device
* id
){
390 unsigned char sum
= 0;
391 for (unsigned i
= 0; i
< sizeof(id
->serial_no
); i
++) {
392 sum
+= id
->serial_no
[i
]; sum
-= id
->serial_no
[i
] = 'X';
395 bool must_swap
= !!isbigendian();
397 swapx(id
->words088_255
+255-88);
399 if ((id
->words088_255
[255-88] & 0x00ff) == 0x00a5)
400 id
->words088_255
[255-88] += sum
<< 8;
403 swapx(id
->words088_255
+255-88);
407 static const char * const commandstrings
[]={
410 "SMART AUTOMATIC ATTRIBUTE SAVE",
411 "SMART IMMEDIATE OFFLINE",
412 "SMART AUTO OFFLINE",
414 "SMART STATUS CHECK",
415 "SMART READ ATTRIBUTE VALUES",
416 "SMART READ ATTRIBUTE THRESHOLDS",
419 "IDENTIFY PACKET DEVICE",
422 "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT
")\n"
426 static const char * preg(const ata_register
& r
, char * buf
)
431 sprintf(buf
, "0x%02x", r
.val()); return buf
;
434 static void print_regs(const char * prefix
, const ata_in_regs
& r
, const char * suffix
= "\n")
436 char bufs
[7][4+1+13];
437 pout("%s FR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, CMD=%s%s", prefix
,
438 preg(r
.features
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
439 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
440 preg(r
.command
, bufs
[6]), suffix
);
443 static void print_regs(const char * prefix
, const ata_out_regs
& r
, const char * suffix
= "\n")
445 char bufs
[7][4+1+13];
446 pout("%sERR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, STS=%s%s", prefix
,
447 preg(r
.error
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
448 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
449 preg(r
.status
, bufs
[6]), suffix
);
452 static void prettyprint(const unsigned char *p
, const char *name
){
453 pout("\n===== [%s] DATA START (BASE-16) =====\n", name
);
454 for (int i
=0; i
<512; i
+=16, p
+=16)
455 #define P(n) (isprint((int)(p[n]))?(int)(p[n]):'.')
456 // print complete line to avoid slow tty output and extra lines in syslog.
457 pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x "
458 "%02x %02x %02x %02x %02x %02x %02x %02x"
459 " |%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c|"
462 p
[ 0], p
[ 1], p
[ 2], p
[ 3], p
[ 4], p
[ 5], p
[ 6], p
[ 7],
463 p
[ 8], p
[ 9], p
[10], p
[11], p
[12], p
[13], p
[14], p
[15],
464 P( 0), P( 1), P( 2), P( 3), P( 4), P( 5), P( 6), P( 7),
465 P( 8), P( 9), P(10), P(11), P(12), P(13), P(14), P(15),
468 pout("===== [%s] DATA END (512 Bytes) =====\n\n", name
);
471 // This function provides the pretty-print reporting for SMART
472 // commands: it implements the various -r "reporting" options for ATA
474 int smartcommandhandler(ata_device
* device
, smart_command_set command
, int select
, char *data
){
475 // TODO: Rework old stuff below
476 // This conditional is true for commands that return data
477 int getsdata
=(command
==PIDENTIFY
||
480 command
==READ_THRESHOLDS
||
481 command
==READ_VALUES
||
482 command
==CHECK_POWER_MODE
);
484 int sendsdata
=(command
==WRITE_LOG
);
486 // If reporting is enabled, say what the command will be before it's executed
488 // conditional is true for commands that use parameters
489 int usesparam
=(command
==READ_LOG
||
490 command
==AUTO_OFFLINE
||
492 command
==IMMEDIATE_OFFLINE
||
495 pout("\nREPORT-IOCTL: Device=%s Command=%s", device
->get_dev_name(), commandstrings
[command
]);
497 pout(" InputParameter=%d\n", select
);
502 if ((getsdata
|| sendsdata
) && !data
){
503 pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings
[command
]);
507 // The reporting is cleaner, and we will find coding bugs faster, if
508 // the commands that failed clearly return empty (zeroed) data
511 if (command
==CHECK_POWER_MODE
)
514 memset(data
, '\0', 512);
518 // if requested, pretty-print the input data structure
519 if (ata_debugmode
> 1 && sendsdata
)
520 //pout("REPORT-IOCTL: Device=%s Command=%s\n", device->get_dev_name(), commandstrings[command]);
521 prettyprint((unsigned char *)data
, commandstrings
[command
]);
523 // now execute the command
527 // Set common register values
529 default: // SMART commands
530 in
.in_regs
.command
= ATA_SMART_CMD
;
531 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
533 case IDENTIFY
: case PIDENTIFY
: case CHECK_POWER_MODE
: // Non SMART commands
536 // Set specific values
539 in
.in_regs
.command
= ATA_IDENTIFY_DEVICE
;
540 in
.set_data_in(data
, 1);
543 in
.in_regs
.command
= ATA_IDENTIFY_PACKET_DEVICE
;
544 in
.set_data_in(data
, 1);
546 case CHECK_POWER_MODE
:
547 in
.in_regs
.command
= ATA_CHECK_POWER_MODE
;
548 in
.out_needed
.sector_count
= true; // Powermode returned here
551 in
.in_regs
.features
= ATA_SMART_READ_VALUES
;
552 in
.set_data_in(data
, 1);
554 case READ_THRESHOLDS
:
555 in
.in_regs
.features
= ATA_SMART_READ_THRESHOLDS
;
556 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
557 in
.set_data_in(data
, 1);
560 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
561 in
.in_regs
.lba_low
= select
;
562 in
.set_data_in(data
, 1);
565 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
566 in
.in_regs
.lba_low
= select
;
567 in
.set_data_out(data
, 1);
570 in
.in_regs
.features
= ATA_SMART_ENABLE
;
571 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
574 in
.in_regs
.features
= ATA_SMART_DISABLE
;
575 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
578 in
.out_needed
.lba_high
= in
.out_needed
.lba_mid
= true; // Status returned here
580 in
.in_regs
.features
= ATA_SMART_STATUS
;
583 in
.in_regs
.features
= ATA_SMART_AUTO_OFFLINE
;
584 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
587 in
.in_regs
.features
= ATA_SMART_AUTOSAVE
;
588 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
590 case IMMEDIATE_OFFLINE
:
591 in
.in_regs
.features
= ATA_SMART_IMMEDIATE_OFFLINE
;
592 in
.in_regs
.lba_low
= select
;
595 pout("Unrecognized command %d in smartcommandhandler()\n"
596 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
597 device
->set_err(ENOSYS
);
603 print_regs(" Input: ", in
.in_regs
,
604 (in
.direction
==ata_cmd_in::data_in
? " IN\n":
605 in
.direction
==ata_cmd_in::data_out
? " OUT\n":"\n"));
608 bool ok
= device
->ata_pass_through(in
, out
);
610 if (ata_debugmode
&& out
.out_regs
.is_set())
611 print_regs(" Output: ", out
.out_regs
);
613 if (ok
) switch (command
) {
617 case CHECK_POWER_MODE
:
618 data
[0] = out
.out_regs
.sector_count
;
622 // Cyl low and Cyl high unchanged means "Good SMART status"
623 if ((out
.out_regs
.lba_high
== SMART_CYL_HI
) &&
624 (out
.out_regs
.lba_mid
== SMART_CYL_LOW
))
626 // These values mean "Bad SMART status"
627 else if ((out
.out_regs
.lba_high
== SRET_STATUS_HI_EXCEEDED
) &&
628 (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
))
630 else if (out
.out_regs
.lba_mid
== SMART_CYL_LOW
) {
633 pout("SMART STATUS RETURN: half healthy response sequence, "
634 "probable SAT/USB truncation\n");
635 } else if (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
) {
638 pout("SMART STATUS RETURN: half unhealthy response sequence, "
639 "probable SAT/USB truncation\n");
641 // We haven't gotten output that makes sense; print out some debugging info
642 pout("Error SMART Status command failed\n");
643 pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE
);
644 pout("Register values returned from SMART Status command are:\n");
645 print_regs(" ", out
.out_regs
);
653 // If requested, invalidate serial number before any printing is done
654 if ((command
== IDENTIFY
|| command
== PIDENTIFY
) && !retval
&& dont_print_serial_number
)
655 invalidate_serno((ata_identify_device
*)data
);
657 // If reporting is enabled, say what output was produced by the command
659 if (device
->get_errno())
660 pout("REPORT-IOCTL: Device=%s Command=%s returned %d errno=%d [%s]\n",
661 device
->get_dev_name(), commandstrings
[command
], retval
,
662 device
->get_errno(), device
->get_errmsg());
664 pout("REPORT-IOCTL: Device=%s Command=%s returned %d\n",
665 device
->get_dev_name(), commandstrings
[command
], retval
);
667 // if requested, pretty-print the output data structure
668 if (ata_debugmode
> 1 && getsdata
) {
669 if (command
==CHECK_POWER_MODE
)
670 pout("Sector Count Register (BASE-16): %02x\n", (unsigned char)(*data
));
672 prettyprint((unsigned char *)data
, commandstrings
[command
]);
676 errno
= device
->get_errno(); // TODO: Callers should not call syserror()
680 // Get number of sectors from IDENTIFY sector. If the drive doesn't
681 // support LBA addressing or has no user writable sectors
682 // (eg, CDROM or DVD) then routine returns zero.
683 uint64_t get_num_sectors(const ata_identify_device
* drive
)
685 unsigned short command_set_2
= drive
->command_set_2
;
686 unsigned short capabilities_0
= drive
->words047_079
[49-47];
687 unsigned short sects_16
= drive
->words047_079
[60-47];
688 unsigned short sects_32
= drive
->words047_079
[61-47];
689 unsigned short lba_16
= drive
->words088_255
[100-88];
690 unsigned short lba_32
= drive
->words088_255
[101-88];
691 unsigned short lba_48
= drive
->words088_255
[102-88];
692 unsigned short lba_64
= drive
->words088_255
[103-88];
695 if (!(capabilities_0
& 0x0200))
698 // if drive supports LBA addressing, determine 32-bit LBA capacity
699 uint64_t lba32
= (unsigned int)sects_32
<< 16 |
700 (unsigned int)sects_16
<< 0 ;
703 // if drive supports 48-bit addressing, determine THAT capacity
704 if ((command_set_2
& 0xc000) == 0x4000 && (command_set_2
& 0x0400))
705 lba64
= (uint64_t)lba_64
<< 48 |
706 (uint64_t)lba_48
<< 32 |
707 (uint64_t)lba_32
<< 16 |
708 (uint64_t)lba_16
<< 0 ;
710 // return the larger of the two possible capacities
711 return (lba32
> lba64
? lba32
: lba64
);
714 // This function computes the checksum of a single disk sector (512
715 // bytes). Returns zero if checksum is OK, nonzero if the checksum is
716 // incorrect. The size (512) is correct for all SMART structures.
717 unsigned char checksum(const void * data
)
719 unsigned char sum
= 0;
720 for (int i
= 0; i
< 512; i
++)
721 sum
+= ((const unsigned char *)data
)[i
];
725 // Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
727 static void swapbytes(char * out
, const char * in
, size_t n
)
729 for (size_t i
= 0; i
< n
; i
+= 2) {
735 // Copies in to out, but removes leading and trailing whitespace.
736 static void trim(char * out
, const char * in
)
738 // Find the first non-space character (maybe none).
741 for (i
= 0; in
[i
]; i
++)
742 if (!isspace((int)in
[i
])) {
748 // There are no non-space characters.
753 // Find the last non-space character.
754 for (i
= strlen(in
)-1; i
>= first
&& isspace((int)in
[i
]); i
--)
758 strncpy(out
, in
+first
, last
-first
+1);
759 out
[last
-first
+1] = '\0';
762 // Convenience function for formatting strings from ata_identify_device
763 void ata_format_id_string(char * out
, const unsigned char * in
, int n
)
765 bool must_swap
= true;
767 /* NetBSD kernel delivers IDENTIFY data in host byte order (but all else is LE) */
768 // TODO: Handle NetBSD case in os_netbsd.cpp
770 must_swap
= !must_swap
;
776 strncpy(tmp
, (const char *)in
, n
);
778 swapbytes(tmp
, (const char *)in
, n
);
783 // returns -1 if command fails or the device is in Sleep mode, else
784 // value of Sector Count register. Sector Count result values:
785 // 00h device is in Standby mode.
786 // 80h device is in Idle mode.
787 // FFh device is in Active mode or Idle mode.
789 int ataCheckPowerMode(ata_device
* device
) {
790 unsigned char result
;
792 if ((smartcommandhandler(device
, CHECK_POWER_MODE
, 0, (char *)&result
)))
795 if (result
!=0 && result
!=0x80 && result
!=0xff)
796 pout("ataCheckPowerMode(): ATA CHECK POWER MODE returned unknown Sector Count Register value %02x\n", result
);
804 // Reads current Device Identity info (512 bytes) into buf. Returns 0
805 // if all OK. Returns -1 if no ATA Device identity can be
806 // established. Returns >0 if Device is ATA Packet Device (not SMART
807 // capable). The value of the integer helps identify the type of
808 // Packet device, which is useful so that the user can connect the
809 // formal device number with whatever object is inside their computer.
810 int ata_read_identity(ata_device
* device
, ata_identify_device
* buf
, bool fix_swapped_id
)
812 unsigned short *rawshort
=(unsigned short *)buf
;
813 unsigned char *rawbyte
=(unsigned char *)buf
;
815 // See if device responds either to IDENTIFY DEVICE or IDENTIFY
818 if ((smartcommandhandler(device
, IDENTIFY
, 0, (char *)buf
))){
819 if (smartcommandhandler(device
, PIDENTIFY
, 0, (char *)buf
)){
826 if (fix_swapped_id
) {
828 for (i
= 0; i
< sizeof(buf
->serial_no
)-1; i
+= 2)
829 swap2((char *)(buf
->serial_no
+i
));
830 for (i
= 0; i
< sizeof(buf
->fw_rev
)-1; i
+= 2)
831 swap2((char *)(buf
->fw_rev
+i
));
832 for (i
= 0; i
< sizeof(buf
->model
)-1; i
+= 2)
833 swap2((char *)(buf
->model
+i
));
837 // if machine is big-endian, swap byte order as needed
838 // NetBSD kernel delivers IDENTIFY data in host byte order
839 // TODO: Handle NetBSD case in os_netbsd.cpp
842 // swap various capability words that are needed
844 swap2((char *)(buf
->words047_079
+i
));
846 for (i
=80; i
<=87; i
++)
847 swap2((char *)(rawshort
+i
));
849 for (i
=0; i
<168; i
++)
850 swap2((char *)(buf
->words088_255
+i
));
854 // If there is a checksum there, validate it
855 if ((rawshort
[255] & 0x00ff) == 0x00a5 && checksum(rawbyte
))
856 checksumwarning("Drive Identity Structure");
858 // AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
859 // T13/1699-D Revision 6a (Final Draft), September 6, 2008.
860 // Sections 7.16.7 and 7.17.6:
862 // Word 0 of IDENTIFY DEVICE data:
863 // Bit 15 = 0 : ATA device
865 // Word 0 of IDENTIFY PACKET DEVICE data:
866 // Bits 15:14 = 10b : ATAPI device
867 // Bits 15:14 = 11b : Reserved
868 // Bits 12:8 : Device type (SPC-4, e.g 0x05 = CD/DVD)
870 // CF+ and CompactFlash Specification Revision 4.0, May 24, 2006.
873 // Word 0 of IDENTIFY DEVICE data:
874 // 848Ah = Signature for CompactFlash Storage Card
875 // 044Ah = Alternate value turns on ATA device while preserving all retired bits
876 // 0040h = Alternate value turns on ATA device while zeroing all retired bits
878 // Assume ATA if IDENTIFY DEVICE returns CompactFlash Signature
879 if (!packet
&& rawbyte
[1] == 0x84 && rawbyte
[0] == 0x8a)
882 // If this is a PACKET DEVICE, return device type
883 if (rawbyte
[1] & 0x80)
884 return 1+(rawbyte
[1] & 0x1f);
886 // Not a PACKET DEVICE
890 // Returns ATA version as an integer, and a pointer to a string
891 // describing which revision. Note that Revision 0 of ATA-3 does NOT
892 // support SMART. For this one case we return -3 rather than +3 as
893 // the version number. See notes above.
894 int ataVersionInfo(const char ** description
, const ata_identify_device
* drive
, unsigned short * minor
)
896 // get major and minor ATA revision numbers
897 unsigned short major
= drive
->major_rev_num
;
898 *minor
=drive
->minor_rev_num
;
900 // First check if device has ANY ATA version information in it
901 if (major
==NOVAL_0
|| major
==NOVAL_1
) {
903 return 0; // No info found
906 // The minor revision number has more information - try there first
907 if (*minor
&& (*minor
<=MINOR_MAX
)){
908 int std
= actual_ver
[*minor
];
910 *description
=minor_str
[*minor
];
915 // Try new ATA-8 ACS minor revision numbers.
916 // Table 55 of T13/2015-D Revision 4a (ACS-2), December 9, 2010.
917 // (not in actual_ver/minor_str to avoid large sparse tables)
920 case 0x0027: desc
= "ATA-8-ACS revision 3c"; break;
921 case 0x0028: desc
= "ATA-8-ACS revision 6"; break;
922 case 0x0029: desc
= "ATA-8-ACS revision 4"; break;
923 case 0x0031: desc
= "ACS-2 revision 2"; break;
924 case 0x0033: desc
= "ATA-8-ACS revision 3e"; break;
925 case 0x0039: desc
= "ATA-8-ACS revision 4c"; break;
926 case 0x0042: desc
= "ATA-8-ACS revision 3f"; break;
927 case 0x0052: desc
= "ATA-8-ACS revision 3b"; break;
928 case 0x0107: desc
= "ATA-8-ACS revision 2d"; break;
929 case 0x0110: desc
= "ACS-2 revision 3"; break;
930 default: desc
= 0; break;
937 // HDPARM has a very complicated algorithm from here on. Since SMART only
938 // exists on ATA-3 and later standards, let's punt on this. If you don't
939 // like it, please fix it. The code's in CVS.
942 if (major
& (0x1<<i
))
952 // returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
953 int ataSmartSupport(const ata_identify_device
* drive
)
955 unsigned short word82
=drive
->command_set_1
;
956 unsigned short word83
=drive
->command_set_2
;
958 // check if words 82/83 contain valid info
959 if ((word83
>>14) == 0x01)
960 // return value of SMART support bit
961 return word82
& 0x0001;
963 // since we can're rely on word 82, we don't know if SMART supported
967 // returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
968 int ataIsSmartEnabled(const ata_identify_device
* drive
)
970 unsigned short word85
=drive
->cfs_enable_1
;
971 unsigned short word87
=drive
->csf_default
;
973 // check if words 85/86/87 contain valid info
974 if ((word87
>>14) == 0x01)
975 // return value of SMART enabled bit
976 return word85
& 0x0001;
978 // Since we can't rely word85, we don't know if SMART is enabled.
983 // Reads SMART attributes into *data
984 int ataReadSmartValues(ata_device
* device
, struct ata_smart_values
*data
){
986 if (smartcommandhandler(device
, READ_VALUES
, 0, (char *)data
)){
987 syserror("Error SMART Values Read failed");
993 checksumwarning("SMART Attribute Data Structure");
995 // swap endian order if needed
998 swap2((char *)&(data
->revnumber
));
999 swap2((char *)&(data
->total_time_to_complete_off_line
));
1000 swap2((char *)&(data
->smart_capability
));
1001 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
1002 struct ata_smart_attribute
*x
=data
->vendor_attributes
+i
;
1003 swap2((char *)&(x
->flags
));
1011 // This corrects some quantities that are byte reversed in the SMART
1013 static void fixsamsungselftestlog(ata_smart_selftestlog
* data
)
1015 // bytes 508/509 (numbered from 0) swapped (swap of self-test index
1016 // with one byte of reserved.
1017 swap2((char *)&(data
->mostrecenttest
));
1019 // LBA low register (here called 'selftestnumber", containing
1020 // information about the TYPE of the self-test) is byte swapped with
1021 // Self-test execution status byte. These are bytes N, N+1 in the
1023 for (int i
= 0; i
< 21; i
++)
1024 swap2((char *)&(data
->selftest_struct
[i
].selftestnumber
));
1029 // Reads the Self Test Log (log #6)
1030 int ataReadSelfTestLog (ata_device
* device
, ata_smart_selftestlog
* data
,
1031 unsigned char fix_firmwarebug
)
1034 // get data from device
1035 if (smartcommandhandler(device
, READ_LOG
, 0x06, (char *)data
)){
1036 syserror("Error SMART Error Self-Test Log Read failed");
1040 // compute its checksum, and issue a warning if needed
1042 checksumwarning("SMART Self-Test Log Structure");
1044 // fix firmware bugs in self-test log
1045 if (fix_firmwarebug
== FIX_SAMSUNG
)
1046 fixsamsungselftestlog(data
);
1048 // swap endian order if needed
1051 swap2((char*)&(data
->revnumber
));
1052 for (i
=0; i
<21; i
++){
1053 struct ata_smart_selftestlog_struct
*x
=data
->selftest_struct
+i
;
1054 swap2((char *)&(x
->timestamp
));
1055 swap4((char *)&(x
->lbafirstfailure
));
1062 // Print checksum warning for multi sector log
1063 static void check_multi_sector_sum(const void * data
, unsigned nsectors
, const char * msg
)
1066 for (unsigned i
= 0; i
< nsectors
; i
++) {
1067 if (checksum((const unsigned char *)data
+ i
*512))
1072 checksumwarning(msg
);
1074 checksumwarning(strprintf("%s (%u/%u)", msg
, errs
, nsectors
).c_str());
1078 // Read SMART Extended Self-test Log
1079 bool ataReadExtSelfTestLog(ata_device
* device
, ata_smart_extselftestlog
* log
,
1082 if (!ataReadLogExt(device
, 0x07, 0x00, 0, log
, nsectors
))
1085 check_multi_sector_sum(log
, nsectors
, "SMART Extended Self-test Log Structure");
1087 if (isbigendian()) {
1088 swapx(&log
->log_desc_index
);
1089 for (unsigned i
= 0; i
< nsectors
; i
++) {
1090 for (unsigned j
= 0; j
< 19; j
++)
1091 swapx(&log
->log_descs
[i
].timestamp
);
1098 // Read GP Log page(s)
1099 bool ataReadLogExt(ata_device
* device
, unsigned char logaddr
,
1100 unsigned char features
, unsigned page
,
1101 void * data
, unsigned nsectors
)
1104 in
.in_regs
.command
= ATA_READ_LOG_EXT
;
1105 in
.in_regs
.features
= features
; // log specific
1106 in
.set_data_in_48bit(data
, nsectors
);
1107 in
.in_regs
.lba_low
= logaddr
;
1108 in
.in_regs
.lba_mid_16
= page
;
1110 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1111 if (nsectors
<= 1) {
1112 pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n",
1113 logaddr
, features
, page
, nsectors
, device
->get_errmsg());
1117 // Recurse to retry with single sectors,
1118 // multi-sector reads may not be supported by ioctl.
1119 for (unsigned i
= 0; i
< nsectors
; i
++) {
1120 if (!ataReadLogExt(device
, logaddr
,
1122 (char *)data
+ 512*i
, 1))
1130 // Read SMART Log page(s)
1131 bool ataReadSmartLog(ata_device
* device
, unsigned char logaddr
,
1132 void * data
, unsigned nsectors
)
1135 in
.in_regs
.command
= ATA_SMART_CMD
;
1136 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
1137 in
.set_data_in(data
, nsectors
);
1138 in
.in_regs
.lba_high
= SMART_CYL_HI
;
1139 in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
1140 in
.in_regs
.lba_low
= logaddr
;
1142 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1143 pout("ATA_SMART_READ_LOG failed: %s\n", device
->get_errmsg());
1151 // Reads the SMART or GPL Log Directory (log #0)
1152 int ataReadLogDirectory(ata_device
* device
, ata_smart_log_directory
* data
, bool gpl
)
1154 if (!gpl
) { // SMART Log directory
1155 if (smartcommandhandler(device
, READ_LOG
, 0x00, (char *)data
))
1158 else { // GP Log directory
1159 if (!ataReadLogExt(device
, 0x00, 0x00, 0, data
, 1))
1163 // swap endian order if needed
1165 swapx(&data
->logversion
);
1171 // Reads the selective self-test log (log #9)
1172 int ataReadSelectiveSelfTestLog(ata_device
* device
, struct ata_selective_self_test_log
*data
){
1174 // get data from device
1175 if (smartcommandhandler(device
, READ_LOG
, 0x09, (char *)data
)){
1176 syserror("Error SMART Read Selective Self-Test Log failed");
1180 // compute its checksum, and issue a warning if needed
1182 checksumwarning("SMART Selective Self-Test Log Structure");
1184 // swap endian order if needed
1187 swap2((char *)&(data
->logversion
));
1189 swap8((char *)&(data
->span
[i
].start
));
1190 swap8((char *)&(data
->span
[i
].end
));
1192 swap8((char *)&(data
->currentlba
));
1193 swap2((char *)&(data
->currentspan
));
1194 swap2((char *)&(data
->flags
));
1195 swap2((char *)&(data
->pendingtime
));
1198 if (data
->logversion
!= 1)
1199 pout("Note: selective self-test log revision number (%d) not 1 implies that no selective self-test has ever been run\n", data
->logversion
);
1204 // Writes the selective self-test log (log #9)
1205 int ataWriteSelectiveSelfTestLog(ata_device
* device
, ata_selective_selftest_args
& args
,
1206 const ata_smart_values
* sv
, uint64_t num_sectors
,
1207 const ata_selective_selftest_args
* prev_args
)
1209 // Disk size must be known
1211 pout("Disk size is unknown, unable to check selective self-test spans\n");
1216 struct ata_selective_self_test_log sstlog
, *data
=&sstlog
;
1217 unsigned char *ptr
=(unsigned char *)data
;
1218 if (ataReadSelectiveSelfTestLog(device
, data
)) {
1219 pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
1224 data
->logversion
= 1;
1226 // Host is NOT allowed to write selective self-test log if a selective
1227 // self-test is in progress.
1228 if (0<data
->currentspan
&& data
->currentspan
<6 && ((sv
->self_test_exec_status
)>>4)==15) {
1229 pout("Error SMART Selective or other Self-Test in progress.\n");
1233 // Set start/end values based on old spans for special -t select,... options
1235 for (i
= 0; i
< args
.num_spans
; i
++) {
1236 int mode
= args
.span
[i
].mode
;
1237 uint64_t start
= args
.span
[i
].start
;
1238 uint64_t end
= args
.span
[i
].end
;
1239 if (mode
== SEL_CONT
) {// redo or next dependig on last test status
1240 switch (sv
->self_test_exec_status
>> 4) {
1241 case 1: case 2: // Aborted/Interrupted by host
1242 pout("Continue Selective Self-Test: Redo last span\n");
1245 default: // All others
1246 pout("Continue Selective Self-Test: Start next span\n");
1252 if ( (mode
== SEL_REDO
|| mode
== SEL_NEXT
)
1253 && prev_args
&& i
< prev_args
->num_spans
1254 && !data
->span
[i
].start
&& !data
->span
[i
].end
) {
1255 // Some drives do not preserve the selective self-test log accross
1256 // power-cyles. If old span on drive is cleared use span provided
1257 // by caller. This is used by smartd (first span only).
1258 data
->span
[i
].start
= prev_args
->span
[i
].start
;
1259 data
->span
[i
].end
= prev_args
->span
[i
].end
;
1263 case SEL_RANGE
: // -t select,START-END
1265 case SEL_REDO
: // -t select,redo... => Redo current
1266 start
= data
->span
[i
].start
;
1267 if (end
> 0) { // -t select,redo+SIZE
1268 end
--; end
+= start
; // [oldstart, oldstart+SIZE)
1270 else // -t select,redo
1271 end
= data
->span
[i
].end
; // [oldstart, oldend]
1273 case SEL_NEXT
: // -t select,next... => Do next
1274 if (data
->span
[i
].end
== 0) {
1275 start
= end
= 0; break; // skip empty spans
1277 start
= data
->span
[i
].end
+ 1;
1278 if (start
>= num_sectors
)
1279 start
= 0; // wrap around
1280 if (end
> 0) { // -t select,next+SIZE
1281 end
--; end
+= start
; // (oldend, oldend+SIZE]
1283 else { // -t select,next
1284 uint64_t oldsize
= data
->span
[i
].end
- data
->span
[i
].start
+ 1;
1285 end
= start
+ oldsize
- 1; // (oldend, oldend+oldsize]
1286 if (end
>= num_sectors
) {
1287 // Adjust size to allow round-robin testing without future size decrease
1288 uint64_t spans
= (num_sectors
+ oldsize
-1) / oldsize
;
1289 uint64_t newsize
= (num_sectors
+ spans
-1) / spans
;
1290 uint64_t newstart
= num_sectors
- newsize
, newend
= num_sectors
- 1;
1291 pout("Span %d changed from %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors)\n",
1292 i
, start
, end
, oldsize
);
1293 pout(" to %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors) (%"PRIu64
" spans)\n",
1294 newstart
, newend
, newsize
, spans
);
1295 start
= newstart
; end
= newend
;
1300 pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode
);
1304 if (start
< num_sectors
&& num_sectors
<= end
) {
1305 if (end
!= ~(uint64_t)0) // -t select,N-max
1306 pout("Size of self-test span %d decreased according to disk size\n", i
);
1307 end
= num_sectors
- 1;
1309 if (!(start
<= end
&& end
< num_sectors
)) {
1310 pout("Invalid selective self-test span %d: %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors)\n",
1311 i
, start
, end
, num_sectors
);
1314 // Return the actual mode and range to caller.
1315 args
.span
[i
].mode
= mode
;
1316 args
.span
[i
].start
= start
;
1317 args
.span
[i
].end
= end
;
1322 memset(data
->span
+i
, 0, sizeof(struct test_span
));
1324 // Set spans for testing
1325 for (i
= 0; i
< args
.num_spans
; i
++){
1326 data
->span
[i
].start
= args
.span
[i
].start
;
1327 data
->span
[i
].end
= args
.span
[i
].end
;
1330 // host must initialize to zero before initiating selective self-test
1332 data
->currentspan
=0;
1334 // Perform off-line scan after selective test?
1335 if (args
.scan_after_select
== 1)
1337 data
->flags
&= ~SELECTIVE_FLAG_DOSCAN
;
1338 else if (args
.scan_after_select
== 2)
1340 data
->flags
|= SELECTIVE_FLAG_DOSCAN
;
1342 // Must clear active and pending flags before writing
1343 data
->flags
&= ~(SELECTIVE_FLAG_ACTIVE
);
1344 data
->flags
&= ~(SELECTIVE_FLAG_PENDING
);
1346 // modify pending time?
1347 if (args
.pending_time
)
1348 data
->pendingtime
= (unsigned short)(args
.pending_time
-1);
1350 // Set checksum to zero, then compute checksum
1352 unsigned char cksum
=0;
1353 for (i
=0; i
<512; i
++)
1357 data
->checksum
=cksum
;
1359 // swap endian order if needed
1361 swap2((char *)&(data
->logversion
));
1362 for (int b
= 0; b
< 5; b
++) {
1363 swap8((char *)&(data
->span
[b
].start
));
1364 swap8((char *)&(data
->span
[b
].end
));
1366 swap8((char *)&(data
->currentlba
));
1367 swap2((char *)&(data
->currentspan
));
1368 swap2((char *)&(data
->flags
));
1369 swap2((char *)&(data
->pendingtime
));
1372 // write new selective self-test log
1373 if (smartcommandhandler(device
, WRITE_LOG
, 0x09, (char *)data
)){
1374 syserror("Error Write Selective Self-Test Log failed");
1381 // This corrects some quantities that are byte reversed in the SMART
1383 static void fixsamsungerrorlog(ata_smart_errorlog
* data
)
1385 // FIXED IN SAMSUNG -25 FIRMWARE???
1386 // Device error count in bytes 452-3
1387 swap2((char *)&(data
->ata_error_count
));
1389 // FIXED IN SAMSUNG -22a FIRMWARE
1390 // step through 5 error log data structures
1391 for (int i
= 0; i
< 5; i
++){
1392 // step through 5 command data structures
1393 for (int j
= 0; j
< 5; j
++)
1394 // Command data structure 4-byte millisec timestamp. These are
1395 // bytes (N+8, N+9, N+10, N+11).
1396 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1397 // Error data structure two-byte hour life timestamp. These are
1398 // bytes (N+28, N+29).
1399 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1404 // NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
1405 static void fixsamsungerrorlog2(ata_smart_errorlog
* data
)
1407 // Device error count in bytes 452-3
1408 swap2((char *)&(data
->ata_error_count
));
1412 // Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1413 // Error Log is #2, and the Extended Comprehensive SMART Error log is
1415 int ataReadErrorLog (ata_device
* device
, ata_smart_errorlog
*data
,
1416 unsigned char fix_firmwarebug
)
1419 // get data from device
1420 if (smartcommandhandler(device
, READ_LOG
, 0x01, (char *)data
)){
1421 syserror("Error SMART Error Log Read failed");
1425 // compute its checksum, and issue a warning if needed
1427 checksumwarning("SMART ATA Error Log Structure");
1429 // Some disks have the byte order reversed in some SMART Summary
1430 // Error log entries
1431 if (fix_firmwarebug
== FIX_SAMSUNG
)
1432 fixsamsungerrorlog(data
);
1433 else if (fix_firmwarebug
== FIX_SAMSUNG2
)
1434 fixsamsungerrorlog2(data
);
1436 // swap endian order if needed
1440 // Device error count in bytes 452-3
1441 swap2((char *)&(data
->ata_error_count
));
1443 // step through 5 error log data structures
1444 for (i
=0; i
<5; i
++){
1445 // step through 5 command data structures
1447 // Command data structure 4-byte millisec timestamp
1448 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1449 // Error data structure life timestamp
1450 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1457 // Read Extended Comprehensive Error Log
1458 bool ataReadExtErrorLog(ata_device
* device
, ata_smart_exterrlog
* log
,
1461 if (!ataReadLogExt(device
, 0x03, 0x00, 0, log
, nsectors
))
1464 check_multi_sector_sum(log
, nsectors
, "SMART Extended Comprehensive Error Log Structure");
1466 if (isbigendian()) {
1467 swapx(&log
->device_error_count
);
1468 swapx(&log
->error_log_index
);
1470 for (unsigned i
= 0; i
< nsectors
; i
++) {
1471 for (unsigned j
= 0; j
< 4; j
++)
1472 swapx(&log
->error_logs
[i
].commands
[j
].timestamp
);
1473 swapx(&log
->error_logs
[i
].error
.timestamp
);
1481 int ataReadSmartThresholds (ata_device
* device
, struct ata_smart_thresholds_pvt
*data
){
1483 // get data from device
1484 if (smartcommandhandler(device
, READ_THRESHOLDS
, 0, (char *)data
)){
1485 syserror("Error SMART Thresholds Read failed");
1489 // compute its checksum, and issue a warning if needed
1491 checksumwarning("SMART Attribute Thresholds Structure");
1493 // swap endian order if needed
1495 swap2((char *)&(data
->revnumber
));
1500 int ataEnableSmart (ata_device
* device
){
1501 if (smartcommandhandler(device
, ENABLE
, 0, NULL
)){
1502 syserror("Error SMART Enable failed");
1508 int ataDisableSmart (ata_device
* device
){
1510 if (smartcommandhandler(device
, DISABLE
, 0, NULL
)){
1511 syserror("Error SMART Disable failed");
1517 int ataEnableAutoSave(ata_device
* device
){
1518 if (smartcommandhandler(device
, AUTOSAVE
, 241, NULL
)){
1519 syserror("Error SMART Enable Auto-save failed");
1525 int ataDisableAutoSave(ata_device
* device
){
1527 if (smartcommandhandler(device
, AUTOSAVE
, 0, NULL
)){
1528 syserror("Error SMART Disable Auto-save failed");
1534 // In *ALL* ATA standards the Enable/Disable AutoOffline command is
1535 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1536 // vendors still support it for backwards compatibility. IBM documents
1537 // it for some drives.
1538 int ataEnableAutoOffline (ata_device
* device
){
1540 /* timer hard coded to 4 hours */
1541 if (smartcommandhandler(device
, AUTO_OFFLINE
, 248, NULL
)){
1542 syserror("Error SMART Enable Automatic Offline failed");
1548 // Another Obsolete Command. See comments directly above, associated
1549 // with the corresponding Enable command.
1550 int ataDisableAutoOffline (ata_device
* device
){
1552 if (smartcommandhandler(device
, AUTO_OFFLINE
, 0, NULL
)){
1553 syserror("Error SMART Disable Automatic Offline failed");
1559 // If SMART is enabled, supported, and working, then this call is
1560 // guaranteed to return 1, else zero. Note that it should return 1
1561 // regardless of whether the disk's SMART status is 'healthy' or
1563 int ataDoesSmartWork(ata_device
* device
){
1564 int retval
=smartcommandhandler(device
, STATUS
, 0, NULL
);
1572 // This function uses a different interface (DRIVE_TASK) than the
1573 // other commands in this file.
1574 int ataSmartStatus2(ata_device
* device
){
1575 return smartcommandhandler(device
, STATUS_CHECK
, 0, NULL
);
1578 // This is the way to execute ALL tests: offline, short self-test,
1579 // extended self test, with and without captive mode, etc.
1580 // TODO: Move to ataprint.cpp ?
1581 int ataSmartTest(ata_device
* device
, int testtype
, const ata_selective_selftest_args
& selargs
,
1582 const ata_smart_values
* sv
, uint64_t num_sectors
)
1584 char cmdmsg
[128]; const char *type
, *captive
;
1585 int errornum
, cap
, retval
, select
=0;
1587 // Boolean, if set, says test is captive
1588 cap
=testtype
& CAPTIVE_MASK
;
1590 // Set up strings that describe the type of test
1596 if (testtype
==OFFLINE_FULL_SCAN
)
1598 else if (testtype
==SHORT_SELF_TEST
|| testtype
==SHORT_CAPTIVE_SELF_TEST
)
1599 type
="Short self-test";
1600 else if (testtype
==EXTEND_SELF_TEST
|| testtype
==EXTEND_CAPTIVE_SELF_TEST
)
1601 type
="Extended self-test";
1602 else if (testtype
==CONVEYANCE_SELF_TEST
|| testtype
==CONVEYANCE_CAPTIVE_SELF_TEST
)
1603 type
="Conveyance self-test";
1604 else if ((select
=(testtype
==SELECTIVE_SELF_TEST
|| testtype
==SELECTIVE_CAPTIVE_SELF_TEST
)))
1605 type
="Selective self-test";
1609 // If doing a selective self-test, first use WRITE_LOG to write the
1610 // selective self-test log.
1611 ata_selective_selftest_args selargs_io
= selargs
; // filled with info about actual spans
1612 if (select
&& (retval
= ataWriteSelectiveSelfTestLog(device
, selargs_io
, sv
, num_sectors
))) {
1614 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1618 // Print ouf message that we are sending the command to test
1619 if (testtype
==ABORT_SELF_TEST
)
1620 sprintf(cmdmsg
,"Abort SMART off-line mode self-test routine");
1622 sprintf(cmdmsg
, "SMART EXECUTE OFF-LINE IMMEDIATE subcommand 0x%02x", testtype
);
1624 sprintf(cmdmsg
,"Execute SMART %s routine immediately in %s mode",type
,captive
);
1625 pout("Sending command: \"%s\".\n",cmdmsg
);
1629 pout("SPAN STARTING_LBA ENDING_LBA\n");
1630 for (i
= 0; i
< selargs_io
.num_spans
; i
++)
1631 pout(" %d %20"PRId64
" %20"PRId64
"\n", i
,
1632 selargs_io
.span
[i
].start
,
1633 selargs_io
.span
[i
].end
);
1636 // Now send the command to test
1637 errornum
=smartcommandhandler(device
, IMMEDIATE_OFFLINE
, testtype
, NULL
);
1639 if (errornum
&& !(cap
&& errno
==EIO
)){
1641 sprintf(errormsg
,"Command \"%s\" failed",cmdmsg
);
1647 // Since the command succeeded, tell user
1648 if (testtype
==ABORT_SELF_TEST
)
1649 pout("Self-testing aborted!\n");
1651 pout("Drive command \"%s\" successful.\n", cmdmsg
);
1653 pout("Testing has begun.\n");
1658 /* Test Time Functions */
1659 int TestTime(const ata_smart_values
*data
, int testtype
)
1662 case OFFLINE_FULL_SCAN
:
1663 return (int) data
->total_time_to_complete_off_line
;
1664 case SHORT_SELF_TEST
:
1665 case SHORT_CAPTIVE_SELF_TEST
:
1666 return (int) data
->short_test_completion_time
;
1667 case EXTEND_SELF_TEST
:
1668 case EXTEND_CAPTIVE_SELF_TEST
:
1669 return (int) data
->extend_test_completion_time
;
1670 case CONVEYANCE_SELF_TEST
:
1671 case CONVEYANCE_CAPTIVE_SELF_TEST
:
1672 return (int) data
->conveyance_test_completion_time
;
1678 // This function tells you both about the ATA error log and the
1679 // self-test error log capability (introduced in ATA-5). The bit is
1680 // poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1681 // SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1682 // word 84 and 87. Top two bits must match the pattern 01. BEFORE
1683 // ATA-6 these top two bits still had to match the pattern 01, but the
1684 // remaining bits were reserved (==0).
1685 int isSmartErrorLogCapable (const ata_smart_values
* data
, const ata_identify_device
* identity
)
1687 unsigned short word84
=identity
->command_set_extension
;
1688 unsigned short word87
=identity
->csf_default
;
1689 int isata6
=identity
->major_rev_num
& (0x01<<6);
1690 int isata7
=identity
->major_rev_num
& (0x01<<7);
1692 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x01))
1695 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x01))
1698 // otherwise we'll use the poorly documented capability bit
1699 return data
->errorlog_capability
& 0x01;
1702 // See previous function. If the error log exists then the self-test
1703 // log should (must?) also exist.
1704 int isSmartTestLogCapable (const ata_smart_values
* data
, const ata_identify_device
*identity
)
1706 unsigned short word84
=identity
->command_set_extension
;
1707 unsigned short word87
=identity
->csf_default
;
1708 int isata6
=identity
->major_rev_num
& (0x01<<6);
1709 int isata7
=identity
->major_rev_num
& (0x01<<7);
1711 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x02))
1714 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x02))
1718 // otherwise we'll use the poorly documented capability bit
1719 return data
->errorlog_capability
& 0x01;
1723 int isGeneralPurposeLoggingCapable(const ata_identify_device
*identity
)
1725 unsigned short word84
=identity
->command_set_extension
;
1726 unsigned short word87
=identity
->csf_default
;
1728 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1729 // cleared to zero, the contents of word 84 contains valid support
1730 // information. If not, support information is not valid in this
1732 if ((word84
>>14) == 0x01)
1733 // If bit 5 of word 84 is set to one, the device supports the
1734 // General Purpose Logging feature set.
1735 return (word84
& (0x01 << 5));
1737 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1738 // cleared to zero, the contents of words (87:85) contain valid
1739 // information. If not, information is not valid in these words.
1740 if ((word87
>>14) == 0x01)
1741 // If bit 5 of word 87 is set to one, the device supports
1742 // the General Purpose Logging feature set.
1743 return (word87
& (0x01 << 5));
1750 // SMART self-test capability is also indicated in bit 1 of DEVICE
1751 // IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1752 // However this was only introduced in ATA-6 (but self-test log was in
1754 int isSupportExecuteOfflineImmediate(const ata_smart_values
*data
)
1756 return data
->offline_data_collection_capability
& 0x01;
1759 // Note in the ATA-5 standard, the following bit is listed as "Vendor
1760 // Specific". So it may not be reliable. The only use of this that I
1761 // have found is in IBM drives, where it is well-documented. See for
1762 // example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1763 // hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
1764 int isSupportAutomaticTimer(const ata_smart_values
* data
)
1766 return data
->offline_data_collection_capability
& 0x02;
1768 int isSupportOfflineAbort(const ata_smart_values
*data
)
1770 return data
->offline_data_collection_capability
& 0x04;
1772 int isSupportOfflineSurfaceScan(const ata_smart_values
* data
)
1774 return data
->offline_data_collection_capability
& 0x08;
1776 int isSupportSelfTest (const ata_smart_values
* data
)
1778 return data
->offline_data_collection_capability
& 0x10;
1780 int isSupportConveyanceSelfTest(const ata_smart_values
* data
)
1782 return data
->offline_data_collection_capability
& 0x20;
1784 int isSupportSelectiveSelfTest(const ata_smart_values
* data
)
1786 return data
->offline_data_collection_capability
& 0x40;
1789 // Get attribute state
1790 ata_attr_state
ata_get_attr_state(const ata_smart_attribute
& attr
,
1792 const ata_smart_threshold_entry
* thresholds
,
1793 const ata_vendor_attr_defs
& defs
,
1794 unsigned char * threshval
/* = 0 */)
1797 return ATTRSTATE_NON_EXISTING
;
1799 // Normalized values (current,worst,threshold) not valid
1800 // if specified by '-v' option.
1801 // (Some SSD disks uses these bytes to store raw value).
1802 if (defs
[attr
.id
].flags
& ATTRFLAG_NO_NORMVAL
)
1803 return ATTRSTATE_NO_NORMVAL
;
1805 // Normally threshold is at same index as attribute
1807 if (thresholds
[i
].id
!= attr
.id
) {
1808 // Find threshold id in table
1809 for (i
= 0; thresholds
[i
].id
!= attr
.id
; ) {
1810 if (++i
>= NUMBER_ATA_SMART_ATTRIBUTES
)
1811 // Threshold id missing or thresholds cannot be read
1812 return ATTRSTATE_NO_THRESHOLD
;
1815 unsigned char threshold
= thresholds
[i
].threshold
;
1817 // Return threshold if requested
1819 *threshval
= threshold
;
1821 // Don't report a failed attribute if its threshold is 0.
1822 // ATA-3 (X3T13/2008D Revision 7b) declares 0x00 as the "always passing"
1823 // threshold (Later ATA versions declare all thresholds as "obsolete").
1824 // In practice, threshold value 0 is often used for usage attributes.
1826 return ATTRSTATE_OK
;
1828 // Failed now if current value is below threshold
1829 if (attr
.current
<= threshold
)
1830 return ATTRSTATE_FAILED_NOW
;
1832 // Failed in the past if worst value is below threshold
1833 if (!(defs
[attr
.id
].flags
& ATTRFLAG_NO_WORSTVAL
) && attr
.worst
<= threshold
)
1834 return ATTRSTATE_FAILED_PAST
;
1836 return ATTRSTATE_OK
;
1839 // Get default raw value print format
1840 static ata_attr_raw_format
get_default_raw_format(unsigned char id
)
1843 case 3: // Spin-up time
1844 return RAWFMT_RAW16_OPT_AVG16
;
1846 case 5: // Reallocated sector count
1847 case 196: // Reallocated event count
1848 return RAWFMT_RAW16_OPT_RAW16
;
1850 case 190: // Temperature
1852 return RAWFMT_TEMPMINMAX
;
1855 return RAWFMT_RAW48
;
1859 // Get attribute raw value.
1860 uint64_t ata_get_attr_raw_value(const ata_smart_attribute
& attr
,
1861 const ata_vendor_attr_defs
& defs
)
1863 const ata_vendor_attr_defs::entry
& def
= defs
[attr
.id
];
1865 // Use default byteorder if not specified
1866 const char * byteorder
= def
.byteorder
;
1868 switch (def
.raw_format
) {
1871 byteorder
= "543210wv"; break;
1872 case RAWFMT_RAW24_DIV_RAW32
:
1873 case RAWFMT_MSEC24_HOUR32
:
1874 byteorder
= "r543210"; break;
1876 byteorder
= "543210"; break;
1880 // Build 64-bit value from selected bytes
1881 uint64_t rawvalue
= 0;
1882 for (int i
= 0; byteorder
[i
]; i
++) {
1884 switch (byteorder
[i
]) {
1885 case '0': b
= attr
.raw
[0]; break;
1886 case '1': b
= attr
.raw
[1]; break;
1887 case '2': b
= attr
.raw
[2]; break;
1888 case '3': b
= attr
.raw
[3]; break;
1889 case '4': b
= attr
.raw
[4]; break;
1890 case '5': b
= attr
.raw
[5]; break;
1891 case 'r': b
= attr
.reserv
; break;
1892 case 'v': b
= attr
.current
; break;
1893 case 'w': b
= attr
.worst
; break;
1894 default : b
= 0; break;
1896 rawvalue
<<= 8; rawvalue
|= b
;
1903 // Format attribute raw value.
1904 std::string
ata_format_attr_raw_value(const ata_smart_attribute
& attr
,
1905 const ata_vendor_attr_defs
& defs
)
1907 // Get 48 bit or 64 bit raw value
1908 uint64_t rawvalue
= ata_get_attr_raw_value(attr
, defs
);
1911 // TODO: rebuild raw[6] from rawvalue
1912 const unsigned char * raw
= attr
.raw
;
1914 word
[0] = raw
[0] | (raw
[1] << 8);
1915 word
[1] = raw
[2] | (raw
[3] << 8);
1916 word
[2] = raw
[4] | (raw
[5] << 8);
1919 ata_attr_raw_format format
= defs
[attr
.id
].raw_format
;
1920 if (format
== RAWFMT_DEFAULT
)
1921 format
= get_default_raw_format(attr
.id
);
1927 s
= strprintf("%d %d %d %d %d %d",
1928 raw
[5], raw
[4], raw
[3], raw
[2], raw
[1], raw
[0]);
1932 s
= strprintf("%u %u %u", word
[2], word
[1], word
[0]);
1937 s
= strprintf("%"PRIu64
, rawvalue
);
1941 s
= strprintf("0x%012"PRIx64
, rawvalue
);
1945 s
= strprintf("0x%016"PRIx64
, rawvalue
);
1948 case RAWFMT_RAW16_OPT_RAW16
:
1949 s
= strprintf("%u", word
[0]);
1950 if (word
[1] || word
[2])
1951 s
+= strprintf(" (%u, %u)", word
[2], word
[1]);
1954 case RAWFMT_RAW16_OPT_AVG16
:
1955 s
= strprintf("%u", word
[0]);
1957 s
+= strprintf(" (Average %u)", word
[1]);
1960 case RAWFMT_RAW24_DIV_RAW24
:
1961 s
= strprintf("%u/%u",
1962 (unsigned)(rawvalue
>> 24), (unsigned)(rawvalue
& 0x00ffffffULL
));
1965 case RAWFMT_RAW24_DIV_RAW32
:
1966 s
= strprintf("%u/%u",
1967 (unsigned)(rawvalue
>> 32), (unsigned)(rawvalue
& 0xffffffffULL
));
1970 case RAWFMT_MIN2HOUR
:
1973 int64_t temp
= word
[0]+(word
[1]<<16);
1974 int64_t tmp1
= temp
/60;
1975 int64_t tmp2
= temp
%60;
1976 s
= strprintf("%"PRIu64
"h+%02"PRIu64
"m", tmp1
, tmp2
);
1978 s
+= strprintf(" (%u)", word
[2]);
1982 case RAWFMT_SEC2HOUR
:
1985 int64_t hours
= rawvalue
/3600;
1986 int64_t minutes
= (rawvalue
-3600*hours
)/60;
1987 int64_t seconds
= rawvalue
%60;
1988 s
= strprintf("%"PRIu64
"h+%02"PRIu64
"m+%02"PRIu64
"s", hours
, minutes
, seconds
);
1992 case RAWFMT_HALFMIN2HOUR
:
1994 // 30-second counter
1995 int64_t hours
= rawvalue
/120;
1996 int64_t minutes
= (rawvalue
-120*hours
)/2;
1997 s
+= strprintf("%"PRIu64
"h+%02"PRIu64
"m", hours
, minutes
);
2001 case RAWFMT_MSEC24_HOUR32
:
2003 // hours + milliseconds
2004 unsigned hours
= (unsigned)(rawvalue
& 0xffffffffULL
);
2005 unsigned milliseconds
= (unsigned)(rawvalue
>> 32);
2006 unsigned seconds
= milliseconds
/ 1000;
2007 s
= strprintf("%uh+%02um+%02u.%03us",
2008 hours
, seconds
/ 60, seconds
% 60, milliseconds
% 1000);
2012 case RAWFMT_TEMPMINMAX
:
2014 s
= strprintf("%u", word
[0]);
2015 if (word
[1] || word
[2]) {
2016 unsigned lo
= ~0, hi
= ~0;
2018 // 00 HH 00 LL 00 TT (IBM)
2019 hi
= word
[2]; lo
= word
[1];
2021 else if (!word
[2]) {
2022 // 00 00 HH LL 00 TT (Maxtor)
2023 hi
= raw
[3]; lo
= raw
[2];
2026 unsigned t
= lo
; lo
= hi
; hi
= t
;
2028 if (lo
<= word
[0] && word
[0] <= hi
)
2029 s
+= strprintf(" (Min/Max %u/%u)", lo
, hi
);
2031 s
+= strprintf(" (%d %d %d %d)", raw
[5], raw
[4], raw
[3], raw
[2]);
2035 case RAWFMT_TEMP10X
:
2036 // ten times temperature in Celsius
2037 s
= strprintf("%d.%d", word
[0]/10, word
[0]%10);
2041 s
= "?"; // Should not happen
2048 // Attribute names shouldn't be longer than 23 chars, otherwise they break the
2049 // output of smartctl.
2050 static const char * get_default_attr_name(unsigned char id
)
2054 return "Raw_Read_Error_Rate";
2056 return "Throughput_Performance";
2058 return "Spin_Up_Time";
2060 return "Start_Stop_Count";
2062 return "Reallocated_Sector_Ct";
2064 return "Read_Channel_Margin";
2066 return "Seek_Error_Rate";
2068 return "Seek_Time_Performance";
2070 return "Power_On_Hours";
2072 return "Spin_Retry_Count";
2074 return "Calibration_Retry_Count";
2076 return "Power_Cycle_Count";
2078 return "Read_Soft_Error_Rate";
2080 return "Program_Fail_Count_Chip";
2082 return "Erase_Fail_Count_Chip";
2084 return "Wear_Leveling_Count";
2086 return "Used_Rsvd_Blk_Cnt_Chip";
2088 return "Used_Rsvd_Blk_Cnt_Tot";
2090 return "Unused_Rsvd_Blk_Cnt_Tot";
2092 return "Program_Fail_Cnt_Total";
2094 return "Erase_Fail_Count_Total";
2096 return "Runtime_Bad_Block";
2098 return "End-to-End_Error";
2100 return "Reported_Uncorrect";
2102 return "Command_Timeout";
2104 return "High_Fly_Writes";
2106 // Western Digital uses this for temperature.
2107 // It's identical to Attribute 194 except that it
2108 // has a failure threshold set to correspond to the
2109 // max allowed operating temperature of the drive, which
2110 // is typically 55C. So if this attribute has failed
2111 // in the past, it indicates that the drive temp exceeded
2112 // 55C sometime in the past.
2113 return "Airflow_Temperature_Cel";
2115 return "G-Sense_Error_Rate";
2117 return "Power-Off_Retract_Count";
2119 return "Load_Cycle_Count";
2121 return "Temperature_Celsius";
2123 // Fujitsu: "ECC_On_The_Fly_Count";
2124 return "Hardware_ECC_Recovered";
2126 return "Reallocated_Event_Count";
2128 return "Current_Pending_Sector";
2130 return "Offline_Uncorrectable";
2132 return "UDMA_CRC_Error_Count";
2135 return "Multi_Zone_Error_Rate";
2137 return "Soft_Read_Error_Rate";
2139 // Fujitsu: "TA_Increase_Count"
2140 return "Data_Address_Mark_Errs";
2143 return "Run_Out_Cancel";
2144 // Maxtor: ECC Errors
2146 // Fujitsu: "Shock_Count_Write_Opern"
2147 return "Soft_ECC_Correction";
2149 // Fujitsu: "Shock_Rate_Write_Opern"
2150 return "Thermal_Asperity_Rate";
2153 return "Flying_Height";
2156 return "Spin_High_Current";
2162 return "Offline_Seek_Performnce";
2164 return "Disk_Shift";
2166 return "G-Sense_Error_Rate";
2168 return "Loaded_Hours";
2170 return "Load_Retry_Count";
2172 return "Load_Friction";
2174 return "Load_Cycle_Count";
2176 return "Load-in_Time";
2178 return "Torq-amp_Count";
2180 return "Power-off_Retract_Count";
2182 // seen in IBM DTPA-353750
2183 return "Head_Amplitude";
2185 return "Temperature_Celsius";
2187 // seen in Intel X25-E SSD
2188 return "Available_Reservd_Space";
2190 // seen in Intel X25-E SSD
2191 return "Media_Wearout_Indicator";
2193 return "Head_Flying_Hours";
2195 return "Total_LBAs_Written";
2197 return "Total_LBAs_Read";
2199 return "Read_Error_Retry_Rate";
2201 return "Free_Fall_Sensor";
2203 return "Unknown_Attribute";
2207 // Get attribute name
2208 std::string
ata_get_smart_attr_name(unsigned char id
, const ata_vendor_attr_defs
& defs
)
2210 if (!defs
[id
].name
.empty())
2211 return defs
[id
].name
;
2213 return get_default_attr_name(id
);
2216 // Find attribute index for attribute id, -1 if not found.
2217 int ata_find_attr_index(unsigned char id
, const ata_smart_values
& smartval
)
2221 for (int i
= 0; i
< NUMBER_ATA_SMART_ATTRIBUTES
; i
++) {
2222 if (smartval
.vendor_attributes
[i
].id
== id
)
2228 // Return Temperature Attribute raw value selected according to possible
2229 // non-default interpretations. If the Attribute does not exist, return 0
2230 unsigned char ata_return_temperature_value(const ata_smart_values
* data
, const ata_vendor_attr_defs
& defs
)
2232 for (int i
= 0; i
< 3; i
++) {
2233 static const unsigned char ids
[3] = {194, 9, 220};
2234 unsigned char id
= ids
[i
];
2235 const ata_attr_raw_format format
= defs
[id
].raw_format
;
2236 if (!( (id
== 194 && format
== RAWFMT_DEFAULT
)
2237 || format
== RAWFMT_TEMPMINMAX
|| format
== RAWFMT_TEMP10X
))
2239 int idx
= ata_find_attr_index(id
, *data
);
2242 uint64_t raw
= ata_get_attr_raw_value(data
->vendor_attributes
[idx
], defs
);
2243 unsigned temp
= (unsigned short)raw
; // ignore possible min/max values in high words
2244 if (format
== RAWFMT_TEMP10X
) // -v N,temp10x
2245 temp
= (temp
+5) / 10;
2246 if (!(0 < temp
&& temp
<= 255))
2250 // No valid attribute found
2256 int ataReadSCTStatus(ata_device
* device
, ata_sct_status_response
* sts
)
2258 // read SCT status via SMART log 0xe0
2259 memset(sts
, 0, sizeof(*sts
));
2260 if (smartcommandhandler(device
, READ_LOG
, 0xe0, (char *)sts
)){
2261 syserror("Error Read SCT Status failed");
2265 // swap endian order if needed
2267 swapx(&sts
->format_version
);
2268 swapx(&sts
->sct_version
);
2269 swapx(&sts
->sct_spec
);
2270 swapx(&sts
->ext_status_code
);
2271 swapx(&sts
->action_code
);
2272 swapx(&sts
->function_code
);
2273 swapx(&sts
->over_limit_count
);
2274 swapx(&sts
->under_limit_count
);
2277 // Check format version
2278 if (!(sts
->format_version
== 2 || sts
->format_version
== 3)) {
2279 pout("Error unknown SCT Status format version %u, should be 2 or 3.\n", sts
->format_version
);
2285 // Read SCT Temperature History Table and Status
2286 int ataReadSCTTempHist(ata_device
* device
, ata_sct_temperature_history_table
* tmh
,
2287 ata_sct_status_response
* sts
)
2289 // Check initial status
2290 if (ataReadSCTStatus(device
, sts
))
2293 // Do nothing if other SCT command is executing
2294 if (sts
->ext_status_code
== 0xffff) {
2295 pout("Another SCT command is executing, abort Read Data Table\n"
2296 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2297 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2301 ata_sct_data_table_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2302 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2303 cmd
.action_code
= 5; // Data table command
2304 cmd
.function_code
= 1; // Read table
2305 cmd
.table_id
= 2; // Temperature History Table
2307 // swap endian order if needed
2308 if (isbigendian()) {
2309 swapx(&cmd
.action_code
);
2310 swapx(&cmd
.function_code
);
2311 swapx(&cmd
.table_id
);
2314 // write command via SMART log page 0xe0
2315 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2316 syserror("Error Write SCT Data Table command failed");
2320 // read SCT data via SMART log page 0xe1
2321 memset(tmh
, 0, sizeof(*tmh
));
2322 if (smartcommandhandler(device
, READ_LOG
, 0xe1, (char *)tmh
)){
2323 syserror("Error Read SCT Data Table failed");
2327 // re-read and check SCT status
2328 if (ataReadSCTStatus(device
, sts
))
2331 if (!(sts
->ext_status_code
== 0 && sts
->action_code
== 5 && sts
->function_code
== 1)) {
2332 pout("Error unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2333 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2337 // swap endian order if needed
2339 swapx(&tmh
->format_version
);
2340 swapx(&tmh
->sampling_period
);
2341 swapx(&tmh
->interval
);
2344 // Check format version
2345 if (tmh
->format_version
!= 2) {
2346 pout("Error unknown SCT Temperature History Format Version (%u), should be 2.\n", tmh
->format_version
);
2352 // Set SCT Temperature Logging Interval
2353 int ataSetSCTTempInterval(ata_device
* device
, unsigned interval
, bool persistent
)
2355 // Check initial status
2356 ata_sct_status_response sts
;
2357 if (ataReadSCTStatus(device
, &sts
))
2360 // Do nothing if other SCT command is executing
2361 if (sts
.ext_status_code
== 0xffff) {
2362 pout("Another SCT command is executing, abort Feature Control\n"
2363 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2364 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2368 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2369 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2370 cmd
.action_code
= 4; // Feature Control command
2371 cmd
.function_code
= 1; // Set state
2372 cmd
.feature_code
= 3; // Temperature logging interval
2373 cmd
.state
= interval
;
2374 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2376 // swap endian order if needed
2377 if (isbigendian()) {
2378 swapx(&cmd
.action_code
);
2379 swapx(&cmd
.function_code
);
2380 swapx(&cmd
.feature_code
);
2382 swapx(&cmd
.option_flags
);
2385 // write command via SMART log page 0xe0
2386 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2387 syserror("Error Write SCT Feature Control Command failed");
2391 // re-read and check SCT status
2392 if (ataReadSCTStatus(device
, &sts
))
2395 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== 1)) {
2396 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2397 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2403 // Get/Set SCT Error Recovery Control
2404 static int ataGetSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
,
2405 bool set
, unsigned short & time_limit
)
2407 // Check initial status
2408 ata_sct_status_response sts
;
2409 if (ataReadSCTStatus(device
, &sts
))
2412 // Do nothing if other SCT command is executing
2413 if (sts
.ext_status_code
== 0xffff) {
2414 pout("Another SCT command is executing, abort Error Recovery Control\n"
2415 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2416 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2420 ata_sct_error_recovery_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2421 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2422 cmd
.action_code
= 3; // Error Recovery Control command
2423 cmd
.function_code
= (set
? 1 : 2); // 1=Set timer, 2=Get timer
2424 cmd
.selection_code
= type
; // 1=Read timer, 2=Write timer
2426 cmd
.time_limit
= time_limit
;
2428 // swap endian order if needed
2429 if (isbigendian()) {
2430 swapx(&cmd
.action_code
);
2431 swapx(&cmd
.function_code
);
2432 swapx(&cmd
.selection_code
);
2433 swapx(&cmd
.time_limit
);
2436 // write command via SMART log page 0xe0
2437 // TODO: Debug output
2439 in
.in_regs
.command
= ATA_SMART_CMD
;
2440 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
2441 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
2442 in
.in_regs
.lba_low
= 0xe0;
2443 in
.set_data_out(&cmd
, 1);
2446 // Time limit returned in ATA registers
2447 in
.out_needed
.sector_count
= in
.out_needed
.lba_low
= true;
2450 if (!device
->ata_pass_through(in
, out
)) {
2451 pout("Error Write SCT (%cet) Error Recovery Control Command failed: %s\n",
2452 (!set
? 'G' : 'S'), device
->get_errmsg());
2456 // re-read and check SCT status
2457 if (ataReadSCTStatus(device
, &sts
))
2460 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 3 && sts
.function_code
== (set
? 1 : 2))) {
2461 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2462 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2467 // Check whether registers are properly returned by ioctl()
2468 if (!(out
.out_regs
.sector_count
.is_set() && out
.out_regs
.lba_low
.is_set())) {
2469 // TODO: Output register support should be checked within each ata_pass_through()
2470 // implementation before command is issued.
2471 pout("Error SMART WRITE LOG does not return COUNT and LBA_LOW register\n");
2474 // Return value to caller
2475 time_limit
= out
.out_regs
.sector_count
| (out
.out_regs
.lba_low
<< 8);
2481 // Get SCT Error Recovery Control
2482 int ataGetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short & time_limit
)
2484 return ataGetSetSCTErrorRecoveryControltime(device
, type
, false/*get*/, time_limit
);
2487 // Set SCT Error Recovery Control
2488 int ataSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short time_limit
)
2490 return ataGetSetSCTErrorRecoveryControltime(device
, type
, true/*set*/, time_limit
);
2494 // Print one self-test log entry.
2496 // -1: self-test failed
2497 // 1: extended self-test completed without error
2499 int ataPrintSmartSelfTestEntry(unsigned testnum
, unsigned char test_type
,
2500 unsigned char test_status
,
2501 unsigned short timestamp
,
2502 uint64_t failing_lba
,
2503 bool print_error_only
, bool & print_header
)
2505 // Check status and type for return value
2507 switch (test_status
>> 4) {
2509 if ((test_type
& 0x0f) == 0x02)
2510 retval
= 1; // extended self-test completed without error
2515 retval
= -1; // self-test failed
2519 if (retval
>= 0 && print_error_only
)
2522 std::string msgtest
;
2523 switch (test_type
) {
2524 case 0x00: msgtest
= "Offline"; break;
2525 case 0x01: msgtest
= "Short offline"; break;
2526 case 0x02: msgtest
= "Extended offline"; break;
2527 case 0x03: msgtest
= "Conveyance offline"; break;
2528 case 0x04: msgtest
= "Selective offline"; break;
2529 case 0x7f: msgtest
= "Abort offline test"; break;
2530 case 0x81: msgtest
= "Short captive"; break;
2531 case 0x82: msgtest
= "Extended captive"; break;
2532 case 0x83: msgtest
= "Conveyance captive"; break;
2533 case 0x84: msgtest
= "Selective captive"; break;
2535 if ((0x40 <= test_type
&& test_type
<= 0x7e) || 0x90 <= test_type
)
2536 msgtest
= strprintf("Vendor (0x%02x)", test_type
);
2538 msgtest
= strprintf("Reserved (0x%02x)", test_type
);
2541 std::string msgstat
;
2542 switch (test_status
>> 4) {
2543 case 0x0: msgstat
= "Completed without error"; break;
2544 case 0x1: msgstat
= "Aborted by host"; break;
2545 case 0x2: msgstat
= "Interrupted (host reset)"; break;
2546 case 0x3: msgstat
= "Fatal or unknown error"; break;
2547 case 0x4: msgstat
= "Completed: unknown failure"; break;
2548 case 0x5: msgstat
= "Completed: electrical failure"; break;
2549 case 0x6: msgstat
= "Completed: servo/seek failure"; break;
2550 case 0x7: msgstat
= "Completed: read failure"; break;
2551 case 0x8: msgstat
= "Completed: handling damage??"; break;
2552 case 0xf: msgstat
= "Self-test routine in progress"; break;
2553 default: msgstat
= strprintf("Unknown status (0x%x)", test_status
>> 4);
2556 // Print header once
2558 print_header
= false;
2559 pout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2563 if (retval
< 0 && failing_lba
< 0xffffffffffffULL
)
2564 snprintf(msglba
, sizeof(msglba
), "%"PRIu64
, failing_lba
);
2566 strcpy(msglba
, "-");
2568 pout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum
,
2569 msgtest
.c_str(), msgstat
.c_str(), test_status
& 0x0f, timestamp
, msglba
);
2574 // Print Smart self-test log, used by smartctl and smartd.
2576 // bottom 8 bits: number of entries found where self-test showed an error
2577 // remaining bits: if nonzero, power on hours of last self-test where error was found
2578 int ataPrintSmartSelfTestlog(const ata_smart_selftestlog
* data
, bool allentries
,
2579 unsigned char fix_firmwarebug
)
2582 pout("SMART Self-test log structure revision number %d\n",(int)data
->revnumber
);
2583 if ((data
->revnumber
!=0x0001) && allentries
&& fix_firmwarebug
!= FIX_SAMSUNG
)
2584 pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2585 if (data
->mostrecenttest
==0){
2587 pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
2591 bool noheaderprinted
= true;
2592 int errcnt
= 0, hours
= 0, igncnt
= 0;
2593 int testno
= 0, ext_ok_testno
= -1;
2596 for (int i
= 20; i
>= 0; i
--) {
2597 // log is a circular buffer
2598 int j
= (i
+data
->mostrecenttest
)%21;
2599 const ata_smart_selftestlog_struct
* log
= data
->selftest_struct
+j
;
2601 if (nonempty(log
, sizeof(*log
))) {
2602 // count entry based on non-empty structures -- needed for
2603 // Seagate only -- other vendors don't have blank entries 'in
2607 // T13/1321D revision 1c: (Data structure Rev #1)
2609 //The failing LBA shall be the LBA of the uncorrectable sector
2610 //that caused the test to fail. If the device encountered more
2611 //than one uncorrectable sector during the test, this field
2612 //shall indicate the LBA of the first uncorrectable sector
2613 //encountered. If the test passed or the test failed for some
2614 //reason other than an uncorrectable sector, the value of this
2615 //field is undefined.
2617 // This is true in ALL ATA-5 specs
2618 uint64_t lba48
= (log
->lbafirstfailure
< 0xffffffff ? log
->lbafirstfailure
: 0xffffffffffffULL
);
2621 int state
= ataPrintSmartSelfTestEntry(testno
,
2622 log
->selftestnumber
, log
->selfteststatus
,
2623 log
->timestamp
, lba48
, !allentries
, noheaderprinted
);
2626 // Self-test showed an error
2627 if (ext_ok_testno
< 0) {
2630 // keep track of time of most recent error
2632 hours
= log
->timestamp
;
2635 // Newer successful extended self-test exits
2638 else if (state
> 0 && ext_ok_testno
< 0) {
2639 // Latest successful extended self-test
2640 ext_ok_testno
= testno
;
2646 pout("%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2647 igncnt
, igncnt
+errcnt
, ext_ok_testno
);
2649 if (!allentries
&& !noheaderprinted
)
2652 return ((hours
<< 8) | errcnt
);
2656 /////////////////////////////////////////////////////////////////////////////
2657 // Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2658 // an ATA device with same behaviour
2662 class parsed_ata_device
2663 : public /*implements*/ ata_device_with_command_set
2666 parsed_ata_device(smart_interface
* intf
, const char * dev_name
);
2668 virtual ~parsed_ata_device() throw();
2670 virtual bool is_open() const;
2672 virtual bool open();
2674 virtual bool close();
2676 virtual bool ata_identify_is_cached() const;
2679 virtual int ata_command_interface(smart_command_set command
, int select
, char * data
);
2682 // Table of parsed commands, return value, data
2683 struct parsed_ata_command
2685 smart_command_set command
;
2691 enum { max_num_commands
= 32 };
2692 parsed_ata_command m_command_table
[max_num_commands
];
2695 int m_next_replay_command
;
2696 bool m_replay_out_of_sync
;
2697 bool m_ata_identify_is_cached
;
2700 static const char * nextline(const char * s
, int & lineno
)
2702 for (s
+= strcspn(s
, "\r\n"); *s
== '\r' || *s
== '\n'; s
++) {
2703 if (*s
== '\r' && s
[1] == '\n')
2710 static int name2command(const char * s
)
2712 for (int i
= 0; i
< (int)(sizeof(commandstrings
)/sizeof(commandstrings
[0])); i
++) {
2713 if (!strcmp(s
, commandstrings
[i
]))
2719 static bool matchcpy(char * dest
, size_t size
, const char * src
, const regmatch_t
& srcmatch
)
2721 if (srcmatch
.rm_so
< 0)
2723 size_t n
= srcmatch
.rm_eo
- srcmatch
.rm_so
;
2726 memcpy(dest
, src
+ srcmatch
.rm_so
, n
);
2731 static inline int matchtoi(const char * src
, const regmatch_t
& srcmatch
, int defval
)
2733 if (srcmatch
.rm_so
< 0)
2735 return atoi(src
+ srcmatch
.rm_so
);
2738 parsed_ata_device::parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2739 : smart_device(intf
, dev_name
, "ata", ""),
2741 m_next_replay_command(0),
2742 m_replay_out_of_sync(false),
2743 m_ata_identify_is_cached(false)
2745 memset(m_command_table
, 0, sizeof(m_command_table
));
2748 parsed_ata_device::~parsed_ata_device() throw()
2753 bool parsed_ata_device::is_open() const
2755 return (m_num_commands
> 0);
2758 // Parse stdin and build command table
2759 bool parsed_ata_device::open()
2761 const char * pathname
= get_dev_name();
2762 if (strcmp(pathname
, "-"))
2763 return set_err(EINVAL
);
2764 pathname
= "<stdin>";
2766 char buffer
[64*1024];
2768 while (size
< (int)sizeof(buffer
)) {
2769 int nr
= fread(buffer
, 1, sizeof(buffer
), stdin
);
2775 return set_err(ENOENT
, "%s: Unexpected EOF", pathname
);
2776 if (size
>= (int)sizeof(buffer
))
2777 return set_err(EIO
, "%s: Buffer overflow", pathname
);
2780 // Regex to match output from "-r ataioctl,2"
2781 static const char pattern
[] = "^"
2783 "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
2785 "( InputParameter=([0-9]+))?" // (4 (5))
2787 "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2789 "[\r\n]" // EOL match necessary to match optional parts above
2791 "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2793 " *(En|Dis)abled status cached by OS, " // (11)
2797 const regular_expression
regex(pattern
, REG_EXTENDED
);
2800 const char * errmsg
= 0;
2801 int i
= -1, state
= 0, lineno
= 1;
2802 for (const char * line
= buffer
; *line
; line
= nextline(line
, lineno
)) {
2804 if (!(line
[0] == 'R' || line
[0] == '=' || line
[0] == ' '))
2806 const int nmatch
= 1+11;
2807 regmatch_t match
[nmatch
];
2808 if (!regex
.execute(line
, nmatch
, match
))
2812 if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[2])) { // "REPORT-IOCTL:... Command=%s ..."
2813 int nc
= name2command(cmdname
);
2815 errmsg
= "Unknown ATA command name"; break;
2817 if (match
[7].rm_so
< 0) { // "returned %d"
2819 if (!(state
== 0 || state
== 2)) {
2820 errmsg
= "Missing REPORT-IOCTL result"; break;
2822 if (++i
>= max_num_commands
) {
2823 errmsg
= "Too many ATA commands"; break;
2825 m_command_table
[i
].command
= (smart_command_set
)nc
;
2826 m_command_table
[i
].select
= matchtoi(line
, match
[5], 0); // "InputParameter=%d"
2831 if (!(state
== 1 && (int)m_command_table
[i
].command
== nc
)) {
2832 errmsg
= "Missing REPORT-IOCTL start"; break;
2834 m_command_table
[i
].retval
= matchtoi(line
, match
[7], -1); // "returned %d"
2835 m_command_table
[i
].errval
= matchtoi(line
, match
[9], 0); // "errno=%d"
2839 else if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[10])) { // "===== [%s] DATA START "
2840 // Start of sector hexdump
2841 int nc
= name2command(cmdname
);
2842 if (!(state
== (nc
== WRITE_LOG
? 1 : 2) && (int)m_command_table
[i
].command
== nc
)) {
2843 errmsg
= "Unexpected DATA START"; break;
2845 line
= nextline(line
, lineno
);
2846 char * data
= (char *)malloc(512);
2848 for (j
= 0; j
< 32; j
++) {
2850 unsigned u1
, u2
; int n1
= -1;
2851 if (!(sscanf(line
, "%3u-%3u: "
2852 "%2x %2x %2x %2x %2x %2x %2x %2x "
2853 "%2x %2x %2x %2x %2x %2x %2x %2x%n",
2855 b
+ 0, b
+ 1, b
+ 2, b
+ 3, b
+ 4, b
+ 5, b
+ 6, b
+ 7,
2856 b
+ 8, b
+ 9, b
+10, b
+11, b
+12, b
+13, b
+14, b
+15, &n1
) == 18
2857 && n1
>= 56 && u1
== j
*16 && u2
== j
*16+15))
2859 for (unsigned k
= 0; k
< 16; k
++)
2860 data
[j
*16+k
] = b
[k
];
2861 line
= nextline(line
, lineno
);
2865 errmsg
= "Incomplete sector hex dump"; break;
2867 m_command_table
[i
].data
= data
;
2868 if (nc
!= WRITE_LOG
)
2871 else if (match
[11].rm_so
> 0) { // "(En|Dis)abled status cached by OS"
2872 m_ata_identify_is_cached
= true;
2876 if (!(state
== 0 || state
== 2))
2877 errmsg
= "Missing REPORT-IOCTL result";
2879 if (!errmsg
&& i
< 0)
2880 errmsg
= "No information found";
2882 m_num_commands
= i
+1;
2883 m_next_replay_command
= 0;
2884 m_replay_out_of_sync
= false;
2888 return set_err(EIO
, "%s(%d): Syntax error: %s", pathname
, lineno
, errmsg
);
2893 // Report warnings and free command table
2894 bool parsed_ata_device::close()
2896 if (m_replay_out_of_sync
)
2897 pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
2898 else if (m_next_replay_command
!= 0)
2899 pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands
-m_next_replay_command
);
2901 for (int i
= 0; i
< m_num_commands
; i
++) {
2902 if (m_command_table
[i
].data
) {
2903 free(m_command_table
[i
].data
); m_command_table
[i
].data
= 0;
2907 m_next_replay_command
= 0;
2908 m_replay_out_of_sync
= false;
2913 bool parsed_ata_device::ata_identify_is_cached() const
2915 return m_ata_identify_is_cached
;
2919 // Simulate ATA command from command table
2920 int parsed_ata_device::ata_command_interface(smart_command_set command
, int select
, char * data
)
2922 // Find command, try round-robin if out of sync
2923 int i
= m_next_replay_command
;
2924 for (int j
= 0; ; j
++) {
2925 if (j
>= m_num_commands
) {
2926 pout("REPLAY-IOCTL: Warning: Command not found\n");
2930 if (m_command_table
[i
].command
== command
&& m_command_table
[i
].select
== select
)
2932 if (!m_replay_out_of_sync
) {
2933 m_replay_out_of_sync
= true;
2934 pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i
+1);
2936 if (++i
>= m_num_commands
)
2939 m_next_replay_command
= i
;
2940 if (++m_next_replay_command
>= m_num_commands
)
2941 m_next_replay_command
= 0;
2943 // Return command data
2948 case READ_THRESHOLDS
:
2950 if (m_command_table
[i
].data
)
2951 memcpy(data
, m_command_table
[i
].data
, 512);
2954 if (!(m_command_table
[i
].data
&& !memcmp(data
, m_command_table
[i
].data
, 512)))
2955 pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
2957 case CHECK_POWER_MODE
:
2958 data
[0] = (char)0xff;
2963 if (m_command_table
[i
].errval
)
2964 errno
= m_command_table
[i
].errval
;
2965 return m_command_table
[i
].retval
;
2970 ata_device
* get_parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2972 return new parsed_ata_device(intf
, dev_name
);