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 3065 2010-02-10 22:16:50Z 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 increase
= !!(defs
[id
].flags
& ATTRFLAG_INCREASING
);
160 #if 0 // TODO: never used
161 // This are the meanings of the Self-test failure checkpoint byte.
162 // This is in the self-test log at offset 4 bytes into the self-test
163 // descriptor and in the SMART READ DATA structure at byte offset
164 // 371. These codes are not well documented. The meanings returned by
165 // this routine are used (at least) by Maxtor and IBM. Returns NULL if
166 // not recognized. Currently the maximum length is 15 bytes.
167 const char *SelfTestFailureCodeName(unsigned char which
){
173 return "Servo_Basic";
175 return "Servo_Random";
177 return "G-list_Scan";
179 return "Handling_Damage";
189 // Table of raw print format names
190 struct format_name_entry
193 ata_attr_raw_format format
;
196 const format_name_entry format_names
[] = {
197 {"raw8" , RAWFMT_RAW8
},
198 {"raw16" , RAWFMT_RAW16
},
199 {"raw48" , RAWFMT_RAW48
},
200 {"hex48" , RAWFMT_HEX48
},
201 {"raw64" , RAWFMT_RAW64
},
202 {"hex64" , RAWFMT_HEX64
},
203 {"raw16(raw16)" , RAWFMT_RAW16_OPT_RAW16
},
204 {"raw16(avg16)" , RAWFMT_RAW16_OPT_AVG16
},
205 {"raw24/raw24" , RAWFMT_RAW24_RAW24
},
206 {"sec2hour" , RAWFMT_SEC2HOUR
},
207 {"min2hour" , RAWFMT_MIN2HOUR
},
208 {"halfmin2hour" , RAWFMT_HALFMIN2HOUR
},
209 {"tempminmax" , RAWFMT_TEMPMINMAX
},
210 {"temp10x" , RAWFMT_TEMP10X
},
213 const unsigned num_format_names
= sizeof(format_names
)/sizeof(format_names
[0]);
215 // Table to map old to new '-v' option arguments
216 const char * map_old_vendor_opts
[][2] = {
217 { "9,halfminutes" , "9,halfmin2hour,Power_On_Half_Minutes"},
218 { "9,minutes" , "9,min2hour,Power_On_Minutes"},
219 { "9,seconds" , "9,sec2hour,Power_On_Seconds"},
220 { "9,temp" , "9,tempminmax,Temperature_Celsius"},
221 {"192,emergencyretractcyclect" , "192,raw48,Emerg_Retract_Cycle_Ct"},
222 {"193,loadunload" , "193,raw24/raw24"},
223 {"194,10xCelsius" , "194,temp10x,Temperature_Celsius_x10"},
224 {"194,unknown" , "194,raw48,Unknown_Attribute"},
225 {"197,increasing" , "197,raw48+,Total_Pending_Sectors"}, // '+' sets flag
226 {"198,offlinescanuncsectorct" , "198,raw48,Offline_Scan_UNC_SectCt"},
227 {"198,increasing" , "198,raw48+,Total_Offl_Uncorrectabl"}, // '+' sets flag
228 {"200,writeerrorcount" , "200,raw48,Write_Error_Count"},
229 {"201,detectedtacount" , "201,raw48,Detected_TA_Count"},
230 {"220,temp" , "220,raw48,Temperature_Celsius"},
233 const unsigned num_old_vendor_opts
= sizeof(map_old_vendor_opts
)/sizeof(map_old_vendor_opts
[0]);
235 // Parse vendor attribute display def (-v option).
236 // Return false on error.
237 bool parse_attribute_def(const char * opt
, ata_vendor_attr_defs
& defs
,
238 ata_vendor_def_prior priority
)
240 // Map old -> new options
242 for (i
= 0; i
< num_old_vendor_opts
; i
++) {
243 if (!strcmp(opt
, map_old_vendor_opts
[i
][0])) {
244 opt
= map_old_vendor_opts
[i
][1];
250 int len
= strlen(opt
);
251 int id
= 0, n1
= -1, n2
= -1;
252 char fmtname
[32+1], attrname
[32+1];
255 if (!( sscanf(opt
, "N,%32[^,]%n,%32[^,]%n", fmtname
, &n1
, attrname
, &n2
) >= 1
256 && (n1
== len
|| n2
== len
)))
260 // "id,format[+][,name]"
261 if (!( sscanf(opt
, "%d,%32[^,]%n,%32[^,]%n", &id
, fmtname
, &n1
, attrname
, &n2
) >= 2
262 && 1 <= id
&& id
<= 255 && (n1
== len
|| n2
== len
)))
269 // For "-v 19[78],increasing" above
270 if (fmtname
[strlen(fmtname
)-1] == '+') {
271 fmtname
[strlen(fmtname
)-1] = 0;
272 flags
= ATTRFLAG_INCREASING
;
275 // Split "format[:byteorder]"
276 char byteorder
[8+1] = "";
277 if (strchr(fmtname
, ':')) {
278 if (!( sscanf(fmtname
, "%*[^:]%n:%8[012345rvwz]%n", &n1
, byteorder
, &n2
) >= 1
279 && n2
== (int)strlen(fmtname
)))
282 if (strchr(byteorder
, 'v'))
283 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
284 if (strchr(byteorder
, 'w'))
285 flags
|= ATTRFLAG_NO_WORSTVAL
;
290 if (i
>= num_format_names
)
291 return false; // Not found
292 if (!strcmp(fmtname
, format_names
[i
].name
))
295 ata_attr_raw_format format
= format_names
[i
].format
;
297 // 64-bit formats use the normalized and worst value bytes.
298 if (!*byteorder
&& (format
== RAWFMT_RAW64
|| format
== RAWFMT_HEX64
))
299 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
302 // "N,format" -> set format for all entries
303 for (i
= 0; i
< MAX_ATTRIBUTE_NUM
; i
++) {
304 if (defs
[i
].priority
>= priority
)
307 defs
[i
].name
= attrname
;
308 defs
[i
].priority
= priority
;
309 defs
[i
].raw_format
= format
;
310 defs
[i
].flags
= flags
;
311 strcpy(defs
[i
].byteorder
, byteorder
);
314 else if (defs
[id
].priority
<= priority
) {
315 // "id,format[,name]"
317 defs
[id
].name
= attrname
;
318 defs
[id
].raw_format
= format
;
319 defs
[id
].priority
= priority
;
320 defs
[id
].flags
= flags
;
321 strcpy(defs
[id
].byteorder
, byteorder
);
328 // Return a multiline string containing a list of valid arguments for
329 // parse_attribute_def(). The strings are preceeded by tabs and followed
330 // (except for the last) by newlines.
331 std::string
create_vendor_attribute_arg_list()
335 for (i
= 0; i
< num_format_names
; i
++)
336 s
+= strprintf("%s\tN,%s[:012345rvwz][,ATTR_NAME]",
337 (i
>0 ? "\n" : ""), format_names
[i
].name
);
338 for (i
= 0; i
< num_old_vendor_opts
; i
++)
339 s
+= strprintf("\n\t%s", map_old_vendor_opts
[i
][0]);
343 // swap two bytes. Point to low address
344 void swap2(char *location
){
346 *location
=*(location
+1);
351 // swap four bytes. Point to low address
352 void swap4(char *location
){
354 *location
=*(location
+3);
360 // swap eight bytes. Points to low address
361 void swap8(char *location
){
363 *location
=*(location
+7);
366 *(location
+1)=*(location
+6);
372 // Invalidate serial number and adjust checksum in IDENTIFY data
373 static void invalidate_serno(ata_identify_device
* id
){
374 unsigned char sum
= 0;
375 for (unsigned i
= 0; i
< sizeof(id
->serial_no
); i
++) {
376 sum
+= id
->serial_no
[i
]; sum
-= id
->serial_no
[i
] = 'X';
379 bool must_swap
= !!isbigendian();
381 swapx(id
->words088_255
+255-88);
383 if ((id
->words088_255
[255-88] & 0x00ff) == 0x00a5)
384 id
->words088_255
[255-88] += sum
<< 8;
387 swapx(id
->words088_255
+255-88);
391 static const char * const commandstrings
[]={
394 "SMART AUTOMATIC ATTRIBUTE SAVE",
395 "SMART IMMEDIATE OFFLINE",
396 "SMART AUTO OFFLINE",
398 "SMART STATUS CHECK",
399 "SMART READ ATTRIBUTE VALUES",
400 "SMART READ ATTRIBUTE THRESHOLDS",
403 "IDENTIFY PACKET DEVICE",
406 "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT
")\n"
410 static const char * preg(const ata_register
& r
, char * buf
)
415 sprintf(buf
, "0x%02x", r
.val()); return buf
;
418 void print_regs(const char * prefix
, const ata_in_regs
& r
, const char * suffix
= "\n")
420 char bufs
[7][4+1+13];
421 pout("%s FR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, CMD=%s%s", prefix
,
422 preg(r
.features
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
423 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
424 preg(r
.command
, bufs
[6]), suffix
);
427 void print_regs(const char * prefix
, const ata_out_regs
& r
, const char * suffix
= "\n")
429 char bufs
[7][4+1+13];
430 pout("%sERR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, STS=%s%s", prefix
,
431 preg(r
.error
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
432 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
433 preg(r
.status
, bufs
[6]), suffix
);
436 static void prettyprint(const unsigned char *p
, const char *name
){
437 pout("\n===== [%s] DATA START (BASE-16) =====\n", name
);
438 for (int i
=0; i
<512; i
+=16, p
+=16)
439 #define P(n) (isprint((int)(p[n]))?(int)(p[n]):'.')
440 // print complete line to avoid slow tty output and extra lines in syslog.
441 pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x "
442 "%02x %02x %02x %02x %02x %02x %02x %02x"
443 " |%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c|"
446 p
[ 0], p
[ 1], p
[ 2], p
[ 3], p
[ 4], p
[ 5], p
[ 6], p
[ 7],
447 p
[ 8], p
[ 9], p
[10], p
[11], p
[12], p
[13], p
[14], p
[15],
448 P( 0), P( 1), P( 2), P( 3), P( 4), P( 5), P( 6), P( 7),
449 P( 8), P( 9), P(10), P(11), P(12), P(13), P(14), P(15),
452 pout("===== [%s] DATA END (512 Bytes) =====\n\n", name
);
455 // This function provides the pretty-print reporting for SMART
456 // commands: it implements the various -r "reporting" options for ATA
458 int smartcommandhandler(ata_device
* device
, smart_command_set command
, int select
, char *data
){
459 // TODO: Rework old stuff below
460 // This conditional is true for commands that return data
461 int getsdata
=(command
==PIDENTIFY
||
464 command
==READ_THRESHOLDS
||
465 command
==READ_VALUES
||
466 command
==CHECK_POWER_MODE
);
468 int sendsdata
=(command
==WRITE_LOG
);
470 // If reporting is enabled, say what the command will be before it's executed
471 if (con
->reportataioctl
){
472 // conditional is true for commands that use parameters
473 int usesparam
=(command
==READ_LOG
||
474 command
==AUTO_OFFLINE
||
476 command
==IMMEDIATE_OFFLINE
||
479 pout("\nREPORT-IOCTL: Device=%s Command=%s", device
->get_dev_name(), commandstrings
[command
]);
481 pout(" InputParameter=%d\n", select
);
486 if ((getsdata
|| sendsdata
) && !data
){
487 pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings
[command
]);
491 // The reporting is cleaner, and we will find coding bugs faster, if
492 // the commands that failed clearly return empty (zeroed) data
495 if (command
==CHECK_POWER_MODE
)
498 memset(data
, '\0', 512);
502 // if requested, pretty-print the input data structure
503 if (con
->reportataioctl
>1 && sendsdata
)
504 //pout("REPORT-IOCTL: Device=%s Command=%s\n", device->get_dev_name(), commandstrings[command]);
505 prettyprint((unsigned char *)data
, commandstrings
[command
]);
507 // now execute the command
511 // Set common register values
513 default: // SMART commands
514 in
.in_regs
.command
= ATA_SMART_CMD
;
515 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
517 case IDENTIFY
: case PIDENTIFY
: case CHECK_POWER_MODE
: // Non SMART commands
520 // Set specific values
523 in
.in_regs
.command
= ATA_IDENTIFY_DEVICE
;
524 in
.set_data_in(data
, 1);
527 in
.in_regs
.command
= ATA_IDENTIFY_PACKET_DEVICE
;
528 in
.set_data_in(data
, 1);
530 case CHECK_POWER_MODE
:
531 in
.in_regs
.command
= ATA_CHECK_POWER_MODE
;
532 in
.out_needed
.sector_count
= true; // Powermode returned here
535 in
.in_regs
.features
= ATA_SMART_READ_VALUES
;
536 in
.set_data_in(data
, 1);
538 case READ_THRESHOLDS
:
539 in
.in_regs
.features
= ATA_SMART_READ_THRESHOLDS
;
540 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
541 in
.set_data_in(data
, 1);
544 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
545 in
.in_regs
.lba_low
= select
;
546 in
.set_data_in(data
, 1);
549 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
550 in
.in_regs
.lba_low
= select
;
551 in
.set_data_out(data
, 1);
554 in
.in_regs
.features
= ATA_SMART_ENABLE
;
555 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
558 in
.in_regs
.features
= ATA_SMART_DISABLE
;
559 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
562 in
.out_needed
.lba_high
= in
.out_needed
.lba_mid
= true; // Status returned here
564 in
.in_regs
.features
= ATA_SMART_STATUS
;
567 in
.in_regs
.features
= ATA_SMART_AUTO_OFFLINE
;
568 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
571 in
.in_regs
.features
= ATA_SMART_AUTOSAVE
;
572 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
574 case IMMEDIATE_OFFLINE
:
575 in
.in_regs
.features
= ATA_SMART_IMMEDIATE_OFFLINE
;
576 in
.in_regs
.lba_low
= select
;
579 pout("Unrecognized command %d in smartcommandhandler()\n"
580 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
581 device
->set_err(ENOSYS
);
586 if (con
->reportataioctl
)
587 print_regs(" Input: ", in
.in_regs
,
588 (in
.direction
==ata_cmd_in::data_in
? " IN\n":
589 in
.direction
==ata_cmd_in::data_out
? " OUT\n":"\n"));
592 bool ok
= device
->ata_pass_through(in
, out
);
594 if (con
->reportataioctl
&& out
.out_regs
.is_set())
595 print_regs(" Output: ", out
.out_regs
);
597 if (ok
) switch (command
) {
601 case CHECK_POWER_MODE
:
602 data
[0] = out
.out_regs
.sector_count
;
606 // Cyl low and Cyl high unchanged means "Good SMART status"
607 if ((out
.out_regs
.lba_high
== SMART_CYL_HI
) &&
608 (out
.out_regs
.lba_mid
== SMART_CYL_LOW
))
610 // These values mean "Bad SMART status"
611 else if ((out
.out_regs
.lba_high
== SRET_STATUS_HI_EXCEEDED
) &&
612 (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
))
614 else if (out
.out_regs
.lba_mid
== SMART_CYL_LOW
) {
616 if (con
->reportataioctl
)
617 pout("SMART STATUS RETURN: half healthy response sequence, "
618 "probable SAT/USB truncation\n");
619 } else if (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
) {
621 if (con
->reportataioctl
)
622 pout("SMART STATUS RETURN: half unhealthy response sequence, "
623 "probable SAT/USB truncation\n");
625 // We haven't gotten output that makes sense; print out some debugging info
626 pout("Error SMART Status command failed\n");
627 pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE
);
628 pout("Register values returned from SMART Status command are:\n");
629 print_regs(" ", out
.out_regs
);
637 // If requested, invalidate serial number before any printing is done
638 if ((command
== IDENTIFY
|| command
== PIDENTIFY
) && !retval
&& con
->dont_print_serial
)
639 invalidate_serno((ata_identify_device
*)data
);
641 // If reporting is enabled, say what output was produced by the command
642 if (con
->reportataioctl
){
643 if (device
->get_errno())
644 pout("REPORT-IOCTL: Device=%s Command=%s returned %d errno=%d [%s]\n",
645 device
->get_dev_name(), commandstrings
[command
], retval
,
646 device
->get_errno(), device
->get_errmsg());
648 pout("REPORT-IOCTL: Device=%s Command=%s returned %d\n",
649 device
->get_dev_name(), commandstrings
[command
], retval
);
651 // if requested, pretty-print the output data structure
652 if (con
->reportataioctl
>1 && getsdata
) {
653 if (command
==CHECK_POWER_MODE
)
654 pout("Sector Count Register (BASE-16): %02x\n", (unsigned char)(*data
));
656 prettyprint((unsigned char *)data
, commandstrings
[command
]);
660 errno
= device
->get_errno(); // TODO: Callers should not call syserror()
664 // Get number of sectors from IDENTIFY sector. If the drive doesn't
665 // support LBA addressing or has no user writable sectors
666 // (eg, CDROM or DVD) then routine returns zero.
667 uint64_t get_num_sectors(const ata_identify_device
* drive
)
669 unsigned short command_set_2
= drive
->command_set_2
;
670 unsigned short capabilities_0
= drive
->words047_079
[49-47];
671 unsigned short sects_16
= drive
->words047_079
[60-47];
672 unsigned short sects_32
= drive
->words047_079
[61-47];
673 unsigned short lba_16
= drive
->words088_255
[100-88];
674 unsigned short lba_32
= drive
->words088_255
[101-88];
675 unsigned short lba_48
= drive
->words088_255
[102-88];
676 unsigned short lba_64
= drive
->words088_255
[103-88];
679 if (!(capabilities_0
& 0x0200))
682 // if drive supports LBA addressing, determine 32-bit LBA capacity
683 uint64_t lba32
= (unsigned int)sects_32
<< 16 |
684 (unsigned int)sects_16
<< 0 ;
687 // if drive supports 48-bit addressing, determine THAT capacity
688 if ((command_set_2
& 0xc000) == 0x4000 && (command_set_2
& 0x0400))
689 lba64
= (uint64_t)lba_64
<< 48 |
690 (uint64_t)lba_48
<< 32 |
691 (uint64_t)lba_32
<< 16 |
692 (uint64_t)lba_16
<< 0 ;
694 // return the larger of the two possible capacities
695 return (lba32
> lba64
? lba32
: lba64
);
698 // This function computes the checksum of a single disk sector (512
699 // bytes). Returns zero if checksum is OK, nonzero if the checksum is
700 // incorrect. The size (512) is correct for all SMART structures.
701 unsigned char checksum(const void * data
)
703 unsigned char sum
= 0;
704 for (int i
= 0; i
< 512; i
++)
705 sum
+= ((const unsigned char *)data
)[i
];
709 // Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
711 static void swapbytes(char * out
, const char * in
, size_t n
)
713 for (size_t i
= 0; i
< n
; i
+= 2) {
719 // Copies in to out, but removes leading and trailing whitespace.
720 static void trim(char * out
, const char * in
)
722 // Find the first non-space character (maybe none).
725 for (i
= 0; in
[i
]; i
++)
726 if (!isspace((int)in
[i
])) {
732 // There are no non-space characters.
737 // Find the last non-space character.
738 for (i
= strlen(in
)-1; i
>= first
&& isspace((int)in
[i
]); i
--)
742 strncpy(out
, in
+first
, last
-first
+1);
743 out
[last
-first
+1] = '\0';
746 // Convenience function for formatting strings from ata_identify_device
747 void format_ata_string(char * out
, const char * in
, int n
, bool fix_swap
)
749 bool must_swap
= !fix_swap
;
751 /* NetBSD kernel delivers IDENTIFY data in host byte order (but all else is LE) */
753 must_swap
= !must_swap
;
761 swapbytes(tmp
, in
, n
);
766 // returns -1 if command fails or the device is in Sleep mode, else
767 // value of Sector Count register. Sector Count result values:
768 // 00h device is in Standby mode.
769 // 80h device is in Idle mode.
770 // FFh device is in Active mode or Idle mode.
772 int ataCheckPowerMode(ata_device
* device
) {
773 unsigned char result
;
775 if ((smartcommandhandler(device
, CHECK_POWER_MODE
, 0, (char *)&result
)))
778 if (result
!=0 && result
!=0x80 && result
!=0xff)
779 pout("ataCheckPowerMode(): ATA CHECK POWER MODE returned unknown Sector Count Register value %02x\n", result
);
787 // Reads current Device Identity info (512 bytes) into buf. Returns 0
788 // if all OK. Returns -1 if no ATA Device identity can be
789 // established. Returns >0 if Device is ATA Packet Device (not SMART
790 // capable). The value of the integer helps identify the type of
791 // Packet device, which is useful so that the user can connect the
792 // formal device number with whatever object is inside their computer.
793 int ataReadHDIdentity (ata_device
* device
, struct ata_identify_device
*buf
){
794 unsigned short *rawshort
=(unsigned short *)buf
;
795 unsigned char *rawbyte
=(unsigned char *)buf
;
797 // See if device responds either to IDENTIFY DEVICE or IDENTIFY
799 if ((smartcommandhandler(device
, IDENTIFY
, 0, (char *)buf
))){
800 if (smartcommandhandler(device
, PIDENTIFY
, 0, (char *)buf
)){
806 // if machine is big-endian, swap byte order as needed
807 // NetBSD kernel delivers IDENTIFY data in host byte order
811 // swap various capability words that are needed
813 swap2((char *)(buf
->words047_079
+i
));
815 for (i
=80; i
<=87; i
++)
816 swap2((char *)(rawshort
+i
));
818 for (i
=0; i
<168; i
++)
819 swap2((char *)(buf
->words088_255
+i
));
823 // If there is a checksum there, validate it
824 if ((rawshort
[255] & 0x00ff) == 0x00a5 && checksum(rawbyte
))
825 checksumwarning("Drive Identity Structure");
827 // If this is a PACKET DEVICE, return device type
828 if (rawbyte
[1] & 0x80)
829 return 1+(rawbyte
[1] & 0x1f);
831 // Not a PACKET DEVICE
835 // Returns ATA version as an integer, and a pointer to a string
836 // describing which revision. Note that Revision 0 of ATA-3 does NOT
837 // support SMART. For this one case we return -3 rather than +3 as
838 // the version number. See notes above.
839 int ataVersionInfo(const char ** description
, const ata_identify_device
* drive
, unsigned short * minor
)
841 // check that arrays at the top of this file are defined
843 if (sizeof(minor_str
) != sizeof(char *)*(1+MINOR_MAX
)){
844 pout("Internal error in ataVersionInfo(). minor_str[] size %d\n"
845 "is not consistent with value of MINOR_MAX+1 = %d\n",
846 (int)(sizeof(minor_str
)/sizeof(char *)), MINOR_MAX
+1);
850 if (sizeof(actual_ver
) != sizeof(int)*(1+MINOR_MAX
)){
851 pout("Internal error in ataVersionInfo(). actual_ver[] size %d\n"
852 "is not consistent with value of MINOR_MAX = %d\n",
853 (int)(sizeof(actual_ver
)/sizeof(int)), MINOR_MAX
+1);
858 // get major and minor ATA revision numbers
859 unsigned short major
= drive
->major_rev_num
;
860 *minor
=drive
->minor_rev_num
;
862 // First check if device has ANY ATA version information in it
863 if (major
==NOVAL_0
|| major
==NOVAL_1
) {
865 return 0; // No info found
868 // The minor revision number has more information - try there first
869 if (*minor
&& (*minor
<=MINOR_MAX
)){
870 int std
= actual_ver
[*minor
];
872 *description
=minor_str
[*minor
];
877 // Try new ATA-8 minor revision numbers (Table 31 of T13/1699-D Revision 6)
878 // (not in actual_ver/minor_str to avoid large sparse tables)
881 case 0x0027: desc
= "ATA-8-ACS revision 3c"; break;
882 case 0x0028: desc
= "ATA-8-ACS revision 6"; break;
883 case 0x0029: desc
= "ATA-8-ACS revision 4"; break;
884 case 0x0033: desc
= "ATA-8-ACS revision 3e"; break;
885 case 0x0039: desc
= "ATA-8-ACS revision 4c"; break;
886 case 0x0042: desc
= "ATA-8-ACS revision 3f"; break;
887 case 0x0052: desc
= "ATA-8-ACS revision 3b"; break;
888 case 0x0107: desc
= "ATA-8-ACS revision 2d"; break;
889 default: desc
= 0; break;
896 // HDPARM has a very complicated algorithm from here on. Since SMART only
897 // exists on ATA-3 and later standards, let's punt on this. If you don't
898 // like it, please fix it. The code's in CVS.
901 if (major
& (0x1<<i
))
911 // returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
912 int ataSmartSupport(const ata_identify_device
* drive
)
914 unsigned short word82
=drive
->command_set_1
;
915 unsigned short word83
=drive
->command_set_2
;
917 // check if words 82/83 contain valid info
918 if ((word83
>>14) == 0x01)
919 // return value of SMART support bit
920 return word82
& 0x0001;
922 // since we can're rely on word 82, we don't know if SMART supported
926 // returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
927 int ataIsSmartEnabled(const ata_identify_device
* drive
)
929 unsigned short word85
=drive
->cfs_enable_1
;
930 unsigned short word87
=drive
->csf_default
;
932 // check if words 85/86/87 contain valid info
933 if ((word87
>>14) == 0x01)
934 // return value of SMART enabled bit
935 return word85
& 0x0001;
937 // Since we can't rely word85, we don't know if SMART is enabled.
942 // Reads SMART attributes into *data
943 int ataReadSmartValues(ata_device
* device
, struct ata_smart_values
*data
){
945 if (smartcommandhandler(device
, READ_VALUES
, 0, (char *)data
)){
946 syserror("Error SMART Values Read failed");
952 checksumwarning("SMART Attribute Data Structure");
954 // swap endian order if needed
957 swap2((char *)&(data
->revnumber
));
958 swap2((char *)&(data
->total_time_to_complete_off_line
));
959 swap2((char *)&(data
->smart_capability
));
960 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
961 struct ata_smart_attribute
*x
=data
->vendor_attributes
+i
;
962 swap2((char *)&(x
->flags
));
970 // This corrects some quantities that are byte reversed in the SMART
972 static void fixsamsungselftestlog(ata_smart_selftestlog
* data
)
974 // bytes 508/509 (numbered from 0) swapped (swap of self-test index
975 // with one byte of reserved.
976 swap2((char *)&(data
->mostrecenttest
));
978 // LBA low register (here called 'selftestnumber", containing
979 // information about the TYPE of the self-test) is byte swapped with
980 // Self-test execution status byte. These are bytes N, N+1 in the
982 for (int i
= 0; i
< 21; i
++)
983 swap2((char *)&(data
->selftest_struct
[i
].selftestnumber
));
988 // Reads the Self Test Log (log #6)
989 int ataReadSelfTestLog (ata_device
* device
, ata_smart_selftestlog
* data
,
990 unsigned char fix_firmwarebug
)
993 // get data from device
994 if (smartcommandhandler(device
, READ_LOG
, 0x06, (char *)data
)){
995 syserror("Error SMART Error Self-Test Log Read failed");
999 // compute its checksum, and issue a warning if needed
1001 checksumwarning("SMART Self-Test Log Structure");
1003 // fix firmware bugs in self-test log
1004 if (fix_firmwarebug
== FIX_SAMSUNG
)
1005 fixsamsungselftestlog(data
);
1007 // swap endian order if needed
1010 swap2((char*)&(data
->revnumber
));
1011 for (i
=0; i
<21; i
++){
1012 struct ata_smart_selftestlog_struct
*x
=data
->selftest_struct
+i
;
1013 swap2((char *)&(x
->timestamp
));
1014 swap4((char *)&(x
->lbafirstfailure
));
1021 // Print checksum warning for multi sector log
1022 static void check_multi_sector_sum(const void * data
, unsigned nsectors
, const char * msg
)
1025 for (unsigned i
= 0; i
< nsectors
; i
++) {
1026 if (checksum((const unsigned char *)data
+ i
*512))
1031 checksumwarning(msg
);
1033 checksumwarning(strprintf("%s (%u/%u)", msg
, errs
, nsectors
).c_str());
1037 // Read SMART Extended Self-test Log
1038 bool ataReadExtSelfTestLog(ata_device
* device
, ata_smart_extselftestlog
* log
,
1041 if (!ataReadLogExt(device
, 0x07, 0x00, 0, log
, nsectors
))
1044 check_multi_sector_sum(log
, nsectors
, "SMART Extended Self-test Log Structure");
1046 if (isbigendian()) {
1047 swapx(&log
->log_desc_index
);
1048 for (unsigned i
= 0; i
< nsectors
; i
++) {
1049 for (unsigned j
= 0; j
< 19; j
++)
1050 swapx(&log
->log_descs
[i
].timestamp
);
1057 // Read GP Log page(s)
1058 bool ataReadLogExt(ata_device
* device
, unsigned char logaddr
,
1059 unsigned char features
, unsigned page
,
1060 void * data
, unsigned nsectors
)
1063 in
.in_regs
.command
= ATA_READ_LOG_EXT
;
1064 in
.in_regs
.features
= features
; // log specific
1065 in
.set_data_in_48bit(data
, nsectors
);
1066 in
.in_regs
.lba_low
= logaddr
;
1067 in
.in_regs
.lba_mid_16
= page
;
1069 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1070 if (nsectors
<= 1) {
1071 pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n",
1072 logaddr
, features
, page
, nsectors
, device
->get_errmsg());
1076 // Recurse to retry with single sectors,
1077 // multi-sector reads may not be supported by ioctl.
1078 for (unsigned i
= 0; i
< nsectors
; i
++) {
1079 if (!ataReadLogExt(device
, logaddr
,
1081 (char *)data
+ 512*i
, 1))
1089 // Read SMART Log page(s)
1090 bool ataReadSmartLog(ata_device
* device
, unsigned char logaddr
,
1091 void * data
, unsigned nsectors
)
1094 in
.in_regs
.command
= ATA_SMART_CMD
;
1095 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
1096 in
.set_data_in(data
, nsectors
);
1097 in
.in_regs
.lba_high
= SMART_CYL_HI
;
1098 in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
1099 in
.in_regs
.lba_low
= logaddr
;
1101 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1102 pout("ATA_SMART_READ_LOG failed: %s\n", device
->get_errmsg());
1110 // Reads the SMART or GPL Log Directory (log #0)
1111 int ataReadLogDirectory(ata_device
* device
, ata_smart_log_directory
* data
, bool gpl
)
1113 if (!gpl
) { // SMART Log directory
1114 if (smartcommandhandler(device
, READ_LOG
, 0x00, (char *)data
))
1117 else { // GP Log directory
1118 if (!ataReadLogExt(device
, 0x00, 0x00, 0, data
, 1))
1122 // swap endian order if needed
1124 swapx(&data
->logversion
);
1130 // Reads the selective self-test log (log #9)
1131 int ataReadSelectiveSelfTestLog(ata_device
* device
, struct ata_selective_self_test_log
*data
){
1133 // get data from device
1134 if (smartcommandhandler(device
, READ_LOG
, 0x09, (char *)data
)){
1135 syserror("Error SMART Read Selective Self-Test Log failed");
1139 // compute its checksum, and issue a warning if needed
1141 checksumwarning("SMART Selective Self-Test Log Structure");
1143 // swap endian order if needed
1146 swap2((char *)&(data
->logversion
));
1148 swap8((char *)&(data
->span
[i
].start
));
1149 swap8((char *)&(data
->span
[i
].end
));
1151 swap8((char *)&(data
->currentlba
));
1152 swap2((char *)&(data
->currentspan
));
1153 swap2((char *)&(data
->flags
));
1154 swap2((char *)&(data
->pendingtime
));
1157 if (data
->logversion
!= 1)
1158 pout("Note: selective self-test log revision number (%d) not 1 implies that no selective self-test has ever been run\n", data
->logversion
);
1163 // Writes the selective self-test log (log #9)
1164 int ataWriteSelectiveSelfTestLog(ata_device
* device
, ata_selective_selftest_args
& args
,
1165 const ata_smart_values
* sv
, uint64_t num_sectors
)
1167 // Disk size must be known
1169 pout("Disk size is unknown, unable to check selective self-test spans\n");
1174 struct ata_selective_self_test_log sstlog
, *data
=&sstlog
;
1175 unsigned char *ptr
=(unsigned char *)data
;
1176 if (ataReadSelectiveSelfTestLog(device
, data
)) {
1177 pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
1182 data
->logversion
= 1;
1184 // Host is NOT allowed to write selective self-test log if a selective
1185 // self-test is in progress.
1186 if (0<data
->currentspan
&& data
->currentspan
<6 && ((sv
->self_test_exec_status
)>>4)==15) {
1187 pout("Error SMART Selective or other Self-Test in progress.\n");
1191 // Set start/end values based on old spans for special -t select,... options
1193 for (i
= 0; i
< args
.num_spans
; i
++) {
1194 int mode
= args
.span
[i
].mode
;
1195 uint64_t start
= args
.span
[i
].start
;
1196 uint64_t end
= args
.span
[i
].end
;
1197 if (mode
== SEL_CONT
) {// redo or next dependig on last test status
1198 switch (sv
->self_test_exec_status
>> 4) {
1199 case 1: case 2: // Aborted/Interrupted by host
1200 pout("Continue Selective Self-Test: Redo last span\n");
1203 default: // All others
1204 pout("Continue Selective Self-Test: Start next span\n");
1210 case SEL_RANGE
: // -t select,START-END
1212 case SEL_REDO
: // -t select,redo... => Redo current
1213 start
= data
->span
[i
].start
;
1214 if (end
> 0) { // -t select,redo+SIZE
1215 end
--; end
+= start
; // [oldstart, oldstart+SIZE)
1217 else // -t select,redo
1218 end
= data
->span
[i
].end
; // [oldstart, oldend]
1220 case SEL_NEXT
: // -t select,next... => Do next
1221 if (data
->span
[i
].end
== 0) {
1222 start
= end
= 0; break; // skip empty spans
1224 start
= data
->span
[i
].end
+ 1;
1225 if (start
>= num_sectors
)
1226 start
= 0; // wrap around
1227 if (end
> 0) { // -t select,next+SIZE
1228 end
--; end
+= start
; // (oldend, oldend+SIZE]
1230 else { // -t select,next
1231 uint64_t oldsize
= data
->span
[i
].end
- data
->span
[i
].start
+ 1;
1232 end
= start
+ oldsize
- 1; // (oldend, oldend+oldsize]
1233 if (end
>= num_sectors
) {
1234 // Adjust size to allow round-robin testing without future size decrease
1235 uint64_t spans
= (num_sectors
+ oldsize
-1) / oldsize
;
1236 uint64_t newsize
= (num_sectors
+ spans
-1) / spans
;
1237 uint64_t newstart
= num_sectors
- newsize
, newend
= num_sectors
- 1;
1238 pout("Span %d changed from %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors)\n",
1239 i
, start
, end
, oldsize
);
1240 pout(" to %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors) (%"PRIu64
" spans)\n",
1241 newstart
, newend
, newsize
, spans
);
1242 start
= newstart
; end
= newend
;
1247 pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode
);
1251 if (start
< num_sectors
&& num_sectors
<= end
) {
1252 if (end
!= ~(uint64_t)0) // -t select,N-max
1253 pout("Size of self-test span %d decreased according to disk size\n", i
);
1254 end
= num_sectors
- 1;
1256 if (!(start
<= end
&& end
< num_sectors
)) {
1257 pout("Invalid selective self-test span %d: %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors)\n",
1258 i
, start
, end
, num_sectors
);
1261 // Return the actual mode and range to caller.
1262 args
.span
[i
].mode
= mode
;
1263 args
.span
[i
].start
= start
;
1264 args
.span
[i
].end
= end
;
1269 memset(data
->span
+i
, 0, sizeof(struct test_span
));
1271 // Set spans for testing
1272 for (i
= 0; i
< args
.num_spans
; i
++){
1273 data
->span
[i
].start
= args
.span
[i
].start
;
1274 data
->span
[i
].end
= args
.span
[i
].end
;
1277 // host must initialize to zero before initiating selective self-test
1279 data
->currentspan
=0;
1281 // Perform off-line scan after selective test?
1282 if (args
.scan_after_select
== 1)
1284 data
->flags
&= ~SELECTIVE_FLAG_DOSCAN
;
1285 else if (args
.scan_after_select
== 2)
1287 data
->flags
|= SELECTIVE_FLAG_DOSCAN
;
1289 // Must clear active and pending flags before writing
1290 data
->flags
&= ~(SELECTIVE_FLAG_ACTIVE
);
1291 data
->flags
&= ~(SELECTIVE_FLAG_PENDING
);
1293 // modify pending time?
1294 if (args
.pending_time
)
1295 data
->pendingtime
= (unsigned short)(args
.pending_time
-1);
1297 // Set checksum to zero, then compute checksum
1299 unsigned char cksum
=0;
1300 for (i
=0; i
<512; i
++)
1304 data
->checksum
=cksum
;
1306 // swap endian order if needed
1308 swap2((char *)&(data
->logversion
));
1309 for (int i
=0;i
<5;i
++){
1310 swap8((char *)&(data
->span
[i
].start
));
1311 swap8((char *)&(data
->span
[i
].end
));
1313 swap8((char *)&(data
->currentlba
));
1314 swap2((char *)&(data
->currentspan
));
1315 swap2((char *)&(data
->flags
));
1316 swap2((char *)&(data
->pendingtime
));
1319 // write new selective self-test log
1320 if (smartcommandhandler(device
, WRITE_LOG
, 0x09, (char *)data
)){
1321 syserror("Error Write Selective Self-Test Log failed");
1328 // This corrects some quantities that are byte reversed in the SMART
1330 static void fixsamsungerrorlog(ata_smart_errorlog
* data
)
1332 // FIXED IN SAMSUNG -25 FIRMWARE???
1333 // Device error count in bytes 452-3
1334 swap2((char *)&(data
->ata_error_count
));
1336 // FIXED IN SAMSUNG -22a FIRMWARE
1337 // step through 5 error log data structures
1338 for (int i
= 0; i
< 5; i
++){
1339 // step through 5 command data structures
1340 for (int j
= 0; j
< 5; j
++)
1341 // Command data structure 4-byte millisec timestamp. These are
1342 // bytes (N+8, N+9, N+10, N+11).
1343 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1344 // Error data structure two-byte hour life timestamp. These are
1345 // bytes (N+28, N+29).
1346 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1351 // NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
1352 static void fixsamsungerrorlog2(ata_smart_errorlog
* data
)
1354 // Device error count in bytes 452-3
1355 swap2((char *)&(data
->ata_error_count
));
1359 // Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1360 // Error Log is #2, and the Extended Comprehensive SMART Error log is
1362 int ataReadErrorLog (ata_device
* device
, ata_smart_errorlog
*data
,
1363 unsigned char fix_firmwarebug
)
1366 // get data from device
1367 if (smartcommandhandler(device
, READ_LOG
, 0x01, (char *)data
)){
1368 syserror("Error SMART Error Log Read failed");
1372 // compute its checksum, and issue a warning if needed
1374 checksumwarning("SMART ATA Error Log Structure");
1376 // Some disks have the byte order reversed in some SMART Summary
1377 // Error log entries
1378 if (fix_firmwarebug
== FIX_SAMSUNG
)
1379 fixsamsungerrorlog(data
);
1380 else if (fix_firmwarebug
== FIX_SAMSUNG2
)
1381 fixsamsungerrorlog2(data
);
1383 // swap endian order if needed
1387 // Device error count in bytes 452-3
1388 swap2((char *)&(data
->ata_error_count
));
1390 // step through 5 error log data structures
1391 for (i
=0; i
<5; i
++){
1392 // step through 5 command data structures
1394 // Command data structure 4-byte millisec timestamp
1395 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1396 // Error data structure life timestamp
1397 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1404 // Read Extended Comprehensive Error Log
1405 bool ataReadExtErrorLog(ata_device
* device
, ata_smart_exterrlog
* log
,
1408 if (!ataReadLogExt(device
, 0x03, 0x00, 0, log
, nsectors
))
1411 check_multi_sector_sum(log
, nsectors
, "SMART Extended Comprehensive Error Log Structure");
1413 if (isbigendian()) {
1414 swapx(&log
->device_error_count
);
1415 swapx(&log
->error_log_index
);
1417 for (unsigned i
= 0; i
< nsectors
; i
++) {
1418 for (unsigned j
= 0; j
< 4; j
++)
1419 swapx(&log
->error_logs
[i
].commands
[j
].timestamp
);
1420 swapx(&log
->error_logs
[i
].error
.timestamp
);
1428 int ataReadSmartThresholds (ata_device
* device
, struct ata_smart_thresholds_pvt
*data
){
1430 // get data from device
1431 if (smartcommandhandler(device
, READ_THRESHOLDS
, 0, (char *)data
)){
1432 syserror("Error SMART Thresholds Read failed");
1436 // compute its checksum, and issue a warning if needed
1438 checksumwarning("SMART Attribute Thresholds Structure");
1440 // swap endian order if needed
1442 swap2((char *)&(data
->revnumber
));
1447 int ataEnableSmart (ata_device
* device
){
1448 if (smartcommandhandler(device
, ENABLE
, 0, NULL
)){
1449 syserror("Error SMART Enable failed");
1455 int ataDisableSmart (ata_device
* device
){
1457 if (smartcommandhandler(device
, DISABLE
, 0, NULL
)){
1458 syserror("Error SMART Disable failed");
1464 int ataEnableAutoSave(ata_device
* device
){
1465 if (smartcommandhandler(device
, AUTOSAVE
, 241, NULL
)){
1466 syserror("Error SMART Enable Auto-save failed");
1472 int ataDisableAutoSave(ata_device
* device
){
1474 if (smartcommandhandler(device
, AUTOSAVE
, 0, NULL
)){
1475 syserror("Error SMART Disable Auto-save failed");
1481 // In *ALL* ATA standards the Enable/Disable AutoOffline command is
1482 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1483 // vendors still support it for backwards compatibility. IBM documents
1484 // it for some drives.
1485 int ataEnableAutoOffline (ata_device
* device
){
1487 /* timer hard coded to 4 hours */
1488 if (smartcommandhandler(device
, AUTO_OFFLINE
, 248, NULL
)){
1489 syserror("Error SMART Enable Automatic Offline failed");
1495 // Another Obsolete Command. See comments directly above, associated
1496 // with the corresponding Enable command.
1497 int ataDisableAutoOffline (ata_device
* device
){
1499 if (smartcommandhandler(device
, AUTO_OFFLINE
, 0, NULL
)){
1500 syserror("Error SMART Disable Automatic Offline failed");
1506 // If SMART is enabled, supported, and working, then this call is
1507 // guaranteed to return 1, else zero. Note that it should return 1
1508 // regardless of whether the disk's SMART status is 'healthy' or
1510 int ataDoesSmartWork(ata_device
* device
){
1511 int retval
=smartcommandhandler(device
, STATUS
, 0, NULL
);
1519 // This function uses a different interface (DRIVE_TASK) than the
1520 // other commands in this file.
1521 int ataSmartStatus2(ata_device
* device
){
1522 return smartcommandhandler(device
, STATUS_CHECK
, 0, NULL
);
1525 // This is the way to execute ALL tests: offline, short self-test,
1526 // extended self test, with and without captive mode, etc.
1527 // TODO: Move to ataprint.cpp ?
1528 int ataSmartTest(ata_device
* device
, int testtype
, const ata_selective_selftest_args
& selargs
,
1529 const ata_smart_values
* sv
, uint64_t num_sectors
)
1531 char cmdmsg
[128]; const char *type
, *captive
;
1532 int errornum
, cap
, retval
, select
=0;
1534 // Boolean, if set, says test is captive
1535 cap
=testtype
& CAPTIVE_MASK
;
1537 // Set up strings that describe the type of test
1543 if (testtype
==OFFLINE_FULL_SCAN
)
1545 else if (testtype
==SHORT_SELF_TEST
|| testtype
==SHORT_CAPTIVE_SELF_TEST
)
1546 type
="Short self-test";
1547 else if (testtype
==EXTEND_SELF_TEST
|| testtype
==EXTEND_CAPTIVE_SELF_TEST
)
1548 type
="Extended self-test";
1549 else if (testtype
==CONVEYANCE_SELF_TEST
|| testtype
==CONVEYANCE_CAPTIVE_SELF_TEST
)
1550 type
="Conveyance self-test";
1551 else if ((select
=(testtype
==SELECTIVE_SELF_TEST
|| testtype
==SELECTIVE_CAPTIVE_SELF_TEST
)))
1552 type
="Selective self-test";
1554 type
="[Unrecognized] self-test";
1556 // If doing a selective self-test, first use WRITE_LOG to write the
1557 // selective self-test log.
1558 ata_selective_selftest_args selargs_io
= selargs
; // filled with info about actual spans
1559 if (select
&& (retval
= ataWriteSelectiveSelfTestLog(device
, selargs_io
, sv
, num_sectors
))) {
1561 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1565 // Print ouf message that we are sending the command to test
1566 if (testtype
==ABORT_SELF_TEST
)
1567 sprintf(cmdmsg
,"Abort SMART off-line mode self-test routine");
1569 sprintf(cmdmsg
,"Execute SMART %s routine immediately in %s mode",type
,captive
);
1570 pout("Sending command: \"%s\".\n",cmdmsg
);
1574 pout("SPAN STARTING_LBA ENDING_LBA\n");
1575 for (i
= 0; i
< selargs_io
.num_spans
; i
++)
1576 pout(" %d %20"PRId64
" %20"PRId64
"\n", i
,
1577 selargs_io
.span
[i
].start
,
1578 selargs_io
.span
[i
].end
);
1581 // Now send the command to test
1582 errornum
=smartcommandhandler(device
, IMMEDIATE_OFFLINE
, testtype
, NULL
);
1584 if (errornum
&& !(cap
&& errno
==EIO
)){
1586 sprintf(errormsg
,"Command \"%s\" failed",cmdmsg
);
1592 // Since the command succeeded, tell user
1593 if (testtype
==ABORT_SELF_TEST
)
1594 pout("Self-testing aborted!\n");
1596 pout("Drive command \"%s\" successful.\nTesting has begun.\n",cmdmsg
);
1600 /* Test Time Functions */
1601 int TestTime(const ata_smart_values
*data
, int testtype
)
1604 case OFFLINE_FULL_SCAN
:
1605 return (int) data
->total_time_to_complete_off_line
;
1606 case SHORT_SELF_TEST
:
1607 case SHORT_CAPTIVE_SELF_TEST
:
1608 return (int) data
->short_test_completion_time
;
1609 case EXTEND_SELF_TEST
:
1610 case EXTEND_CAPTIVE_SELF_TEST
:
1611 return (int) data
->extend_test_completion_time
;
1612 case CONVEYANCE_SELF_TEST
:
1613 case CONVEYANCE_CAPTIVE_SELF_TEST
:
1614 return (int) data
->conveyance_test_completion_time
;
1620 // This function tells you both about the ATA error log and the
1621 // self-test error log capability (introduced in ATA-5). The bit is
1622 // poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1623 // SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1624 // word 84 and 87. Top two bits must match the pattern 01. BEFORE
1625 // ATA-6 these top two bits still had to match the pattern 01, but the
1626 // remaining bits were reserved (==0).
1627 int isSmartErrorLogCapable (const ata_smart_values
* data
, const ata_identify_device
* identity
)
1629 unsigned short word84
=identity
->command_set_extension
;
1630 unsigned short word87
=identity
->csf_default
;
1631 int isata6
=identity
->major_rev_num
& (0x01<<6);
1632 int isata7
=identity
->major_rev_num
& (0x01<<7);
1634 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x01))
1637 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x01))
1640 // otherwise we'll use the poorly documented capability bit
1641 return data
->errorlog_capability
& 0x01;
1644 // See previous function. If the error log exists then the self-test
1645 // log should (must?) also exist.
1646 int isSmartTestLogCapable (const ata_smart_values
* data
, const ata_identify_device
*identity
)
1648 unsigned short word84
=identity
->command_set_extension
;
1649 unsigned short word87
=identity
->csf_default
;
1650 int isata6
=identity
->major_rev_num
& (0x01<<6);
1651 int isata7
=identity
->major_rev_num
& (0x01<<7);
1653 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x02))
1656 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x02))
1660 // otherwise we'll use the poorly documented capability bit
1661 return data
->errorlog_capability
& 0x01;
1665 int isGeneralPurposeLoggingCapable(const ata_identify_device
*identity
)
1667 unsigned short word84
=identity
->command_set_extension
;
1668 unsigned short word87
=identity
->csf_default
;
1670 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1671 // cleared to zero, the contents of word 84 contains valid support
1672 // information. If not, support information is not valid in this
1674 if ((word84
>>14) == 0x01)
1675 // If bit 5 of word 84 is set to one, the device supports the
1676 // General Purpose Logging feature set.
1677 return (word84
& (0x01 << 5));
1679 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1680 // cleared to zero, the contents of words (87:85) contain valid
1681 // information. If not, information is not valid in these words.
1682 if ((word87
>>14) == 0x01)
1683 // If bit 5 of word 87 is set to one, the device supports
1684 // the General Purpose Logging feature set.
1685 return (word87
& (0x01 << 5));
1692 // SMART self-test capability is also indicated in bit 1 of DEVICE
1693 // IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1694 // However this was only introduced in ATA-6 (but self-test log was in
1696 int isSupportExecuteOfflineImmediate(const ata_smart_values
*data
)
1698 return data
->offline_data_collection_capability
& 0x01;
1701 // Note in the ATA-5 standard, the following bit is listed as "Vendor
1702 // Specific". So it may not be reliable. The only use of this that I
1703 // have found is in IBM drives, where it is well-documented. See for
1704 // example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1705 // hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
1706 int isSupportAutomaticTimer(const ata_smart_values
* data
)
1708 return data
->offline_data_collection_capability
& 0x02;
1710 int isSupportOfflineAbort(const ata_smart_values
*data
)
1712 return data
->offline_data_collection_capability
& 0x04;
1714 int isSupportOfflineSurfaceScan(const ata_smart_values
* data
)
1716 return data
->offline_data_collection_capability
& 0x08;
1718 int isSupportSelfTest (const ata_smart_values
* data
)
1720 return data
->offline_data_collection_capability
& 0x10;
1722 int isSupportConveyanceSelfTest(const ata_smart_values
* data
)
1724 return data
->offline_data_collection_capability
& 0x20;
1726 int isSupportSelectiveSelfTest(const ata_smart_values
* data
)
1728 return data
->offline_data_collection_capability
& 0x40;
1731 // Get attribute state
1732 ata_attr_state
ata_get_attr_state(const ata_smart_attribute
& attr
,
1733 const ata_smart_threshold_entry
& thre
,
1734 const ata_vendor_attr_defs
& defs
)
1737 return ATTRSTATE_NON_EXISTING
;
1739 // Normalized values (current,worst,threshold) not valid
1740 // if specified by '-v' option.
1741 // (Some SSD disks uses these bytes to store raw value).
1742 if (defs
[attr
.id
].flags
& ATTRFLAG_NO_NORMVAL
)
1743 return ATTRSTATE_NO_NORMVAL
;
1745 // No threshold if thresholds cannot be read.
1746 if (!thre
.id
&& !thre
.threshold
)
1747 return ATTRSTATE_NO_THRESHOLD
;
1749 // Bad threshold if id's don't match
1750 if (attr
.id
!= thre
.id
)
1751 return ATTRSTATE_BAD_THRESHOLD
;
1753 // Don't report a failed attribute if its threshold is 0.
1754 // ATA-3 (X3T13/2008D Revision 7b) declares 0x00 as the "always passing"
1755 // threshold (Later ATA versions declare all thresholds as "obsolete").
1756 // In practice, threshold value 0 is often used for usage attributes.
1757 if (!thre
.threshold
)
1758 return ATTRSTATE_OK
;
1760 // Failed now if current value is below threshold
1761 if (attr
.current
<= thre
.threshold
)
1762 return ATTRSTATE_FAILED_NOW
;
1764 // Failed in the past if worst value is below threshold
1765 if (!(defs
[attr
.id
].flags
& ATTRFLAG_NO_WORSTVAL
) && attr
.worst
<= thre
.threshold
)
1766 return ATTRSTATE_FAILED_PAST
;
1768 return ATTRSTATE_OK
;
1771 // Get default raw value print format
1772 static ata_attr_raw_format
get_default_raw_format(unsigned char id
)
1775 case 3: // Spin-up time
1776 return RAWFMT_RAW16_OPT_AVG16
;
1778 case 5: // Reallocated sector count
1779 case 196: // Reallocated event count
1780 return RAWFMT_RAW16_OPT_RAW16
;
1782 case 190: // Temperature
1784 return RAWFMT_TEMPMINMAX
;
1787 return RAWFMT_RAW48
;
1791 // Get attribute raw value.
1792 uint64_t ata_get_attr_raw_value(const ata_smart_attribute
& attr
,
1793 const ata_vendor_attr_defs
& defs
)
1795 const ata_vendor_attr_defs::entry
& def
= defs
[attr
.id
];
1797 // Use default byteorder if not specified
1798 const char * byteorder
= def
.byteorder
;
1800 if (def
.raw_format
== RAWFMT_RAW64
|| def
.raw_format
== RAWFMT_HEX64
)
1801 byteorder
= "543210wv";
1803 byteorder
= "543210";
1806 // Build 64-bit value from selected bytes
1807 uint64_t rawvalue
= 0;
1808 for (int i
= 0; byteorder
[i
]; i
++) {
1810 switch (byteorder
[i
]) {
1811 case '0': b
= attr
.raw
[0]; break;
1812 case '1': b
= attr
.raw
[1]; break;
1813 case '2': b
= attr
.raw
[2]; break;
1814 case '3': b
= attr
.raw
[3]; break;
1815 case '4': b
= attr
.raw
[4]; break;
1816 case '5': b
= attr
.raw
[5]; break;
1817 case 'r': b
= attr
.reserv
; break;
1818 case 'v': b
= attr
.current
; break;
1819 case 'w': b
= attr
.worst
; break;
1820 default : b
= 0; break;
1822 rawvalue
<<= 8; rawvalue
|= b
;
1829 // Format attribute raw value.
1830 std::string
ata_format_attr_raw_value(const ata_smart_attribute
& attr
,
1831 const ata_vendor_attr_defs
& defs
)
1833 // Get 48 bit or 64 bit raw value
1834 uint64_t rawvalue
= ata_get_attr_raw_value(attr
, defs
);
1837 const unsigned char * raw
= attr
.raw
;
1839 word
[0] = raw
[0] | (raw
[1] << 8);
1840 word
[1] = raw
[2] | (raw
[3] << 8);
1841 word
[2] = raw
[4] | (raw
[5] << 8);
1844 ata_attr_raw_format format
= defs
[attr
.id
].raw_format
;
1845 if (format
== RAWFMT_DEFAULT
)
1846 format
= get_default_raw_format(attr
.id
);
1852 s
= strprintf("%d %d %d %d %d %d",
1853 raw
[5], raw
[4], raw
[3], raw
[2], raw
[1], raw
[0]);
1857 s
= strprintf("%u %u %u", word
[2], word
[1], word
[0]);
1862 s
= strprintf("%"PRIu64
, rawvalue
);
1866 s
= strprintf("0x%012"PRIx64
, rawvalue
);
1870 s
= strprintf("0x%016"PRIx64
, rawvalue
);
1873 case RAWFMT_RAW16_OPT_RAW16
:
1874 s
= strprintf("%u", word
[0]);
1875 if (word
[1] || word
[2])
1876 s
+= strprintf(" (%u, %u)", word
[2], word
[1]);
1879 case RAWFMT_RAW16_OPT_AVG16
:
1880 s
= strprintf("%u", word
[0]);
1882 s
+= strprintf(" (Average %u)", word
[1]);
1885 case RAWFMT_RAW24_RAW24
:
1886 s
= strprintf("%d/%d",
1887 raw
[0] | (raw
[1]<<8) | (raw
[2]<<16),
1888 raw
[3] | (raw
[4]<<8) | (raw
[5]<<16));
1891 case RAWFMT_MIN2HOUR
:
1894 int64_t temp
= word
[0]+(word
[1]<<16);
1895 int64_t tmp1
= temp
/60;
1896 int64_t tmp2
= temp
%60;
1897 s
= strprintf("%"PRIu64
"h+%02"PRIu64
"m", tmp1
, tmp2
);
1899 s
+= strprintf(" (%u)", word
[2]);
1903 case RAWFMT_SEC2HOUR
:
1906 int64_t hours
= rawvalue
/3600;
1907 int64_t minutes
= (rawvalue
-3600*hours
)/60;
1908 int64_t seconds
= rawvalue
%60;
1909 s
= strprintf("%"PRIu64
"h+%02"PRIu64
"m+%02"PRIu64
"s", hours
, minutes
, seconds
);
1913 case RAWFMT_HALFMIN2HOUR
:
1915 // 30-second counter
1916 int64_t hours
= rawvalue
/120;
1917 int64_t minutes
= (rawvalue
-120*hours
)/2;
1918 s
+= strprintf("%"PRIu64
"h+%02"PRIu64
"m", hours
, minutes
);
1922 case RAWFMT_TEMPMINMAX
:
1924 s
= strprintf("%u", word
[0]);
1925 if (word
[1] || word
[2]) {
1926 unsigned lo
= ~0, hi
= ~0;
1928 // 00 HH 00 LL 00 TT (IBM)
1929 hi
= word
[2]; lo
= word
[1];
1931 else if (!word
[2]) {
1932 // 00 00 HH LL 00 TT (Maxtor)
1933 hi
= raw
[3]; lo
= raw
[2];
1936 unsigned t
= lo
; lo
= hi
; hi
= t
;
1938 if (lo
<= word
[0] && word
[0] <= hi
)
1939 s
+= strprintf(" (Lifetime Min/Max %u/%u)", lo
, hi
);
1941 s
+= strprintf(" (%d %d %d %d)", raw
[5], raw
[4], raw
[3], raw
[2]);
1945 case RAWFMT_TEMP10X
:
1946 // ten times temperature in Celsius
1947 s
= strprintf("%d.%d", word
[0]/10, word
[0]%10);
1951 s
= "?"; // Should not happen
1958 // Attribute names shouldn't be longer than 23 chars, otherwise they break the
1959 // output of smartctl.
1960 static const char * get_default_attr_name(unsigned char id
)
1964 return "Raw_Read_Error_Rate";
1966 return "Throughput_Performance";
1968 return "Spin_Up_Time";
1970 return "Start_Stop_Count";
1972 return "Reallocated_Sector_Ct";
1974 return "Read_Channel_Margin";
1976 return "Seek_Error_Rate";
1978 return "Seek_Time_Performance";
1980 return "Power_On_Hours";
1982 return "Spin_Retry_Count";
1984 return "Calibration_Retry_Count";
1986 return "Power_Cycle_Count";
1988 return "Read_Soft_Error_Rate";
1990 return "Program_Fail_Count_Chip";
1992 return "Erase_Fail_Count_Chip";
1994 return "Wear_Leveling_Count";
1996 return "Used_Rsvd_Blk_Cnt_Chip";
1998 return "Used_Rsvd_Blk_Cnt_Tot";
2000 return "Unused_Rsvd_Blk_Cnt_Tot";
2002 return "Program_Fail_Cnt_Total";
2004 return "Erase_Fail_Count_Total";
2006 return "Runtime_Bad_Block";
2008 return "End-to-End_Error";
2010 return "Reported_Uncorrect";
2012 return "Command_Timeout";
2014 return "High_Fly_Writes";
2016 // Western Digital uses this for temperature.
2017 // It's identical to Attribute 194 except that it
2018 // has a failure threshold set to correspond to the
2019 // max allowed operating temperature of the drive, which
2020 // is typically 55C. So if this attribute has failed
2021 // in the past, it indicates that the drive temp exceeded
2022 // 55C sometime in the past.
2023 return "Airflow_Temperature_Cel";
2025 return "G-Sense_Error_Rate";
2027 return "Power-Off_Retract_Count";
2029 return "Load_Cycle_Count";
2031 return "Temperature_Celsius";
2033 // Fujitsu: "ECC_On_The_Fly_Count";
2034 return "Hardware_ECC_Recovered";
2036 return "Reallocated_Event_Count";
2038 return "Current_Pending_Sector";
2040 return "Offline_Uncorrectable";
2042 return "UDMA_CRC_Error_Count";
2045 return "Multi_Zone_Error_Rate";
2047 return "Soft_Read_Error_Rate";
2049 // Fujitsu: "TA_Increase_Count"
2050 return "Data_Address_Mark_Errs";
2053 return "Run_Out_Cancel";
2054 // Maxtor: ECC Errors
2056 // Fujitsu: "Shock_Count_Write_Opern"
2057 return "Soft_ECC_Correction";
2059 // Fujitsu: "Shock_Rate_Write_Opern"
2060 return "Thermal_Asperity_Rate";
2063 return "Flying_Height";
2066 return "Spin_High_Current";
2072 return "Offline_Seek_Performnce";
2074 return "Disk_Shift";
2076 return "G-Sense_Error_Rate";
2078 return "Loaded_Hours";
2080 return "Load_Retry_Count";
2082 return "Load_Friction";
2084 return "Load_Cycle_Count";
2086 return "Load-in_Time";
2088 return "Torq-amp_Count";
2090 return "Power-off_Retract_Count";
2092 // seen in IBM DTPA-353750
2093 return "Head_Amplitude";
2095 return "Temperature_Celsius";
2097 // seen in Intel X25-E SSD
2098 return "Available_Reservd_Space";
2100 // seen in Intel X25-E SSD
2101 return "Media_Wearout_Indicator";
2103 return "Head_Flying_Hours";
2105 return "Total_LBAs_Written";
2107 return "Total_LBAs_Read";
2109 return "Read_Error_Retry_Rate";
2111 return "Free_Fall_Sensor";
2113 return "Unknown_Attribute";
2117 // Get attribute name
2118 std::string
ata_get_smart_attr_name(unsigned char id
, const ata_vendor_attr_defs
& defs
)
2120 if (!defs
[id
].name
.empty())
2121 return defs
[id
].name
;
2123 return get_default_attr_name(id
);
2126 // Find attribute index for attribute id, -1 if not found.
2127 int ata_find_attr_index(unsigned char id
, const ata_smart_values
& smartval
)
2131 for (int i
= 0; i
< NUMBER_ATA_SMART_ATTRIBUTES
; i
++) {
2132 if (smartval
.vendor_attributes
[i
].id
== id
)
2138 // Return Temperature Attribute raw value selected according to possible
2139 // non-default interpretations. If the Attribute does not exist, return 0
2140 unsigned char ata_return_temperature_value(const ata_smart_values
* data
, const ata_vendor_attr_defs
& defs
)
2142 for (int i
= 0; i
< 3; i
++) {
2143 static const unsigned char ids
[3] = {194, 9, 220};
2144 unsigned char id
= ids
[i
];
2145 const ata_attr_raw_format format
= defs
[id
].raw_format
;
2146 if (!( (id
== 194 && format
== RAWFMT_DEFAULT
)
2147 || format
== RAWFMT_TEMPMINMAX
|| format
== RAWFMT_TEMP10X
))
2149 int idx
= ata_find_attr_index(id
, *data
);
2152 uint64_t raw
= ata_get_attr_raw_value(data
->vendor_attributes
[idx
], defs
);
2153 unsigned temp
= (unsigned short)raw
; // ignore possible min/max values in high words
2154 if (format
== RAWFMT_TEMP10X
) // -v N,temp10x
2155 temp
= (temp
+5) / 10;
2156 if (!(0 < temp
&& temp
<= 255))
2160 // No valid attribute found
2166 int ataReadSCTStatus(ata_device
* device
, ata_sct_status_response
* sts
)
2168 // read SCT status via SMART log 0xe0
2169 memset(sts
, 0, sizeof(*sts
));
2170 if (smartcommandhandler(device
, READ_LOG
, 0xe0, (char *)sts
)){
2171 syserror("Error Read SCT Status failed");
2175 // swap endian order if needed
2177 swapx(&sts
->format_version
);
2178 swapx(&sts
->sct_version
);
2179 swapx(&sts
->sct_spec
);
2180 swapx(&sts
->ext_status_code
);
2181 swapx(&sts
->action_code
);
2182 swapx(&sts
->function_code
);
2183 swapx(&sts
->over_limit_count
);
2184 swapx(&sts
->under_limit_count
);
2187 // Check format version
2188 if (!(sts
->format_version
== 2 || sts
->format_version
== 3)) {
2189 pout("Error unknown SCT Status format version %u, should be 2 or 3.\n", sts
->format_version
);
2195 // Read SCT Temperature History Table and Status
2196 int ataReadSCTTempHist(ata_device
* device
, ata_sct_temperature_history_table
* tmh
,
2197 ata_sct_status_response
* sts
)
2199 // Check initial status
2200 if (ataReadSCTStatus(device
, sts
))
2203 // Do nothing if other SCT command is executing
2204 if (sts
->ext_status_code
== 0xffff) {
2205 pout("Another SCT command is executing, abort Read Data Table\n"
2206 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2207 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2211 ata_sct_data_table_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2212 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2213 cmd
.action_code
= 5; // Data table command
2214 cmd
.function_code
= 1; // Read table
2215 cmd
.table_id
= 2; // Temperature History Table
2217 // swap endian order if needed
2218 if (isbigendian()) {
2219 swapx(&cmd
.action_code
);
2220 swapx(&cmd
.function_code
);
2221 swapx(&cmd
.table_id
);
2224 // write command via SMART log page 0xe0
2225 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2226 syserror("Error Write SCT Data Table command failed");
2230 // read SCT data via SMART log page 0xe1
2231 memset(tmh
, 0, sizeof(*tmh
));
2232 if (smartcommandhandler(device
, READ_LOG
, 0xe1, (char *)tmh
)){
2233 syserror("Error Read SCT Data Table failed");
2237 // re-read and check SCT status
2238 if (ataReadSCTStatus(device
, sts
))
2241 if (!(sts
->ext_status_code
== 0 && sts
->action_code
== 5 && sts
->function_code
== 1)) {
2242 pout("Error unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2243 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2247 // swap endian order if needed
2249 swapx(&tmh
->format_version
);
2250 swapx(&tmh
->sampling_period
);
2251 swapx(&tmh
->interval
);
2254 // Check format version
2255 if (tmh
->format_version
!= 2) {
2256 pout("Error unknown SCT Temperature History Format Version (%u), should be 2.\n", tmh
->format_version
);
2262 // Set SCT Temperature Logging Interval
2263 int ataSetSCTTempInterval(ata_device
* device
, unsigned interval
, bool persistent
)
2265 // Check initial status
2266 ata_sct_status_response sts
;
2267 if (ataReadSCTStatus(device
, &sts
))
2270 // Do nothing if other SCT command is executing
2271 if (sts
.ext_status_code
== 0xffff) {
2272 pout("Another SCT command is executing, abort Feature Control\n"
2273 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2274 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2278 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2279 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2280 cmd
.action_code
= 4; // Feature Control command
2281 cmd
.function_code
= 1; // Set state
2282 cmd
.feature_code
= 3; // Temperature logging interval
2283 cmd
.state
= interval
;
2284 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2286 // swap endian order if needed
2287 if (isbigendian()) {
2288 swapx(&cmd
.action_code
);
2289 swapx(&cmd
.function_code
);
2290 swapx(&cmd
.feature_code
);
2292 swapx(&cmd
.option_flags
);
2295 // write command via SMART log page 0xe0
2296 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2297 syserror("Error Write SCT Feature Control Command failed");
2301 // re-read and check SCT status
2302 if (ataReadSCTStatus(device
, &sts
))
2305 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== 1)) {
2306 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2307 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2313 // Get/Set SCT Error Recovery Control
2314 static int ataGetSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
,
2315 bool set
, unsigned short & time_limit
)
2317 // Check initial status
2318 ata_sct_status_response sts
;
2319 if (ataReadSCTStatus(device
, &sts
))
2322 // Do nothing if other SCT command is executing
2323 if (sts
.ext_status_code
== 0xffff) {
2324 pout("Another SCT command is executing, abort Error Recovery Control\n"
2325 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2326 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2330 ata_sct_error_recovery_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2331 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2332 cmd
.action_code
= 3; // Error Recovery Control command
2333 cmd
.function_code
= (set
? 1 : 2); // 1=Set timer, 2=Get timer
2334 cmd
.selection_code
= type
; // 1=Read timer, 2=Write timer
2336 cmd
.time_limit
= time_limit
;
2338 // swap endian order if needed
2339 if (isbigendian()) {
2340 swapx(&cmd
.action_code
);
2341 swapx(&cmd
.function_code
);
2342 swapx(&cmd
.selection_code
);
2343 swapx(&cmd
.time_limit
);
2346 // write command via SMART log page 0xe0
2347 // TODO: Debug output
2349 in
.in_regs
.command
= ATA_SMART_CMD
;
2350 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
2351 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
2352 in
.in_regs
.lba_low
= 0xe0;
2353 in
.set_data_out(&cmd
, 1);
2356 // Time limit returned in ATA registers
2357 in
.out_needed
.sector_count
= in
.out_needed
.lba_low
= true;
2360 if (!device
->ata_pass_through(in
, out
)) {
2361 pout("Error Write SCT Error Recovery Control Command failed: %s\n", device
->get_errmsg());
2365 // re-read and check SCT status
2366 if (ataReadSCTStatus(device
, &sts
))
2369 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 3 && sts
.function_code
== (set
? 1 : 2))) {
2370 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2371 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2376 // Check whether registers are properly returned by ioctl()
2377 if (!(out
.out_regs
.sector_count
.is_set() && out
.out_regs
.lba_low
.is_set())) {
2378 // TODO: Output register support should be checked within each ata_pass_through()
2379 // implementation before command is issued.
2380 pout("Error SMART WRITE LOG does not return COUNT and LBA_LOW register\n");
2383 // Return value to caller
2384 time_limit
= out
.out_regs
.sector_count
| (out
.out_regs
.lba_low
<< 8);
2390 // Get SCT Error Recovery Control
2391 int ataGetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short & time_limit
)
2393 return ataGetSetSCTErrorRecoveryControltime(device
, type
, false/*get*/, time_limit
);
2396 // Set SCT Error Recovery Control
2397 int ataSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short time_limit
)
2399 return ataGetSetSCTErrorRecoveryControltime(device
, type
, true/*set*/, time_limit
);
2403 // Print one self-test log entry.
2404 // Returns true if self-test showed an error.
2405 bool ataPrintSmartSelfTestEntry(unsigned testnum
, unsigned char test_type
,
2406 unsigned char test_status
,
2407 unsigned short timestamp
,
2408 uint64_t failing_lba
,
2409 bool print_error_only
, bool & print_header
)
2411 const char * msgtest
;
2412 switch (test_type
) {
2413 case 0x00: msgtest
= "Offline"; break;
2414 case 0x01: msgtest
= "Short offline"; break;
2415 case 0x02: msgtest
= "Extended offline"; break;
2416 case 0x03: msgtest
= "Conveyance offline"; break;
2417 case 0x04: msgtest
= "Selective offline"; break;
2418 case 0x7f: msgtest
= "Abort offline test"; break;
2419 case 0x81: msgtest
= "Short captive"; break;
2420 case 0x82: msgtest
= "Extended captive"; break;
2421 case 0x83: msgtest
= "Conveyance captive"; break;
2422 case 0x84: msgtest
= "Selective captive"; break;
2424 if ((0x40 <= test_type
&& test_type
<= 0x7e) || 0x90 <= test_type
)
2425 msgtest
= "Vendor offline";
2427 msgtest
= "Reserved offline";
2430 bool is_error
= false;
2431 const char * msgstat
;
2432 switch (test_status
>> 4) {
2433 case 0x0: msgstat
= "Completed without error"; break;
2434 case 0x1: msgstat
= "Aborted by host"; break;
2435 case 0x2: msgstat
= "Interrupted (host reset)"; break;
2436 case 0x3: msgstat
= "Fatal or unknown error"; is_error
= true; break;
2437 case 0x4: msgstat
= "Completed: unknown failure"; is_error
= true; break;
2438 case 0x5: msgstat
= "Completed: electrical failure"; is_error
= true; break;
2439 case 0x6: msgstat
= "Completed: servo/seek failure"; is_error
= true; break;
2440 case 0x7: msgstat
= "Completed: read failure"; is_error
= true; break;
2441 case 0x8: msgstat
= "Completed: handling damage??"; is_error
= true; break;
2442 case 0xf: msgstat
= "Self-test routine in progress"; break;
2443 default: msgstat
= "Unknown/reserved test status";
2446 if (!is_error
&& print_error_only
)
2449 // Print header once
2451 print_header
= false;
2452 pout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2456 if (is_error
&& failing_lba
< 0xffffffffffffULL
)
2457 snprintf(msglba
, sizeof(msglba
), "%"PRIu64
, failing_lba
);
2459 strcpy(msglba
, "-");
2461 pout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum
, msgtest
, msgstat
,
2462 test_status
& 0x0f, timestamp
, msglba
);
2467 // Print Smart self-test log, used by smartctl and smartd.
2469 // bottom 8 bits: number of entries found where self-test showed an error
2470 // remaining bits: if nonzero, power on hours of last self-test where error was found
2471 int ataPrintSmartSelfTestlog(const ata_smart_selftestlog
* data
, bool allentries
,
2472 unsigned char fix_firmwarebug
)
2475 pout("SMART Self-test log structure revision number %d\n",(int)data
->revnumber
);
2476 if ((data
->revnumber
!=0x0001) && allentries
&& fix_firmwarebug
!= FIX_SAMSUNG
)
2477 pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2478 if (data
->mostrecenttest
==0){
2480 pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
2484 bool noheaderprinted
= true;
2485 int retval
=0, hours
=0, testno
=0;
2488 for (int i
= 20; i
>= 0; i
--) {
2489 // log is a circular buffer
2490 int j
= (i
+data
->mostrecenttest
)%21;
2491 const ata_smart_selftestlog_struct
* log
= data
->selftest_struct
+j
;
2493 if (nonempty(log
, sizeof(*log
))) {
2494 // count entry based on non-empty structures -- needed for
2495 // Seagate only -- other vendors don't have blank entries 'in
2499 // T13/1321D revision 1c: (Data structure Rev #1)
2501 //The failing LBA shall be the LBA of the uncorrectable sector
2502 //that caused the test to fail. If the device encountered more
2503 //than one uncorrectable sector during the test, this field
2504 //shall indicate the LBA of the first uncorrectable sector
2505 //encountered. If the test passed or the test failed for some
2506 //reason other than an uncorrectable sector, the value of this
2507 //field is undefined.
2509 // This is true in ALL ATA-5 specs
2510 uint64_t lba48
= (log
->lbafirstfailure
< 0xffffffff ? log
->lbafirstfailure
: 0xffffffffffffULL
);
2513 if (ataPrintSmartSelfTestEntry(testno
,
2514 log
->selftestnumber
, log
->selfteststatus
,
2515 log
->timestamp
, lba48
, !allentries
, noheaderprinted
)) {
2517 // Self-test showed an error
2520 // keep track of time of most recent error
2522 hours
= log
->timestamp
;
2526 if (!allentries
&& retval
)
2530 return (retval
| hours
);
2534 /////////////////////////////////////////////////////////////////////////////
2535 // Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2536 // an ATA device with same behaviour
2540 class parsed_ata_device
2541 : public /*implements*/ ata_device_with_command_set
2544 parsed_ata_device(smart_interface
* intf
, const char * dev_name
);
2546 virtual ~parsed_ata_device() throw();
2548 virtual bool is_open() const;
2550 virtual bool open();
2552 virtual bool close();
2554 virtual bool ata_identify_is_cached() const;
2557 virtual int ata_command_interface(smart_command_set command
, int select
, char * data
);
2560 // Table of parsed commands, return value, data
2561 struct parsed_ata_command
2563 smart_command_set command
;
2569 enum { max_num_commands
= 32 };
2570 parsed_ata_command m_command_table
[max_num_commands
];
2573 int m_next_replay_command
;
2574 bool m_replay_out_of_sync
;
2575 bool m_ata_identify_is_cached
;
2578 static const char * nextline(const char * s
, int & lineno
)
2580 for (s
+= strcspn(s
, "\r\n"); *s
== '\r' || *s
== '\n'; s
++) {
2581 if (*s
== '\r' && s
[1] == '\n')
2588 static int name2command(const char * s
)
2590 for (int i
= 0; i
< (int)(sizeof(commandstrings
)/sizeof(commandstrings
[0])); i
++) {
2591 if (!strcmp(s
, commandstrings
[i
]))
2597 static bool matchcpy(char * dest
, size_t size
, const char * src
, const regmatch_t
& srcmatch
)
2599 if (srcmatch
.rm_so
< 0)
2601 size_t n
= srcmatch
.rm_eo
- srcmatch
.rm_so
;
2604 memcpy(dest
, src
+ srcmatch
.rm_so
, n
);
2609 static inline int matchtoi(const char * src
, const regmatch_t
& srcmatch
, int defval
)
2611 if (srcmatch
.rm_so
< 0)
2613 return atoi(src
+ srcmatch
.rm_so
);
2616 parsed_ata_device::parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2617 : smart_device(intf
, dev_name
, "ata", ""),
2619 m_next_replay_command(0),
2620 m_replay_out_of_sync(false),
2621 m_ata_identify_is_cached(false)
2623 memset(m_command_table
, 0, sizeof(m_command_table
));
2626 parsed_ata_device::~parsed_ata_device() throw()
2631 bool parsed_ata_device::is_open() const
2633 return (m_num_commands
> 0);
2636 // Parse stdin and build command table
2637 bool parsed_ata_device::open()
2639 const char * pathname
= get_dev_name();
2640 if (strcmp(pathname
, "-"))
2641 return set_err(EINVAL
);
2642 pathname
= "<stdin>";
2644 char buffer
[64*1024];
2646 while (size
< (int)sizeof(buffer
)) {
2647 int nr
= fread(buffer
, 1, sizeof(buffer
), stdin
);
2653 return set_err(ENOENT
, "%s: Unexpected EOF", pathname
);
2654 if (size
>= (int)sizeof(buffer
))
2655 return set_err(EIO
, "%s: Buffer overflow", pathname
);
2658 // Regex to match output from "-r ataioctl,2"
2659 static const char pattern
[] = "^"
2661 "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
2663 "( InputParameter=([0-9]+))?" // (4 (5))
2665 "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2667 "[\r\n]" // EOL match necessary to match optional parts above
2669 "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2671 " *(En|Dis)abled status cached by OS, " // (11)
2675 regular_expression regex
;
2676 if (!regex
.compile(pattern
, REG_EXTENDED
))
2677 return set_err(EIO
, "invalid regex");
2680 const char * errmsg
= 0;
2681 int i
= -1, state
= 0, lineno
= 1;
2682 for (const char * line
= buffer
; *line
; line
= nextline(line
, lineno
)) {
2684 if (!(line
[0] == 'R' || line
[0] == '=' || line
[0] == ' '))
2686 const int nmatch
= 1+11;
2687 regmatch_t match
[nmatch
];
2688 if (!regex
.execute(line
, nmatch
, match
))
2692 if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[2])) { // "REPORT-IOCTL:... Command=%s ..."
2693 int nc
= name2command(cmdname
);
2695 errmsg
= "Unknown ATA command name"; break;
2697 if (match
[7].rm_so
< 0) { // "returned %d"
2699 if (!(state
== 0 || state
== 2)) {
2700 errmsg
= "Missing REPORT-IOCTL result"; break;
2702 if (++i
>= max_num_commands
) {
2703 errmsg
= "Too many ATA commands"; break;
2705 m_command_table
[i
].command
= (smart_command_set
)nc
;
2706 m_command_table
[i
].select
= matchtoi(line
, match
[5], 0); // "InputParameter=%d"
2711 if (!(state
== 1 && (int)m_command_table
[i
].command
== nc
)) {
2712 errmsg
= "Missing REPORT-IOCTL start"; break;
2714 m_command_table
[i
].retval
= matchtoi(line
, match
[7], -1); // "returned %d"
2715 m_command_table
[i
].errval
= matchtoi(line
, match
[9], 0); // "errno=%d"
2719 else if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[10])) { // "===== [%s] DATA START "
2720 // Start of sector hexdump
2721 int nc
= name2command(cmdname
);
2722 if (!(state
== (nc
== WRITE_LOG
? 1 : 2) && (int)m_command_table
[i
].command
== nc
)) {
2723 errmsg
= "Unexpected DATA START"; break;
2725 line
= nextline(line
, lineno
);
2726 char * data
= (char *)malloc(512);
2728 for (j
= 0; j
< 32; j
++) {
2730 unsigned u1
, u2
; int n1
= -1;
2731 if (!(sscanf(line
, "%3u-%3u: "
2732 "%2x %2x %2x %2x %2x %2x %2x %2x "
2733 "%2x %2x %2x %2x %2x %2x %2x %2x%n",
2735 b
+ 0, b
+ 1, b
+ 2, b
+ 3, b
+ 4, b
+ 5, b
+ 6, b
+ 7,
2736 b
+ 8, b
+ 9, b
+10, b
+11, b
+12, b
+13, b
+14, b
+15, &n1
) == 18
2737 && n1
>= 56 && u1
== j
*16 && u2
== j
*16+15))
2739 for (unsigned k
= 0; k
< 16; k
++)
2740 data
[j
*16+k
] = b
[k
];
2741 line
= nextline(line
, lineno
);
2745 errmsg
= "Incomplete sector hex dump"; break;
2747 m_command_table
[i
].data
= data
;
2748 if (nc
!= WRITE_LOG
)
2751 else if (match
[11].rm_so
> 0) { // "(En|Dis)abled status cached by OS"
2752 m_ata_identify_is_cached
= true;
2756 if (!(state
== 0 || state
== 2))
2757 errmsg
= "Missing REPORT-IOCTL result";
2759 if (!errmsg
&& i
< 0)
2760 errmsg
= "No information found";
2762 m_num_commands
= i
+1;
2763 m_next_replay_command
= 0;
2764 m_replay_out_of_sync
= false;
2768 return set_err(EIO
, "%s(%d): Syntax error: %s", pathname
, lineno
, errmsg
);
2773 // Report warnings and free command table
2774 bool parsed_ata_device::close()
2776 if (m_replay_out_of_sync
)
2777 pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
2778 else if (m_next_replay_command
!= 0)
2779 pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands
-m_next_replay_command
);
2781 for (int i
= 0; i
< m_num_commands
; i
++) {
2782 if (m_command_table
[i
].data
) {
2783 free(m_command_table
[i
].data
); m_command_table
[i
].data
= 0;
2787 m_next_replay_command
= 0;
2788 m_replay_out_of_sync
= false;
2793 bool parsed_ata_device::ata_identify_is_cached() const
2795 return m_ata_identify_is_cached
;
2799 // Simulate ATA command from command table
2800 int parsed_ata_device::ata_command_interface(smart_command_set command
, int select
, char * data
)
2802 // Find command, try round-robin if out of sync
2803 int i
= m_next_replay_command
;
2804 for (int j
= 0; ; j
++) {
2805 if (j
>= m_num_commands
) {
2806 pout("REPLAY-IOCTL: Warning: Command not found\n");
2810 if (m_command_table
[i
].command
== command
&& m_command_table
[i
].select
== select
)
2812 if (!m_replay_out_of_sync
) {
2813 m_replay_out_of_sync
= true;
2814 pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i
+1);
2816 if (++i
>= m_num_commands
)
2819 m_next_replay_command
= i
;
2820 if (++m_next_replay_command
>= m_num_commands
)
2821 m_next_replay_command
= 0;
2823 // Return command data
2828 case READ_THRESHOLDS
:
2830 if (m_command_table
[i
].data
)
2831 memcpy(data
, m_command_table
[i
].data
, 512);
2834 if (!(m_command_table
[i
].data
&& !memcmp(data
, m_command_table
[i
].data
, 512)))
2835 pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
2837 case CHECK_POWER_MODE
:
2838 data
[0] = (char)0xff;
2843 if (m_command_table
[i
].errval
)
2844 errno
= m_command_table
[i
].errval
;
2845 return m_command_table
[i
].retval
;
2850 ata_device
* get_parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2852 return new parsed_ata_device(intf
, dev_name
);