4 * Home page of code is: http://smartmontools.sourceforge.net
6 * Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
7 * Copyright (C) 2008-10 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/
38 #include "dev_ata_cmd_set.h" // for parsed_ata_device
40 const char * atacmds_cpp_cvsid
= "$Id: atacmds.cpp 3117 2010-06-08 15:41:04Z chrfranke $"
43 // for passing global control variables
44 extern smartmonctrl
*con
;
46 #define SMART_CYL_LOW 0x4F
47 #define SMART_CYL_HI 0xC2
49 // SMART RETURN STATUS yields SMART_CYL_HI,SMART_CYL_LOW to indicate drive
50 // is healthy and SRET_STATUS_HI_EXCEEDED,SRET_STATUS_MID_EXCEEDED to
51 // indicate that a threshhold exceeded condition has been detected.
52 // Those values (byte pairs) are placed in ATA register "LBA 23:8".
53 #define SRET_STATUS_HI_EXCEEDED 0x2C
54 #define SRET_STATUS_MID_EXCEEDED 0xF4
56 // These Drive Identity tables are taken from hdparm 5.2, and are also
57 // given in the ATA/ATAPI specs for the IDENTIFY DEVICE command. Note
58 // that SMART was first added into the ATA/ATAPI-3 Standard with
59 // Revision 3 of the document, July 25, 1995. Look at the "Document
60 // Status" revision commands at the beginning of
61 // http://www.t13.org/Documents/UploadedDocuments/project/d2008r7b-ATA-3.pdf
63 #define NOVAL_0 0x0000
64 #define NOVAL_1 0xffff
65 /* word 81: minor version number */
66 #define MINOR_MAX 0x22
67 static const char * const minor_str
[] = { /* word 81 value: */
68 "Device does not report version", /* 0x0000 */
69 "ATA-1 X3T9.2 781D prior to revision 4", /* 0x0001 */
70 "ATA-1 published, ANSI X3.221-1994", /* 0x0002 */
71 "ATA-1 X3T9.2 781D revision 4", /* 0x0003 */
72 "ATA-2 published, ANSI X3.279-1996", /* 0x0004 */
73 "ATA-2 X3T10 948D prior to revision 2k", /* 0x0005 */
74 "ATA-3 X3T10 2008D revision 1", /* 0x0006 */ /* SMART NOT INCLUDED */
75 "ATA-2 X3T10 948D revision 2k", /* 0x0007 */
76 "ATA-3 X3T10 2008D revision 0", /* 0x0008 */
77 "ATA-2 X3T10 948D revision 3", /* 0x0009 */
78 "ATA-3 published, ANSI X3.298-199x", /* 0x000a */
79 "ATA-3 X3T10 2008D revision 6", /* 0x000b */ /* 1st VERSION WITH SMART */
80 "ATA-3 X3T13 2008D revision 7 and 7a", /* 0x000c */
81 "ATA/ATAPI-4 X3T13 1153D revision 6", /* 0x000d */
82 "ATA/ATAPI-4 T13 1153D revision 13", /* 0x000e */
83 "ATA/ATAPI-4 X3T13 1153D revision 7", /* 0x000f */
84 "ATA/ATAPI-4 T13 1153D revision 18", /* 0x0010 */
85 "ATA/ATAPI-4 T13 1153D revision 15", /* 0x0011 */
86 "ATA/ATAPI-4 published, ANSI NCITS 317-1998", /* 0x0012 */
87 "ATA/ATAPI-5 T13 1321D revision 3", /* 0x0013 */
88 "ATA/ATAPI-4 T13 1153D revision 14", /* 0x0014 */
89 "ATA/ATAPI-5 T13 1321D revision 1", /* 0x0015 */
90 "ATA/ATAPI-5 published, ANSI NCITS 340-2000", /* 0x0016 */
91 "ATA/ATAPI-4 T13 1153D revision 17", /* 0x0017 */
92 "ATA/ATAPI-6 T13 1410D revision 0", /* 0x0018 */
93 "ATA/ATAPI-6 T13 1410D revision 3a", /* 0x0019 */
94 "ATA/ATAPI-7 T13 1532D revision 1", /* 0x001a */
95 "ATA/ATAPI-6 T13 1410D revision 2", /* 0x001b */
96 "ATA/ATAPI-6 T13 1410D revision 1", /* 0x001c */
97 "ATA/ATAPI-7 published, ANSI INCITS 397-2005",/* 0x001d */
98 "ATA/ATAPI-7 T13 1532D revision 0", /* 0x001e */
99 "reserved", /* 0x001f */
100 "reserved", /* 0x0020 */
101 "ATA/ATAPI-7 T13 1532D revision 4a", /* 0x0021 */
102 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" /* 0x0022 */
105 // NOTE ATA/ATAPI-4 REV 4 was the LAST revision where the device
106 // attribute structures were NOT completely vendor specific. So any
107 // disk that is ATA/ATAPI-4 or above can not be trusted to show the
108 // vendor values in sensible format.
110 // Negative values below are because it doesn't support SMART
111 static const int actual_ver
[] = {
113 0, /* 0x0000 WARNING: */
114 1, /* 0x0001 WARNING: */
115 1, /* 0x0002 WARNING: */
116 1, /* 0x0003 WARNING: */
117 2, /* 0x0004 WARNING: This array */
118 2, /* 0x0005 WARNING: corresponds */
119 -3, /*<== */ /* 0x0006 WARNING: *exactly* */
120 2, /* 0x0007 WARNING: to the ATA/ */
121 -3, /*<== */ /* 0x0008 WARNING: ATAPI version */
122 2, /* 0x0009 WARNING: listed in */
123 3, /* 0x000a WARNING: the */
124 3, /* 0x000b WARNING: minor_str */
125 3, /* 0x000c WARNING: array */
126 4, /* 0x000d WARNING: above. */
127 4, /* 0x000e WARNING: */
128 4, /* 0x000f WARNING: If you change */
129 4, /* 0x0010 WARNING: that one, */
130 4, /* 0x0011 WARNING: change this one */
131 4, /* 0x0012 WARNING: too!!! */
132 5, /* 0x0013 WARNING: */
133 4, /* 0x0014 WARNING: */
134 5, /* 0x0015 WARNING: */
135 5, /* 0x0016 WARNING: */
136 4, /* 0x0017 WARNING: */
137 6, /* 0x0018 WARNING: */
138 6, /* 0x0019 WARNING: */
139 7, /* 0x001a WARNING: */
140 6, /* 0x001b WARNING: */
141 6, /* 0x001c WARNING: */
142 7, /* 0x001d WARNING: */
143 7, /* 0x001e WARNING: */
144 0, /* 0x001f WARNING: */
145 0, /* 0x0020 WARNING: */
146 7, /* 0x0021 WARNING: */
147 6 /* 0x0022 WARNING: */
150 // Get ID and increase flag of current pending or offline
151 // uncorrectable attribute.
152 unsigned char get_unc_attr_id(bool offline
, const ata_vendor_attr_defs
& defs
,
155 unsigned char id
= (!offline
? 197 : 198);
156 const ata_vendor_attr_defs::entry
& def
= defs
[id
];
157 if (def
.flags
& ATTRFLAG_INCREASING
)
158 increase
= true; // '-v 19[78],increasing' option
159 else if (def
.name
.empty() || (id
== 198 && def
.name
== "Offline_Scan_UNC_SectCt"))
160 increase
= false; // no or '-v 198,offlinescanuncsectorct' option
162 id
= 0; // other '-v 19[78],...' option
166 #if 0 // TODO: never used
167 // This are the meanings of the Self-test failure checkpoint byte.
168 // This is in the self-test log at offset 4 bytes into the self-test
169 // descriptor and in the SMART READ DATA structure at byte offset
170 // 371. These codes are not well documented. The meanings returned by
171 // this routine are used (at least) by Maxtor and IBM. Returns NULL if
172 // not recognized. Currently the maximum length is 15 bytes.
173 const char *SelfTestFailureCodeName(unsigned char which
){
179 return "Servo_Basic";
181 return "Servo_Random";
183 return "G-list_Scan";
185 return "Handling_Damage";
195 // Table of raw print format names
196 struct format_name_entry
199 ata_attr_raw_format format
;
202 const format_name_entry format_names
[] = {
203 {"raw8" , RAWFMT_RAW8
},
204 {"raw16" , RAWFMT_RAW16
},
205 {"raw48" , RAWFMT_RAW48
},
206 {"hex48" , RAWFMT_HEX48
},
207 {"raw64" , RAWFMT_RAW64
},
208 {"hex64" , RAWFMT_HEX64
},
209 {"raw16(raw16)" , RAWFMT_RAW16_OPT_RAW16
},
210 {"raw16(avg16)" , RAWFMT_RAW16_OPT_AVG16
},
211 {"raw24/raw24" , RAWFMT_RAW24_RAW24
},
212 {"sec2hour" , RAWFMT_SEC2HOUR
},
213 {"min2hour" , RAWFMT_MIN2HOUR
},
214 {"halfmin2hour" , RAWFMT_HALFMIN2HOUR
},
215 {"tempminmax" , RAWFMT_TEMPMINMAX
},
216 {"temp10x" , RAWFMT_TEMP10X
},
219 const unsigned num_format_names
= sizeof(format_names
)/sizeof(format_names
[0]);
221 // Table to map old to new '-v' option arguments
222 const char * map_old_vendor_opts
[][2] = {
223 { "9,halfminutes" , "9,halfmin2hour,Power_On_Half_Minutes"},
224 { "9,minutes" , "9,min2hour,Power_On_Minutes"},
225 { "9,seconds" , "9,sec2hour,Power_On_Seconds"},
226 { "9,temp" , "9,tempminmax,Temperature_Celsius"},
227 {"192,emergencyretractcyclect" , "192,raw48,Emerg_Retract_Cycle_Ct"},
228 {"193,loadunload" , "193,raw24/raw24"},
229 {"194,10xCelsius" , "194,temp10x,Temperature_Celsius_x10"},
230 {"194,unknown" , "194,raw48,Unknown_Attribute"},
231 {"197,increasing" , "197,raw48+,Total_Pending_Sectors"}, // '+' sets flag
232 {"198,offlinescanuncsectorct" , "198,raw48,Offline_Scan_UNC_SectCt"}, // see also get_unc_attr_id() above
233 {"198,increasing" , "198,raw48+,Total_Offl_Uncorrectabl"}, // '+' sets flag
234 {"200,writeerrorcount" , "200,raw48,Write_Error_Count"},
235 {"201,detectedtacount" , "201,raw48,Detected_TA_Count"},
236 {"220,temp" , "220,raw48,Temperature_Celsius"},
239 const unsigned num_old_vendor_opts
= sizeof(map_old_vendor_opts
)/sizeof(map_old_vendor_opts
[0]);
241 // Parse vendor attribute display def (-v option).
242 // Return false on error.
243 bool parse_attribute_def(const char * opt
, ata_vendor_attr_defs
& defs
,
244 ata_vendor_def_prior priority
)
246 // Map old -> new options
248 for (i
= 0; i
< num_old_vendor_opts
; i
++) {
249 if (!strcmp(opt
, map_old_vendor_opts
[i
][0])) {
250 opt
= map_old_vendor_opts
[i
][1];
256 int len
= strlen(opt
);
257 int id
= 0, n1
= -1, n2
= -1;
258 char fmtname
[32+1], attrname
[32+1];
261 if (!( sscanf(opt
, "N,%32[^,]%n,%32[^,]%n", fmtname
, &n1
, attrname
, &n2
) >= 1
262 && (n1
== len
|| n2
== len
)))
266 // "id,format[+][,name]"
267 if (!( sscanf(opt
, "%d,%32[^,]%n,%32[^,]%n", &id
, fmtname
, &n1
, attrname
, &n2
) >= 2
268 && 1 <= id
&& id
<= 255 && (n1
== len
|| n2
== len
)))
275 // For "-v 19[78],increasing" above
276 if (fmtname
[strlen(fmtname
)-1] == '+') {
277 fmtname
[strlen(fmtname
)-1] = 0;
278 flags
= ATTRFLAG_INCREASING
;
281 // Split "format[:byteorder]"
282 char byteorder
[8+1] = "";
283 if (strchr(fmtname
, ':')) {
284 if (!( sscanf(fmtname
, "%*[^:]%n:%8[012345rvwz]%n", &n1
, byteorder
, &n2
) >= 1
285 && n2
== (int)strlen(fmtname
)))
288 if (strchr(byteorder
, 'v'))
289 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
290 if (strchr(byteorder
, 'w'))
291 flags
|= ATTRFLAG_NO_WORSTVAL
;
296 if (i
>= num_format_names
)
297 return false; // Not found
298 if (!strcmp(fmtname
, format_names
[i
].name
))
301 ata_attr_raw_format format
= format_names
[i
].format
;
303 // 64-bit formats use the normalized and worst value bytes.
304 if (!*byteorder
&& (format
== RAWFMT_RAW64
|| format
== RAWFMT_HEX64
))
305 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
308 // "N,format" -> set format for all entries
309 for (i
= 0; i
< MAX_ATTRIBUTE_NUM
; i
++) {
310 if (defs
[i
].priority
>= priority
)
313 defs
[i
].name
= attrname
;
314 defs
[i
].priority
= priority
;
315 defs
[i
].raw_format
= format
;
316 defs
[i
].flags
= flags
;
317 strcpy(defs
[i
].byteorder
, byteorder
);
320 else if (defs
[id
].priority
<= priority
) {
321 // "id,format[,name]"
323 defs
[id
].name
= attrname
;
324 defs
[id
].raw_format
= format
;
325 defs
[id
].priority
= priority
;
326 defs
[id
].flags
= flags
;
327 strcpy(defs
[id
].byteorder
, byteorder
);
334 // Return a multiline string containing a list of valid arguments for
335 // parse_attribute_def(). The strings are preceeded by tabs and followed
336 // (except for the last) by newlines.
337 std::string
create_vendor_attribute_arg_list()
341 for (i
= 0; i
< num_format_names
; i
++)
342 s
+= strprintf("%s\tN,%s[:012345rvwz][,ATTR_NAME]",
343 (i
>0 ? "\n" : ""), format_names
[i
].name
);
344 for (i
= 0; i
< num_old_vendor_opts
; i
++)
345 s
+= strprintf("\n\t%s", map_old_vendor_opts
[i
][0]);
349 // swap two bytes. Point to low address
350 void swap2(char *location
){
352 *location
=*(location
+1);
357 // swap four bytes. Point to low address
358 void swap4(char *location
){
360 *location
=*(location
+3);
366 // swap eight bytes. Points to low address
367 void swap8(char *location
){
369 *location
=*(location
+7);
372 *(location
+1)=*(location
+6);
378 // Invalidate serial number and adjust checksum in IDENTIFY data
379 static void invalidate_serno(ata_identify_device
* id
){
380 unsigned char sum
= 0;
381 for (unsigned i
= 0; i
< sizeof(id
->serial_no
); i
++) {
382 sum
+= id
->serial_no
[i
]; sum
-= id
->serial_no
[i
] = 'X';
385 bool must_swap
= !!isbigendian();
387 swapx(id
->words088_255
+255-88);
389 if ((id
->words088_255
[255-88] & 0x00ff) == 0x00a5)
390 id
->words088_255
[255-88] += sum
<< 8;
393 swapx(id
->words088_255
+255-88);
397 static const char * const commandstrings
[]={
400 "SMART AUTOMATIC ATTRIBUTE SAVE",
401 "SMART IMMEDIATE OFFLINE",
402 "SMART AUTO OFFLINE",
404 "SMART STATUS CHECK",
405 "SMART READ ATTRIBUTE VALUES",
406 "SMART READ ATTRIBUTE THRESHOLDS",
409 "IDENTIFY PACKET DEVICE",
412 "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT
")\n"
416 static const char * preg(const ata_register
& r
, char * buf
)
421 sprintf(buf
, "0x%02x", r
.val()); return buf
;
424 void print_regs(const char * prefix
, const ata_in_regs
& r
, const char * suffix
= "\n")
426 char bufs
[7][4+1+13];
427 pout("%s FR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, CMD=%s%s", prefix
,
428 preg(r
.features
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
429 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
430 preg(r
.command
, bufs
[6]), suffix
);
433 void print_regs(const char * prefix
, const ata_out_regs
& r
, const char * suffix
= "\n")
435 char bufs
[7][4+1+13];
436 pout("%sERR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, STS=%s%s", prefix
,
437 preg(r
.error
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
438 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
439 preg(r
.status
, bufs
[6]), suffix
);
442 static void prettyprint(const unsigned char *p
, const char *name
){
443 pout("\n===== [%s] DATA START (BASE-16) =====\n", name
);
444 for (int i
=0; i
<512; i
+=16, p
+=16)
445 #define P(n) (isprint((int)(p[n]))?(int)(p[n]):'.')
446 // print complete line to avoid slow tty output and extra lines in syslog.
447 pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x "
448 "%02x %02x %02x %02x %02x %02x %02x %02x"
449 " |%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c|"
452 p
[ 0], p
[ 1], p
[ 2], p
[ 3], p
[ 4], p
[ 5], p
[ 6], p
[ 7],
453 p
[ 8], p
[ 9], p
[10], p
[11], p
[12], p
[13], p
[14], p
[15],
454 P( 0), P( 1), P( 2), P( 3), P( 4), P( 5), P( 6), P( 7),
455 P( 8), P( 9), P(10), P(11), P(12), P(13), P(14), P(15),
458 pout("===== [%s] DATA END (512 Bytes) =====\n\n", name
);
461 // This function provides the pretty-print reporting for SMART
462 // commands: it implements the various -r "reporting" options for ATA
464 int smartcommandhandler(ata_device
* device
, smart_command_set command
, int select
, char *data
){
465 // TODO: Rework old stuff below
466 // This conditional is true for commands that return data
467 int getsdata
=(command
==PIDENTIFY
||
470 command
==READ_THRESHOLDS
||
471 command
==READ_VALUES
||
472 command
==CHECK_POWER_MODE
);
474 int sendsdata
=(command
==WRITE_LOG
);
476 // If reporting is enabled, say what the command will be before it's executed
477 if (con
->reportataioctl
){
478 // conditional is true for commands that use parameters
479 int usesparam
=(command
==READ_LOG
||
480 command
==AUTO_OFFLINE
||
482 command
==IMMEDIATE_OFFLINE
||
485 pout("\nREPORT-IOCTL: Device=%s Command=%s", device
->get_dev_name(), commandstrings
[command
]);
487 pout(" InputParameter=%d\n", select
);
492 if ((getsdata
|| sendsdata
) && !data
){
493 pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings
[command
]);
497 // The reporting is cleaner, and we will find coding bugs faster, if
498 // the commands that failed clearly return empty (zeroed) data
501 if (command
==CHECK_POWER_MODE
)
504 memset(data
, '\0', 512);
508 // if requested, pretty-print the input data structure
509 if (con
->reportataioctl
>1 && sendsdata
)
510 //pout("REPORT-IOCTL: Device=%s Command=%s\n", device->get_dev_name(), commandstrings[command]);
511 prettyprint((unsigned char *)data
, commandstrings
[command
]);
513 // now execute the command
517 // Set common register values
519 default: // SMART commands
520 in
.in_regs
.command
= ATA_SMART_CMD
;
521 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
523 case IDENTIFY
: case PIDENTIFY
: case CHECK_POWER_MODE
: // Non SMART commands
526 // Set specific values
529 in
.in_regs
.command
= ATA_IDENTIFY_DEVICE
;
530 in
.set_data_in(data
, 1);
533 in
.in_regs
.command
= ATA_IDENTIFY_PACKET_DEVICE
;
534 in
.set_data_in(data
, 1);
536 case CHECK_POWER_MODE
:
537 in
.in_regs
.command
= ATA_CHECK_POWER_MODE
;
538 in
.out_needed
.sector_count
= true; // Powermode returned here
541 in
.in_regs
.features
= ATA_SMART_READ_VALUES
;
542 in
.set_data_in(data
, 1);
544 case READ_THRESHOLDS
:
545 in
.in_regs
.features
= ATA_SMART_READ_THRESHOLDS
;
546 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
547 in
.set_data_in(data
, 1);
550 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
551 in
.in_regs
.lba_low
= select
;
552 in
.set_data_in(data
, 1);
555 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
556 in
.in_regs
.lba_low
= select
;
557 in
.set_data_out(data
, 1);
560 in
.in_regs
.features
= ATA_SMART_ENABLE
;
561 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
564 in
.in_regs
.features
= ATA_SMART_DISABLE
;
565 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
568 in
.out_needed
.lba_high
= in
.out_needed
.lba_mid
= true; // Status returned here
570 in
.in_regs
.features
= ATA_SMART_STATUS
;
573 in
.in_regs
.features
= ATA_SMART_AUTO_OFFLINE
;
574 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
577 in
.in_regs
.features
= ATA_SMART_AUTOSAVE
;
578 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
580 case IMMEDIATE_OFFLINE
:
581 in
.in_regs
.features
= ATA_SMART_IMMEDIATE_OFFLINE
;
582 in
.in_regs
.lba_low
= select
;
585 pout("Unrecognized command %d in smartcommandhandler()\n"
586 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
587 device
->set_err(ENOSYS
);
592 if (con
->reportataioctl
)
593 print_regs(" Input: ", in
.in_regs
,
594 (in
.direction
==ata_cmd_in::data_in
? " IN\n":
595 in
.direction
==ata_cmd_in::data_out
? " OUT\n":"\n"));
598 bool ok
= device
->ata_pass_through(in
, out
);
600 if (con
->reportataioctl
&& out
.out_regs
.is_set())
601 print_regs(" Output: ", out
.out_regs
);
603 if (ok
) switch (command
) {
607 case CHECK_POWER_MODE
:
608 data
[0] = out
.out_regs
.sector_count
;
612 // Cyl low and Cyl high unchanged means "Good SMART status"
613 if ((out
.out_regs
.lba_high
== SMART_CYL_HI
) &&
614 (out
.out_regs
.lba_mid
== SMART_CYL_LOW
))
616 // These values mean "Bad SMART status"
617 else if ((out
.out_regs
.lba_high
== SRET_STATUS_HI_EXCEEDED
) &&
618 (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
))
620 else if (out
.out_regs
.lba_mid
== SMART_CYL_LOW
) {
622 if (con
->reportataioctl
)
623 pout("SMART STATUS RETURN: half healthy response sequence, "
624 "probable SAT/USB truncation\n");
625 } else if (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
) {
627 if (con
->reportataioctl
)
628 pout("SMART STATUS RETURN: half unhealthy response sequence, "
629 "probable SAT/USB truncation\n");
631 // We haven't gotten output that makes sense; print out some debugging info
632 pout("Error SMART Status command failed\n");
633 pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE
);
634 pout("Register values returned from SMART Status command are:\n");
635 print_regs(" ", out
.out_regs
);
643 // If requested, invalidate serial number before any printing is done
644 if ((command
== IDENTIFY
|| command
== PIDENTIFY
) && !retval
&& con
->dont_print_serial
)
645 invalidate_serno((ata_identify_device
*)data
);
647 // If reporting is enabled, say what output was produced by the command
648 if (con
->reportataioctl
){
649 if (device
->get_errno())
650 pout("REPORT-IOCTL: Device=%s Command=%s returned %d errno=%d [%s]\n",
651 device
->get_dev_name(), commandstrings
[command
], retval
,
652 device
->get_errno(), device
->get_errmsg());
654 pout("REPORT-IOCTL: Device=%s Command=%s returned %d\n",
655 device
->get_dev_name(), commandstrings
[command
], retval
);
657 // if requested, pretty-print the output data structure
658 if (con
->reportataioctl
>1 && getsdata
) {
659 if (command
==CHECK_POWER_MODE
)
660 pout("Sector Count Register (BASE-16): %02x\n", (unsigned char)(*data
));
662 prettyprint((unsigned char *)data
, commandstrings
[command
]);
666 errno
= device
->get_errno(); // TODO: Callers should not call syserror()
670 // Get number of sectors from IDENTIFY sector. If the drive doesn't
671 // support LBA addressing or has no user writable sectors
672 // (eg, CDROM or DVD) then routine returns zero.
673 uint64_t get_num_sectors(const ata_identify_device
* drive
)
675 unsigned short command_set_2
= drive
->command_set_2
;
676 unsigned short capabilities_0
= drive
->words047_079
[49-47];
677 unsigned short sects_16
= drive
->words047_079
[60-47];
678 unsigned short sects_32
= drive
->words047_079
[61-47];
679 unsigned short lba_16
= drive
->words088_255
[100-88];
680 unsigned short lba_32
= drive
->words088_255
[101-88];
681 unsigned short lba_48
= drive
->words088_255
[102-88];
682 unsigned short lba_64
= drive
->words088_255
[103-88];
685 if (!(capabilities_0
& 0x0200))
688 // if drive supports LBA addressing, determine 32-bit LBA capacity
689 uint64_t lba32
= (unsigned int)sects_32
<< 16 |
690 (unsigned int)sects_16
<< 0 ;
693 // if drive supports 48-bit addressing, determine THAT capacity
694 if ((command_set_2
& 0xc000) == 0x4000 && (command_set_2
& 0x0400))
695 lba64
= (uint64_t)lba_64
<< 48 |
696 (uint64_t)lba_48
<< 32 |
697 (uint64_t)lba_32
<< 16 |
698 (uint64_t)lba_16
<< 0 ;
700 // return the larger of the two possible capacities
701 return (lba32
> lba64
? lba32
: lba64
);
704 // This function computes the checksum of a single disk sector (512
705 // bytes). Returns zero if checksum is OK, nonzero if the checksum is
706 // incorrect. The size (512) is correct for all SMART structures.
707 unsigned char checksum(const void * data
)
709 unsigned char sum
= 0;
710 for (int i
= 0; i
< 512; i
++)
711 sum
+= ((const unsigned char *)data
)[i
];
715 // Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
717 static void swapbytes(char * out
, const char * in
, size_t n
)
719 for (size_t i
= 0; i
< n
; i
+= 2) {
725 // Copies in to out, but removes leading and trailing whitespace.
726 static void trim(char * out
, const char * in
)
728 // Find the first non-space character (maybe none).
731 for (i
= 0; in
[i
]; i
++)
732 if (!isspace((int)in
[i
])) {
738 // There are no non-space characters.
743 // Find the last non-space character.
744 for (i
= strlen(in
)-1; i
>= first
&& isspace((int)in
[i
]); i
--)
748 strncpy(out
, in
+first
, last
-first
+1);
749 out
[last
-first
+1] = '\0';
752 // Convenience function for formatting strings from ata_identify_device
753 void format_ata_string(char * out
, const char * in
, int n
, bool fix_swap
)
755 bool must_swap
= !fix_swap
;
757 /* NetBSD kernel delivers IDENTIFY data in host byte order (but all else is LE) */
759 must_swap
= !must_swap
;
767 swapbytes(tmp
, in
, n
);
772 // returns -1 if command fails or the device is in Sleep mode, else
773 // value of Sector Count register. Sector Count result values:
774 // 00h device is in Standby mode.
775 // 80h device is in Idle mode.
776 // FFh device is in Active mode or Idle mode.
778 int ataCheckPowerMode(ata_device
* device
) {
779 unsigned char result
;
781 if ((smartcommandhandler(device
, CHECK_POWER_MODE
, 0, (char *)&result
)))
784 if (result
!=0 && result
!=0x80 && result
!=0xff)
785 pout("ataCheckPowerMode(): ATA CHECK POWER MODE returned unknown Sector Count Register value %02x\n", result
);
793 // Reads current Device Identity info (512 bytes) into buf. Returns 0
794 // if all OK. Returns -1 if no ATA Device identity can be
795 // established. Returns >0 if Device is ATA Packet Device (not SMART
796 // capable). The value of the integer helps identify the type of
797 // Packet device, which is useful so that the user can connect the
798 // formal device number with whatever object is inside their computer.
799 int ataReadHDIdentity (ata_device
* device
, struct ata_identify_device
*buf
){
800 unsigned short *rawshort
=(unsigned short *)buf
;
801 unsigned char *rawbyte
=(unsigned char *)buf
;
803 // See if device responds either to IDENTIFY DEVICE or IDENTIFY
805 if ((smartcommandhandler(device
, IDENTIFY
, 0, (char *)buf
))){
806 if (smartcommandhandler(device
, PIDENTIFY
, 0, (char *)buf
)){
812 // if machine is big-endian, swap byte order as needed
813 // NetBSD kernel delivers IDENTIFY data in host byte order
817 // swap various capability words that are needed
819 swap2((char *)(buf
->words047_079
+i
));
821 for (i
=80; i
<=87; i
++)
822 swap2((char *)(rawshort
+i
));
824 for (i
=0; i
<168; i
++)
825 swap2((char *)(buf
->words088_255
+i
));
829 // If there is a checksum there, validate it
830 if ((rawshort
[255] & 0x00ff) == 0x00a5 && checksum(rawbyte
))
831 checksumwarning("Drive Identity Structure");
833 // If this is a PACKET DEVICE, return device type
834 if (rawbyte
[1] & 0x80)
835 return 1+(rawbyte
[1] & 0x1f);
837 // Not a PACKET DEVICE
841 // Returns ATA version as an integer, and a pointer to a string
842 // describing which revision. Note that Revision 0 of ATA-3 does NOT
843 // support SMART. For this one case we return -3 rather than +3 as
844 // the version number. See notes above.
845 int ataVersionInfo(const char ** description
, const ata_identify_device
* drive
, unsigned short * minor
)
847 // check that arrays at the top of this file are defined
849 if (sizeof(minor_str
) != sizeof(char *)*(1+MINOR_MAX
)){
850 pout("Internal error in ataVersionInfo(). minor_str[] size %d\n"
851 "is not consistent with value of MINOR_MAX+1 = %d\n",
852 (int)(sizeof(minor_str
)/sizeof(char *)), MINOR_MAX
+1);
856 if (sizeof(actual_ver
) != sizeof(int)*(1+MINOR_MAX
)){
857 pout("Internal error in ataVersionInfo(). actual_ver[] size %d\n"
858 "is not consistent with value of MINOR_MAX = %d\n",
859 (int)(sizeof(actual_ver
)/sizeof(int)), MINOR_MAX
+1);
864 // get major and minor ATA revision numbers
865 unsigned short major
= drive
->major_rev_num
;
866 *minor
=drive
->minor_rev_num
;
868 // First check if device has ANY ATA version information in it
869 if (major
==NOVAL_0
|| major
==NOVAL_1
) {
871 return 0; // No info found
874 // The minor revision number has more information - try there first
875 if (*minor
&& (*minor
<=MINOR_MAX
)){
876 int std
= actual_ver
[*minor
];
878 *description
=minor_str
[*minor
];
883 // Try new ATA-8 minor revision numbers (Table 31 of T13/1699-D Revision 6)
884 // (not in actual_ver/minor_str to avoid large sparse tables)
887 case 0x0027: desc
= "ATA-8-ACS revision 3c"; break;
888 case 0x0028: desc
= "ATA-8-ACS revision 6"; break;
889 case 0x0029: desc
= "ATA-8-ACS revision 4"; break;
890 case 0x0033: desc
= "ATA-8-ACS revision 3e"; break;
891 case 0x0039: desc
= "ATA-8-ACS revision 4c"; break;
892 case 0x0042: desc
= "ATA-8-ACS revision 3f"; break;
893 case 0x0052: desc
= "ATA-8-ACS revision 3b"; break;
894 case 0x0107: desc
= "ATA-8-ACS revision 2d"; break;
895 default: desc
= 0; break;
902 // HDPARM has a very complicated algorithm from here on. Since SMART only
903 // exists on ATA-3 and later standards, let's punt on this. If you don't
904 // like it, please fix it. The code's in CVS.
907 if (major
& (0x1<<i
))
917 // returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
918 int ataSmartSupport(const ata_identify_device
* drive
)
920 unsigned short word82
=drive
->command_set_1
;
921 unsigned short word83
=drive
->command_set_2
;
923 // check if words 82/83 contain valid info
924 if ((word83
>>14) == 0x01)
925 // return value of SMART support bit
926 return word82
& 0x0001;
928 // since we can're rely on word 82, we don't know if SMART supported
932 // returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
933 int ataIsSmartEnabled(const ata_identify_device
* drive
)
935 unsigned short word85
=drive
->cfs_enable_1
;
936 unsigned short word87
=drive
->csf_default
;
938 // check if words 85/86/87 contain valid info
939 if ((word87
>>14) == 0x01)
940 // return value of SMART enabled bit
941 return word85
& 0x0001;
943 // Since we can't rely word85, we don't know if SMART is enabled.
948 // Reads SMART attributes into *data
949 int ataReadSmartValues(ata_device
* device
, struct ata_smart_values
*data
){
951 if (smartcommandhandler(device
, READ_VALUES
, 0, (char *)data
)){
952 syserror("Error SMART Values Read failed");
958 checksumwarning("SMART Attribute Data Structure");
960 // swap endian order if needed
963 swap2((char *)&(data
->revnumber
));
964 swap2((char *)&(data
->total_time_to_complete_off_line
));
965 swap2((char *)&(data
->smart_capability
));
966 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
967 struct ata_smart_attribute
*x
=data
->vendor_attributes
+i
;
968 swap2((char *)&(x
->flags
));
976 // This corrects some quantities that are byte reversed in the SMART
978 static void fixsamsungselftestlog(ata_smart_selftestlog
* data
)
980 // bytes 508/509 (numbered from 0) swapped (swap of self-test index
981 // with one byte of reserved.
982 swap2((char *)&(data
->mostrecenttest
));
984 // LBA low register (here called 'selftestnumber", containing
985 // information about the TYPE of the self-test) is byte swapped with
986 // Self-test execution status byte. These are bytes N, N+1 in the
988 for (int i
= 0; i
< 21; i
++)
989 swap2((char *)&(data
->selftest_struct
[i
].selftestnumber
));
994 // Reads the Self Test Log (log #6)
995 int ataReadSelfTestLog (ata_device
* device
, ata_smart_selftestlog
* data
,
996 unsigned char fix_firmwarebug
)
999 // get data from device
1000 if (smartcommandhandler(device
, READ_LOG
, 0x06, (char *)data
)){
1001 syserror("Error SMART Error Self-Test Log Read failed");
1005 // compute its checksum, and issue a warning if needed
1007 checksumwarning("SMART Self-Test Log Structure");
1009 // fix firmware bugs in self-test log
1010 if (fix_firmwarebug
== FIX_SAMSUNG
)
1011 fixsamsungselftestlog(data
);
1013 // swap endian order if needed
1016 swap2((char*)&(data
->revnumber
));
1017 for (i
=0; i
<21; i
++){
1018 struct ata_smart_selftestlog_struct
*x
=data
->selftest_struct
+i
;
1019 swap2((char *)&(x
->timestamp
));
1020 swap4((char *)&(x
->lbafirstfailure
));
1027 // Print checksum warning for multi sector log
1028 static void check_multi_sector_sum(const void * data
, unsigned nsectors
, const char * msg
)
1031 for (unsigned i
= 0; i
< nsectors
; i
++) {
1032 if (checksum((const unsigned char *)data
+ i
*512))
1037 checksumwarning(msg
);
1039 checksumwarning(strprintf("%s (%u/%u)", msg
, errs
, nsectors
).c_str());
1043 // Read SMART Extended Self-test Log
1044 bool ataReadExtSelfTestLog(ata_device
* device
, ata_smart_extselftestlog
* log
,
1047 if (!ataReadLogExt(device
, 0x07, 0x00, 0, log
, nsectors
))
1050 check_multi_sector_sum(log
, nsectors
, "SMART Extended Self-test Log Structure");
1052 if (isbigendian()) {
1053 swapx(&log
->log_desc_index
);
1054 for (unsigned i
= 0; i
< nsectors
; i
++) {
1055 for (unsigned j
= 0; j
< 19; j
++)
1056 swapx(&log
->log_descs
[i
].timestamp
);
1063 // Read GP Log page(s)
1064 bool ataReadLogExt(ata_device
* device
, unsigned char logaddr
,
1065 unsigned char features
, unsigned page
,
1066 void * data
, unsigned nsectors
)
1069 in
.in_regs
.command
= ATA_READ_LOG_EXT
;
1070 in
.in_regs
.features
= features
; // log specific
1071 in
.set_data_in_48bit(data
, nsectors
);
1072 in
.in_regs
.lba_low
= logaddr
;
1073 in
.in_regs
.lba_mid_16
= page
;
1075 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1076 if (nsectors
<= 1) {
1077 pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n",
1078 logaddr
, features
, page
, nsectors
, device
->get_errmsg());
1082 // Recurse to retry with single sectors,
1083 // multi-sector reads may not be supported by ioctl.
1084 for (unsigned i
= 0; i
< nsectors
; i
++) {
1085 if (!ataReadLogExt(device
, logaddr
,
1087 (char *)data
+ 512*i
, 1))
1095 // Read SMART Log page(s)
1096 bool ataReadSmartLog(ata_device
* device
, unsigned char logaddr
,
1097 void * data
, unsigned nsectors
)
1100 in
.in_regs
.command
= ATA_SMART_CMD
;
1101 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
1102 in
.set_data_in(data
, nsectors
);
1103 in
.in_regs
.lba_high
= SMART_CYL_HI
;
1104 in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
1105 in
.in_regs
.lba_low
= logaddr
;
1107 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1108 pout("ATA_SMART_READ_LOG failed: %s\n", device
->get_errmsg());
1116 // Reads the SMART or GPL Log Directory (log #0)
1117 int ataReadLogDirectory(ata_device
* device
, ata_smart_log_directory
* data
, bool gpl
)
1119 if (!gpl
) { // SMART Log directory
1120 if (smartcommandhandler(device
, READ_LOG
, 0x00, (char *)data
))
1123 else { // GP Log directory
1124 if (!ataReadLogExt(device
, 0x00, 0x00, 0, data
, 1))
1128 // swap endian order if needed
1130 swapx(&data
->logversion
);
1136 // Reads the selective self-test log (log #9)
1137 int ataReadSelectiveSelfTestLog(ata_device
* device
, struct ata_selective_self_test_log
*data
){
1139 // get data from device
1140 if (smartcommandhandler(device
, READ_LOG
, 0x09, (char *)data
)){
1141 syserror("Error SMART Read Selective Self-Test Log failed");
1145 // compute its checksum, and issue a warning if needed
1147 checksumwarning("SMART Selective Self-Test Log Structure");
1149 // swap endian order if needed
1152 swap2((char *)&(data
->logversion
));
1154 swap8((char *)&(data
->span
[i
].start
));
1155 swap8((char *)&(data
->span
[i
].end
));
1157 swap8((char *)&(data
->currentlba
));
1158 swap2((char *)&(data
->currentspan
));
1159 swap2((char *)&(data
->flags
));
1160 swap2((char *)&(data
->pendingtime
));
1163 if (data
->logversion
!= 1)
1164 pout("Note: selective self-test log revision number (%d) not 1 implies that no selective self-test has ever been run\n", data
->logversion
);
1169 // Writes the selective self-test log (log #9)
1170 int ataWriteSelectiveSelfTestLog(ata_device
* device
, ata_selective_selftest_args
& args
,
1171 const ata_smart_values
* sv
, uint64_t num_sectors
)
1173 // Disk size must be known
1175 pout("Disk size is unknown, unable to check selective self-test spans\n");
1180 struct ata_selective_self_test_log sstlog
, *data
=&sstlog
;
1181 unsigned char *ptr
=(unsigned char *)data
;
1182 if (ataReadSelectiveSelfTestLog(device
, data
)) {
1183 pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
1188 data
->logversion
= 1;
1190 // Host is NOT allowed to write selective self-test log if a selective
1191 // self-test is in progress.
1192 if (0<data
->currentspan
&& data
->currentspan
<6 && ((sv
->self_test_exec_status
)>>4)==15) {
1193 pout("Error SMART Selective or other Self-Test in progress.\n");
1197 // Set start/end values based on old spans for special -t select,... options
1199 for (i
= 0; i
< args
.num_spans
; i
++) {
1200 int mode
= args
.span
[i
].mode
;
1201 uint64_t start
= args
.span
[i
].start
;
1202 uint64_t end
= args
.span
[i
].end
;
1203 if (mode
== SEL_CONT
) {// redo or next dependig on last test status
1204 switch (sv
->self_test_exec_status
>> 4) {
1205 case 1: case 2: // Aborted/Interrupted by host
1206 pout("Continue Selective Self-Test: Redo last span\n");
1209 default: // All others
1210 pout("Continue Selective Self-Test: Start next span\n");
1216 case SEL_RANGE
: // -t select,START-END
1218 case SEL_REDO
: // -t select,redo... => Redo current
1219 start
= data
->span
[i
].start
;
1220 if (end
> 0) { // -t select,redo+SIZE
1221 end
--; end
+= start
; // [oldstart, oldstart+SIZE)
1223 else // -t select,redo
1224 end
= data
->span
[i
].end
; // [oldstart, oldend]
1226 case SEL_NEXT
: // -t select,next... => Do next
1227 if (data
->span
[i
].end
== 0) {
1228 start
= end
= 0; break; // skip empty spans
1230 start
= data
->span
[i
].end
+ 1;
1231 if (start
>= num_sectors
)
1232 start
= 0; // wrap around
1233 if (end
> 0) { // -t select,next+SIZE
1234 end
--; end
+= start
; // (oldend, oldend+SIZE]
1236 else { // -t select,next
1237 uint64_t oldsize
= data
->span
[i
].end
- data
->span
[i
].start
+ 1;
1238 end
= start
+ oldsize
- 1; // (oldend, oldend+oldsize]
1239 if (end
>= num_sectors
) {
1240 // Adjust size to allow round-robin testing without future size decrease
1241 uint64_t spans
= (num_sectors
+ oldsize
-1) / oldsize
;
1242 uint64_t newsize
= (num_sectors
+ spans
-1) / spans
;
1243 uint64_t newstart
= num_sectors
- newsize
, newend
= num_sectors
- 1;
1244 pout("Span %d changed from %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors)\n",
1245 i
, start
, end
, oldsize
);
1246 pout(" to %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors) (%"PRIu64
" spans)\n",
1247 newstart
, newend
, newsize
, spans
);
1248 start
= newstart
; end
= newend
;
1253 pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode
);
1257 if (start
< num_sectors
&& num_sectors
<= end
) {
1258 if (end
!= ~(uint64_t)0) // -t select,N-max
1259 pout("Size of self-test span %d decreased according to disk size\n", i
);
1260 end
= num_sectors
- 1;
1262 if (!(start
<= end
&& end
< num_sectors
)) {
1263 pout("Invalid selective self-test span %d: %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors)\n",
1264 i
, start
, end
, num_sectors
);
1267 // Return the actual mode and range to caller.
1268 args
.span
[i
].mode
= mode
;
1269 args
.span
[i
].start
= start
;
1270 args
.span
[i
].end
= end
;
1275 memset(data
->span
+i
, 0, sizeof(struct test_span
));
1277 // Set spans for testing
1278 for (i
= 0; i
< args
.num_spans
; i
++){
1279 data
->span
[i
].start
= args
.span
[i
].start
;
1280 data
->span
[i
].end
= args
.span
[i
].end
;
1283 // host must initialize to zero before initiating selective self-test
1285 data
->currentspan
=0;
1287 // Perform off-line scan after selective test?
1288 if (args
.scan_after_select
== 1)
1290 data
->flags
&= ~SELECTIVE_FLAG_DOSCAN
;
1291 else if (args
.scan_after_select
== 2)
1293 data
->flags
|= SELECTIVE_FLAG_DOSCAN
;
1295 // Must clear active and pending flags before writing
1296 data
->flags
&= ~(SELECTIVE_FLAG_ACTIVE
);
1297 data
->flags
&= ~(SELECTIVE_FLAG_PENDING
);
1299 // modify pending time?
1300 if (args
.pending_time
)
1301 data
->pendingtime
= (unsigned short)(args
.pending_time
-1);
1303 // Set checksum to zero, then compute checksum
1305 unsigned char cksum
=0;
1306 for (i
=0; i
<512; i
++)
1310 data
->checksum
=cksum
;
1312 // swap endian order if needed
1314 swap2((char *)&(data
->logversion
));
1315 for (int i
=0;i
<5;i
++){
1316 swap8((char *)&(data
->span
[i
].start
));
1317 swap8((char *)&(data
->span
[i
].end
));
1319 swap8((char *)&(data
->currentlba
));
1320 swap2((char *)&(data
->currentspan
));
1321 swap2((char *)&(data
->flags
));
1322 swap2((char *)&(data
->pendingtime
));
1325 // write new selective self-test log
1326 if (smartcommandhandler(device
, WRITE_LOG
, 0x09, (char *)data
)){
1327 syserror("Error Write Selective Self-Test Log failed");
1334 // This corrects some quantities that are byte reversed in the SMART
1336 static void fixsamsungerrorlog(ata_smart_errorlog
* data
)
1338 // FIXED IN SAMSUNG -25 FIRMWARE???
1339 // Device error count in bytes 452-3
1340 swap2((char *)&(data
->ata_error_count
));
1342 // FIXED IN SAMSUNG -22a FIRMWARE
1343 // step through 5 error log data structures
1344 for (int i
= 0; i
< 5; i
++){
1345 // step through 5 command data structures
1346 for (int j
= 0; j
< 5; j
++)
1347 // Command data structure 4-byte millisec timestamp. These are
1348 // bytes (N+8, N+9, N+10, N+11).
1349 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1350 // Error data structure two-byte hour life timestamp. These are
1351 // bytes (N+28, N+29).
1352 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1357 // NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
1358 static void fixsamsungerrorlog2(ata_smart_errorlog
* data
)
1360 // Device error count in bytes 452-3
1361 swap2((char *)&(data
->ata_error_count
));
1365 // Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1366 // Error Log is #2, and the Extended Comprehensive SMART Error log is
1368 int ataReadErrorLog (ata_device
* device
, ata_smart_errorlog
*data
,
1369 unsigned char fix_firmwarebug
)
1372 // get data from device
1373 if (smartcommandhandler(device
, READ_LOG
, 0x01, (char *)data
)){
1374 syserror("Error SMART Error Log Read failed");
1378 // compute its checksum, and issue a warning if needed
1380 checksumwarning("SMART ATA Error Log Structure");
1382 // Some disks have the byte order reversed in some SMART Summary
1383 // Error log entries
1384 if (fix_firmwarebug
== FIX_SAMSUNG
)
1385 fixsamsungerrorlog(data
);
1386 else if (fix_firmwarebug
== FIX_SAMSUNG2
)
1387 fixsamsungerrorlog2(data
);
1389 // swap endian order if needed
1393 // Device error count in bytes 452-3
1394 swap2((char *)&(data
->ata_error_count
));
1396 // step through 5 error log data structures
1397 for (i
=0; i
<5; i
++){
1398 // step through 5 command data structures
1400 // Command data structure 4-byte millisec timestamp
1401 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1402 // Error data structure life timestamp
1403 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1410 // Read Extended Comprehensive Error Log
1411 bool ataReadExtErrorLog(ata_device
* device
, ata_smart_exterrlog
* log
,
1414 if (!ataReadLogExt(device
, 0x03, 0x00, 0, log
, nsectors
))
1417 check_multi_sector_sum(log
, nsectors
, "SMART Extended Comprehensive Error Log Structure");
1419 if (isbigendian()) {
1420 swapx(&log
->device_error_count
);
1421 swapx(&log
->error_log_index
);
1423 for (unsigned i
= 0; i
< nsectors
; i
++) {
1424 for (unsigned j
= 0; j
< 4; j
++)
1425 swapx(&log
->error_logs
[i
].commands
[j
].timestamp
);
1426 swapx(&log
->error_logs
[i
].error
.timestamp
);
1434 int ataReadSmartThresholds (ata_device
* device
, struct ata_smart_thresholds_pvt
*data
){
1436 // get data from device
1437 if (smartcommandhandler(device
, READ_THRESHOLDS
, 0, (char *)data
)){
1438 syserror("Error SMART Thresholds Read failed");
1442 // compute its checksum, and issue a warning if needed
1444 checksumwarning("SMART Attribute Thresholds Structure");
1446 // swap endian order if needed
1448 swap2((char *)&(data
->revnumber
));
1453 int ataEnableSmart (ata_device
* device
){
1454 if (smartcommandhandler(device
, ENABLE
, 0, NULL
)){
1455 syserror("Error SMART Enable failed");
1461 int ataDisableSmart (ata_device
* device
){
1463 if (smartcommandhandler(device
, DISABLE
, 0, NULL
)){
1464 syserror("Error SMART Disable failed");
1470 int ataEnableAutoSave(ata_device
* device
){
1471 if (smartcommandhandler(device
, AUTOSAVE
, 241, NULL
)){
1472 syserror("Error SMART Enable Auto-save failed");
1478 int ataDisableAutoSave(ata_device
* device
){
1480 if (smartcommandhandler(device
, AUTOSAVE
, 0, NULL
)){
1481 syserror("Error SMART Disable Auto-save failed");
1487 // In *ALL* ATA standards the Enable/Disable AutoOffline command is
1488 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1489 // vendors still support it for backwards compatibility. IBM documents
1490 // it for some drives.
1491 int ataEnableAutoOffline (ata_device
* device
){
1493 /* timer hard coded to 4 hours */
1494 if (smartcommandhandler(device
, AUTO_OFFLINE
, 248, NULL
)){
1495 syserror("Error SMART Enable Automatic Offline failed");
1501 // Another Obsolete Command. See comments directly above, associated
1502 // with the corresponding Enable command.
1503 int ataDisableAutoOffline (ata_device
* device
){
1505 if (smartcommandhandler(device
, AUTO_OFFLINE
, 0, NULL
)){
1506 syserror("Error SMART Disable Automatic Offline failed");
1512 // If SMART is enabled, supported, and working, then this call is
1513 // guaranteed to return 1, else zero. Note that it should return 1
1514 // regardless of whether the disk's SMART status is 'healthy' or
1516 int ataDoesSmartWork(ata_device
* device
){
1517 int retval
=smartcommandhandler(device
, STATUS
, 0, NULL
);
1525 // This function uses a different interface (DRIVE_TASK) than the
1526 // other commands in this file.
1527 int ataSmartStatus2(ata_device
* device
){
1528 return smartcommandhandler(device
, STATUS_CHECK
, 0, NULL
);
1531 // This is the way to execute ALL tests: offline, short self-test,
1532 // extended self test, with and without captive mode, etc.
1533 // TODO: Move to ataprint.cpp ?
1534 int ataSmartTest(ata_device
* device
, int testtype
, const ata_selective_selftest_args
& selargs
,
1535 const ata_smart_values
* sv
, uint64_t num_sectors
)
1537 char cmdmsg
[128]; const char *type
, *captive
;
1538 int errornum
, cap
, retval
, select
=0;
1540 // Boolean, if set, says test is captive
1541 cap
=testtype
& CAPTIVE_MASK
;
1543 // Set up strings that describe the type of test
1549 if (testtype
==OFFLINE_FULL_SCAN
)
1551 else if (testtype
==SHORT_SELF_TEST
|| testtype
==SHORT_CAPTIVE_SELF_TEST
)
1552 type
="Short self-test";
1553 else if (testtype
==EXTEND_SELF_TEST
|| testtype
==EXTEND_CAPTIVE_SELF_TEST
)
1554 type
="Extended self-test";
1555 else if (testtype
==CONVEYANCE_SELF_TEST
|| testtype
==CONVEYANCE_CAPTIVE_SELF_TEST
)
1556 type
="Conveyance self-test";
1557 else if ((select
=(testtype
==SELECTIVE_SELF_TEST
|| testtype
==SELECTIVE_CAPTIVE_SELF_TEST
)))
1558 type
="Selective self-test";
1560 type
="[Unrecognized] self-test";
1562 // If doing a selective self-test, first use WRITE_LOG to write the
1563 // selective self-test log.
1564 ata_selective_selftest_args selargs_io
= selargs
; // filled with info about actual spans
1565 if (select
&& (retval
= ataWriteSelectiveSelfTestLog(device
, selargs_io
, sv
, num_sectors
))) {
1567 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1571 // Print ouf message that we are sending the command to test
1572 if (testtype
==ABORT_SELF_TEST
)
1573 sprintf(cmdmsg
,"Abort SMART off-line mode self-test routine");
1575 sprintf(cmdmsg
,"Execute SMART %s routine immediately in %s mode",type
,captive
);
1576 pout("Sending command: \"%s\".\n",cmdmsg
);
1580 pout("SPAN STARTING_LBA ENDING_LBA\n");
1581 for (i
= 0; i
< selargs_io
.num_spans
; i
++)
1582 pout(" %d %20"PRId64
" %20"PRId64
"\n", i
,
1583 selargs_io
.span
[i
].start
,
1584 selargs_io
.span
[i
].end
);
1587 // Now send the command to test
1588 errornum
=smartcommandhandler(device
, IMMEDIATE_OFFLINE
, testtype
, NULL
);
1590 if (errornum
&& !(cap
&& errno
==EIO
)){
1592 sprintf(errormsg
,"Command \"%s\" failed",cmdmsg
);
1598 // Since the command succeeded, tell user
1599 if (testtype
==ABORT_SELF_TEST
)
1600 pout("Self-testing aborted!\n");
1602 pout("Drive command \"%s\" successful.\nTesting has begun.\n",cmdmsg
);
1606 /* Test Time Functions */
1607 int TestTime(const ata_smart_values
*data
, int testtype
)
1610 case OFFLINE_FULL_SCAN
:
1611 return (int) data
->total_time_to_complete_off_line
;
1612 case SHORT_SELF_TEST
:
1613 case SHORT_CAPTIVE_SELF_TEST
:
1614 return (int) data
->short_test_completion_time
;
1615 case EXTEND_SELF_TEST
:
1616 case EXTEND_CAPTIVE_SELF_TEST
:
1617 return (int) data
->extend_test_completion_time
;
1618 case CONVEYANCE_SELF_TEST
:
1619 case CONVEYANCE_CAPTIVE_SELF_TEST
:
1620 return (int) data
->conveyance_test_completion_time
;
1626 // This function tells you both about the ATA error log and the
1627 // self-test error log capability (introduced in ATA-5). The bit is
1628 // poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1629 // SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1630 // word 84 and 87. Top two bits must match the pattern 01. BEFORE
1631 // ATA-6 these top two bits still had to match the pattern 01, but the
1632 // remaining bits were reserved (==0).
1633 int isSmartErrorLogCapable (const ata_smart_values
* data
, const ata_identify_device
* identity
)
1635 unsigned short word84
=identity
->command_set_extension
;
1636 unsigned short word87
=identity
->csf_default
;
1637 int isata6
=identity
->major_rev_num
& (0x01<<6);
1638 int isata7
=identity
->major_rev_num
& (0x01<<7);
1640 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x01))
1643 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x01))
1646 // otherwise we'll use the poorly documented capability bit
1647 return data
->errorlog_capability
& 0x01;
1650 // See previous function. If the error log exists then the self-test
1651 // log should (must?) also exist.
1652 int isSmartTestLogCapable (const ata_smart_values
* data
, const ata_identify_device
*identity
)
1654 unsigned short word84
=identity
->command_set_extension
;
1655 unsigned short word87
=identity
->csf_default
;
1656 int isata6
=identity
->major_rev_num
& (0x01<<6);
1657 int isata7
=identity
->major_rev_num
& (0x01<<7);
1659 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x02))
1662 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x02))
1666 // otherwise we'll use the poorly documented capability bit
1667 return data
->errorlog_capability
& 0x01;
1671 int isGeneralPurposeLoggingCapable(const ata_identify_device
*identity
)
1673 unsigned short word84
=identity
->command_set_extension
;
1674 unsigned short word87
=identity
->csf_default
;
1676 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1677 // cleared to zero, the contents of word 84 contains valid support
1678 // information. If not, support information is not valid in this
1680 if ((word84
>>14) == 0x01)
1681 // If bit 5 of word 84 is set to one, the device supports the
1682 // General Purpose Logging feature set.
1683 return (word84
& (0x01 << 5));
1685 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1686 // cleared to zero, the contents of words (87:85) contain valid
1687 // information. If not, information is not valid in these words.
1688 if ((word87
>>14) == 0x01)
1689 // If bit 5 of word 87 is set to one, the device supports
1690 // the General Purpose Logging feature set.
1691 return (word87
& (0x01 << 5));
1698 // SMART self-test capability is also indicated in bit 1 of DEVICE
1699 // IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1700 // However this was only introduced in ATA-6 (but self-test log was in
1702 int isSupportExecuteOfflineImmediate(const ata_smart_values
*data
)
1704 return data
->offline_data_collection_capability
& 0x01;
1707 // Note in the ATA-5 standard, the following bit is listed as "Vendor
1708 // Specific". So it may not be reliable. The only use of this that I
1709 // have found is in IBM drives, where it is well-documented. See for
1710 // example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1711 // hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
1712 int isSupportAutomaticTimer(const ata_smart_values
* data
)
1714 return data
->offline_data_collection_capability
& 0x02;
1716 int isSupportOfflineAbort(const ata_smart_values
*data
)
1718 return data
->offline_data_collection_capability
& 0x04;
1720 int isSupportOfflineSurfaceScan(const ata_smart_values
* data
)
1722 return data
->offline_data_collection_capability
& 0x08;
1724 int isSupportSelfTest (const ata_smart_values
* data
)
1726 return data
->offline_data_collection_capability
& 0x10;
1728 int isSupportConveyanceSelfTest(const ata_smart_values
* data
)
1730 return data
->offline_data_collection_capability
& 0x20;
1732 int isSupportSelectiveSelfTest(const ata_smart_values
* data
)
1734 return data
->offline_data_collection_capability
& 0x40;
1737 // Get attribute state
1738 ata_attr_state
ata_get_attr_state(const ata_smart_attribute
& attr
,
1739 const ata_smart_threshold_entry
& thre
,
1740 const ata_vendor_attr_defs
& defs
)
1743 return ATTRSTATE_NON_EXISTING
;
1745 // Normalized values (current,worst,threshold) not valid
1746 // if specified by '-v' option.
1747 // (Some SSD disks uses these bytes to store raw value).
1748 if (defs
[attr
.id
].flags
& ATTRFLAG_NO_NORMVAL
)
1749 return ATTRSTATE_NO_NORMVAL
;
1751 // No threshold if thresholds cannot be read.
1752 if (!thre
.id
&& !thre
.threshold
)
1753 return ATTRSTATE_NO_THRESHOLD
;
1755 // Bad threshold if id's don't match
1756 if (attr
.id
!= thre
.id
)
1757 return ATTRSTATE_BAD_THRESHOLD
;
1759 // Don't report a failed attribute if its threshold is 0.
1760 // ATA-3 (X3T13/2008D Revision 7b) declares 0x00 as the "always passing"
1761 // threshold (Later ATA versions declare all thresholds as "obsolete").
1762 // In practice, threshold value 0 is often used for usage attributes.
1763 if (!thre
.threshold
)
1764 return ATTRSTATE_OK
;
1766 // Failed now if current value is below threshold
1767 if (attr
.current
<= thre
.threshold
)
1768 return ATTRSTATE_FAILED_NOW
;
1770 // Failed in the past if worst value is below threshold
1771 if (!(defs
[attr
.id
].flags
& ATTRFLAG_NO_WORSTVAL
) && attr
.worst
<= thre
.threshold
)
1772 return ATTRSTATE_FAILED_PAST
;
1774 return ATTRSTATE_OK
;
1777 // Get default raw value print format
1778 static ata_attr_raw_format
get_default_raw_format(unsigned char id
)
1781 case 3: // Spin-up time
1782 return RAWFMT_RAW16_OPT_AVG16
;
1784 case 5: // Reallocated sector count
1785 case 196: // Reallocated event count
1786 return RAWFMT_RAW16_OPT_RAW16
;
1788 case 190: // Temperature
1790 return RAWFMT_TEMPMINMAX
;
1793 return RAWFMT_RAW48
;
1797 // Get attribute raw value.
1798 uint64_t ata_get_attr_raw_value(const ata_smart_attribute
& attr
,
1799 const ata_vendor_attr_defs
& defs
)
1801 const ata_vendor_attr_defs::entry
& def
= defs
[attr
.id
];
1803 // Use default byteorder if not specified
1804 const char * byteorder
= def
.byteorder
;
1806 if (def
.raw_format
== RAWFMT_RAW64
|| def
.raw_format
== RAWFMT_HEX64
)
1807 byteorder
= "543210wv";
1809 byteorder
= "543210";
1812 // Build 64-bit value from selected bytes
1813 uint64_t rawvalue
= 0;
1814 for (int i
= 0; byteorder
[i
]; i
++) {
1816 switch (byteorder
[i
]) {
1817 case '0': b
= attr
.raw
[0]; break;
1818 case '1': b
= attr
.raw
[1]; break;
1819 case '2': b
= attr
.raw
[2]; break;
1820 case '3': b
= attr
.raw
[3]; break;
1821 case '4': b
= attr
.raw
[4]; break;
1822 case '5': b
= attr
.raw
[5]; break;
1823 case 'r': b
= attr
.reserv
; break;
1824 case 'v': b
= attr
.current
; break;
1825 case 'w': b
= attr
.worst
; break;
1826 default : b
= 0; break;
1828 rawvalue
<<= 8; rawvalue
|= b
;
1835 // Format attribute raw value.
1836 std::string
ata_format_attr_raw_value(const ata_smart_attribute
& attr
,
1837 const ata_vendor_attr_defs
& defs
)
1839 // Get 48 bit or 64 bit raw value
1840 uint64_t rawvalue
= ata_get_attr_raw_value(attr
, defs
);
1843 const unsigned char * raw
= attr
.raw
;
1845 word
[0] = raw
[0] | (raw
[1] << 8);
1846 word
[1] = raw
[2] | (raw
[3] << 8);
1847 word
[2] = raw
[4] | (raw
[5] << 8);
1850 ata_attr_raw_format format
= defs
[attr
.id
].raw_format
;
1851 if (format
== RAWFMT_DEFAULT
)
1852 format
= get_default_raw_format(attr
.id
);
1858 s
= strprintf("%d %d %d %d %d %d",
1859 raw
[5], raw
[4], raw
[3], raw
[2], raw
[1], raw
[0]);
1863 s
= strprintf("%u %u %u", word
[2], word
[1], word
[0]);
1868 s
= strprintf("%"PRIu64
, rawvalue
);
1872 s
= strprintf("0x%012"PRIx64
, rawvalue
);
1876 s
= strprintf("0x%016"PRIx64
, rawvalue
);
1879 case RAWFMT_RAW16_OPT_RAW16
:
1880 s
= strprintf("%u", word
[0]);
1881 if (word
[1] || word
[2])
1882 s
+= strprintf(" (%u, %u)", word
[2], word
[1]);
1885 case RAWFMT_RAW16_OPT_AVG16
:
1886 s
= strprintf("%u", word
[0]);
1888 s
+= strprintf(" (Average %u)", word
[1]);
1891 case RAWFMT_RAW24_RAW24
:
1892 s
= strprintf("%d/%d",
1893 raw
[0] | (raw
[1]<<8) | (raw
[2]<<16),
1894 raw
[3] | (raw
[4]<<8) | (raw
[5]<<16));
1897 case RAWFMT_MIN2HOUR
:
1900 int64_t temp
= word
[0]+(word
[1]<<16);
1901 int64_t tmp1
= temp
/60;
1902 int64_t tmp2
= temp
%60;
1903 s
= strprintf("%"PRIu64
"h+%02"PRIu64
"m", tmp1
, tmp2
);
1905 s
+= strprintf(" (%u)", word
[2]);
1909 case RAWFMT_SEC2HOUR
:
1912 int64_t hours
= rawvalue
/3600;
1913 int64_t minutes
= (rawvalue
-3600*hours
)/60;
1914 int64_t seconds
= rawvalue
%60;
1915 s
= strprintf("%"PRIu64
"h+%02"PRIu64
"m+%02"PRIu64
"s", hours
, minutes
, seconds
);
1919 case RAWFMT_HALFMIN2HOUR
:
1921 // 30-second counter
1922 int64_t hours
= rawvalue
/120;
1923 int64_t minutes
= (rawvalue
-120*hours
)/2;
1924 s
+= strprintf("%"PRIu64
"h+%02"PRIu64
"m", hours
, minutes
);
1928 case RAWFMT_TEMPMINMAX
:
1930 s
= strprintf("%u", word
[0]);
1931 if (word
[1] || word
[2]) {
1932 unsigned lo
= ~0, hi
= ~0;
1934 // 00 HH 00 LL 00 TT (IBM)
1935 hi
= word
[2]; lo
= word
[1];
1937 else if (!word
[2]) {
1938 // 00 00 HH LL 00 TT (Maxtor)
1939 hi
= raw
[3]; lo
= raw
[2];
1942 unsigned t
= lo
; lo
= hi
; hi
= t
;
1944 if (lo
<= word
[0] && word
[0] <= hi
)
1945 s
+= strprintf(" (Lifetime Min/Max %u/%u)", lo
, hi
);
1947 s
+= strprintf(" (%d %d %d %d)", raw
[5], raw
[4], raw
[3], raw
[2]);
1951 case RAWFMT_TEMP10X
:
1952 // ten times temperature in Celsius
1953 s
= strprintf("%d.%d", word
[0]/10, word
[0]%10);
1957 s
= "?"; // Should not happen
1964 // Attribute names shouldn't be longer than 23 chars, otherwise they break the
1965 // output of smartctl.
1966 static const char * get_default_attr_name(unsigned char id
)
1970 return "Raw_Read_Error_Rate";
1972 return "Throughput_Performance";
1974 return "Spin_Up_Time";
1976 return "Start_Stop_Count";
1978 return "Reallocated_Sector_Ct";
1980 return "Read_Channel_Margin";
1982 return "Seek_Error_Rate";
1984 return "Seek_Time_Performance";
1986 return "Power_On_Hours";
1988 return "Spin_Retry_Count";
1990 return "Calibration_Retry_Count";
1992 return "Power_Cycle_Count";
1994 return "Read_Soft_Error_Rate";
1996 return "Program_Fail_Count_Chip";
1998 return "Erase_Fail_Count_Chip";
2000 return "Wear_Leveling_Count";
2002 return "Used_Rsvd_Blk_Cnt_Chip";
2004 return "Used_Rsvd_Blk_Cnt_Tot";
2006 return "Unused_Rsvd_Blk_Cnt_Tot";
2008 return "Program_Fail_Cnt_Total";
2010 return "Erase_Fail_Count_Total";
2012 return "Runtime_Bad_Block";
2014 return "End-to-End_Error";
2016 return "Reported_Uncorrect";
2018 return "Command_Timeout";
2020 return "High_Fly_Writes";
2022 // Western Digital uses this for temperature.
2023 // It's identical to Attribute 194 except that it
2024 // has a failure threshold set to correspond to the
2025 // max allowed operating temperature of the drive, which
2026 // is typically 55C. So if this attribute has failed
2027 // in the past, it indicates that the drive temp exceeded
2028 // 55C sometime in the past.
2029 return "Airflow_Temperature_Cel";
2031 return "G-Sense_Error_Rate";
2033 return "Power-Off_Retract_Count";
2035 return "Load_Cycle_Count";
2037 return "Temperature_Celsius";
2039 // Fujitsu: "ECC_On_The_Fly_Count";
2040 return "Hardware_ECC_Recovered";
2042 return "Reallocated_Event_Count";
2044 return "Current_Pending_Sector";
2046 return "Offline_Uncorrectable";
2048 return "UDMA_CRC_Error_Count";
2051 return "Multi_Zone_Error_Rate";
2053 return "Soft_Read_Error_Rate";
2055 // Fujitsu: "TA_Increase_Count"
2056 return "Data_Address_Mark_Errs";
2059 return "Run_Out_Cancel";
2060 // Maxtor: ECC Errors
2062 // Fujitsu: "Shock_Count_Write_Opern"
2063 return "Soft_ECC_Correction";
2065 // Fujitsu: "Shock_Rate_Write_Opern"
2066 return "Thermal_Asperity_Rate";
2069 return "Flying_Height";
2072 return "Spin_High_Current";
2078 return "Offline_Seek_Performnce";
2080 return "Disk_Shift";
2082 return "G-Sense_Error_Rate";
2084 return "Loaded_Hours";
2086 return "Load_Retry_Count";
2088 return "Load_Friction";
2090 return "Load_Cycle_Count";
2092 return "Load-in_Time";
2094 return "Torq-amp_Count";
2096 return "Power-off_Retract_Count";
2098 // seen in IBM DTPA-353750
2099 return "Head_Amplitude";
2101 return "Temperature_Celsius";
2103 // seen in Intel X25-E SSD
2104 return "Available_Reservd_Space";
2106 // seen in Intel X25-E SSD
2107 return "Media_Wearout_Indicator";
2109 return "Head_Flying_Hours";
2111 return "Total_LBAs_Written";
2113 return "Total_LBAs_Read";
2115 return "Read_Error_Retry_Rate";
2117 return "Free_Fall_Sensor";
2119 return "Unknown_Attribute";
2123 // Get attribute name
2124 std::string
ata_get_smart_attr_name(unsigned char id
, const ata_vendor_attr_defs
& defs
)
2126 if (!defs
[id
].name
.empty())
2127 return defs
[id
].name
;
2129 return get_default_attr_name(id
);
2132 // Find attribute index for attribute id, -1 if not found.
2133 int ata_find_attr_index(unsigned char id
, const ata_smart_values
& smartval
)
2137 for (int i
= 0; i
< NUMBER_ATA_SMART_ATTRIBUTES
; i
++) {
2138 if (smartval
.vendor_attributes
[i
].id
== id
)
2144 // Return Temperature Attribute raw value selected according to possible
2145 // non-default interpretations. If the Attribute does not exist, return 0
2146 unsigned char ata_return_temperature_value(const ata_smart_values
* data
, const ata_vendor_attr_defs
& defs
)
2148 for (int i
= 0; i
< 3; i
++) {
2149 static const unsigned char ids
[3] = {194, 9, 220};
2150 unsigned char id
= ids
[i
];
2151 const ata_attr_raw_format format
= defs
[id
].raw_format
;
2152 if (!( (id
== 194 && format
== RAWFMT_DEFAULT
)
2153 || format
== RAWFMT_TEMPMINMAX
|| format
== RAWFMT_TEMP10X
))
2155 int idx
= ata_find_attr_index(id
, *data
);
2158 uint64_t raw
= ata_get_attr_raw_value(data
->vendor_attributes
[idx
], defs
);
2159 unsigned temp
= (unsigned short)raw
; // ignore possible min/max values in high words
2160 if (format
== RAWFMT_TEMP10X
) // -v N,temp10x
2161 temp
= (temp
+5) / 10;
2162 if (!(0 < temp
&& temp
<= 255))
2166 // No valid attribute found
2172 int ataReadSCTStatus(ata_device
* device
, ata_sct_status_response
* sts
)
2174 // read SCT status via SMART log 0xe0
2175 memset(sts
, 0, sizeof(*sts
));
2176 if (smartcommandhandler(device
, READ_LOG
, 0xe0, (char *)sts
)){
2177 syserror("Error Read SCT Status failed");
2181 // swap endian order if needed
2183 swapx(&sts
->format_version
);
2184 swapx(&sts
->sct_version
);
2185 swapx(&sts
->sct_spec
);
2186 swapx(&sts
->ext_status_code
);
2187 swapx(&sts
->action_code
);
2188 swapx(&sts
->function_code
);
2189 swapx(&sts
->over_limit_count
);
2190 swapx(&sts
->under_limit_count
);
2193 // Check format version
2194 if (!(sts
->format_version
== 2 || sts
->format_version
== 3)) {
2195 pout("Error unknown SCT Status format version %u, should be 2 or 3.\n", sts
->format_version
);
2201 // Read SCT Temperature History Table and Status
2202 int ataReadSCTTempHist(ata_device
* device
, ata_sct_temperature_history_table
* tmh
,
2203 ata_sct_status_response
* sts
)
2205 // Check initial status
2206 if (ataReadSCTStatus(device
, sts
))
2209 // Do nothing if other SCT command is executing
2210 if (sts
->ext_status_code
== 0xffff) {
2211 pout("Another SCT command is executing, abort Read Data Table\n"
2212 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2213 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2217 ata_sct_data_table_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2218 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2219 cmd
.action_code
= 5; // Data table command
2220 cmd
.function_code
= 1; // Read table
2221 cmd
.table_id
= 2; // Temperature History Table
2223 // swap endian order if needed
2224 if (isbigendian()) {
2225 swapx(&cmd
.action_code
);
2226 swapx(&cmd
.function_code
);
2227 swapx(&cmd
.table_id
);
2230 // write command via SMART log page 0xe0
2231 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2232 syserror("Error Write SCT Data Table command failed");
2236 // read SCT data via SMART log page 0xe1
2237 memset(tmh
, 0, sizeof(*tmh
));
2238 if (smartcommandhandler(device
, READ_LOG
, 0xe1, (char *)tmh
)){
2239 syserror("Error Read SCT Data Table failed");
2243 // re-read and check SCT status
2244 if (ataReadSCTStatus(device
, sts
))
2247 if (!(sts
->ext_status_code
== 0 && sts
->action_code
== 5 && sts
->function_code
== 1)) {
2248 pout("Error unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2249 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2253 // swap endian order if needed
2255 swapx(&tmh
->format_version
);
2256 swapx(&tmh
->sampling_period
);
2257 swapx(&tmh
->interval
);
2260 // Check format version
2261 if (tmh
->format_version
!= 2) {
2262 pout("Error unknown SCT Temperature History Format Version (%u), should be 2.\n", tmh
->format_version
);
2268 // Set SCT Temperature Logging Interval
2269 int ataSetSCTTempInterval(ata_device
* device
, unsigned interval
, bool persistent
)
2271 // Check initial status
2272 ata_sct_status_response sts
;
2273 if (ataReadSCTStatus(device
, &sts
))
2276 // Do nothing if other SCT command is executing
2277 if (sts
.ext_status_code
== 0xffff) {
2278 pout("Another SCT command is executing, abort Feature Control\n"
2279 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2280 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2284 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2285 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2286 cmd
.action_code
= 4; // Feature Control command
2287 cmd
.function_code
= 1; // Set state
2288 cmd
.feature_code
= 3; // Temperature logging interval
2289 cmd
.state
= interval
;
2290 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2292 // swap endian order if needed
2293 if (isbigendian()) {
2294 swapx(&cmd
.action_code
);
2295 swapx(&cmd
.function_code
);
2296 swapx(&cmd
.feature_code
);
2298 swapx(&cmd
.option_flags
);
2301 // write command via SMART log page 0xe0
2302 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2303 syserror("Error Write SCT Feature Control Command failed");
2307 // re-read and check SCT status
2308 if (ataReadSCTStatus(device
, &sts
))
2311 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== 1)) {
2312 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2313 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2319 // Get/Set SCT Error Recovery Control
2320 static int ataGetSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
,
2321 bool set
, unsigned short & time_limit
)
2323 // Check initial status
2324 ata_sct_status_response sts
;
2325 if (ataReadSCTStatus(device
, &sts
))
2328 // Do nothing if other SCT command is executing
2329 if (sts
.ext_status_code
== 0xffff) {
2330 pout("Another SCT command is executing, abort Error Recovery Control\n"
2331 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2332 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2336 ata_sct_error_recovery_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2337 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2338 cmd
.action_code
= 3; // Error Recovery Control command
2339 cmd
.function_code
= (set
? 1 : 2); // 1=Set timer, 2=Get timer
2340 cmd
.selection_code
= type
; // 1=Read timer, 2=Write timer
2342 cmd
.time_limit
= time_limit
;
2344 // swap endian order if needed
2345 if (isbigendian()) {
2346 swapx(&cmd
.action_code
);
2347 swapx(&cmd
.function_code
);
2348 swapx(&cmd
.selection_code
);
2349 swapx(&cmd
.time_limit
);
2352 // write command via SMART log page 0xe0
2353 // TODO: Debug output
2355 in
.in_regs
.command
= ATA_SMART_CMD
;
2356 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
2357 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
2358 in
.in_regs
.lba_low
= 0xe0;
2359 in
.set_data_out(&cmd
, 1);
2362 // Time limit returned in ATA registers
2363 in
.out_needed
.sector_count
= in
.out_needed
.lba_low
= true;
2366 if (!device
->ata_pass_through(in
, out
)) {
2367 pout("Error Write SCT Error Recovery Control Command failed: %s\n", device
->get_errmsg());
2371 // re-read and check SCT status
2372 if (ataReadSCTStatus(device
, &sts
))
2375 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 3 && sts
.function_code
== (set
? 1 : 2))) {
2376 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2377 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2382 // Check whether registers are properly returned by ioctl()
2383 if (!(out
.out_regs
.sector_count
.is_set() && out
.out_regs
.lba_low
.is_set())) {
2384 // TODO: Output register support should be checked within each ata_pass_through()
2385 // implementation before command is issued.
2386 pout("Error SMART WRITE LOG does not return COUNT and LBA_LOW register\n");
2389 // Return value to caller
2390 time_limit
= out
.out_regs
.sector_count
| (out
.out_regs
.lba_low
<< 8);
2396 // Get SCT Error Recovery Control
2397 int ataGetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short & time_limit
)
2399 return ataGetSetSCTErrorRecoveryControltime(device
, type
, false/*get*/, time_limit
);
2402 // Set SCT Error Recovery Control
2403 int ataSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short time_limit
)
2405 return ataGetSetSCTErrorRecoveryControltime(device
, type
, true/*set*/, time_limit
);
2409 // Print one self-test log entry.
2410 // Returns true if self-test showed an error.
2411 bool ataPrintSmartSelfTestEntry(unsigned testnum
, unsigned char test_type
,
2412 unsigned char test_status
,
2413 unsigned short timestamp
,
2414 uint64_t failing_lba
,
2415 bool print_error_only
, bool & print_header
)
2417 const char * msgtest
;
2418 switch (test_type
) {
2419 case 0x00: msgtest
= "Offline"; break;
2420 case 0x01: msgtest
= "Short offline"; break;
2421 case 0x02: msgtest
= "Extended offline"; break;
2422 case 0x03: msgtest
= "Conveyance offline"; break;
2423 case 0x04: msgtest
= "Selective offline"; break;
2424 case 0x7f: msgtest
= "Abort offline test"; break;
2425 case 0x81: msgtest
= "Short captive"; break;
2426 case 0x82: msgtest
= "Extended captive"; break;
2427 case 0x83: msgtest
= "Conveyance captive"; break;
2428 case 0x84: msgtest
= "Selective captive"; break;
2430 if ((0x40 <= test_type
&& test_type
<= 0x7e) || 0x90 <= test_type
)
2431 msgtest
= "Vendor offline";
2433 msgtest
= "Reserved offline";
2436 bool is_error
= false;
2437 const char * msgstat
;
2438 switch (test_status
>> 4) {
2439 case 0x0: msgstat
= "Completed without error"; break;
2440 case 0x1: msgstat
= "Aborted by host"; break;
2441 case 0x2: msgstat
= "Interrupted (host reset)"; break;
2442 case 0x3: msgstat
= "Fatal or unknown error"; is_error
= true; break;
2443 case 0x4: msgstat
= "Completed: unknown failure"; is_error
= true; break;
2444 case 0x5: msgstat
= "Completed: electrical failure"; is_error
= true; break;
2445 case 0x6: msgstat
= "Completed: servo/seek failure"; is_error
= true; break;
2446 case 0x7: msgstat
= "Completed: read failure"; is_error
= true; break;
2447 case 0x8: msgstat
= "Completed: handling damage??"; is_error
= true; break;
2448 case 0xf: msgstat
= "Self-test routine in progress"; break;
2449 default: msgstat
= "Unknown/reserved test status";
2452 if (!is_error
&& print_error_only
)
2455 // Print header once
2457 print_header
= false;
2458 pout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2462 if (is_error
&& failing_lba
< 0xffffffffffffULL
)
2463 snprintf(msglba
, sizeof(msglba
), "%"PRIu64
, failing_lba
);
2465 strcpy(msglba
, "-");
2467 pout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum
, msgtest
, msgstat
,
2468 test_status
& 0x0f, timestamp
, msglba
);
2473 // Print Smart self-test log, used by smartctl and smartd.
2475 // bottom 8 bits: number of entries found where self-test showed an error
2476 // remaining bits: if nonzero, power on hours of last self-test where error was found
2477 int ataPrintSmartSelfTestlog(const ata_smart_selftestlog
* data
, bool allentries
,
2478 unsigned char fix_firmwarebug
)
2481 pout("SMART Self-test log structure revision number %d\n",(int)data
->revnumber
);
2482 if ((data
->revnumber
!=0x0001) && allentries
&& fix_firmwarebug
!= FIX_SAMSUNG
)
2483 pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2484 if (data
->mostrecenttest
==0){
2486 pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
2490 bool noheaderprinted
= true;
2491 int retval
=0, hours
=0, testno
=0;
2494 for (int i
= 20; i
>= 0; i
--) {
2495 // log is a circular buffer
2496 int j
= (i
+data
->mostrecenttest
)%21;
2497 const ata_smart_selftestlog_struct
* log
= data
->selftest_struct
+j
;
2499 if (nonempty(log
, sizeof(*log
))) {
2500 // count entry based on non-empty structures -- needed for
2501 // Seagate only -- other vendors don't have blank entries 'in
2505 // T13/1321D revision 1c: (Data structure Rev #1)
2507 //The failing LBA shall be the LBA of the uncorrectable sector
2508 //that caused the test to fail. If the device encountered more
2509 //than one uncorrectable sector during the test, this field
2510 //shall indicate the LBA of the first uncorrectable sector
2511 //encountered. If the test passed or the test failed for some
2512 //reason other than an uncorrectable sector, the value of this
2513 //field is undefined.
2515 // This is true in ALL ATA-5 specs
2516 uint64_t lba48
= (log
->lbafirstfailure
< 0xffffffff ? log
->lbafirstfailure
: 0xffffffffffffULL
);
2519 if (ataPrintSmartSelfTestEntry(testno
,
2520 log
->selftestnumber
, log
->selfteststatus
,
2521 log
->timestamp
, lba48
, !allentries
, noheaderprinted
)) {
2523 // Self-test showed an error
2526 // keep track of time of most recent error
2528 hours
= log
->timestamp
;
2532 if (!allentries
&& retval
)
2536 return (retval
| hours
);
2540 /////////////////////////////////////////////////////////////////////////////
2541 // Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2542 // an ATA device with same behaviour
2546 class parsed_ata_device
2547 : public /*implements*/ ata_device_with_command_set
2550 parsed_ata_device(smart_interface
* intf
, const char * dev_name
);
2552 virtual ~parsed_ata_device() throw();
2554 virtual bool is_open() const;
2556 virtual bool open();
2558 virtual bool close();
2560 virtual bool ata_identify_is_cached() const;
2563 virtual int ata_command_interface(smart_command_set command
, int select
, char * data
);
2566 // Table of parsed commands, return value, data
2567 struct parsed_ata_command
2569 smart_command_set command
;
2575 enum { max_num_commands
= 32 };
2576 parsed_ata_command m_command_table
[max_num_commands
];
2579 int m_next_replay_command
;
2580 bool m_replay_out_of_sync
;
2581 bool m_ata_identify_is_cached
;
2584 static const char * nextline(const char * s
, int & lineno
)
2586 for (s
+= strcspn(s
, "\r\n"); *s
== '\r' || *s
== '\n'; s
++) {
2587 if (*s
== '\r' && s
[1] == '\n')
2594 static int name2command(const char * s
)
2596 for (int i
= 0; i
< (int)(sizeof(commandstrings
)/sizeof(commandstrings
[0])); i
++) {
2597 if (!strcmp(s
, commandstrings
[i
]))
2603 static bool matchcpy(char * dest
, size_t size
, const char * src
, const regmatch_t
& srcmatch
)
2605 if (srcmatch
.rm_so
< 0)
2607 size_t n
= srcmatch
.rm_eo
- srcmatch
.rm_so
;
2610 memcpy(dest
, src
+ srcmatch
.rm_so
, n
);
2615 static inline int matchtoi(const char * src
, const regmatch_t
& srcmatch
, int defval
)
2617 if (srcmatch
.rm_so
< 0)
2619 return atoi(src
+ srcmatch
.rm_so
);
2622 parsed_ata_device::parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2623 : smart_device(intf
, dev_name
, "ata", ""),
2625 m_next_replay_command(0),
2626 m_replay_out_of_sync(false),
2627 m_ata_identify_is_cached(false)
2629 memset(m_command_table
, 0, sizeof(m_command_table
));
2632 parsed_ata_device::~parsed_ata_device() throw()
2637 bool parsed_ata_device::is_open() const
2639 return (m_num_commands
> 0);
2642 // Parse stdin and build command table
2643 bool parsed_ata_device::open()
2645 const char * pathname
= get_dev_name();
2646 if (strcmp(pathname
, "-"))
2647 return set_err(EINVAL
);
2648 pathname
= "<stdin>";
2650 char buffer
[64*1024];
2652 while (size
< (int)sizeof(buffer
)) {
2653 int nr
= fread(buffer
, 1, sizeof(buffer
), stdin
);
2659 return set_err(ENOENT
, "%s: Unexpected EOF", pathname
);
2660 if (size
>= (int)sizeof(buffer
))
2661 return set_err(EIO
, "%s: Buffer overflow", pathname
);
2664 // Regex to match output from "-r ataioctl,2"
2665 static const char pattern
[] = "^"
2667 "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
2669 "( InputParameter=([0-9]+))?" // (4 (5))
2671 "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2673 "[\r\n]" // EOL match necessary to match optional parts above
2675 "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2677 " *(En|Dis)abled status cached by OS, " // (11)
2681 regular_expression regex
;
2682 if (!regex
.compile(pattern
, REG_EXTENDED
))
2683 return set_err(EIO
, "invalid regex");
2686 const char * errmsg
= 0;
2687 int i
= -1, state
= 0, lineno
= 1;
2688 for (const char * line
= buffer
; *line
; line
= nextline(line
, lineno
)) {
2690 if (!(line
[0] == 'R' || line
[0] == '=' || line
[0] == ' '))
2692 const int nmatch
= 1+11;
2693 regmatch_t match
[nmatch
];
2694 if (!regex
.execute(line
, nmatch
, match
))
2698 if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[2])) { // "REPORT-IOCTL:... Command=%s ..."
2699 int nc
= name2command(cmdname
);
2701 errmsg
= "Unknown ATA command name"; break;
2703 if (match
[7].rm_so
< 0) { // "returned %d"
2705 if (!(state
== 0 || state
== 2)) {
2706 errmsg
= "Missing REPORT-IOCTL result"; break;
2708 if (++i
>= max_num_commands
) {
2709 errmsg
= "Too many ATA commands"; break;
2711 m_command_table
[i
].command
= (smart_command_set
)nc
;
2712 m_command_table
[i
].select
= matchtoi(line
, match
[5], 0); // "InputParameter=%d"
2717 if (!(state
== 1 && (int)m_command_table
[i
].command
== nc
)) {
2718 errmsg
= "Missing REPORT-IOCTL start"; break;
2720 m_command_table
[i
].retval
= matchtoi(line
, match
[7], -1); // "returned %d"
2721 m_command_table
[i
].errval
= matchtoi(line
, match
[9], 0); // "errno=%d"
2725 else if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[10])) { // "===== [%s] DATA START "
2726 // Start of sector hexdump
2727 int nc
= name2command(cmdname
);
2728 if (!(state
== (nc
== WRITE_LOG
? 1 : 2) && (int)m_command_table
[i
].command
== nc
)) {
2729 errmsg
= "Unexpected DATA START"; break;
2731 line
= nextline(line
, lineno
);
2732 char * data
= (char *)malloc(512);
2734 for (j
= 0; j
< 32; j
++) {
2736 unsigned u1
, u2
; int n1
= -1;
2737 if (!(sscanf(line
, "%3u-%3u: "
2738 "%2x %2x %2x %2x %2x %2x %2x %2x "
2739 "%2x %2x %2x %2x %2x %2x %2x %2x%n",
2741 b
+ 0, b
+ 1, b
+ 2, b
+ 3, b
+ 4, b
+ 5, b
+ 6, b
+ 7,
2742 b
+ 8, b
+ 9, b
+10, b
+11, b
+12, b
+13, b
+14, b
+15, &n1
) == 18
2743 && n1
>= 56 && u1
== j
*16 && u2
== j
*16+15))
2745 for (unsigned k
= 0; k
< 16; k
++)
2746 data
[j
*16+k
] = b
[k
];
2747 line
= nextline(line
, lineno
);
2751 errmsg
= "Incomplete sector hex dump"; break;
2753 m_command_table
[i
].data
= data
;
2754 if (nc
!= WRITE_LOG
)
2757 else if (match
[11].rm_so
> 0) { // "(En|Dis)abled status cached by OS"
2758 m_ata_identify_is_cached
= true;
2762 if (!(state
== 0 || state
== 2))
2763 errmsg
= "Missing REPORT-IOCTL result";
2765 if (!errmsg
&& i
< 0)
2766 errmsg
= "No information found";
2768 m_num_commands
= i
+1;
2769 m_next_replay_command
= 0;
2770 m_replay_out_of_sync
= false;
2774 return set_err(EIO
, "%s(%d): Syntax error: %s", pathname
, lineno
, errmsg
);
2779 // Report warnings and free command table
2780 bool parsed_ata_device::close()
2782 if (m_replay_out_of_sync
)
2783 pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
2784 else if (m_next_replay_command
!= 0)
2785 pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands
-m_next_replay_command
);
2787 for (int i
= 0; i
< m_num_commands
; i
++) {
2788 if (m_command_table
[i
].data
) {
2789 free(m_command_table
[i
].data
); m_command_table
[i
].data
= 0;
2793 m_next_replay_command
= 0;
2794 m_replay_out_of_sync
= false;
2799 bool parsed_ata_device::ata_identify_is_cached() const
2801 return m_ata_identify_is_cached
;
2805 // Simulate ATA command from command table
2806 int parsed_ata_device::ata_command_interface(smart_command_set command
, int select
, char * data
)
2808 // Find command, try round-robin if out of sync
2809 int i
= m_next_replay_command
;
2810 for (int j
= 0; ; j
++) {
2811 if (j
>= m_num_commands
) {
2812 pout("REPLAY-IOCTL: Warning: Command not found\n");
2816 if (m_command_table
[i
].command
== command
&& m_command_table
[i
].select
== select
)
2818 if (!m_replay_out_of_sync
) {
2819 m_replay_out_of_sync
= true;
2820 pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i
+1);
2822 if (++i
>= m_num_commands
)
2825 m_next_replay_command
= i
;
2826 if (++m_next_replay_command
>= m_num_commands
)
2827 m_next_replay_command
= 0;
2829 // Return command data
2834 case READ_THRESHOLDS
:
2836 if (m_command_table
[i
].data
)
2837 memcpy(data
, m_command_table
[i
].data
, 512);
2840 if (!(m_command_table
[i
].data
&& !memcmp(data
, m_command_table
[i
].data
, 512)))
2841 pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
2843 case CHECK_POWER_MODE
:
2844 data
[0] = (char)0xff;
2849 if (m_command_table
[i
].errval
)
2850 errno
= m_command_table
[i
].errval
;
2851 return m_command_table
[i
].retval
;
2856 ata_device
* get_parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2858 return new parsed_ata_device(intf
, dev_name
);