4 * Home page of code is: http://www.smartmontools.org
7 * Copyright (C) 2002-11 Bruce Allen
8 * Copyright (C) 2008-15 Christian Franke
10 * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
11 * Copyright (C) 2008-15 Christian Franke <smartmontools-support@lists.sourceforge.net>
12 >>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
13 * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
14 * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
21 * You should have received a copy of the GNU General Public License
22 * (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
24 * This code was originally developed as a Senior Thesis by Michael Cornwell
25 * at the Concurrent Systems Laboratory (now part of the Storage Systems
26 * Research Center), Jack Baskin School of Engineering, University of
27 * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
40 #include "knowndrives.h" // get_default_attr_defs()
42 #include "dev_ata_cmd_set.h" // for parsed_ata_device
45 const char * atacmds_cpp_cvsid
= "$Id: atacmds.cpp 4301 2016-04-16 20:48:29Z chrfranke $"
47 const char * atacmds_cpp_cvsid
= "$Id: atacmds.cpp 4048 2015-03-29 16:09:04Z chrfranke $"
48 >>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
51 // Print ATA debug messages?
52 unsigned char ata_debugmode
= 0;
54 // Suppress serial number?
55 // (also used in scsiprint.cpp)
56 bool dont_print_serial_number
= false;
59 #define SMART_CYL_LOW 0x4F
60 #define SMART_CYL_HI 0xC2
62 // SMART RETURN STATUS yields SMART_CYL_HI,SMART_CYL_LOW to indicate drive
63 // is healthy and SRET_STATUS_HI_EXCEEDED,SRET_STATUS_MID_EXCEEDED to
64 // indicate that a threshhold exceeded condition has been detected.
65 // Those values (byte pairs) are placed in ATA register "LBA 23:8".
66 #define SRET_STATUS_HI_EXCEEDED 0x2C
67 #define SRET_STATUS_MID_EXCEEDED 0xF4
70 // Get ID and increase flag of current pending or offline
71 // uncorrectable attribute.
72 unsigned char get_unc_attr_id(bool offline
, const ata_vendor_attr_defs
& defs
,
75 unsigned char id
= (!offline
? 197 : 198);
76 const ata_vendor_attr_defs::entry
& def
= defs
[id
];
77 if (def
.flags
& ATTRFLAG_INCREASING
)
78 increase
= true; // '-v 19[78],increasing' option
79 else if (def
.name
.empty() || (id
== 198 && def
.name
== "Offline_Scan_UNC_SectCt"))
80 increase
= false; // no or '-v 198,offlinescanuncsectorct' option
82 id
= 0; // other '-v 19[78],...' option
86 #if 0 // TODO: never used
87 // This are the meanings of the Self-test failure checkpoint byte.
88 // This is in the self-test log at offset 4 bytes into the self-test
89 // descriptor and in the SMART READ DATA structure at byte offset
90 // 371. These codes are not well documented. The meanings returned by
91 // this routine are used (at least) by Maxtor and IBM. Returns NULL if
92 // not recognized. Currently the maximum length is 15 bytes.
93 const char *SelfTestFailureCodeName(unsigned char which
){
101 return "Servo_Random";
103 return "G-list_Scan";
105 return "Handling_Damage";
115 // Table of raw print format names
116 struct format_name_entry
119 ata_attr_raw_format format
;
122 const format_name_entry format_names
[] = {
123 {"raw8" , RAWFMT_RAW8
},
124 {"raw16" , RAWFMT_RAW16
},
125 {"raw48" , RAWFMT_RAW48
},
126 {"hex48" , RAWFMT_HEX48
},
127 {"raw56" , RAWFMT_RAW56
},
128 {"hex56" , RAWFMT_HEX56
},
129 {"raw64" , RAWFMT_RAW64
},
130 {"hex64" , RAWFMT_HEX64
},
131 {"raw16(raw16)" , RAWFMT_RAW16_OPT_RAW16
},
132 {"raw16(avg16)" , RAWFMT_RAW16_OPT_AVG16
},
133 {"raw24(raw8)" , RAWFMT_RAW24_OPT_RAW8
},
134 {"raw24/raw24" , RAWFMT_RAW24_DIV_RAW24
},
135 {"raw24/raw32" , RAWFMT_RAW24_DIV_RAW32
},
136 {"sec2hour" , RAWFMT_SEC2HOUR
},
137 {"min2hour" , RAWFMT_MIN2HOUR
},
138 {"halfmin2hour" , RAWFMT_HALFMIN2HOUR
},
139 {"msec24hour32" , RAWFMT_MSEC24_HOUR32
},
140 {"tempminmax" , RAWFMT_TEMPMINMAX
},
141 {"temp10x" , RAWFMT_TEMP10X
},
144 const unsigned num_format_names
= sizeof(format_names
)/sizeof(format_names
[0]);
146 // Table to map old to new '-v' option arguments
147 const char * const map_old_vendor_opts
[][2] = {
148 { "9,halfminutes" , "9,halfmin2hour,Power_On_Half_Minutes"},
149 { "9,minutes" , "9,min2hour,Power_On_Minutes"},
150 { "9,seconds" , "9,sec2hour,Power_On_Seconds"},
151 { "9,temp" , "9,tempminmax,Temperature_Celsius"},
152 {"192,emergencyretractcyclect" , "192,raw48,Emerg_Retract_Cycle_Ct"},
153 {"193,loadunload" , "193,raw24/raw24"},
154 {"194,10xCelsius" , "194,temp10x,Temperature_Celsius_x10"},
155 {"194,unknown" , "194,raw48,Unknown_Attribute"},
156 {"197,increasing" , "197,raw48+,Total_Pending_Sectors"}, // '+' sets flag
157 {"198,offlinescanuncsectorct" , "198,raw48,Offline_Scan_UNC_SectCt"}, // see also get_unc_attr_id() above
158 {"198,increasing" , "198,raw48+,Total_Offl_Uncorrectabl"}, // '+' sets flag
159 {"200,writeerrorcount" , "200,raw48,Write_Error_Count"},
160 {"201,detectedtacount" , "201,raw48,Detected_TA_Count"},
161 {"220,temp" , "220,tempminmax,Temperature_Celsius"},
164 const unsigned num_old_vendor_opts
= sizeof(map_old_vendor_opts
)/sizeof(map_old_vendor_opts
[0]);
166 // Parse vendor attribute display def (-v option).
167 // Return false on error.
168 bool parse_attribute_def(const char * opt
, ata_vendor_attr_defs
& defs
,
169 ata_vendor_def_prior priority
)
171 // Map old -> new options
173 for (i
= 0; i
< num_old_vendor_opts
; i
++) {
174 if (!strcmp(opt
, map_old_vendor_opts
[i
][0])) {
175 opt
= map_old_vendor_opts
[i
][1];
181 int len
= strlen(opt
);
182 int id
= 0, n1
= -1, n2
= -1;
183 char fmtname
[32+1], attrname
[32+1], hddssd
[3+1];
184 attrname
[0] = hddssd
[0] = 0;
188 if (!( sscanf(opt
, "N,%32[^,]%n,%32[^,]%n", fmtname
, &n1
, attrname
, &n2
) >= 1
189 && (n1
== len
|| n2
== len
)))
193 // "id,format[+][,name[,HDD|SSD]]"
195 if (!( sscanf(opt
, "%d,%32[^,]%n,%32[^,]%n,%3[DHS]%n",
196 &id
, fmtname
, &n1
, attrname
, &n2
, hddssd
, &n3
) >= 2
197 && 1 <= id
&& id
<= 255
198 && ( n1
== len
|| n2
== len
199 // ",HDD|SSD" for DEFAULT settings only
200 || (n3
== len
&& priority
== PRIOR_DEFAULT
))))
205 // For "-v 19[78],increasing" above
206 if (fmtname
[strlen(fmtname
)-1] == '+') {
207 fmtname
[strlen(fmtname
)-1] = 0;
208 flags
= ATTRFLAG_INCREASING
;
211 // Split "format[:byteorder]"
212 char byteorder
[8+1] = "";
213 if (strchr(fmtname
, ':')) {
214 if (priority
== PRIOR_DEFAULT
)
215 // TODO: Allow Byteorder in DEFAULT entry
218 if (!( sscanf(fmtname
, "%*[^:]%n:%8[012345rvwz]%n", &n1
, byteorder
, &n2
) >= 1
219 && n2
== (int)strlen(fmtname
)))
222 if (strchr(byteorder
, 'v'))
223 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
224 if (strchr(byteorder
, 'w'))
225 flags
|= ATTRFLAG_NO_WORSTVAL
;
230 if (i
>= num_format_names
)
231 return false; // Not found
232 if (!strcmp(fmtname
, format_names
[i
].name
))
235 ata_attr_raw_format format
= format_names
[i
].format
;
237 // 64-bit formats use the normalized and worst value bytes.
238 if (!*byteorder
&& (format
== RAWFMT_RAW64
|| format
== RAWFMT_HEX64
))
239 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
241 // ",HDD|SSD" suffix for DEFAULT settings
243 if (!strcmp(hddssd
, "HDD"))
244 flags
|= ATTRFLAG_HDD_ONLY
;
245 else if (!strcmp(hddssd
, "SSD"))
246 flags
|= ATTRFLAG_SSD_ONLY
;
252 // "N,format" -> set format for all entries
253 for (i
= 0; i
< MAX_ATTRIBUTE_NUM
; i
++) {
254 if (defs
[i
].priority
>= priority
)
257 defs
[i
].name
= attrname
;
258 defs
[i
].priority
= priority
;
259 defs
[i
].raw_format
= format
;
260 defs
[i
].flags
= flags
;
261 snprintf(defs
[i
].byteorder
, sizeof(defs
[i
].byteorder
), "%s", byteorder
);
264 else if (defs
[id
].priority
<= priority
) {
265 // "id,format[,name]"
267 defs
[id
].name
= attrname
;
268 defs
[id
].raw_format
= format
;
269 defs
[id
].priority
= priority
;
270 defs
[id
].flags
= flags
;
271 snprintf(defs
[id
].byteorder
, sizeof(defs
[id
].byteorder
), "%s", byteorder
);
278 // Return a multiline string containing a list of valid arguments for
279 // parse_attribute_def(). The strings are preceeded by tabs and followed
280 // (except for the last) by newlines.
281 std::string
create_vendor_attribute_arg_list()
285 for (i
= 0; i
< num_format_names
; i
++)
286 s
+= strprintf("%s\tN,%s[:012345rvwz][,ATTR_NAME]",
287 (i
>0 ? "\n" : ""), format_names
[i
].name
);
288 for (i
= 0; i
< num_old_vendor_opts
; i
++)
289 s
+= strprintf("\n\t%s", map_old_vendor_opts
[i
][0]);
294 // Parse firmwarebug def (-F option).
295 // Return false on error.
296 bool parse_firmwarebug_def(const char * opt
, firmwarebug_defs
& firmwarebugs
)
298 if (!strcmp(opt
, "none"))
299 firmwarebugs
.set(BUG_NONE
);
300 else if (!strcmp(opt
, "nologdir"))
301 firmwarebugs
.set(BUG_NOLOGDIR
);
302 else if (!strcmp(opt
, "samsung"))
303 firmwarebugs
.set(BUG_SAMSUNG
);
304 else if (!strcmp(opt
, "samsung2"))
305 firmwarebugs
.set(BUG_SAMSUNG2
);
306 else if (!strcmp(opt
, "samsung3"))
307 firmwarebugs
.set(BUG_SAMSUNG3
);
308 else if (!strcmp(opt
, "xerrorlba"))
309 firmwarebugs
.set(BUG_XERRORLBA
);
315 // Return a string of valid argument words for parse_firmwarebug_def()
316 const char * get_valid_firmwarebug_args()
318 return "none, nologdir, samsung, samsung2, samsung3, xerrorlba";
322 // swap two bytes. Point to low address
323 void swap2(char *location
){
325 *location
=*(location
+1);
330 // swap four bytes. Point to low address
331 void swap4(char *location
){
333 *location
=*(location
+3);
339 // swap eight bytes. Points to low address
340 void swap8(char *location
){
342 *location
=*(location
+7);
345 *(location
+1)=*(location
+6);
351 // Invalidate serial number and WWN and adjust checksum in IDENTIFY data
352 static void invalidate_serno(ata_identify_device
* id
)
354 unsigned char sum
= 0;
356 for (i
= 0; i
< sizeof(id
->serial_no
); i
++) {
357 sum
+= id
->serial_no
[i
]; sum
-= id
->serial_no
[i
] = 'X';
359 unsigned char * b
= (unsigned char *)id
;
360 for (i
= 2*108; i
< 2*112; i
++) { // words108-111: WWN
361 sum
+= b
[i
]; sum
-= b
[i
] = 0x00;
365 bool must_swap
= !!isbigendian();
367 swapx(id
->words088_255
+255-88);
369 if ((id
->words088_255
[255-88] & 0x00ff) == 0x00a5)
370 id
->words088_255
[255-88] += sum
<< 8;
373 swapx(id
->words088_255
+255-88);
377 static const char * const commandstrings
[]={
380 "SMART AUTOMATIC ATTRIBUTE SAVE",
381 "SMART IMMEDIATE OFFLINE",
382 "SMART AUTO OFFLINE",
384 "SMART STATUS CHECK",
385 "SMART READ ATTRIBUTE VALUES",
386 "SMART READ ATTRIBUTE THRESHOLDS",
389 "IDENTIFY PACKET DEVICE",
392 "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT
")\n"
396 static const char * preg(const ata_register
& r
, char (& buf
)[8])
401 snprintf(buf
, sizeof(buf
), "0x%02x", r
.val());
405 static void print_regs(const char * prefix
, const ata_in_regs
& r
, const char * suffix
= "\n")
408 pout("%s FR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, CMD=%s%s", prefix
,
409 preg(r
.features
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
410 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
411 preg(r
.command
, bufs
[6]), suffix
);
414 static void print_regs(const char * prefix
, const ata_out_regs
& r
, const char * suffix
= "\n")
417 pout("%sERR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, STS=%s%s", prefix
,
418 preg(r
.error
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
419 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
420 preg(r
.status
, bufs
[6]), suffix
);
423 static void prettyprint(const unsigned char *p
, const char *name
){
424 pout("\n===== [%s] DATA START (BASE-16) =====\n", name
);
425 for (int i
=0; i
<512; i
+=16, p
+=16)
426 #define P(n) (' ' <= p[n] && p[n] <= '~' ? (int)p[n] : '.')
427 // print complete line to avoid slow tty output and extra lines in syslog.
428 pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x "
429 "%02x %02x %02x %02x %02x %02x %02x %02x"
430 " |%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c|"
433 p
[ 0], p
[ 1], p
[ 2], p
[ 3], p
[ 4], p
[ 5], p
[ 6], p
[ 7],
434 p
[ 8], p
[ 9], p
[10], p
[11], p
[12], p
[13], p
[14], p
[15],
435 P( 0), P( 1), P( 2), P( 3), P( 4), P( 5), P( 6), P( 7),
436 P( 8), P( 9), P(10), P(11), P(12), P(13), P(14), P(15),
439 pout("===== [%s] DATA END (512 Bytes) =====\n\n", name
);
442 // This function provides the pretty-print reporting for SMART
443 // commands: it implements the various -r "reporting" options for ATA
445 int smartcommandhandler(ata_device
* device
, smart_command_set command
, int select
, char *data
){
446 // TODO: Rework old stuff below
447 // This conditional is true for commands that return data
448 int getsdata
=(command
==PIDENTIFY
||
451 command
==READ_THRESHOLDS
||
452 command
==READ_VALUES
||
453 command
==CHECK_POWER_MODE
);
455 int sendsdata
=(command
==WRITE_LOG
);
457 // If reporting is enabled, say what the command will be before it's executed
459 // conditional is true for commands that use parameters
460 int usesparam
=(command
==READ_LOG
||
461 command
==AUTO_OFFLINE
||
463 command
==IMMEDIATE_OFFLINE
||
466 pout("\nREPORT-IOCTL: Device=%s Command=%s", device
->get_dev_name(), commandstrings
[command
]);
468 pout(" InputParameter=%d\n", select
);
473 if ((getsdata
|| sendsdata
) && !data
){
474 pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings
[command
]);
478 // The reporting is cleaner, and we will find coding bugs faster, if
479 // the commands that failed clearly return empty (zeroed) data
482 if (command
==CHECK_POWER_MODE
)
485 memset(data
, '\0', 512);
489 // if requested, pretty-print the input data structure
490 if (ata_debugmode
> 1 && sendsdata
)
491 //pout("REPORT-IOCTL: Device=%s Command=%s\n", device->get_dev_name(), commandstrings[command]);
492 prettyprint((unsigned char *)data
, commandstrings
[command
]);
494 // now execute the command
498 // Set common register values
500 default: // SMART commands
501 in
.in_regs
.command
= ATA_SMART_CMD
;
502 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
504 case IDENTIFY
: case PIDENTIFY
: case CHECK_POWER_MODE
: // Non SMART commands
507 // Set specific values
510 in
.in_regs
.command
= ATA_IDENTIFY_DEVICE
;
511 in
.set_data_in(data
, 1);
514 in
.in_regs
.command
= ATA_IDENTIFY_PACKET_DEVICE
;
515 in
.set_data_in(data
, 1);
517 case CHECK_POWER_MODE
:
518 in
.in_regs
.command
= ATA_CHECK_POWER_MODE
;
519 in
.out_needed
.sector_count
= true; // Powermode returned here
522 in
.in_regs
.features
= ATA_SMART_READ_VALUES
;
523 in
.set_data_in(data
, 1);
525 case READ_THRESHOLDS
:
526 in
.in_regs
.features
= ATA_SMART_READ_THRESHOLDS
;
527 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
528 in
.set_data_in(data
, 1);
531 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
532 in
.in_regs
.lba_low
= select
;
533 in
.set_data_in(data
, 1);
536 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
537 in
.in_regs
.lba_low
= select
;
538 in
.set_data_out(data
, 1);
541 in
.in_regs
.features
= ATA_SMART_ENABLE
;
542 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
545 in
.in_regs
.features
= ATA_SMART_DISABLE
;
546 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
549 in
.out_needed
.lba_high
= in
.out_needed
.lba_mid
= true; // Status returned here
551 in
.in_regs
.features
= ATA_SMART_STATUS
;
554 in
.in_regs
.features
= ATA_SMART_AUTO_OFFLINE
;
555 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
558 in
.in_regs
.features
= ATA_SMART_AUTOSAVE
;
559 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
561 case IMMEDIATE_OFFLINE
:
562 in
.in_regs
.features
= ATA_SMART_IMMEDIATE_OFFLINE
;
563 in
.in_regs
.lba_low
= select
;
566 pout("Unrecognized command %d in smartcommandhandler()\n"
567 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
568 device
->set_err(ENOSYS
);
573 print_regs(" Input: ", in
.in_regs
,
574 (in
.direction
==ata_cmd_in::data_in
? " IN\n":
575 in
.direction
==ata_cmd_in::data_out
? " OUT\n":"\n"));
579 int64_t start_usec
= -1;
581 start_usec
= smi()->get_timer_usec();
583 bool ok
= device
->ata_pass_through(in
, out
);
585 if (start_usec
>= 0) {
586 int64_t duration_usec
= smi()->get_timer_usec() - start_usec
;
587 if (duration_usec
>= 500)
588 pout(" [Duration: %.3fs]\n", duration_usec
/ 1000000.0);
591 if (ata_debugmode
&& out
.out_regs
.is_set())
592 print_regs(" Output: ", out
.out_regs
);
594 if (ok
) switch (command
) {
598 case CHECK_POWER_MODE
:
599 if (out
.out_regs
.sector_count
.is_set()) {
600 data
[0] = out
.out_regs
.sector_count
;
604 pout("CHECK POWER MODE: incomplete response, ATA output registers missing\n");
605 device
->set_err(ENOSYS
);
610 // Cyl low and Cyl high unchanged means "Good SMART status"
611 if ((out
.out_regs
.lba_high
== SMART_CYL_HI
) &&
612 (out
.out_regs
.lba_mid
== SMART_CYL_LOW
))
614 // These values mean "Bad SMART status"
615 else if ((out
.out_regs
.lba_high
== SRET_STATUS_HI_EXCEEDED
) &&
616 (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
))
618 else if (out
.out_regs
.lba_mid
== SMART_CYL_LOW
) {
621 pout("SMART STATUS RETURN: half healthy response sequence, "
622 "probable SAT/USB truncation\n");
623 } else if (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
) {
626 pout("SMART STATUS RETURN: half unhealthy response sequence, "
627 "probable SAT/USB truncation\n");
629 else if (!out
.out_regs
.is_set()) {
630 device
->set_err(ENOSYS
, "Incomplete response, ATA output registers missing");
634 // We haven't gotten output that makes sense; print out some debugging info
635 pout("SMART Status command failed\n");
636 pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE
);
637 pout("Register values returned from SMART Status command are:\n");
638 print_regs(" ", out
.out_regs
);
639 device
->set_err(ENOSYS
, "Invalid ATA output register values");
646 // If requested, invalidate serial number before any printing is done
647 if ((command
== IDENTIFY
|| command
== PIDENTIFY
) && !retval
&& dont_print_serial_number
)
648 invalidate_serno( reinterpret_cast<ata_identify_device
*>(data
) );
650 // If reporting is enabled, say what output was produced by the command
652 if (device
->get_errno())
653 pout("REPORT-IOCTL: Device=%s Command=%s returned %d errno=%d [%s]\n",
654 device
->get_dev_name(), commandstrings
[command
], retval
,
655 device
->get_errno(), device
->get_errmsg());
657 pout("REPORT-IOCTL: Device=%s Command=%s returned %d\n",
658 device
->get_dev_name(), commandstrings
[command
], retval
);
660 // if requested, pretty-print the output data structure
661 if (ata_debugmode
> 1 && getsdata
) {
662 if (command
==CHECK_POWER_MODE
)
663 pout("Sector Count Register (BASE-16): %02x\n", (unsigned char)(*data
));
665 prettyprint((unsigned char *)data
, commandstrings
[command
]);
672 // Get capacity and sector sizes from IDENTIFY data
673 void ata_get_size_info(const ata_identify_device
* id
, ata_size_info
& sizes
)
675 sizes
.sectors
= sizes
.capacity
= 0;
676 sizes
.log_sector_size
= sizes
.phy_sector_size
= 0;
677 sizes
.log_sector_offset
= 0;
679 // Return if no LBA support
680 if (!(id
->words047_079
[49-47] & 0x0200))
683 // Determine 28-bit LBA capacity
684 unsigned lba28
= (unsigned)id
->words047_079
[61-47] << 16
685 | (unsigned)id
->words047_079
[60-47] ;
687 // Determine 48-bit LBA capacity if supported
689 if ((id
->command_set_2
& 0xc400) == 0x4400)
690 lba48
= (uint64_t)id
->words088_255
[103-88] << 48
691 | (uint64_t)id
->words088_255
[102-88] << 32
692 | (uint64_t)id
->words088_255
[101-88] << 16
693 | (uint64_t)id
->words088_255
[100-88] ;
695 // Return if capacity unknown (ATAPI CD/DVD)
696 if (!(lba28
|| lba48
))
699 // Determine sector sizes
700 sizes
.log_sector_size
= sizes
.phy_sector_size
= 512;
702 unsigned short word106
= id
->words088_255
[106-88];
703 if ((word106
& 0xc000) == 0x4000) {
704 // Long Logical/Physical Sectors (LLS/LPS) ?
705 if (word106
& 0x1000)
706 // Logical sector size is specified in 16-bit words
707 sizes
.log_sector_size
= sizes
.phy_sector_size
=
708 ((id
->words088_255
[118-88] << 16) | id
->words088_255
[117-88]) << 1;
710 if (word106
& 0x2000)
711 // Physical sector size is multiple of logical sector size
712 sizes
.phy_sector_size
<<= (word106
& 0x0f);
714 unsigned short word209
= id
->words088_255
[209-88];
715 if ((word209
& 0xc000) == 0x4000)
716 sizes
.log_sector_offset
= (word209
& 0x3fff) * sizes
.log_sector_size
;
719 // Some early 4KiB LLS disks (Samsung N3U-3) return bogus lba28 value
720 if (lba48
>= lba28
|| (lba48
&& sizes
.log_sector_size
> 512))
721 sizes
.sectors
= lba48
;
723 sizes
.sectors
= lba28
;
725 sizes
.capacity
= sizes
.sectors
* sizes
.log_sector_size
;
728 // This function computes the checksum of a single disk sector (512
729 // bytes). Returns zero if checksum is OK, nonzero if the checksum is
730 // incorrect. The size (512) is correct for all SMART structures.
731 unsigned char checksum(const void * data
)
733 unsigned char sum
= 0;
734 for (int i
= 0; i
< 512; i
++)
735 sum
+= ((const unsigned char *)data
)[i
];
739 // Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
741 static void swapbytes(char * out
, const char * in
, size_t n
)
743 for (size_t i
= 0; i
< n
; i
+= 2) {
749 // Copies in to out, but removes leading and trailing whitespace.
750 static void trim(char * out
, const char * in
)
752 // Find the first non-space character (maybe none).
755 for (i
= 0; in
[i
]; i
++)
756 if (!isspace((int)in
[i
])) {
762 // There are no non-space characters.
767 // Find the last non-space character.
768 for (i
= strlen(in
)-1; i
>= first
&& isspace((int)in
[i
]); i
--)
772 strncpy(out
, in
+first
, last
-first
+1);
773 out
[last
-first
+1] = '\0';
776 // Convenience function for formatting strings from ata_identify_device
777 void ata_format_id_string(char * out
, const unsigned char * in
, int n
)
779 bool must_swap
= true;
781 /* NetBSD kernel delivers IDENTIFY data in host byte order (but all else is LE) */
782 // TODO: Handle NetBSD case in os_netbsd.cpp
784 must_swap
= !must_swap
;
790 strncpy(tmp
, (const char *)in
, n
);
792 swapbytes(tmp
, (const char *)in
, n
);
797 // returns -1 if command fails or the device is in Sleep mode, else
798 // value of Sector Count register. Sector Count result values:
799 // 00h device is in Standby mode.
800 // 80h device is in Idle mode.
801 // FFh device is in Active mode or Idle mode.
803 int ataCheckPowerMode(ata_device
* device
) {
804 unsigned char result
;
806 if ((smartcommandhandler(device
, CHECK_POWER_MODE
, 0, (char *)&result
)))
812 // Issue a no-data ATA command with optional sector count register value
813 bool ata_nodata_command(ata_device
* device
, unsigned char command
,
814 int sector_count
/* = -1 */)
817 in
.in_regs
.command
= command
;
818 if (sector_count
>= 0)
819 in
.in_regs
.sector_count
= sector_count
;
821 return device
->ata_pass_through(in
);
824 // Issue SET FEATURES command with optional sector count register value
825 bool ata_set_features(ata_device
* device
, unsigned char features
,
826 int sector_count
/* = -1 */)
829 in
.in_regs
.command
= ATA_SET_FEATURES
;
830 in
.in_regs
.features
= features
;
831 if (sector_count
>= 0)
832 in
.in_regs
.sector_count
= sector_count
;
834 return device
->ata_pass_through(in
);
837 // Reads current Device Identity info (512 bytes) into buf. Returns 0
838 // if all OK. Returns -1 if no ATA Device identity can be
839 // established. Returns >0 if Device is ATA Packet Device (not SMART
840 // capable). The value of the integer helps identify the type of
841 // Packet device, which is useful so that the user can connect the
842 // formal device number with whatever object is inside their computer.
843 int ata_read_identity(ata_device
* device
, ata_identify_device
* buf
, bool fix_swapped_id
,
844 unsigned char * raw_buf
/* = 0 */)
846 unsigned short *rawshort
=(unsigned short *)buf
;
847 unsigned char *rawbyte
=(unsigned char *)buf
;
849 // See if device responds either to IDENTIFY DEVICE or IDENTIFY
852 if ((smartcommandhandler(device
, IDENTIFY
, 0, (char *)buf
))){
853 if (smartcommandhandler(device
, PIDENTIFY
, 0, (char *)buf
)){
859 if (fix_swapped_id
) {
862 for (i
= 0; i
< sizeof(buf
->serial_no
)-1; i
+= 2)
863 swap2((char *)(buf
->serial_no
+i
));
864 for (i
= 0; i
< sizeof(buf
->fw_rev
)-1; i
+= 2)
865 swap2((char *)(buf
->fw_rev
+i
));
866 for (i
= 0; i
< sizeof(buf
->model
)-1; i
+= 2)
867 swap2((char *)(buf
->model
+i
));
870 // If requested, save raw data before endianness adjustments
872 memcpy(raw_buf
, buf
, sizeof(*buf
));
875 // if machine is big-endian, swap byte order as needed
876 // NetBSD kernel delivers IDENTIFY data in host byte order
877 // TODO: Handle NetBSD case in os_netbsd.cpp
879 // swap various capability words that are needed
882 swap2((char *)(buf
->words047_079
+i
));
883 for (i
=80; i
<=87; i
++)
884 swap2((char *)(rawshort
+i
));
885 for (i
=0; i
<168; i
++)
886 swap2((char *)(buf
->words088_255
+i
));
890 // If there is a checksum there, validate it
891 if ((rawshort
[255] & 0x00ff) == 0x00a5 && checksum(rawbyte
))
892 checksumwarning("Drive Identity Structure");
894 // AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
895 // T13/1699-D Revision 6a (Final Draft), September 6, 2008.
896 // Sections 7.16.7 and 7.17.6:
898 // Word 0 of IDENTIFY DEVICE data:
899 // Bit 15 = 0 : ATA device
901 // Word 0 of IDENTIFY PACKET DEVICE data:
902 // Bits 15:14 = 10b : ATAPI device
903 // Bits 15:14 = 11b : Reserved
904 // Bits 12:8 : Device type (SPC-4, e.g 0x05 = CD/DVD)
906 // CF+ and CompactFlash Specification Revision 4.0, May 24, 2006.
909 // Word 0 of IDENTIFY DEVICE data:
910 // 848Ah = Signature for CompactFlash Storage Card
911 // 044Ah = Alternate value turns on ATA device while preserving all retired bits
912 // 0040h = Alternate value turns on ATA device while zeroing all retired bits
914 // Assume ATA if IDENTIFY DEVICE returns CompactFlash Signature
915 if (!packet
&& rawbyte
[1] == 0x84 && rawbyte
[0] == 0x8a)
918 // If this is a PACKET DEVICE, return device type
919 if (rawbyte
[1] & 0x80)
920 return 1+(rawbyte
[1] & 0x1f);
922 // Not a PACKET DEVICE
926 // Get World Wide Name (WWN) fields.
927 // Return NAA field or -1 if WWN is unsupported.
928 // Table 34 of T13/1699-D Revision 6a (ATA8-ACS), September 6, 2008.
929 // (WWN was introduced in ATA/ATAPI-7 and is mandatory since ATA8-ACS Revision 3b)
930 int ata_get_wwn(const ata_identify_device
* id
, unsigned & oui
, uint64_t & unique_id
)
932 // Don't use word 84 to be compatible with some older ATA-7 disks
933 unsigned short word087
= id
->csf_default
;
934 if ((word087
& 0xc100) != 0x4100)
935 return -1; // word not valid or WWN support bit 8 not set
937 unsigned short word108
= id
->words088_255
[108-88];
938 unsigned short word109
= id
->words088_255
[109-88];
939 unsigned short word110
= id
->words088_255
[110-88];
940 unsigned short word111
= id
->words088_255
[111-88];
942 oui
= ((word108
& 0x0fff) << 12) | (word109
>> 4);
943 unique_id
= ((uint64_t)(word109
& 0xf) << 32)
944 | (unsigned)((word110
<< 16) | word111
);
945 return (word108
>> 12);
948 // Get nominal media rotation rate.
949 // Returns: 0 = not reported, 1 = SSD, >1 = HDD rpm, < 0 = -(Unknown value)
950 int ata_get_rotation_rate(const ata_identify_device
* id
)
952 // Table 37 of T13/1699-D (ATA8-ACS) Revision 6a, September 6, 2008
953 // Table A.31 of T13/2161-D (ACS-3) Revision 3b, August 25, 2012
954 unsigned short word217
= id
->words088_255
[217-88];
955 if (word217
== 0x0000 || word217
== 0xffff)
957 else if (word217
== 0x0001)
959 else if (word217
> 0x0400)
962 return -(int)word217
;
965 // returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
966 int ataSmartSupport(const ata_identify_device
* drive
)
968 unsigned short word82
=drive
->command_set_1
;
969 unsigned short word83
=drive
->command_set_2
;
971 // check if words 82/83 contain valid info
972 if ((word83
>>14) == 0x01)
973 // return value of SMART support bit
974 return word82
& 0x0001;
976 // since we can're rely on word 82, we don't know if SMART supported
980 // returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
981 int ataIsSmartEnabled(const ata_identify_device
* drive
)
983 unsigned short word85
=drive
->cfs_enable_1
;
984 unsigned short word87
=drive
->csf_default
;
986 // check if words 85/86/87 contain valid info
987 if ((word87
>>14) == 0x01)
988 // return value of SMART enabled bit
989 return word85
& 0x0001;
991 // Since we can't rely word85, we don't know if SMART is enabled.
996 // Reads SMART attributes into *data
997 int ataReadSmartValues(ata_device
* device
, struct ata_smart_values
*data
){
999 if (smartcommandhandler(device
, READ_VALUES
, 0, (char *)data
)){
1005 checksumwarning("SMART Attribute Data Structure");
1007 // swap endian order if needed
1010 swap2((char *)&(data
->revnumber
));
1011 swap2((char *)&(data
->total_time_to_complete_off_line
));
1012 swap2((char *)&(data
->smart_capability
));
1013 swapx(&data
->extend_test_completion_time_w
);
1014 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
1015 struct ata_smart_attribute
*x
=data
->vendor_attributes
+i
;
1016 swap2((char *)&(x
->flags
));
1024 // This corrects some quantities that are byte reversed in the SMART
1026 static void fixsamsungselftestlog(ata_smart_selftestlog
* data
)
1028 // bytes 508/509 (numbered from 0) swapped (swap of self-test index
1029 // with one byte of reserved.
1030 swap2((char *)&(data
->mostrecenttest
));
1032 // LBA low register (here called 'selftestnumber", containing
1033 // information about the TYPE of the self-test) is byte swapped with
1034 // Self-test execution status byte. These are bytes N, N+1 in the
1036 for (int i
= 0; i
< 21; i
++)
1037 swap2((char *)&(data
->selftest_struct
[i
].selftestnumber
));
1042 // Reads the Self Test Log (log #6)
1043 int ataReadSelfTestLog (ata_device
* device
, ata_smart_selftestlog
* data
,
1044 firmwarebug_defs firmwarebugs
)
1047 // get data from device
1048 if (smartcommandhandler(device
, READ_LOG
, 0x06, (char *)data
)){
1052 // compute its checksum, and issue a warning if needed
1054 checksumwarning("SMART Self-Test Log Structure");
1056 // fix firmware bugs in self-test log
1057 if (firmwarebugs
.is_set(BUG_SAMSUNG
))
1058 fixsamsungselftestlog(data
);
1060 // swap endian order if needed
1063 swap2((char*)&(data
->revnumber
));
1064 for (i
=0; i
<21; i
++){
1065 struct ata_smart_selftestlog_struct
*x
=data
->selftest_struct
+i
;
1066 swap2((char *)&(x
->timestamp
));
1067 swap4((char *)&(x
->lbafirstfailure
));
1074 // Print checksum warning for multi sector log
1075 static void check_multi_sector_sum(const void * data
, unsigned nsectors
, const char * msg
)
1078 for (unsigned i
= 0; i
< nsectors
; i
++) {
1079 if (checksum((const unsigned char *)data
+ i
*512))
1084 checksumwarning(msg
);
1086 checksumwarning(strprintf("%s (%u/%u)", msg
, errs
, nsectors
).c_str());
1090 // Read SMART Extended Self-test Log
1091 bool ataReadExtSelfTestLog(ata_device
* device
, ata_smart_extselftestlog
* log
,
1094 if (!ataReadLogExt(device
, 0x07, 0x00, 0, log
, nsectors
))
1097 check_multi_sector_sum(log
, nsectors
, "SMART Extended Self-test Log Structure");
1099 if (isbigendian()) {
1100 swapx(&log
->log_desc_index
);
1101 for (unsigned i
= 0; i
< nsectors
; i
++) {
1102 for (unsigned j
= 0; j
< 19; j
++)
1103 swapx(&log
->log_descs
[i
].timestamp
);
1110 // Read GP Log page(s)
1111 bool ataReadLogExt(ata_device
* device
, unsigned char logaddr
,
1112 unsigned char features
, unsigned page
,
1113 void * data
, unsigned nsectors
)
1116 in
.in_regs
.command
= ATA_READ_LOG_EXT
;
1117 in
.in_regs
.features
= features
; // log specific
1118 in
.set_data_in_48bit(data
, nsectors
);
1119 in
.in_regs
.lba_low
= logaddr
;
1120 in
.in_regs
.lba_mid_16
= page
;
1122 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1123 if (nsectors
<= 1) {
1124 pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n",
1125 logaddr
, features
, page
, nsectors
, device
->get_errmsg());
1129 // Recurse to retry with single sectors,
1130 // multi-sector reads may not be supported by ioctl.
1131 for (unsigned i
= 0; i
< nsectors
; i
++) {
1132 if (!ataReadLogExt(device
, logaddr
,
1134 (char *)data
+ 512*i
, 1))
1142 // Read SMART Log page(s)
1143 bool ataReadSmartLog(ata_device
* device
, unsigned char logaddr
,
1144 void * data
, unsigned nsectors
)
1147 in
.in_regs
.command
= ATA_SMART_CMD
;
1148 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
1149 in
.set_data_in(data
, nsectors
);
1150 in
.in_regs
.lba_high
= SMART_CYL_HI
;
1151 in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
1152 in
.in_regs
.lba_low
= logaddr
;
1154 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1155 pout("ATA_SMART_READ_LOG failed: %s\n", device
->get_errmsg());
1163 // Reads the SMART or GPL Log Directory (log #0)
1164 int ataReadLogDirectory(ata_device
* device
, ata_smart_log_directory
* data
, bool gpl
)
1166 if (!gpl
) { // SMART Log directory
1167 if (smartcommandhandler(device
, READ_LOG
, 0x00, (char *)data
))
1170 else { // GP Log directory
1171 if (!ataReadLogExt(device
, 0x00, 0x00, 0, data
, 1))
1175 // swap endian order if needed
1177 swapx(&data
->logversion
);
1183 // Reads the selective self-test log (log #9)
1184 int ataReadSelectiveSelfTestLog(ata_device
* device
, struct ata_selective_self_test_log
*data
){
1186 // get data from device
1187 if (smartcommandhandler(device
, READ_LOG
, 0x09, (char *)data
)){
1191 // compute its checksum, and issue a warning if needed
1193 checksumwarning("SMART Selective Self-Test Log Structure");
1195 // swap endian order if needed
1198 swap2((char *)&(data
->logversion
));
1200 swap8((char *)&(data
->span
[i
].start
));
1201 swap8((char *)&(data
->span
[i
].end
));
1203 swap8((char *)&(data
->currentlba
));
1204 swap2((char *)&(data
->currentspan
));
1205 swap2((char *)&(data
->flags
));
1206 swap2((char *)&(data
->pendingtime
));
1212 // Writes the selective self-test log (log #9)
1213 int ataWriteSelectiveSelfTestLog(ata_device
* device
, ata_selective_selftest_args
& args
,
1214 const ata_smart_values
* sv
, uint64_t num_sectors
,
1215 const ata_selective_selftest_args
* prev_args
)
1217 // Disk size must be known
1219 pout("Disk size is unknown, unable to check selective self-test spans\n");
1224 struct ata_selective_self_test_log sstlog
, *data
=&sstlog
;
1225 unsigned char *ptr
=(unsigned char *)data
;
1226 if (ataReadSelectiveSelfTestLog(device
, data
)) {
1227 pout("SMART Read Selective Self-test Log failed: %s\n", device
->get_errmsg());
1228 pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
1233 data
->logversion
= 1;
1235 // Host is NOT allowed to write selective self-test log if a selective
1236 // self-test is in progress.
1237 if (0<data
->currentspan
&& data
->currentspan
<6 && ((sv
->self_test_exec_status
)>>4)==15) {
1238 pout("SMART Selective or other Self-test in progress\n");
1242 // Set start/end values based on old spans for special -t select,... options
1244 for (i
= 0; i
< args
.num_spans
; i
++) {
1245 int mode
= args
.span
[i
].mode
;
1246 uint64_t start
= args
.span
[i
].start
;
1247 uint64_t end
= args
.span
[i
].end
;
1248 if (mode
== SEL_CONT
) {// redo or next dependig on last test status
1249 switch (sv
->self_test_exec_status
>> 4) {
1250 case 1: case 2: // Aborted/Interrupted by host
1251 pout("Continue Selective Self-Test: Redo last span\n");
1254 default: // All others
1255 pout("Continue Selective Self-Test: Start next span\n");
1261 if ( (mode
== SEL_REDO
|| mode
== SEL_NEXT
)
1262 && prev_args
&& i
< prev_args
->num_spans
1263 && !data
->span
[i
].start
&& !data
->span
[i
].end
) {
1264 // Some drives do not preserve the selective self-test log accross
1265 // power-cyles. If old span on drive is cleared use span provided
1266 // by caller. This is used by smartd (first span only).
1267 data
->span
[i
].start
= prev_args
->span
[i
].start
;
1268 data
->span
[i
].end
= prev_args
->span
[i
].end
;
1272 case SEL_RANGE
: // -t select,START-END
1274 case SEL_REDO
: // -t select,redo... => Redo current
1275 start
= data
->span
[i
].start
;
1276 if (end
> 0) { // -t select,redo+SIZE
1277 end
--; end
+= start
; // [oldstart, oldstart+SIZE)
1279 else // -t select,redo
1280 end
= data
->span
[i
].end
; // [oldstart, oldend]
1282 case SEL_NEXT
: // -t select,next... => Do next
1283 if (data
->span
[i
].end
== 0) {
1284 start
= end
= 0; break; // skip empty spans
1286 start
= data
->span
[i
].end
+ 1;
1287 if (start
>= num_sectors
)
1288 start
= 0; // wrap around
1289 if (end
> 0) { // -t select,next+SIZE
1290 end
--; end
+= start
; // (oldend, oldend+SIZE]
1292 else { // -t select,next
1293 uint64_t oldsize
= data
->span
[i
].end
- data
->span
[i
].start
+ 1;
1294 end
= start
+ oldsize
- 1; // (oldend, oldend+oldsize]
1295 if (end
>= num_sectors
) {
1296 // Adjust size to allow round-robin testing without future size decrease
1297 uint64_t spans
= (num_sectors
+ oldsize
-1) / oldsize
;
1298 uint64_t newsize
= (num_sectors
+ spans
-1) / spans
;
1299 uint64_t newstart
= num_sectors
- newsize
, newend
= num_sectors
- 1;
1300 pout("Span %d changed from %" PRIu64
"-%" PRIu64
" (%" PRIu64
" sectors)\n",
1301 i
, start
, end
, oldsize
);
1302 pout(" to %" PRIu64
"-%" PRIu64
" (%" PRIu64
" sectors) (%" PRIu64
" spans)\n",
1303 newstart
, newend
, newsize
, spans
);
1304 start
= newstart
; end
= newend
;
1309 pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode
);
1313 if (start
< num_sectors
&& num_sectors
<= end
) {
1314 if (end
!= ~(uint64_t)0) // -t select,N-max
1315 pout("Size of self-test span %d decreased according to disk size\n", i
);
1316 end
= num_sectors
- 1;
1318 if (!(start
<= end
&& end
< num_sectors
)) {
1319 pout("Invalid selective self-test span %d: %" PRIu64
"-%" PRIu64
" (%" PRIu64
" sectors)\n",
1320 i
, start
, end
, num_sectors
);
1323 // Return the actual mode and range to caller.
1324 args
.span
[i
].mode
= mode
;
1325 args
.span
[i
].start
= start
;
1326 args
.span
[i
].end
= end
;
1331 memset(data
->span
+i
, 0, sizeof(struct test_span
));
1333 // Set spans for testing
1334 for (i
= 0; i
< args
.num_spans
; i
++){
1335 data
->span
[i
].start
= args
.span
[i
].start
;
1336 data
->span
[i
].end
= args
.span
[i
].end
;
1339 // host must initialize to zero before initiating selective self-test
1341 data
->currentspan
=0;
1343 // Perform off-line scan after selective test?
1344 if (args
.scan_after_select
== 1)
1346 data
->flags
&= ~SELECTIVE_FLAG_DOSCAN
;
1347 else if (args
.scan_after_select
== 2)
1349 data
->flags
|= SELECTIVE_FLAG_DOSCAN
;
1351 // Must clear active and pending flags before writing
1352 data
->flags
&= ~(SELECTIVE_FLAG_ACTIVE
);
1353 data
->flags
&= ~(SELECTIVE_FLAG_PENDING
);
1355 // modify pending time?
1356 if (args
.pending_time
)
1357 data
->pendingtime
= (unsigned short)(args
.pending_time
-1);
1359 // Set checksum to zero, then compute checksum
1361 unsigned char cksum
=0;
1362 for (i
=0; i
<512; i
++)
1366 data
->checksum
=cksum
;
1368 // swap endian order if needed
1370 swap2((char *)&(data
->logversion
));
1371 for (int b
= 0; b
< 5; b
++) {
1372 swap8((char *)&(data
->span
[b
].start
));
1373 swap8((char *)&(data
->span
[b
].end
));
1375 swap8((char *)&(data
->currentlba
));
1376 swap2((char *)&(data
->currentspan
));
1377 swap2((char *)&(data
->flags
));
1378 swap2((char *)&(data
->pendingtime
));
1381 // write new selective self-test log
1382 if (smartcommandhandler(device
, WRITE_LOG
, 0x09, (char *)data
)){
1383 pout("Write Selective Self-test Log failed: %s\n", device
->get_errmsg());
1390 // This corrects some quantities that are byte reversed in the SMART
1392 static void fixsamsungerrorlog(ata_smart_errorlog
* data
)
1394 // FIXED IN SAMSUNG -25 FIRMWARE???
1395 // Device error count in bytes 452-3
1396 swap2((char *)&(data
->ata_error_count
));
1398 // FIXED IN SAMSUNG -22a FIRMWARE
1399 // step through 5 error log data structures
1400 for (int i
= 0; i
< 5; i
++){
1401 // step through 5 command data structures
1402 for (int j
= 0; j
< 5; j
++)
1403 // Command data structure 4-byte millisec timestamp. These are
1404 // bytes (N+8, N+9, N+10, N+11).
1405 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1406 // Error data structure two-byte hour life timestamp. These are
1407 // bytes (N+28, N+29).
1408 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1413 // NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
1414 static void fixsamsungerrorlog2(ata_smart_errorlog
* data
)
1416 // Device error count in bytes 452-3
1417 swap2((char *)&(data
->ata_error_count
));
1421 // Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1422 // Error Log is #2, and the Extended Comprehensive SMART Error log is
1424 int ataReadErrorLog (ata_device
* device
, ata_smart_errorlog
*data
,
1425 firmwarebug_defs firmwarebugs
)
1428 // get data from device
1429 if (smartcommandhandler(device
, READ_LOG
, 0x01, (char *)data
)){
1433 // compute its checksum, and issue a warning if needed
1435 checksumwarning("SMART ATA Error Log Structure");
1437 // Some disks have the byte order reversed in some SMART Summary
1438 // Error log entries
1439 if (firmwarebugs
.is_set(BUG_SAMSUNG
))
1440 fixsamsungerrorlog(data
);
1441 else if (firmwarebugs
.is_set(BUG_SAMSUNG2
))
1442 fixsamsungerrorlog2(data
);
1444 // swap endian order if needed
1448 // Device error count in bytes 452-3
1449 swap2((char *)&(data
->ata_error_count
));
1451 // step through 5 error log data structures
1452 for (i
=0; i
<5; i
++){
1453 // step through 5 command data structures
1455 // Command data structure 4-byte millisec timestamp
1456 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1457 // Error data structure life timestamp
1458 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1466 // Fix LBA byte ordering of Extended Comprehensive Error Log
1467 // if little endian instead of ATA register ordering is provided
1469 static inline void fix_exterrlog_lba_cmd(T
& cmd
)
1472 cmd
.lba_mid_register_hi
= org
.lba_high_register
;
1473 cmd
.lba_low_register_hi
= org
.lba_mid_register_hi
;
1474 cmd
.lba_high_register
= org
.lba_mid_register
;
1475 cmd
.lba_mid_register
= org
.lba_low_register_hi
;
1478 static void fix_exterrlog_lba(ata_smart_exterrlog
* log
, unsigned nsectors
)
1480 for (unsigned i
= 0; i
< nsectors
; i
++) {
1481 for (int ei
= 0; ei
< 4; ei
++) {
1482 ata_smart_exterrlog_error_log
& entry
= log
[i
].error_logs
[ei
];
1483 fix_exterrlog_lba_cmd(entry
.error
);
1484 for (int ci
= 0; ci
< 5; ci
++)
1485 fix_exterrlog_lba_cmd(entry
.commands
[ci
]);
1490 // Read Extended Comprehensive Error Log
1491 bool ataReadExtErrorLog(ata_device
* device
, ata_smart_exterrlog
* log
,
1492 unsigned page
, unsigned nsectors
, firmwarebug_defs firmwarebugs
)
1494 if (!ataReadLogExt(device
, 0x03, 0x00, page
, log
, nsectors
))
1497 check_multi_sector_sum(log
, nsectors
, "SMART Extended Comprehensive Error Log Structure");
1499 if (isbigendian()) {
1500 swapx(&log
->device_error_count
);
1501 swapx(&log
->error_log_index
);
1502 for (unsigned i
= 0; i
< nsectors
; i
++) {
1503 for (unsigned j
= 0; j
< 4; j
++) {
1504 for (unsigned k
= 0; k
< 5; k
++)
1505 swapx(&log
[i
].error_logs
[j
].commands
[k
].timestamp
);
1506 swapx(&log
[i
].error_logs
[j
].error
.timestamp
);
1511 if (firmwarebugs
.is_set(BUG_XERRORLBA
))
1512 fix_exterrlog_lba(log
, nsectors
);
1518 int ataReadSmartThresholds (ata_device
* device
, struct ata_smart_thresholds_pvt
*data
){
1520 // get data from device
1521 if (smartcommandhandler(device
, READ_THRESHOLDS
, 0, (char *)data
)){
1525 // compute its checksum, and issue a warning if needed
1527 checksumwarning("SMART Attribute Thresholds Structure");
1529 // swap endian order if needed
1531 swap2((char *)&(data
->revnumber
));
1536 int ataEnableSmart (ata_device
* device
){
1537 if (smartcommandhandler(device
, ENABLE
, 0, NULL
)){
1543 int ataDisableSmart (ata_device
* device
){
1545 if (smartcommandhandler(device
, DISABLE
, 0, NULL
)){
1551 int ataEnableAutoSave(ata_device
* device
){
1552 if (smartcommandhandler(device
, AUTOSAVE
, 241, NULL
)){
1558 int ataDisableAutoSave(ata_device
* device
){
1560 if (smartcommandhandler(device
, AUTOSAVE
, 0, NULL
)){
1566 // In *ALL* ATA standards the Enable/Disable AutoOffline command is
1567 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1568 // vendors still support it for backwards compatibility. IBM documents
1569 // it for some drives.
1570 int ataEnableAutoOffline (ata_device
* device
){
1572 /* timer hard coded to 4 hours */
1573 if (smartcommandhandler(device
, AUTO_OFFLINE
, 248, NULL
)){
1579 // Another Obsolete Command. See comments directly above, associated
1580 // with the corresponding Enable command.
1581 int ataDisableAutoOffline (ata_device
* device
){
1583 if (smartcommandhandler(device
, AUTO_OFFLINE
, 0, NULL
)){
1589 // If SMART is enabled, supported, and working, then this call is
1590 // guaranteed to return 1, else zero. Note that it should return 1
1591 // regardless of whether the disk's SMART status is 'healthy' or
1593 int ataDoesSmartWork(ata_device
* device
){
1594 int retval
=smartcommandhandler(device
, STATUS
, 0, NULL
);
1602 // This function uses a different interface (DRIVE_TASK) than the
1603 // other commands in this file.
1604 int ataSmartStatus2(ata_device
* device
){
1605 return smartcommandhandler(device
, STATUS_CHECK
, 0, NULL
);
1608 // This is the way to execute ALL tests: offline, short self-test,
1609 // extended self test, with and without captive mode, etc.
1610 // TODO: Move to ataprint.cpp ?
1611 int ataSmartTest(ata_device
* device
, int testtype
, bool force
,
1612 const ata_selective_selftest_args
& selargs
,
1613 const ata_smart_values
* sv
, uint64_t num_sectors
)
1615 char cmdmsg
[128]; const char *type
, *captive
;
1616 int cap
, retval
, select
=0;
1618 // Boolean, if set, says test is captive
1619 cap
=testtype
& CAPTIVE_MASK
;
1621 // Set up strings that describe the type of test
1627 if (testtype
==OFFLINE_FULL_SCAN
)
1629 else if (testtype
==SHORT_SELF_TEST
|| testtype
==SHORT_CAPTIVE_SELF_TEST
)
1630 type
="Short self-test";
1631 else if (testtype
==EXTEND_SELF_TEST
|| testtype
==EXTEND_CAPTIVE_SELF_TEST
)
1632 type
="Extended self-test";
1633 else if (testtype
==CONVEYANCE_SELF_TEST
|| testtype
==CONVEYANCE_CAPTIVE_SELF_TEST
)
1634 type
="Conveyance self-test";
1635 else if ((select
=(testtype
==SELECTIVE_SELF_TEST
|| testtype
==SELECTIVE_CAPTIVE_SELF_TEST
)))
1636 type
="Selective self-test";
1640 // Check whether another test is already running
1641 if (type
&& (sv
->self_test_exec_status
>> 4) == 0xf) {
1643 pout("Can't start self-test without aborting current test (%d0%% remaining),\n"
1644 "%srun 'smartctl -X' to abort test.\n",
1645 sv
->self_test_exec_status
& 0x0f,
1646 (!select
? "add '-t force' option to override, or " : ""));
1653 // If doing a selective self-test, first use WRITE_LOG to write the
1654 // selective self-test log.
1655 ata_selective_selftest_args selargs_io
= selargs
; // filled with info about actual spans
1656 if (select
&& (retval
= ataWriteSelectiveSelfTestLog(device
, selargs_io
, sv
, num_sectors
))) {
1658 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1662 // Print ouf message that we are sending the command to test
1663 if (testtype
==ABORT_SELF_TEST
)
1664 snprintf(cmdmsg
, sizeof(cmdmsg
), "Abort SMART off-line mode self-test routine");
1666 snprintf(cmdmsg
, sizeof(cmdmsg
), "SMART EXECUTE OFF-LINE IMMEDIATE subcommand 0x%02x", testtype
);
1668 snprintf(cmdmsg
, sizeof(cmdmsg
), "Execute SMART %s routine immediately in %s mode", type
, captive
);
1669 pout("Sending command: \"%s\".\n",cmdmsg
);
1673 pout("SPAN STARTING_LBA ENDING_LBA\n");
1674 for (i
= 0; i
< selargs_io
.num_spans
; i
++)
1675 pout(" %d %20" PRId64
" %20" PRId64
"\n", i
,
1676 selargs_io
.span
[i
].start
,
1677 selargs_io
.span
[i
].end
);
1680 // Now send the command to test
1681 if (smartcommandhandler(device
, IMMEDIATE_OFFLINE
, testtype
, NULL
)) {
1682 if (!(cap
&& device
->get_errno() == EIO
)) {
1683 pout("Command \"%s\" failed: %s\n", cmdmsg
, device
->get_errmsg());
1688 // Since the command succeeded, tell user
1689 if (testtype
==ABORT_SELF_TEST
)
1690 pout("Self-testing aborted!\n");
1692 pout("Drive command \"%s\" successful.\n", cmdmsg
);
1694 pout("Testing has begun%s.\n", (force
? " (previous test aborted)" : ""));
1699 /* Test Time Functions */
1700 int TestTime(const ata_smart_values
*data
, int testtype
)
1703 case OFFLINE_FULL_SCAN
:
1704 return (int) data
->total_time_to_complete_off_line
;
1705 case SHORT_SELF_TEST
:
1706 case SHORT_CAPTIVE_SELF_TEST
:
1707 return (int) data
->short_test_completion_time
;
1708 case EXTEND_SELF_TEST
:
1709 case EXTEND_CAPTIVE_SELF_TEST
:
1710 if (data
->extend_test_completion_time_b
== 0xff
1711 && data
->extend_test_completion_time_w
!= 0x0000
1712 && data
->extend_test_completion_time_w
!= 0xffff)
1713 return data
->extend_test_completion_time_w
; // ATA-8
1715 return data
->extend_test_completion_time_b
;
1716 case CONVEYANCE_SELF_TEST
:
1717 case CONVEYANCE_CAPTIVE_SELF_TEST
:
1718 return (int) data
->conveyance_test_completion_time
;
1724 // This function tells you both about the ATA error log and the
1725 // self-test error log capability (introduced in ATA-5). The bit is
1726 // poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1727 // SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1728 // word 84 and 87. Top two bits must match the pattern 01. BEFORE
1729 // ATA-6 these top two bits still had to match the pattern 01, but the
1730 // remaining bits were reserved (==0).
1731 int isSmartErrorLogCapable (const ata_smart_values
* data
, const ata_identify_device
* identity
)
1733 unsigned short word84
=identity
->command_set_extension
;
1734 unsigned short word87
=identity
->csf_default
;
1735 int isata6
=identity
->major_rev_num
& (0x01<<6);
1736 int isata7
=identity
->major_rev_num
& (0x01<<7);
1738 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x01))
1741 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x01))
1744 // otherwise we'll use the poorly documented capability bit
1745 return data
->errorlog_capability
& 0x01;
1748 // See previous function. If the error log exists then the self-test
1749 // log should (must?) also exist.
1750 int isSmartTestLogCapable (const ata_smart_values
* data
, const ata_identify_device
*identity
)
1752 unsigned short word84
=identity
->command_set_extension
;
1753 unsigned short word87
=identity
->csf_default
;
1754 int isata6
=identity
->major_rev_num
& (0x01<<6);
1755 int isata7
=identity
->major_rev_num
& (0x01<<7);
1757 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x02))
1760 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x02))
1764 // otherwise we'll use the poorly documented capability bit
1765 return data
->errorlog_capability
& 0x01;
1769 int isGeneralPurposeLoggingCapable(const ata_identify_device
*identity
)
1771 unsigned short word84
=identity
->command_set_extension
;
1772 unsigned short word87
=identity
->csf_default
;
1774 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1775 // cleared to zero, the contents of word 84 contains valid support
1776 // information. If not, support information is not valid in this
1778 if ((word84
>>14) == 0x01)
1779 // If bit 5 of word 84 is set to one, the device supports the
1780 // General Purpose Logging feature set.
1781 return (word84
& (0x01 << 5));
1783 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1784 // cleared to zero, the contents of words (87:85) contain valid
1785 // information. If not, information is not valid in these words.
1786 if ((word87
>>14) == 0x01)
1787 // If bit 5 of word 87 is set to one, the device supports
1788 // the General Purpose Logging feature set.
1789 return (word87
& (0x01 << 5));
1796 // SMART self-test capability is also indicated in bit 1 of DEVICE
1797 // IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1798 // However this was only introduced in ATA-6 (but self-test log was in
1800 int isSupportExecuteOfflineImmediate(const ata_smart_values
*data
)
1802 return data
->offline_data_collection_capability
& 0x01;
1805 // Note in the ATA-5 standard, the following bit is listed as "Vendor
1806 // Specific". So it may not be reliable. The only use of this that I
1807 // have found is in IBM drives, where it is well-documented. See for
1808 // example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1809 // hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
1810 int isSupportAutomaticTimer(const ata_smart_values
* data
)
1812 return data
->offline_data_collection_capability
& 0x02;
1814 int isSupportOfflineAbort(const ata_smart_values
*data
)
1816 return data
->offline_data_collection_capability
& 0x04;
1818 int isSupportOfflineSurfaceScan(const ata_smart_values
* data
)
1820 return data
->offline_data_collection_capability
& 0x08;
1822 int isSupportSelfTest (const ata_smart_values
* data
)
1824 return data
->offline_data_collection_capability
& 0x10;
1826 int isSupportConveyanceSelfTest(const ata_smart_values
* data
)
1828 return data
->offline_data_collection_capability
& 0x20;
1830 int isSupportSelectiveSelfTest(const ata_smart_values
* data
)
1832 return data
->offline_data_collection_capability
& 0x40;
1835 // Get attribute state
1836 ata_attr_state
ata_get_attr_state(const ata_smart_attribute
& attr
,
1838 const ata_smart_threshold_entry
* thresholds
,
1839 const ata_vendor_attr_defs
& defs
,
1840 unsigned char * threshval
/* = 0 */)
1843 return ATTRSTATE_NON_EXISTING
;
1845 // Normalized values (current,worst,threshold) not valid
1846 // if specified by '-v' option.
1847 // (Some SSD disks uses these bytes to store raw value).
1848 if (defs
[attr
.id
].flags
& ATTRFLAG_NO_NORMVAL
)
1849 return ATTRSTATE_NO_NORMVAL
;
1851 // Normally threshold is at same index as attribute
1853 if (thresholds
[i
].id
!= attr
.id
) {
1854 // Find threshold id in table
1855 for (i
= 0; thresholds
[i
].id
!= attr
.id
; ) {
1856 if (++i
>= NUMBER_ATA_SMART_ATTRIBUTES
)
1857 // Threshold id missing or thresholds cannot be read
1858 return ATTRSTATE_NO_THRESHOLD
;
1861 unsigned char threshold
= thresholds
[i
].threshold
;
1863 // Return threshold if requested
1865 *threshval
= threshold
;
1867 // Don't report a failed attribute if its threshold is 0.
1868 // ATA-3 (X3T13/2008D Revision 7b) declares 0x00 as the "always passing"
1869 // threshold (Later ATA versions declare all thresholds as "obsolete").
1870 // In practice, threshold value 0 is often used for usage attributes.
1872 return ATTRSTATE_OK
;
1874 // Failed now if current value is below threshold
1875 if (attr
.current
<= threshold
)
1876 return ATTRSTATE_FAILED_NOW
;
1878 // Failed in the past if worst value is below threshold
1879 if (!(defs
[attr
.id
].flags
& ATTRFLAG_NO_WORSTVAL
) && attr
.worst
<= threshold
)
1880 return ATTRSTATE_FAILED_PAST
;
1882 return ATTRSTATE_OK
;
1885 // Get attribute raw value.
1886 uint64_t ata_get_attr_raw_value(const ata_smart_attribute
& attr
,
1887 const ata_vendor_attr_defs
& defs
)
1889 const ata_vendor_attr_defs::entry
& def
= defs
[attr
.id
];
1890 // TODO: Allow Byteorder in DEFAULT entry
1892 // Use default byteorder if not specified
1893 const char * byteorder
= def
.byteorder
;
1895 switch (def
.raw_format
) {
1898 byteorder
= "543210wv"; break;
1901 case RAWFMT_RAW24_DIV_RAW32
:
1902 case RAWFMT_MSEC24_HOUR32
:
1903 byteorder
= "r543210"; break;
1905 byteorder
= "543210"; break;
1909 // Build 64-bit value from selected bytes
1910 uint64_t rawvalue
= 0;
1911 for (int i
= 0; byteorder
[i
]; i
++) {
1913 switch (byteorder
[i
]) {
1914 case '0': b
= attr
.raw
[0]; break;
1915 case '1': b
= attr
.raw
[1]; break;
1916 case '2': b
= attr
.raw
[2]; break;
1917 case '3': b
= attr
.raw
[3]; break;
1918 case '4': b
= attr
.raw
[4]; break;
1919 case '5': b
= attr
.raw
[5]; break;
1920 case 'r': b
= attr
.reserv
; break;
1921 case 'v': b
= attr
.current
; break;
1922 case 'w': b
= attr
.worst
; break;
1923 default : b
= 0; break;
1925 rawvalue
<<= 8; rawvalue
|= b
;
1931 // Helper functions for RAWFMT_TEMPMINMAX
1932 static inline int check_temp_word(unsigned word
)
1935 return 0x11; // >= 0, signed byte or word
1937 return 0x01; // < 0, signed byte
1939 return 0x10; // < 0, signed word
1943 static bool check_temp_range(int t
, unsigned char ut1
, unsigned char ut2
,
1946 int t1
= (signed char)ut1
, t2
= (signed char)ut2
;
1948 int tx
= t1
; t1
= t2
; t2
= tx
;
1951 if ( -60 <= t1
&& t1
<= t
&& t
<= t2
&& t2
<= 120
1952 && !(t1
== -1 && t2
<= 0) ) {
1959 // Format attribute raw value.
1960 std::string
ata_format_attr_raw_value(const ata_smart_attribute
& attr
,
1961 const ata_vendor_attr_defs
& defs
)
1963 // Get 48 bit or 64 bit raw value
1964 uint64_t rawvalue
= ata_get_attr_raw_value(attr
, defs
);
1966 // Split into bytes and words
1967 unsigned char raw
[6];
1968 raw
[0] = (unsigned char) rawvalue
;
1969 raw
[1] = (unsigned char)(rawvalue
>> 8);
1970 raw
[2] = (unsigned char)(rawvalue
>> 16);
1971 raw
[3] = (unsigned char)(rawvalue
>> 24);
1972 raw
[4] = (unsigned char)(rawvalue
>> 32);
1973 raw
[5] = (unsigned char)(rawvalue
>> 40);
1975 word
[0] = raw
[0] | (raw
[1] << 8);
1976 word
[1] = raw
[2] | (raw
[3] << 8);
1977 word
[2] = raw
[4] | (raw
[5] << 8);
1980 ata_attr_raw_format format
= defs
[attr
.id
].raw_format
;
1981 if (format
== RAWFMT_DEFAULT
) {
1982 // Get format from DEFAULT entry
1983 format
= get_default_attr_defs()[attr
.id
].raw_format
;
1984 if (format
== RAWFMT_DEFAULT
)
1985 // Unknown Attribute
1986 format
= RAWFMT_RAW48
;
1993 s
= strprintf("%d %d %d %d %d %d",
1994 raw
[5], raw
[4], raw
[3], raw
[2], raw
[1], raw
[0]);
1998 s
= strprintf("%u %u %u", word
[2], word
[1], word
[0]);
2004 s
= strprintf("%" PRIu64
, rawvalue
);
2008 s
= strprintf("0x%012" PRIx64
, rawvalue
);
2012 s
= strprintf("0x%014" PRIx64
, rawvalue
);
2016 s
= strprintf("0x%016" PRIx64
, rawvalue
);
2019 case RAWFMT_RAW16_OPT_RAW16
:
2020 s
= strprintf("%u", word
[0]);
2021 if (word
[1] || word
[2])
2022 s
+= strprintf(" (%u %u)", word
[2], word
[1]);
2025 case RAWFMT_RAW16_OPT_AVG16
:
2026 s
= strprintf("%u", word
[0]);
2028 s
+= strprintf(" (Average %u)", word
[1]);
2031 case RAWFMT_RAW24_OPT_RAW8
:
2032 s
= strprintf("%u", (unsigned)(rawvalue
& 0x00ffffffULL
));
2033 if (raw
[3] || raw
[4] || raw
[5])
2034 s
+= strprintf(" (%d %d %d)", raw
[5], raw
[4], raw
[3]);
2037 case RAWFMT_RAW24_DIV_RAW24
:
2038 s
= strprintf("%u/%u",
2039 (unsigned)(rawvalue
>> 24), (unsigned)(rawvalue
& 0x00ffffffULL
));
2042 case RAWFMT_RAW24_DIV_RAW32
:
2043 s
= strprintf("%u/%u",
2044 (unsigned)(rawvalue
>> 32), (unsigned)(rawvalue
& 0xffffffffULL
));
2047 case RAWFMT_MIN2HOUR
:
2050 int64_t temp
= word
[0]+(word
[1]<<16);
2051 int64_t tmp1
= temp
/60;
2052 int64_t tmp2
= temp
%60;
2053 s
= strprintf("%" PRIu64
"h+%02" PRIu64
"m", tmp1
, tmp2
);
2055 s
+= strprintf(" (%u)", word
[2]);
2059 case RAWFMT_SEC2HOUR
:
2062 int64_t hours
= rawvalue
/3600;
2063 int64_t minutes
= (rawvalue
-3600*hours
)/60;
2064 int64_t seconds
= rawvalue
%60;
2065 s
= strprintf("%" PRIu64
"h+%02" PRIu64
"m+%02" PRIu64
"s", hours
, minutes
, seconds
);
2069 case RAWFMT_HALFMIN2HOUR
:
2071 // 30-second counter
2072 int64_t hours
= rawvalue
/120;
2073 int64_t minutes
= (rawvalue
-120*hours
)/2;
2074 s
+= strprintf("%" PRIu64
"h+%02" PRIu64
"m", hours
, minutes
);
2078 case RAWFMT_MSEC24_HOUR32
:
2080 // hours + milliseconds
2081 unsigned hours
= (unsigned)(rawvalue
& 0xffffffffULL
);
2082 unsigned milliseconds
= (unsigned)(rawvalue
>> 32);
2083 unsigned seconds
= milliseconds
/ 1000;
2084 s
= strprintf("%uh+%02um+%02u.%03us",
2085 hours
, seconds
/ 60, seconds
% 60, milliseconds
% 1000);
2089 case RAWFMT_TEMPMINMAX
:
2092 // Search for possible min/max values
2093 // [5][4][3][2][1][0] raw[]
2094 // [ 2 ] [ 1 ] [ 0 ] word[]
2095 // xx HH xx LL xx TT (Hitachi/HGST)
2096 // xx LL xx HH xx TT (Kingston SSDs)
2097 // 00 00 HH LL xx TT (Maxtor, Samsung, Seagate, Toshiba)
2098 // 00 00 00 HH LL TT (WDC)
2099 // CC CC HH LL xx TT (WDC, CCCC=over temperature count)
2100 // (xx = 00/ff, possibly sign extension of lower byte)
2102 int t
= (signed char)raw
[0];
2106 int ctw0
= check_temp_word(word
[0]);
2108 if (!word
[1] && ctw0
)
2109 // 00 00 00 00 xx TT
2111 else if (ctw0
&& check_temp_range(t
, raw
[2], raw
[3], lo
, hi
))
2112 // 00 00 HL LH xx TT
2114 else if (!raw
[3] && check_temp_range(t
, raw
[1], raw
[2], lo
, hi
))
2115 // 00 00 00 HL LH TT
2121 if ( (ctw0
& check_temp_word(word
[1]) & check_temp_word(word
[2])) != 0x00
2122 && check_temp_range(t
, raw
[2], raw
[4], lo
, hi
) )
2123 // xx HL xx LH xx TT
2125 else if ( word
[2] < 0x7fff
2126 && check_temp_range(t
, raw
[2], raw
[3], lo
, hi
)
2128 // CC CC HL LH xx TT
2138 s
= strprintf("%d", t
);
2140 case 1: case 2: case 3:
2141 s
= strprintf("%d (Min/Max %d/%d)", t
, lo
, hi
);
2144 s
= strprintf("%d (Min/Max %d/%d #%d)", t
, lo
, hi
, word
[2]);
2147 s
= strprintf("%d (%d %d %d %d %d)", raw
[0], raw
[5], raw
[4], raw
[3], raw
[2], raw
[1]);
2153 case RAWFMT_TEMP10X
:
2154 // ten times temperature in Celsius
2155 s
= strprintf("%d.%d", word
[0]/10, word
[0]%10);
2159 s
= "?"; // Should not happen
2166 // Get attribute name
2167 std::string
ata_get_smart_attr_name(unsigned char id
, const ata_vendor_attr_defs
& defs
,
2170 if (!defs
[id
].name
.empty())
2171 return defs
[id
].name
;
2173 const ata_vendor_attr_defs::entry
& def
= get_default_attr_defs()[id
];
2174 if (def
.name
.empty())
2175 return "Unknown_Attribute";
2176 else if ((def
.flags
& ATTRFLAG_HDD_ONLY
) && rpm
== 1)
2177 return "Unknown_SSD_Attribute";
2178 else if ((def
.flags
& ATTRFLAG_SSD_ONLY
) && rpm
> 1)
2179 return "Unknown_HDD_Attribute";
2185 // Find attribute index for attribute id, -1 if not found.
2186 int ata_find_attr_index(unsigned char id
, const ata_smart_values
& smartval
)
2190 for (int i
= 0; i
< NUMBER_ATA_SMART_ATTRIBUTES
; i
++) {
2191 if (smartval
.vendor_attributes
[i
].id
== id
)
2197 // Return Temperature Attribute raw value selected according to possible
2198 // non-default interpretations. If the Attribute does not exist, return 0
2199 unsigned char ata_return_temperature_value(const ata_smart_values
* data
, const ata_vendor_attr_defs
& defs
)
2201 for (int i
= 0; i
< 4; i
++) {
2202 static const unsigned char ids
[4] = {194, 190, 9, 220};
2203 unsigned char id
= ids
[i
];
2204 const ata_attr_raw_format format
= defs
[id
].raw_format
;
2205 if (!( ((id
== 194 || id
== 190) && format
== RAWFMT_DEFAULT
)
2206 || format
== RAWFMT_TEMPMINMAX
|| format
== RAWFMT_TEMP10X
))
2208 int idx
= ata_find_attr_index(id
, *data
);
2211 uint64_t raw
= ata_get_attr_raw_value(data
->vendor_attributes
[idx
], defs
);
2213 // ignore possible min/max values in high words
2214 if (format
== RAWFMT_TEMP10X
) // -v N,temp10x
2215 temp
= ((unsigned short)raw
+ 5) / 10;
2217 temp
= (unsigned char)raw
;
2218 if (!(0 < temp
&& temp
< 128))
2222 // No valid attribute found
2228 int ataReadSCTStatus(ata_device
* device
, ata_sct_status_response
* sts
)
2230 // read SCT status via SMART log 0xe0
2231 memset(sts
, 0, sizeof(*sts
));
2232 if (smartcommandhandler(device
, READ_LOG
, 0xe0, (char *)sts
)){
2233 pout("Read SCT Status failed: %s\n", device
->get_errmsg());
2237 // swap endian order if needed
2239 swapx(&sts
->format_version
);
2240 swapx(&sts
->sct_version
);
2241 swapx(&sts
->sct_spec
);
2242 swapx(&sts
->ext_status_code
);
2243 swapx(&sts
->action_code
);
2244 swapx(&sts
->function_code
);
2245 swapx(&sts
->over_limit_count
);
2246 swapx(&sts
->under_limit_count
);
2247 swapx(&sts
->smart_status
);
2250 // Check format version
2251 if (!(sts
->format_version
== 2 || sts
->format_version
== 3)) {
2252 pout("Unknown SCT Status format version %u, should be 2 or 3.\n", sts
->format_version
);
2258 // Read SCT Temperature History Table
2259 int ataReadSCTTempHist(ata_device
* device
, ata_sct_temperature_history_table
* tmh
,
2260 ata_sct_status_response
* sts
)
2262 // Initial SCT status must be provided by caller
2264 // Do nothing if other SCT command is executing
2265 if (sts
->ext_status_code
== 0xffff) {
2266 pout("Another SCT command is executing, abort Read Data Table\n"
2267 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2268 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2272 ata_sct_data_table_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2273 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2274 cmd
.action_code
= 5; // Data table command
2275 cmd
.function_code
= 1; // Read table
2276 cmd
.table_id
= 2; // Temperature History Table
2278 // swap endian order if needed
2279 if (isbigendian()) {
2280 swapx(&cmd
.action_code
);
2281 swapx(&cmd
.function_code
);
2282 swapx(&cmd
.table_id
);
2285 // write command via SMART log page 0xe0
2286 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2287 pout("Write SCT Data Table failed: %s\n", device
->get_errmsg());
2291 // read SCT data via SMART log page 0xe1
2292 memset(tmh
, 0, sizeof(*tmh
));
2293 if (smartcommandhandler(device
, READ_LOG
, 0xe1, (char *)tmh
)){
2294 pout("Read SCT Data Table failed: %s\n", device
->get_errmsg());
2298 // re-read and check SCT status
2299 if (ataReadSCTStatus(device
, sts
))
2302 if (!(sts
->ext_status_code
== 0 && sts
->action_code
== 5 && sts
->function_code
== 1)) {
2303 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2304 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2308 // swap endian order if needed
2310 swapx(&tmh
->format_version
);
2311 swapx(&tmh
->sampling_period
);
2312 swapx(&tmh
->interval
);
2313 swapx(&tmh
->cb_index
);
2314 swapx(&tmh
->cb_size
);
2319 // Get/Set Write Cache Reordering
2320 int ataGetSetSCTWriteCacheReordering(ata_device
* device
, bool enable
, bool persistent
, bool set
)
2322 // Check initial status
2323 ata_sct_status_response sts
;
2324 if (ataReadSCTStatus(device
, &sts
))
2327 // Do nothing if other SCT command is executing
2328 if (sts
.ext_status_code
== 0xffff) {
2329 pout("Another SCT command is executing, abort Feature Control\n"
2330 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2331 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2335 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2336 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2337 cmd
.action_code
= 4; // Feature Control command
2338 cmd
.function_code
= (set
? 1 : 2); // 1=Set, 2=Get
2339 cmd
.feature_code
= 2; // Enable/Disable Write Cache Reordering
2340 cmd
.state
= (enable
? 1 : 2); // 1 enable, 2 disable
2341 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2343 // swap endian order if needed
2344 if (isbigendian()) {
2345 swapx(&cmd
.action_code
);
2346 swapx(&cmd
.function_code
);
2347 swapx(&cmd
.feature_code
);
2349 swapx(&cmd
.option_flags
);
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("Write SCT (%cet) Feature Control Command failed: %s\n",
2368 (!set
? 'G' : 'S'), device
->get_errmsg());
2371 int state
= out
.out_regs
.sector_count
| (out
.out_regs
.lba_low
<< 8);
2373 // re-read and check SCT status
2374 if (ataReadSCTStatus(device
, &sts
))
2377 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== (set
? 1 : 2))) {
2378 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2379 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2386 // Set SCT Temperature Logging Interval
2387 int ataSetSCTTempInterval(ata_device
* device
, unsigned interval
, bool persistent
)
2389 // Check initial status
2390 ata_sct_status_response sts
;
2391 if (ataReadSCTStatus(device
, &sts
))
2394 // Do nothing if other SCT command is executing
2395 if (sts
.ext_status_code
== 0xffff) {
2396 pout("Another SCT command is executing, abort Feature Control\n"
2397 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2398 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2402 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2403 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2404 cmd
.action_code
= 4; // Feature Control command
2405 cmd
.function_code
= 1; // Set state
2406 cmd
.feature_code
= 3; // Temperature logging interval
2407 cmd
.state
= interval
;
2408 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2410 // swap endian order if needed
2411 if (isbigendian()) {
2412 swapx(&cmd
.action_code
);
2413 swapx(&cmd
.function_code
);
2414 swapx(&cmd
.feature_code
);
2416 swapx(&cmd
.option_flags
);
2419 // write command via SMART log page 0xe0
2420 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2421 pout("Write SCT Feature Control Command failed: %s\n", device
->get_errmsg());
2425 // re-read and check SCT status
2426 if (ataReadSCTStatus(device
, &sts
))
2429 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== 1)) {
2430 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2431 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2437 // Get/Set SCT Error Recovery Control
2438 static int ataGetSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
,
2439 bool set
, unsigned short & time_limit
)
2441 // Check initial status
2442 ata_sct_status_response sts
;
2443 if (ataReadSCTStatus(device
, &sts
))
2446 // Do nothing if other SCT command is executing
2447 if (sts
.ext_status_code
== 0xffff) {
2448 pout("Another SCT command is executing, abort Error Recovery Control\n"
2449 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2450 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2454 ata_sct_error_recovery_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2455 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2456 cmd
.action_code
= 3; // Error Recovery Control command
2457 cmd
.function_code
= (set
? 1 : 2); // 1=Set timer, 2=Get timer
2458 cmd
.selection_code
= type
; // 1=Read timer, 2=Write timer
2460 cmd
.time_limit
= time_limit
;
2462 // swap endian order if needed
2463 if (isbigendian()) {
2464 swapx(&cmd
.action_code
);
2465 swapx(&cmd
.function_code
);
2466 swapx(&cmd
.selection_code
);
2467 swapx(&cmd
.time_limit
);
2470 // write command via SMART log page 0xe0
2471 // TODO: Debug output
2473 in
.in_regs
.command
= ATA_SMART_CMD
;
2474 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
2475 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
2476 in
.in_regs
.lba_low
= 0xe0;
2477 in
.set_data_out(&cmd
, 1);
2480 // Time limit returned in ATA registers
2481 in
.out_needed
.sector_count
= in
.out_needed
.lba_low
= true;
2484 if (!device
->ata_pass_through(in
, out
)) {
2485 pout("Write SCT (%cet) Error Recovery Control Command failed: %s\n",
2486 (!set
? 'G' : 'S'), device
->get_errmsg());
2490 // re-read and check SCT status
2491 if (ataReadSCTStatus(device
, &sts
))
2494 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 3 && sts
.function_code
== (set
? 1 : 2))) {
2495 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2496 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2501 // Check whether registers are properly returned by ioctl()
2502 if (!(out
.out_regs
.sector_count
.is_set() && out
.out_regs
.lba_low
.is_set())) {
2503 // TODO: Output register support should be checked within each ata_pass_through()
2504 // implementation before command is issued.
2505 pout("SMART WRITE LOG does not return COUNT and LBA_LOW register\n");
2508 if ( out
.out_regs
.sector_count
== in
.in_regs
.sector_count
2509 && out
.out_regs
.lba_low
== in
.in_regs
.lba_low
) {
2510 // 0xe001 (5734.5s) - this is most likely a broken ATA pass-through implementation
2511 pout("SMART WRITE LOG returns COUNT and LBA_LOW register unchanged\n");
2515 // Return value to caller
2516 time_limit
= out
.out_regs
.sector_count
| (out
.out_regs
.lba_low
<< 8);
2522 // Get SCT Error Recovery Control
2523 int ataGetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short & time_limit
)
2525 return ataGetSetSCTErrorRecoveryControltime(device
, type
, false/*get*/, time_limit
);
2528 // Set SCT Error Recovery Control
2529 int ataSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short time_limit
)
2531 return ataGetSetSCTErrorRecoveryControltime(device
, type
, true/*set*/, time_limit
);
2535 // Print one self-test log entry.
2537 // -1: self-test failed
2538 // 1: extended self-test completed without error
2540 int ataPrintSmartSelfTestEntry(unsigned testnum
, unsigned char test_type
,
2541 unsigned char test_status
,
2542 unsigned short timestamp
,
2543 uint64_t failing_lba
,
2544 bool print_error_only
, bool & print_header
)
2546 // Check status and type for return value
2548 switch (test_status
>> 4) {
2550 if ((test_type
& 0x0f) == 0x02)
2551 retval
= 1; // extended self-test completed without error
2556 retval
= -1; // self-test failed
2560 if (retval
>= 0 && print_error_only
)
2563 std::string msgtest
;
2564 switch (test_type
) {
2565 case 0x00: msgtest
= "Offline"; break;
2566 case 0x01: msgtest
= "Short offline"; break;
2567 case 0x02: msgtest
= "Extended offline"; break;
2568 case 0x03: msgtest
= "Conveyance offline"; break;
2569 case 0x04: msgtest
= "Selective offline"; break;
2570 case 0x7f: msgtest
= "Abort offline test"; break;
2571 case 0x81: msgtest
= "Short captive"; break;
2572 case 0x82: msgtest
= "Extended captive"; break;
2573 case 0x83: msgtest
= "Conveyance captive"; break;
2574 case 0x84: msgtest
= "Selective captive"; break;
2576 if ((0x40 <= test_type
&& test_type
<= 0x7e) || 0x90 <= test_type
)
2577 msgtest
= strprintf("Vendor (0x%02x)", test_type
);
2579 msgtest
= strprintf("Reserved (0x%02x)", test_type
);
2582 std::string msgstat
;
2583 switch (test_status
>> 4) {
2584 case 0x0: msgstat
= "Completed without error"; break;
2585 case 0x1: msgstat
= "Aborted by host"; break;
2586 case 0x2: msgstat
= "Interrupted (host reset)"; break;
2587 case 0x3: msgstat
= "Fatal or unknown error"; break;
2588 case 0x4: msgstat
= "Completed: unknown failure"; break;
2589 case 0x5: msgstat
= "Completed: electrical failure"; break;
2590 case 0x6: msgstat
= "Completed: servo/seek failure"; break;
2591 case 0x7: msgstat
= "Completed: read failure"; break;
2592 case 0x8: msgstat
= "Completed: handling damage??"; break;
2593 case 0xf: msgstat
= "Self-test routine in progress"; break;
2594 default: msgstat
= strprintf("Unknown status (0x%x)", test_status
>> 4);
2597 // Print header once
2599 print_header
= false;
2600 pout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2604 if (retval
< 0 && failing_lba
< 0xffffffffffffULL
)
2605 snprintf(msglba
, sizeof(msglba
), "%" PRIu64
, failing_lba
);
2607 msglba
[0] = '-'; msglba
[1] = 0;
2610 pout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum
,
2611 msgtest
.c_str(), msgstat
.c_str(), test_status
& 0x0f, timestamp
, msglba
);
2616 // Print Smart self-test log, used by smartctl and smartd.
2618 // bottom 8 bits: number of entries found where self-test showed an error
2619 // remaining bits: if nonzero, power on hours of last self-test where error was found
2620 int ataPrintSmartSelfTestlog(const ata_smart_selftestlog
* data
, bool allentries
,
2621 firmwarebug_defs firmwarebugs
)
2624 pout("SMART Self-test log structure revision number %d\n",(int)data
->revnumber
);
2625 if (data
->revnumber
!= 0x0001 && allentries
&& !firmwarebugs
.is_set(BUG_SAMSUNG
))
2626 pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2627 if (data
->mostrecenttest
==0){
2629 pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n");
2633 bool noheaderprinted
= true;
2634 int errcnt
= 0, hours
= 0, igncnt
= 0;
2635 int testno
= 0, ext_ok_testno
= -1;
2638 for (int i
= 20; i
>= 0; i
--) {
2639 // log is a circular buffer
2640 int j
= (i
+data
->mostrecenttest
)%21;
2641 const ata_smart_selftestlog_struct
* log
= data
->selftest_struct
+j
;
2643 if (nonempty(log
, sizeof(*log
))) {
2644 // count entry based on non-empty structures -- needed for
2645 // Seagate only -- other vendors don't have blank entries 'in
2649 // T13/1321D revision 1c: (Data structure Rev #1)
2651 //The failing LBA shall be the LBA of the uncorrectable sector
2652 //that caused the test to fail. If the device encountered more
2653 //than one uncorrectable sector during the test, this field
2654 //shall indicate the LBA of the first uncorrectable sector
2655 //encountered. If the test passed or the test failed for some
2656 //reason other than an uncorrectable sector, the value of this
2657 //field is undefined.
2659 // This is true in ALL ATA-5 specs
2660 uint64_t lba48
= (log
->lbafirstfailure
< 0xffffffff ? log
->lbafirstfailure
: 0xffffffffffffULL
);
2663 int state
= ataPrintSmartSelfTestEntry(testno
,
2664 log
->selftestnumber
, log
->selfteststatus
,
2665 log
->timestamp
, lba48
, !allentries
, noheaderprinted
);
2668 // Self-test showed an error
2669 if (ext_ok_testno
< 0) {
2672 // keep track of time of most recent error
2674 hours
= log
->timestamp
;
2677 // Newer successful extended self-test exits
2680 else if (state
> 0 && ext_ok_testno
< 0) {
2681 // Latest successful extended self-test
2682 ext_ok_testno
= testno
;
2688 pout("%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2689 igncnt
, igncnt
+errcnt
, ext_ok_testno
);
2691 if (!allentries
&& !noheaderprinted
)
2694 return ((hours
<< 8) | errcnt
);
2698 /////////////////////////////////////////////////////////////////////////////
2699 // Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2700 // an ATA device with same behaviour
2704 class parsed_ata_device
2705 : public /*implements*/ ata_device_with_command_set
2708 parsed_ata_device(smart_interface
* intf
, const char * dev_name
);
2710 virtual ~parsed_ata_device() throw();
2712 virtual bool is_open() const;
2714 virtual bool open();
2716 virtual bool close();
2718 virtual bool ata_identify_is_cached() const;
2721 virtual int ata_command_interface(smart_command_set command
, int select
, char * data
);
2724 // Table of parsed commands, return value, data
2725 struct parsed_ata_command
2727 smart_command_set command
;
2733 enum { max_num_commands
= 32 };
2734 parsed_ata_command m_command_table
[max_num_commands
];
2737 int m_next_replay_command
;
2738 bool m_replay_out_of_sync
;
2739 bool m_ata_identify_is_cached
;
2742 static const char * nextline(const char * s
, int & lineno
)
2744 for (s
+= strcspn(s
, "\r\n"); *s
== '\r' || *s
== '\n'; s
++) {
2745 if (*s
== '\r' && s
[1] == '\n')
2752 static int name2command(const char * s
)
2754 for (int i
= 0; i
< (int)(sizeof(commandstrings
)/sizeof(commandstrings
[0])); i
++) {
2755 if (!strcmp(s
, commandstrings
[i
]))
2761 static bool matchcpy(char * dest
, size_t size
, const char * src
, const regmatch_t
& srcmatch
)
2763 if (srcmatch
.rm_so
< 0)
2765 size_t n
= srcmatch
.rm_eo
- srcmatch
.rm_so
;
2768 memcpy(dest
, src
+ srcmatch
.rm_so
, n
);
2773 static inline int matchtoi(const char * src
, const regmatch_t
& srcmatch
, int defval
)
2775 if (srcmatch
.rm_so
< 0)
2777 return atoi(src
+ srcmatch
.rm_so
);
2780 parsed_ata_device::parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2781 : smart_device(intf
, dev_name
, "ata", ""),
2783 m_next_replay_command(0),
2784 m_replay_out_of_sync(false),
2785 m_ata_identify_is_cached(false)
2787 memset(m_command_table
, 0, sizeof(m_command_table
));
2790 parsed_ata_device::~parsed_ata_device() throw()
2795 bool parsed_ata_device::is_open() const
2797 return (m_num_commands
> 0);
2800 // Parse stdin and build command table
2801 bool parsed_ata_device::open()
2803 const char * pathname
= get_dev_name();
2804 if (strcmp(pathname
, "-"))
2805 return set_err(EINVAL
);
2806 pathname
= "<stdin>";
2808 char buffer
[64*1024];
2810 while (size
< (int)sizeof(buffer
)) {
2811 int nr
= fread(buffer
, 1, sizeof(buffer
), stdin
);
2817 return set_err(ENOENT
, "%s: Unexpected EOF", pathname
);
2818 if (size
>= (int)sizeof(buffer
))
2819 return set_err(EIO
, "%s: Buffer overflow", pathname
);
2822 // Regex to match output from "-r ataioctl,2"
2823 static const char pattern
[] = "^"
2825 "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
2827 "( InputParameter=([0-9]+))?" // (4 (5))
2829 "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2831 "[\r\n]" // EOL match necessary to match optional parts above
2833 "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2835 " *(En|Dis)abled status cached by OS, " // (11)
2839 const regular_expression
regex(pattern
, REG_EXTENDED
);
2842 const char * errmsg
= 0;
2843 int i
= -1, state
= 0, lineno
= 1;
2844 for (const char * line
= buffer
; *line
; line
= nextline(line
, lineno
)) {
2846 if (!(line
[0] == 'R' || line
[0] == '=' || line
[0] == ' '))
2848 const int nmatch
= 1+11;
2849 regmatch_t match
[nmatch
];
2850 if (!regex
.execute(line
, nmatch
, match
))
2854 if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[2])) { // "REPORT-IOCTL:... Command=%s ..."
2855 int nc
= name2command(cmdname
);
2857 errmsg
= "Unknown ATA command name"; break;
2859 if (match
[7].rm_so
< 0) { // "returned %d"
2861 if (!(state
== 0 || state
== 2)) {
2862 errmsg
= "Missing REPORT-IOCTL result"; break;
2864 if (++i
>= max_num_commands
) {
2865 errmsg
= "Too many ATA commands"; break;
2867 m_command_table
[i
].command
= (smart_command_set
)nc
;
2868 m_command_table
[i
].select
= matchtoi(line
, match
[5], 0); // "InputParameter=%d"
2873 if (!(state
== 1 && (int)m_command_table
[i
].command
== nc
)) {
2874 errmsg
= "Missing REPORT-IOCTL start"; break;
2876 m_command_table
[i
].retval
= matchtoi(line
, match
[7], -1); // "returned %d"
2877 m_command_table
[i
].errval
= matchtoi(line
, match
[9], 0); // "errno=%d"
2881 else if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[10])) { // "===== [%s] DATA START "
2882 // Start of sector hexdump
2883 int nc
= name2command(cmdname
);
2884 if (!(state
== (nc
== WRITE_LOG
? 1 : 2) && (int)m_command_table
[i
].command
== nc
)) {
2885 errmsg
= "Unexpected DATA START"; break;
2887 line
= nextline(line
, lineno
);
2888 char * data
= (char *)malloc(512);
2890 for (j
= 0; j
< 32; j
++) {
2892 unsigned u1
, u2
; int n1
= -1;
2893 if (!(sscanf(line
, "%3u-%3u: "
2894 "%2x %2x %2x %2x %2x %2x %2x %2x "
2895 "%2x %2x %2x %2x %2x %2x %2x %2x%n",
2897 b
+ 0, b
+ 1, b
+ 2, b
+ 3, b
+ 4, b
+ 5, b
+ 6, b
+ 7,
2898 b
+ 8, b
+ 9, b
+10, b
+11, b
+12, b
+13, b
+14, b
+15, &n1
) == 18
2899 && n1
>= 56 && u1
== j
*16 && u2
== j
*16+15))
2901 for (unsigned k
= 0; k
< 16; k
++)
2902 data
[j
*16+k
] = b
[k
];
2903 line
= nextline(line
, lineno
);
2907 errmsg
= "Incomplete sector hex dump"; break;
2909 m_command_table
[i
].data
= data
;
2910 if (nc
!= WRITE_LOG
)
2913 else if (match
[11].rm_so
> 0) { // "(En|Dis)abled status cached by OS"
2914 m_ata_identify_is_cached
= true;
2918 if (!(state
== 0 || state
== 2))
2919 errmsg
= "Missing REPORT-IOCTL result";
2921 if (!errmsg
&& i
< 0)
2922 errmsg
= "No information found";
2924 m_num_commands
= i
+1;
2925 m_next_replay_command
= 0;
2926 m_replay_out_of_sync
= false;
2930 return set_err(EIO
, "%s(%d): Syntax error: %s", pathname
, lineno
, errmsg
);
2935 // Report warnings and free command table
2936 bool parsed_ata_device::close()
2938 if (m_replay_out_of_sync
)
2939 pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
2940 else if (m_next_replay_command
!= 0)
2941 pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands
-m_next_replay_command
);
2943 for (int i
= 0; i
< m_num_commands
; i
++) {
2944 if (m_command_table
[i
].data
) {
2945 free(m_command_table
[i
].data
); m_command_table
[i
].data
= 0;
2949 m_next_replay_command
= 0;
2950 m_replay_out_of_sync
= false;
2955 bool parsed_ata_device::ata_identify_is_cached() const
2957 return m_ata_identify_is_cached
;
2961 // Simulate ATA command from command table
2962 int parsed_ata_device::ata_command_interface(smart_command_set command
, int select
, char * data
)
2964 // Find command, try round-robin if out of sync
2965 int i
= m_next_replay_command
;
2966 for (int j
= 0; ; j
++) {
2967 if (j
>= m_num_commands
) {
2968 pout("REPLAY-IOCTL: Warning: Command not found\n");
2972 if (m_command_table
[i
].command
== command
&& m_command_table
[i
].select
== select
)
2974 if (!m_replay_out_of_sync
) {
2975 m_replay_out_of_sync
= true;
2976 pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i
+1);
2978 if (++i
>= m_num_commands
)
2981 m_next_replay_command
= i
;
2982 if (++m_next_replay_command
>= m_num_commands
)
2983 m_next_replay_command
= 0;
2985 // Return command data
2990 case READ_THRESHOLDS
:
2992 if (m_command_table
[i
].data
)
2993 memcpy(data
, m_command_table
[i
].data
, 512);
2996 if (!(m_command_table
[i
].data
&& !memcmp(data
, m_command_table
[i
].data
, 512)))
2997 pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
2999 case CHECK_POWER_MODE
:
3000 data
[0] = (char)0xff;
3005 if (m_command_table
[i
].errval
)
3006 errno
= m_command_table
[i
].errval
;
3007 return m_command_table
[i
].retval
;
3012 ata_device
* get_parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
3014 return new parsed_ata_device(intf
, dev_name
);