4 * Home page of code is: http://www.smartmontools.org
6 * Copyright (C) 2002-11 Bruce Allen
7 * Copyright (C) 2008-15 Christian Franke
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, see <http://www.gnu.org/licenses/>.
19 * This code was originally developed as a Senior Thesis by Michael Cornwell
20 * at the Concurrent Systems Laboratory (now part of the Storage Systems
21 * Research Center), Jack Baskin School of Engineering, University of
22 * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
35 #include "knowndrives.h" // get_default_attr_defs()
37 #include "dev_ata_cmd_set.h" // for parsed_ata_device
39 const char * atacmds_cpp_cvsid
= "$Id: atacmds.cpp 4178 2015-11-23 18:44:27Z chrfranke $"
42 // Print ATA debug messages?
43 unsigned char ata_debugmode
= 0;
45 // Suppress serial number?
46 // (also used in scsiprint.cpp)
47 bool dont_print_serial_number
= false;
50 #define SMART_CYL_LOW 0x4F
51 #define SMART_CYL_HI 0xC2
53 // SMART RETURN STATUS yields SMART_CYL_HI,SMART_CYL_LOW to indicate drive
54 // is healthy and SRET_STATUS_HI_EXCEEDED,SRET_STATUS_MID_EXCEEDED to
55 // indicate that a threshhold exceeded condition has been detected.
56 // Those values (byte pairs) are placed in ATA register "LBA 23:8".
57 #define SRET_STATUS_HI_EXCEEDED 0x2C
58 #define SRET_STATUS_MID_EXCEEDED 0xF4
61 // Get ID and increase flag of current pending or offline
62 // uncorrectable attribute.
63 unsigned char get_unc_attr_id(bool offline
, const ata_vendor_attr_defs
& defs
,
66 unsigned char id
= (!offline
? 197 : 198);
67 const ata_vendor_attr_defs::entry
& def
= defs
[id
];
68 if (def
.flags
& ATTRFLAG_INCREASING
)
69 increase
= true; // '-v 19[78],increasing' option
70 else if (def
.name
.empty() || (id
== 198 && def
.name
== "Offline_Scan_UNC_SectCt"))
71 increase
= false; // no or '-v 198,offlinescanuncsectorct' option
73 id
= 0; // other '-v 19[78],...' option
77 #if 0 // TODO: never used
78 // This are the meanings of the Self-test failure checkpoint byte.
79 // This is in the self-test log at offset 4 bytes into the self-test
80 // descriptor and in the SMART READ DATA structure at byte offset
81 // 371. These codes are not well documented. The meanings returned by
82 // this routine are used (at least) by Maxtor and IBM. Returns NULL if
83 // not recognized. Currently the maximum length is 15 bytes.
84 const char *SelfTestFailureCodeName(unsigned char which
){
92 return "Servo_Random";
96 return "Handling_Damage";
106 // Table of raw print format names
107 struct format_name_entry
110 ata_attr_raw_format format
;
113 const format_name_entry format_names
[] = {
114 {"raw8" , RAWFMT_RAW8
},
115 {"raw16" , RAWFMT_RAW16
},
116 {"raw48" , RAWFMT_RAW48
},
117 {"hex48" , RAWFMT_HEX48
},
118 {"raw56" , RAWFMT_RAW56
},
119 {"hex56" , RAWFMT_HEX56
},
120 {"raw64" , RAWFMT_RAW64
},
121 {"hex64" , RAWFMT_HEX64
},
122 {"raw16(raw16)" , RAWFMT_RAW16_OPT_RAW16
},
123 {"raw16(avg16)" , RAWFMT_RAW16_OPT_AVG16
},
124 {"raw24(raw8)" , RAWFMT_RAW24_OPT_RAW8
},
125 {"raw24/raw24" , RAWFMT_RAW24_DIV_RAW24
},
126 {"raw24/raw32" , RAWFMT_RAW24_DIV_RAW32
},
127 {"sec2hour" , RAWFMT_SEC2HOUR
},
128 {"min2hour" , RAWFMT_MIN2HOUR
},
129 {"halfmin2hour" , RAWFMT_HALFMIN2HOUR
},
130 {"msec24hour32" , RAWFMT_MSEC24_HOUR32
},
131 {"tempminmax" , RAWFMT_TEMPMINMAX
},
132 {"temp10x" , RAWFMT_TEMP10X
},
135 const unsigned num_format_names
= sizeof(format_names
)/sizeof(format_names
[0]);
137 // Table to map old to new '-v' option arguments
138 const char * const map_old_vendor_opts
[][2] = {
139 { "9,halfminutes" , "9,halfmin2hour,Power_On_Half_Minutes"},
140 { "9,minutes" , "9,min2hour,Power_On_Minutes"},
141 { "9,seconds" , "9,sec2hour,Power_On_Seconds"},
142 { "9,temp" , "9,tempminmax,Temperature_Celsius"},
143 {"192,emergencyretractcyclect" , "192,raw48,Emerg_Retract_Cycle_Ct"},
144 {"193,loadunload" , "193,raw24/raw24"},
145 {"194,10xCelsius" , "194,temp10x,Temperature_Celsius_x10"},
146 {"194,unknown" , "194,raw48,Unknown_Attribute"},
147 {"197,increasing" , "197,raw48+,Total_Pending_Sectors"}, // '+' sets flag
148 {"198,offlinescanuncsectorct" , "198,raw48,Offline_Scan_UNC_SectCt"}, // see also get_unc_attr_id() above
149 {"198,increasing" , "198,raw48+,Total_Offl_Uncorrectabl"}, // '+' sets flag
150 {"200,writeerrorcount" , "200,raw48,Write_Error_Count"},
151 {"201,detectedtacount" , "201,raw48,Detected_TA_Count"},
152 {"220,temp" , "220,tempminmax,Temperature_Celsius"},
155 const unsigned num_old_vendor_opts
= sizeof(map_old_vendor_opts
)/sizeof(map_old_vendor_opts
[0]);
157 // Parse vendor attribute display def (-v option).
158 // Return false on error.
159 bool parse_attribute_def(const char * opt
, ata_vendor_attr_defs
& defs
,
160 ata_vendor_def_prior priority
)
162 // Map old -> new options
164 for (i
= 0; i
< num_old_vendor_opts
; i
++) {
165 if (!strcmp(opt
, map_old_vendor_opts
[i
][0])) {
166 opt
= map_old_vendor_opts
[i
][1];
172 int len
= strlen(opt
);
173 int id
= 0, n1
= -1, n2
= -1;
174 char fmtname
[32+1], attrname
[32+1], hddssd
[3+1];
175 attrname
[0] = hddssd
[0] = 0;
179 if (!( sscanf(opt
, "N,%32[^,]%n,%32[^,]%n", fmtname
, &n1
, attrname
, &n2
) >= 1
180 && (n1
== len
|| n2
== len
)))
184 // "id,format[+][,name[,HDD|SSD]]"
186 if (!( sscanf(opt
, "%d,%32[^,]%n,%32[^,]%n,%3[DHS]%n",
187 &id
, fmtname
, &n1
, attrname
, &n2
, hddssd
, &n3
) >= 2
188 && 1 <= id
&& id
<= 255
189 && ( n1
== len
|| n2
== len
190 // ",HDD|SSD" for DEFAULT settings only
191 || (n3
== len
&& priority
== PRIOR_DEFAULT
))))
196 // For "-v 19[78],increasing" above
197 if (fmtname
[strlen(fmtname
)-1] == '+') {
198 fmtname
[strlen(fmtname
)-1] = 0;
199 flags
= ATTRFLAG_INCREASING
;
202 // Split "format[:byteorder]"
203 char byteorder
[8+1] = "";
204 if (strchr(fmtname
, ':')) {
205 if (priority
== PRIOR_DEFAULT
)
206 // TODO: Allow Byteorder in DEFAULT entry
209 if (!( sscanf(fmtname
, "%*[^:]%n:%8[012345rvwz]%n", &n1
, byteorder
, &n2
) >= 1
210 && n2
== (int)strlen(fmtname
)))
213 if (strchr(byteorder
, 'v'))
214 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
215 if (strchr(byteorder
, 'w'))
216 flags
|= ATTRFLAG_NO_WORSTVAL
;
221 if (i
>= num_format_names
)
222 return false; // Not found
223 if (!strcmp(fmtname
, format_names
[i
].name
))
226 ata_attr_raw_format format
= format_names
[i
].format
;
228 // 64-bit formats use the normalized and worst value bytes.
229 if (!*byteorder
&& (format
== RAWFMT_RAW64
|| format
== RAWFMT_HEX64
))
230 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
232 // ",HDD|SSD" suffix for DEFAULT settings
234 if (!strcmp(hddssd
, "HDD"))
235 flags
|= ATTRFLAG_HDD_ONLY
;
236 else if (!strcmp(hddssd
, "SSD"))
237 flags
|= ATTRFLAG_SSD_ONLY
;
243 // "N,format" -> set format for all entries
244 for (i
= 0; i
< MAX_ATTRIBUTE_NUM
; i
++) {
245 if (defs
[i
].priority
>= priority
)
248 defs
[i
].name
= attrname
;
249 defs
[i
].priority
= priority
;
250 defs
[i
].raw_format
= format
;
251 defs
[i
].flags
= flags
;
252 snprintf(defs
[i
].byteorder
, sizeof(defs
[i
].byteorder
), "%s", byteorder
);
255 else if (defs
[id
].priority
<= priority
) {
256 // "id,format[,name]"
258 defs
[id
].name
= attrname
;
259 defs
[id
].raw_format
= format
;
260 defs
[id
].priority
= priority
;
261 defs
[id
].flags
= flags
;
262 snprintf(defs
[id
].byteorder
, sizeof(defs
[id
].byteorder
), "%s", byteorder
);
269 // Return a multiline string containing a list of valid arguments for
270 // parse_attribute_def(). The strings are preceeded by tabs and followed
271 // (except for the last) by newlines.
272 std::string
create_vendor_attribute_arg_list()
276 for (i
= 0; i
< num_format_names
; i
++)
277 s
+= strprintf("%s\tN,%s[:012345rvwz][,ATTR_NAME]",
278 (i
>0 ? "\n" : ""), format_names
[i
].name
);
279 for (i
= 0; i
< num_old_vendor_opts
; i
++)
280 s
+= strprintf("\n\t%s", map_old_vendor_opts
[i
][0]);
285 // Parse firmwarebug def (-F option).
286 // Return false on error.
287 bool parse_firmwarebug_def(const char * opt
, firmwarebug_defs
& firmwarebugs
)
289 if (!strcmp(opt
, "none"))
290 firmwarebugs
.set(BUG_NONE
);
291 else if (!strcmp(opt
, "nologdir"))
292 firmwarebugs
.set(BUG_NOLOGDIR
);
293 else if (!strcmp(opt
, "samsung"))
294 firmwarebugs
.set(BUG_SAMSUNG
);
295 else if (!strcmp(opt
, "samsung2"))
296 firmwarebugs
.set(BUG_SAMSUNG2
);
297 else if (!strcmp(opt
, "samsung3"))
298 firmwarebugs
.set(BUG_SAMSUNG3
);
299 else if (!strcmp(opt
, "xerrorlba"))
300 firmwarebugs
.set(BUG_XERRORLBA
);
306 // Return a string of valid argument words for parse_firmwarebug_def()
307 const char * get_valid_firmwarebug_args()
309 return "none, nologdir, samsung, samsung2, samsung3, xerrorlba";
313 // swap two bytes. Point to low address
314 void swap2(char *location
){
316 *location
=*(location
+1);
321 // swap four bytes. Point to low address
322 void swap4(char *location
){
324 *location
=*(location
+3);
330 // swap eight bytes. Points to low address
331 void swap8(char *location
){
333 *location
=*(location
+7);
336 *(location
+1)=*(location
+6);
342 // Invalidate serial number and WWN and adjust checksum in IDENTIFY data
343 static void invalidate_serno(ata_identify_device
* id
)
345 unsigned char sum
= 0;
347 for (i
= 0; i
< sizeof(id
->serial_no
); i
++) {
348 sum
+= id
->serial_no
[i
]; sum
-= id
->serial_no
[i
] = 'X';
350 unsigned char * b
= (unsigned char *)id
;
351 for (i
= 2*108; i
< 2*112; i
++) { // words108-111: WWN
352 sum
+= b
[i
]; sum
-= b
[i
] = 0x00;
356 bool must_swap
= !!isbigendian();
358 swapx(id
->words088_255
+255-88);
360 if ((id
->words088_255
[255-88] & 0x00ff) == 0x00a5)
361 id
->words088_255
[255-88] += sum
<< 8;
364 swapx(id
->words088_255
+255-88);
368 static const char * const commandstrings
[]={
371 "SMART AUTOMATIC ATTRIBUTE SAVE",
372 "SMART IMMEDIATE OFFLINE",
373 "SMART AUTO OFFLINE",
375 "SMART STATUS CHECK",
376 "SMART READ ATTRIBUTE VALUES",
377 "SMART READ ATTRIBUTE THRESHOLDS",
380 "IDENTIFY PACKET DEVICE",
383 "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT
")\n"
387 static const char * preg(const ata_register
& r
, char (& buf
)[8])
392 snprintf(buf
, sizeof(buf
), "0x%02x", r
.val());
396 static void print_regs(const char * prefix
, const ata_in_regs
& r
, const char * suffix
= "\n")
399 pout("%s FR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, CMD=%s%s", prefix
,
400 preg(r
.features
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
401 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
402 preg(r
.command
, bufs
[6]), suffix
);
405 static void print_regs(const char * prefix
, const ata_out_regs
& r
, const char * suffix
= "\n")
408 pout("%sERR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, STS=%s%s", prefix
,
409 preg(r
.error
, 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
.status
, bufs
[6]), suffix
);
414 static void prettyprint(const unsigned char *p
, const char *name
){
415 pout("\n===== [%s] DATA START (BASE-16) =====\n", name
);
416 for (int i
=0; i
<512; i
+=16, p
+=16)
417 #define P(n) (' ' <= p[n] && p[n] <= '~' ? (int)p[n] : '.')
418 // print complete line to avoid slow tty output and extra lines in syslog.
419 pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x "
420 "%02x %02x %02x %02x %02x %02x %02x %02x"
421 " |%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c|"
424 p
[ 0], p
[ 1], p
[ 2], p
[ 3], p
[ 4], p
[ 5], p
[ 6], p
[ 7],
425 p
[ 8], p
[ 9], p
[10], p
[11], p
[12], p
[13], p
[14], p
[15],
426 P( 0), P( 1), P( 2), P( 3), P( 4), P( 5), P( 6), P( 7),
427 P( 8), P( 9), P(10), P(11), P(12), P(13), P(14), P(15),
430 pout("===== [%s] DATA END (512 Bytes) =====\n\n", name
);
433 // This function provides the pretty-print reporting for SMART
434 // commands: it implements the various -r "reporting" options for ATA
436 int smartcommandhandler(ata_device
* device
, smart_command_set command
, int select
, char *data
){
437 // TODO: Rework old stuff below
438 // This conditional is true for commands that return data
439 int getsdata
=(command
==PIDENTIFY
||
442 command
==READ_THRESHOLDS
||
443 command
==READ_VALUES
||
444 command
==CHECK_POWER_MODE
);
446 int sendsdata
=(command
==WRITE_LOG
);
448 // If reporting is enabled, say what the command will be before it's executed
450 // conditional is true for commands that use parameters
451 int usesparam
=(command
==READ_LOG
||
452 command
==AUTO_OFFLINE
||
454 command
==IMMEDIATE_OFFLINE
||
457 pout("\nREPORT-IOCTL: Device=%s Command=%s", device
->get_dev_name(), commandstrings
[command
]);
459 pout(" InputParameter=%d\n", select
);
464 if ((getsdata
|| sendsdata
) && !data
){
465 pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings
[command
]);
469 // The reporting is cleaner, and we will find coding bugs faster, if
470 // the commands that failed clearly return empty (zeroed) data
473 if (command
==CHECK_POWER_MODE
)
476 memset(data
, '\0', 512);
480 // if requested, pretty-print the input data structure
481 if (ata_debugmode
> 1 && sendsdata
)
482 //pout("REPORT-IOCTL: Device=%s Command=%s\n", device->get_dev_name(), commandstrings[command]);
483 prettyprint((unsigned char *)data
, commandstrings
[command
]);
485 // now execute the command
489 // Set common register values
491 default: // SMART commands
492 in
.in_regs
.command
= ATA_SMART_CMD
;
493 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
495 case IDENTIFY
: case PIDENTIFY
: case CHECK_POWER_MODE
: // Non SMART commands
498 // Set specific values
501 in
.in_regs
.command
= ATA_IDENTIFY_DEVICE
;
502 in
.set_data_in(data
, 1);
505 in
.in_regs
.command
= ATA_IDENTIFY_PACKET_DEVICE
;
506 in
.set_data_in(data
, 1);
508 case CHECK_POWER_MODE
:
509 in
.in_regs
.command
= ATA_CHECK_POWER_MODE
;
510 in
.out_needed
.sector_count
= true; // Powermode returned here
513 in
.in_regs
.features
= ATA_SMART_READ_VALUES
;
514 in
.set_data_in(data
, 1);
516 case READ_THRESHOLDS
:
517 in
.in_regs
.features
= ATA_SMART_READ_THRESHOLDS
;
518 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
519 in
.set_data_in(data
, 1);
522 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
523 in
.in_regs
.lba_low
= select
;
524 in
.set_data_in(data
, 1);
527 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
528 in
.in_regs
.lba_low
= select
;
529 in
.set_data_out(data
, 1);
532 in
.in_regs
.features
= ATA_SMART_ENABLE
;
533 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
536 in
.in_regs
.features
= ATA_SMART_DISABLE
;
537 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
540 in
.out_needed
.lba_high
= in
.out_needed
.lba_mid
= true; // Status returned here
542 in
.in_regs
.features
= ATA_SMART_STATUS
;
545 in
.in_regs
.features
= ATA_SMART_AUTO_OFFLINE
;
546 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
549 in
.in_regs
.features
= ATA_SMART_AUTOSAVE
;
550 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
552 case IMMEDIATE_OFFLINE
:
553 in
.in_regs
.features
= ATA_SMART_IMMEDIATE_OFFLINE
;
554 in
.in_regs
.lba_low
= select
;
557 pout("Unrecognized command %d in smartcommandhandler()\n"
558 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
559 device
->set_err(ENOSYS
);
564 print_regs(" Input: ", in
.in_regs
,
565 (in
.direction
==ata_cmd_in::data_in
? " IN\n":
566 in
.direction
==ata_cmd_in::data_out
? " OUT\n":"\n"));
570 int64_t start_usec
= -1;
572 start_usec
= smi()->get_timer_usec();
574 bool ok
= device
->ata_pass_through(in
, out
);
576 if (start_usec
>= 0) {
577 int64_t duration_usec
= smi()->get_timer_usec() - start_usec
;
578 if (duration_usec
>= 500)
579 pout(" [Duration: %.3fs]\n", duration_usec
/ 1000000.0);
582 if (ata_debugmode
&& out
.out_regs
.is_set())
583 print_regs(" Output: ", out
.out_regs
);
585 if (ok
) switch (command
) {
589 case CHECK_POWER_MODE
:
590 if (out
.out_regs
.sector_count
.is_set()) {
591 data
[0] = out
.out_regs
.sector_count
;
595 pout("CHECK POWER MODE: incomplete response, ATA output registers missing\n");
596 device
->set_err(ENOSYS
);
601 // Cyl low and Cyl high unchanged means "Good SMART status"
602 if ((out
.out_regs
.lba_high
== SMART_CYL_HI
) &&
603 (out
.out_regs
.lba_mid
== SMART_CYL_LOW
))
605 // These values mean "Bad SMART status"
606 else if ((out
.out_regs
.lba_high
== SRET_STATUS_HI_EXCEEDED
) &&
607 (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
))
609 else if (out
.out_regs
.lba_mid
== SMART_CYL_LOW
) {
612 pout("SMART STATUS RETURN: half healthy response sequence, "
613 "probable SAT/USB truncation\n");
614 } else if (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
) {
617 pout("SMART STATUS RETURN: half unhealthy response sequence, "
618 "probable SAT/USB truncation\n");
620 else if (!out
.out_regs
.is_set()) {
621 device
->set_err(ENOSYS
, "Incomplete response, ATA output registers missing");
625 // We haven't gotten output that makes sense; print out some debugging info
626 pout("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
);
630 device
->set_err(ENOSYS
, "Invalid ATA output register values");
637 // If requested, invalidate serial number before any printing is done
638 if ((command
== IDENTIFY
|| command
== PIDENTIFY
) && !retval
&& dont_print_serial_number
)
639 invalidate_serno( reinterpret_cast<ata_identify_device
*>(data
) );
641 // If reporting is enabled, say what output was produced by the command
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 (ata_debugmode
> 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
]);
663 // Get capacity and sector sizes from IDENTIFY data
664 void ata_get_size_info(const ata_identify_device
* id
, ata_size_info
& sizes
)
666 sizes
.sectors
= sizes
.capacity
= 0;
667 sizes
.log_sector_size
= sizes
.phy_sector_size
= 0;
668 sizes
.log_sector_offset
= 0;
670 // Return if no LBA support
671 if (!(id
->words047_079
[49-47] & 0x0200))
674 // Determine 28-bit LBA capacity
675 unsigned lba28
= (unsigned)id
->words047_079
[61-47] << 16
676 | (unsigned)id
->words047_079
[60-47] ;
678 // Determine 48-bit LBA capacity if supported
680 if ((id
->command_set_2
& 0xc400) == 0x4400)
681 lba48
= (uint64_t)id
->words088_255
[103-88] << 48
682 | (uint64_t)id
->words088_255
[102-88] << 32
683 | (uint64_t)id
->words088_255
[101-88] << 16
684 | (uint64_t)id
->words088_255
[100-88] ;
686 // Return if capacity unknown (ATAPI CD/DVD)
687 if (!(lba28
|| lba48
))
690 // Determine sector sizes
691 sizes
.log_sector_size
= sizes
.phy_sector_size
= 512;
693 unsigned short word106
= id
->words088_255
[106-88];
694 if ((word106
& 0xc000) == 0x4000) {
695 // Long Logical/Physical Sectors (LLS/LPS) ?
696 if (word106
& 0x1000)
697 // Logical sector size is specified in 16-bit words
698 sizes
.log_sector_size
= sizes
.phy_sector_size
=
699 ((id
->words088_255
[118-88] << 16) | id
->words088_255
[117-88]) << 1;
701 if (word106
& 0x2000)
702 // Physical sector size is multiple of logical sector size
703 sizes
.phy_sector_size
<<= (word106
& 0x0f);
705 unsigned short word209
= id
->words088_255
[209-88];
706 if ((word209
& 0xc000) == 0x4000)
707 sizes
.log_sector_offset
= (word209
& 0x3fff) * sizes
.log_sector_size
;
710 // Some early 4KiB LLS disks (Samsung N3U-3) return bogus lba28 value
711 if (lba48
>= lba28
|| (lba48
&& sizes
.log_sector_size
> 512))
712 sizes
.sectors
= lba48
;
714 sizes
.sectors
= lba28
;
716 sizes
.capacity
= sizes
.sectors
* sizes
.log_sector_size
;
719 // This function computes the checksum of a single disk sector (512
720 // bytes). Returns zero if checksum is OK, nonzero if the checksum is
721 // incorrect. The size (512) is correct for all SMART structures.
722 unsigned char checksum(const void * data
)
724 unsigned char sum
= 0;
725 for (int i
= 0; i
< 512; i
++)
726 sum
+= ((const unsigned char *)data
)[i
];
730 // Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
732 static void swapbytes(char * out
, const char * in
, size_t n
)
734 for (size_t i
= 0; i
< n
; i
+= 2) {
740 // Copies in to out, but removes leading and trailing whitespace.
741 static void trim(char * out
, const char * in
)
743 // Find the first non-space character (maybe none).
746 for (i
= 0; in
[i
]; i
++)
747 if (!isspace((int)in
[i
])) {
753 // There are no non-space characters.
758 // Find the last non-space character.
759 for (i
= strlen(in
)-1; i
>= first
&& isspace((int)in
[i
]); i
--)
763 strncpy(out
, in
+first
, last
-first
+1);
764 out
[last
-first
+1] = '\0';
767 // Convenience function for formatting strings from ata_identify_device
768 void ata_format_id_string(char * out
, const unsigned char * in
, int n
)
770 bool must_swap
= true;
772 /* NetBSD kernel delivers IDENTIFY data in host byte order (but all else is LE) */
773 // TODO: Handle NetBSD case in os_netbsd.cpp
775 must_swap
= !must_swap
;
781 strncpy(tmp
, (const char *)in
, n
);
783 swapbytes(tmp
, (const char *)in
, n
);
788 // returns -1 if command fails or the device is in Sleep mode, else
789 // value of Sector Count register. Sector Count result values:
790 // 00h device is in Standby mode.
791 // 80h device is in Idle mode.
792 // FFh device is in Active mode or Idle mode.
794 int ataCheckPowerMode(ata_device
* device
) {
795 unsigned char result
;
797 if ((smartcommandhandler(device
, CHECK_POWER_MODE
, 0, (char *)&result
)))
800 if (result
!=0 && result
!=0x80 && result
!=0xff)
801 pout("ataCheckPowerMode(): ATA CHECK POWER MODE returned unknown Sector Count Register value %02x\n", result
);
806 // Issue a no-data ATA command with optional sector count register value
807 bool ata_nodata_command(ata_device
* device
, unsigned char command
,
808 int sector_count
/* = -1 */)
811 in
.in_regs
.command
= command
;
812 if (sector_count
>= 0)
813 in
.in_regs
.sector_count
= sector_count
;
815 return device
->ata_pass_through(in
);
818 // Issue SET FEATURES command with optional sector count register value
819 bool ata_set_features(ata_device
* device
, unsigned char features
,
820 int sector_count
/* = -1 */)
823 in
.in_regs
.command
= ATA_SET_FEATURES
;
824 in
.in_regs
.features
= features
;
825 if (sector_count
>= 0)
826 in
.in_regs
.sector_count
= sector_count
;
828 return device
->ata_pass_through(in
);
831 // Reads current Device Identity info (512 bytes) into buf. Returns 0
832 // if all OK. Returns -1 if no ATA Device identity can be
833 // established. Returns >0 if Device is ATA Packet Device (not SMART
834 // capable). The value of the integer helps identify the type of
835 // Packet device, which is useful so that the user can connect the
836 // formal device number with whatever object is inside their computer.
837 int ata_read_identity(ata_device
* device
, ata_identify_device
* buf
, bool fix_swapped_id
,
838 unsigned char * raw_buf
/* = 0 */)
840 unsigned short *rawshort
=(unsigned short *)buf
;
841 unsigned char *rawbyte
=(unsigned char *)buf
;
843 // See if device responds either to IDENTIFY DEVICE or IDENTIFY
846 if ((smartcommandhandler(device
, IDENTIFY
, 0, (char *)buf
))){
847 if (smartcommandhandler(device
, PIDENTIFY
, 0, (char *)buf
)){
853 if (fix_swapped_id
) {
856 for (i
= 0; i
< sizeof(buf
->serial_no
)-1; i
+= 2)
857 swap2((char *)(buf
->serial_no
+i
));
858 for (i
= 0; i
< sizeof(buf
->fw_rev
)-1; i
+= 2)
859 swap2((char *)(buf
->fw_rev
+i
));
860 for (i
= 0; i
< sizeof(buf
->model
)-1; i
+= 2)
861 swap2((char *)(buf
->model
+i
));
864 // If requested, save raw data before endianness adjustments
866 memcpy(raw_buf
, buf
, sizeof(*buf
));
869 // if machine is big-endian, swap byte order as needed
870 // NetBSD kernel delivers IDENTIFY data in host byte order
871 // TODO: Handle NetBSD case in os_netbsd.cpp
873 // swap various capability words that are needed
876 swap2((char *)(buf
->words047_079
+i
));
877 for (i
=80; i
<=87; i
++)
878 swap2((char *)(rawshort
+i
));
879 for (i
=0; i
<168; i
++)
880 swap2((char *)(buf
->words088_255
+i
));
884 // If there is a checksum there, validate it
885 if ((rawshort
[255] & 0x00ff) == 0x00a5 && checksum(rawbyte
))
886 checksumwarning("Drive Identity Structure");
888 // AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
889 // T13/1699-D Revision 6a (Final Draft), September 6, 2008.
890 // Sections 7.16.7 and 7.17.6:
892 // Word 0 of IDENTIFY DEVICE data:
893 // Bit 15 = 0 : ATA device
895 // Word 0 of IDENTIFY PACKET DEVICE data:
896 // Bits 15:14 = 10b : ATAPI device
897 // Bits 15:14 = 11b : Reserved
898 // Bits 12:8 : Device type (SPC-4, e.g 0x05 = CD/DVD)
900 // CF+ and CompactFlash Specification Revision 4.0, May 24, 2006.
903 // Word 0 of IDENTIFY DEVICE data:
904 // 848Ah = Signature for CompactFlash Storage Card
905 // 044Ah = Alternate value turns on ATA device while preserving all retired bits
906 // 0040h = Alternate value turns on ATA device while zeroing all retired bits
908 // Assume ATA if IDENTIFY DEVICE returns CompactFlash Signature
909 if (!packet
&& rawbyte
[1] == 0x84 && rawbyte
[0] == 0x8a)
912 // If this is a PACKET DEVICE, return device type
913 if (rawbyte
[1] & 0x80)
914 return 1+(rawbyte
[1] & 0x1f);
916 // Not a PACKET DEVICE
920 // Get World Wide Name (WWN) fields.
921 // Return NAA field or -1 if WWN is unsupported.
922 // Table 34 of T13/1699-D Revision 6a (ATA8-ACS), September 6, 2008.
923 // (WWN was introduced in ATA/ATAPI-7 and is mandatory since ATA8-ACS Revision 3b)
924 int ata_get_wwn(const ata_identify_device
* id
, unsigned & oui
, uint64_t & unique_id
)
926 // Don't use word 84 to be compatible with some older ATA-7 disks
927 unsigned short word087
= id
->csf_default
;
928 if ((word087
& 0xc100) != 0x4100)
929 return -1; // word not valid or WWN support bit 8 not set
931 unsigned short word108
= id
->words088_255
[108-88];
932 unsigned short word109
= id
->words088_255
[109-88];
933 unsigned short word110
= id
->words088_255
[110-88];
934 unsigned short word111
= id
->words088_255
[111-88];
936 oui
= ((word108
& 0x0fff) << 12) | (word109
>> 4);
937 unique_id
= ((uint64_t)(word109
& 0xf) << 32)
938 | (unsigned)((word110
<< 16) | word111
);
939 return (word108
>> 12);
942 // Get nominal media rotation rate.
943 // Returns: 0 = not reported, 1 = SSD, >1 = HDD rpm, < 0 = -(Unknown value)
944 int ata_get_rotation_rate(const ata_identify_device
* id
)
946 // Table 37 of T13/1699-D (ATA8-ACS) Revision 6a, September 6, 2008
947 // Table A.31 of T13/2161-D (ACS-3) Revision 3b, August 25, 2012
948 unsigned short word217
= id
->words088_255
[217-88];
949 if (word217
== 0x0000 || word217
== 0xffff)
951 else if (word217
== 0x0001)
953 else if (word217
> 0x0400)
956 return -(int)word217
;
959 // returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
960 int ataSmartSupport(const ata_identify_device
* drive
)
962 unsigned short word82
=drive
->command_set_1
;
963 unsigned short word83
=drive
->command_set_2
;
965 // check if words 82/83 contain valid info
966 if ((word83
>>14) == 0x01)
967 // return value of SMART support bit
968 return word82
& 0x0001;
970 // since we can're rely on word 82, we don't know if SMART supported
974 // returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
975 int ataIsSmartEnabled(const ata_identify_device
* drive
)
977 unsigned short word85
=drive
->cfs_enable_1
;
978 unsigned short word87
=drive
->csf_default
;
980 // check if words 85/86/87 contain valid info
981 if ((word87
>>14) == 0x01)
982 // return value of SMART enabled bit
983 return word85
& 0x0001;
985 // Since we can't rely word85, we don't know if SMART is enabled.
990 // Reads SMART attributes into *data
991 int ataReadSmartValues(ata_device
* device
, struct ata_smart_values
*data
){
993 if (smartcommandhandler(device
, READ_VALUES
, 0, (char *)data
)){
999 checksumwarning("SMART Attribute Data Structure");
1001 // swap endian order if needed
1004 swap2((char *)&(data
->revnumber
));
1005 swap2((char *)&(data
->total_time_to_complete_off_line
));
1006 swap2((char *)&(data
->smart_capability
));
1007 swapx(&data
->extend_test_completion_time_w
);
1008 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
1009 struct ata_smart_attribute
*x
=data
->vendor_attributes
+i
;
1010 swap2((char *)&(x
->flags
));
1018 // This corrects some quantities that are byte reversed in the SMART
1020 static void fixsamsungselftestlog(ata_smart_selftestlog
* data
)
1022 // bytes 508/509 (numbered from 0) swapped (swap of self-test index
1023 // with one byte of reserved.
1024 swap2((char *)&(data
->mostrecenttest
));
1026 // LBA low register (here called 'selftestnumber", containing
1027 // information about the TYPE of the self-test) is byte swapped with
1028 // Self-test execution status byte. These are bytes N, N+1 in the
1030 for (int i
= 0; i
< 21; i
++)
1031 swap2((char *)&(data
->selftest_struct
[i
].selftestnumber
));
1036 // Reads the Self Test Log (log #6)
1037 int ataReadSelfTestLog (ata_device
* device
, ata_smart_selftestlog
* data
,
1038 firmwarebug_defs firmwarebugs
)
1041 // get data from device
1042 if (smartcommandhandler(device
, READ_LOG
, 0x06, (char *)data
)){
1046 // compute its checksum, and issue a warning if needed
1048 checksumwarning("SMART Self-Test Log Structure");
1050 // fix firmware bugs in self-test log
1051 if (firmwarebugs
.is_set(BUG_SAMSUNG
))
1052 fixsamsungselftestlog(data
);
1054 // swap endian order if needed
1057 swap2((char*)&(data
->revnumber
));
1058 for (i
=0; i
<21; i
++){
1059 struct ata_smart_selftestlog_struct
*x
=data
->selftest_struct
+i
;
1060 swap2((char *)&(x
->timestamp
));
1061 swap4((char *)&(x
->lbafirstfailure
));
1068 // Print checksum warning for multi sector log
1069 static void check_multi_sector_sum(const void * data
, unsigned nsectors
, const char * msg
)
1072 for (unsigned i
= 0; i
< nsectors
; i
++) {
1073 if (checksum((const unsigned char *)data
+ i
*512))
1078 checksumwarning(msg
);
1080 checksumwarning(strprintf("%s (%u/%u)", msg
, errs
, nsectors
).c_str());
1084 // Read SMART Extended Self-test Log
1085 bool ataReadExtSelfTestLog(ata_device
* device
, ata_smart_extselftestlog
* log
,
1088 if (!ataReadLogExt(device
, 0x07, 0x00, 0, log
, nsectors
))
1091 check_multi_sector_sum(log
, nsectors
, "SMART Extended Self-test Log Structure");
1093 if (isbigendian()) {
1094 swapx(&log
->log_desc_index
);
1095 for (unsigned i
= 0; i
< nsectors
; i
++) {
1096 for (unsigned j
= 0; j
< 19; j
++)
1097 swapx(&log
->log_descs
[i
].timestamp
);
1104 // Read GP Log page(s)
1105 bool ataReadLogExt(ata_device
* device
, unsigned char logaddr
,
1106 unsigned char features
, unsigned page
,
1107 void * data
, unsigned nsectors
)
1110 in
.in_regs
.command
= ATA_READ_LOG_EXT
;
1111 in
.in_regs
.features
= features
; // log specific
1112 in
.set_data_in_48bit(data
, nsectors
);
1113 in
.in_regs
.lba_low
= logaddr
;
1114 in
.in_regs
.lba_mid_16
= page
;
1116 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1117 if (nsectors
<= 1) {
1118 pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n",
1119 logaddr
, features
, page
, nsectors
, device
->get_errmsg());
1123 // Recurse to retry with single sectors,
1124 // multi-sector reads may not be supported by ioctl.
1125 for (unsigned i
= 0; i
< nsectors
; i
++) {
1126 if (!ataReadLogExt(device
, logaddr
,
1128 (char *)data
+ 512*i
, 1))
1136 // Read SMART Log page(s)
1137 bool ataReadSmartLog(ata_device
* device
, unsigned char logaddr
,
1138 void * data
, unsigned nsectors
)
1141 in
.in_regs
.command
= ATA_SMART_CMD
;
1142 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
1143 in
.set_data_in(data
, nsectors
);
1144 in
.in_regs
.lba_high
= SMART_CYL_HI
;
1145 in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
1146 in
.in_regs
.lba_low
= logaddr
;
1148 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1149 pout("ATA_SMART_READ_LOG failed: %s\n", device
->get_errmsg());
1157 // Reads the SMART or GPL Log Directory (log #0)
1158 int ataReadLogDirectory(ata_device
* device
, ata_smart_log_directory
* data
, bool gpl
)
1160 if (!gpl
) { // SMART Log directory
1161 if (smartcommandhandler(device
, READ_LOG
, 0x00, (char *)data
))
1164 else { // GP Log directory
1165 if (!ataReadLogExt(device
, 0x00, 0x00, 0, data
, 1))
1169 // swap endian order if needed
1171 swapx(&data
->logversion
);
1177 // Reads the selective self-test log (log #9)
1178 int ataReadSelectiveSelfTestLog(ata_device
* device
, struct ata_selective_self_test_log
*data
){
1180 // get data from device
1181 if (smartcommandhandler(device
, READ_LOG
, 0x09, (char *)data
)){
1185 // compute its checksum, and issue a warning if needed
1187 checksumwarning("SMART Selective Self-Test Log Structure");
1189 // swap endian order if needed
1192 swap2((char *)&(data
->logversion
));
1194 swap8((char *)&(data
->span
[i
].start
));
1195 swap8((char *)&(data
->span
[i
].end
));
1197 swap8((char *)&(data
->currentlba
));
1198 swap2((char *)&(data
->currentspan
));
1199 swap2((char *)&(data
->flags
));
1200 swap2((char *)&(data
->pendingtime
));
1206 // Writes the selective self-test log (log #9)
1207 int ataWriteSelectiveSelfTestLog(ata_device
* device
, ata_selective_selftest_args
& args
,
1208 const ata_smart_values
* sv
, uint64_t num_sectors
,
1209 const ata_selective_selftest_args
* prev_args
)
1211 // Disk size must be known
1213 pout("Disk size is unknown, unable to check selective self-test spans\n");
1218 struct ata_selective_self_test_log sstlog
, *data
=&sstlog
;
1219 unsigned char *ptr
=(unsigned char *)data
;
1220 if (ataReadSelectiveSelfTestLog(device
, data
)) {
1221 pout("SMART Read Selective Self-test Log failed: %s\n", device
->get_errmsg());
1222 pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
1227 data
->logversion
= 1;
1229 // Host is NOT allowed to write selective self-test log if a selective
1230 // self-test is in progress.
1231 if (0<data
->currentspan
&& data
->currentspan
<6 && ((sv
->self_test_exec_status
)>>4)==15) {
1232 pout("SMART Selective or other Self-test in progress\n");
1236 // Set start/end values based on old spans for special -t select,... options
1238 for (i
= 0; i
< args
.num_spans
; i
++) {
1239 int mode
= args
.span
[i
].mode
;
1240 uint64_t start
= args
.span
[i
].start
;
1241 uint64_t end
= args
.span
[i
].end
;
1242 if (mode
== SEL_CONT
) {// redo or next dependig on last test status
1243 switch (sv
->self_test_exec_status
>> 4) {
1244 case 1: case 2: // Aborted/Interrupted by host
1245 pout("Continue Selective Self-Test: Redo last span\n");
1248 default: // All others
1249 pout("Continue Selective Self-Test: Start next span\n");
1255 if ( (mode
== SEL_REDO
|| mode
== SEL_NEXT
)
1256 && prev_args
&& i
< prev_args
->num_spans
1257 && !data
->span
[i
].start
&& !data
->span
[i
].end
) {
1258 // Some drives do not preserve the selective self-test log accross
1259 // power-cyles. If old span on drive is cleared use span provided
1260 // by caller. This is used by smartd (first span only).
1261 data
->span
[i
].start
= prev_args
->span
[i
].start
;
1262 data
->span
[i
].end
= prev_args
->span
[i
].end
;
1266 case SEL_RANGE
: // -t select,START-END
1268 case SEL_REDO
: // -t select,redo... => Redo current
1269 start
= data
->span
[i
].start
;
1270 if (end
> 0) { // -t select,redo+SIZE
1271 end
--; end
+= start
; // [oldstart, oldstart+SIZE)
1273 else // -t select,redo
1274 end
= data
->span
[i
].end
; // [oldstart, oldend]
1276 case SEL_NEXT
: // -t select,next... => Do next
1277 if (data
->span
[i
].end
== 0) {
1278 start
= end
= 0; break; // skip empty spans
1280 start
= data
->span
[i
].end
+ 1;
1281 if (start
>= num_sectors
)
1282 start
= 0; // wrap around
1283 if (end
> 0) { // -t select,next+SIZE
1284 end
--; end
+= start
; // (oldend, oldend+SIZE]
1286 else { // -t select,next
1287 uint64_t oldsize
= data
->span
[i
].end
- data
->span
[i
].start
+ 1;
1288 end
= start
+ oldsize
- 1; // (oldend, oldend+oldsize]
1289 if (end
>= num_sectors
) {
1290 // Adjust size to allow round-robin testing without future size decrease
1291 uint64_t spans
= (num_sectors
+ oldsize
-1) / oldsize
;
1292 uint64_t newsize
= (num_sectors
+ spans
-1) / spans
;
1293 uint64_t newstart
= num_sectors
- newsize
, newend
= num_sectors
- 1;
1294 pout("Span %d changed from %" PRIu64
"-%" PRIu64
" (%" PRIu64
" sectors)\n",
1295 i
, start
, end
, oldsize
);
1296 pout(" to %" PRIu64
"-%" PRIu64
" (%" PRIu64
" sectors) (%" PRIu64
" spans)\n",
1297 newstart
, newend
, newsize
, spans
);
1298 start
= newstart
; end
= newend
;
1303 pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode
);
1307 if (start
< num_sectors
&& num_sectors
<= end
) {
1308 if (end
!= ~(uint64_t)0) // -t select,N-max
1309 pout("Size of self-test span %d decreased according to disk size\n", i
);
1310 end
= num_sectors
- 1;
1312 if (!(start
<= end
&& end
< num_sectors
)) {
1313 pout("Invalid selective self-test span %d: %" PRIu64
"-%" PRIu64
" (%" PRIu64
" sectors)\n",
1314 i
, start
, end
, num_sectors
);
1317 // Return the actual mode and range to caller.
1318 args
.span
[i
].mode
= mode
;
1319 args
.span
[i
].start
= start
;
1320 args
.span
[i
].end
= end
;
1325 memset(data
->span
+i
, 0, sizeof(struct test_span
));
1327 // Set spans for testing
1328 for (i
= 0; i
< args
.num_spans
; i
++){
1329 data
->span
[i
].start
= args
.span
[i
].start
;
1330 data
->span
[i
].end
= args
.span
[i
].end
;
1333 // host must initialize to zero before initiating selective self-test
1335 data
->currentspan
=0;
1337 // Perform off-line scan after selective test?
1338 if (args
.scan_after_select
== 1)
1340 data
->flags
&= ~SELECTIVE_FLAG_DOSCAN
;
1341 else if (args
.scan_after_select
== 2)
1343 data
->flags
|= SELECTIVE_FLAG_DOSCAN
;
1345 // Must clear active and pending flags before writing
1346 data
->flags
&= ~(SELECTIVE_FLAG_ACTIVE
);
1347 data
->flags
&= ~(SELECTIVE_FLAG_PENDING
);
1349 // modify pending time?
1350 if (args
.pending_time
)
1351 data
->pendingtime
= (unsigned short)(args
.pending_time
-1);
1353 // Set checksum to zero, then compute checksum
1355 unsigned char cksum
=0;
1356 for (i
=0; i
<512; i
++)
1360 data
->checksum
=cksum
;
1362 // swap endian order if needed
1364 swap2((char *)&(data
->logversion
));
1365 for (int b
= 0; b
< 5; b
++) {
1366 swap8((char *)&(data
->span
[b
].start
));
1367 swap8((char *)&(data
->span
[b
].end
));
1369 swap8((char *)&(data
->currentlba
));
1370 swap2((char *)&(data
->currentspan
));
1371 swap2((char *)&(data
->flags
));
1372 swap2((char *)&(data
->pendingtime
));
1375 // write new selective self-test log
1376 if (smartcommandhandler(device
, WRITE_LOG
, 0x09, (char *)data
)){
1377 pout("Write Selective Self-test Log failed: %s\n", device
->get_errmsg());
1384 // This corrects some quantities that are byte reversed in the SMART
1386 static void fixsamsungerrorlog(ata_smart_errorlog
* data
)
1388 // FIXED IN SAMSUNG -25 FIRMWARE???
1389 // Device error count in bytes 452-3
1390 swap2((char *)&(data
->ata_error_count
));
1392 // FIXED IN SAMSUNG -22a FIRMWARE
1393 // step through 5 error log data structures
1394 for (int i
= 0; i
< 5; i
++){
1395 // step through 5 command data structures
1396 for (int j
= 0; j
< 5; j
++)
1397 // Command data structure 4-byte millisec timestamp. These are
1398 // bytes (N+8, N+9, N+10, N+11).
1399 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1400 // Error data structure two-byte hour life timestamp. These are
1401 // bytes (N+28, N+29).
1402 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1407 // NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
1408 static void fixsamsungerrorlog2(ata_smart_errorlog
* data
)
1410 // Device error count in bytes 452-3
1411 swap2((char *)&(data
->ata_error_count
));
1415 // Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1416 // Error Log is #2, and the Extended Comprehensive SMART Error log is
1418 int ataReadErrorLog (ata_device
* device
, ata_smart_errorlog
*data
,
1419 firmwarebug_defs firmwarebugs
)
1422 // get data from device
1423 if (smartcommandhandler(device
, READ_LOG
, 0x01, (char *)data
)){
1427 // compute its checksum, and issue a warning if needed
1429 checksumwarning("SMART ATA Error Log Structure");
1431 // Some disks have the byte order reversed in some SMART Summary
1432 // Error log entries
1433 if (firmwarebugs
.is_set(BUG_SAMSUNG
))
1434 fixsamsungerrorlog(data
);
1435 else if (firmwarebugs
.is_set(BUG_SAMSUNG2
))
1436 fixsamsungerrorlog2(data
);
1438 // swap endian order if needed
1442 // Device error count in bytes 452-3
1443 swap2((char *)&(data
->ata_error_count
));
1445 // step through 5 error log data structures
1446 for (i
=0; i
<5; i
++){
1447 // step through 5 command data structures
1449 // Command data structure 4-byte millisec timestamp
1450 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1451 // Error data structure life timestamp
1452 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1460 // Fix LBA byte ordering of Extended Comprehensive Error Log
1461 // if little endian instead of ATA register ordering is provided
1463 static inline void fix_exterrlog_lba_cmd(T
& cmd
)
1466 cmd
.lba_mid_register_hi
= org
.lba_high_register
;
1467 cmd
.lba_low_register_hi
= org
.lba_mid_register_hi
;
1468 cmd
.lba_high_register
= org
.lba_mid_register
;
1469 cmd
.lba_mid_register
= org
.lba_low_register_hi
;
1472 static void fix_exterrlog_lba(ata_smart_exterrlog
* log
, unsigned nsectors
)
1474 for (unsigned i
= 0; i
< nsectors
; i
++) {
1475 for (int ei
= 0; ei
< 4; ei
++) {
1476 ata_smart_exterrlog_error_log
& entry
= log
[i
].error_logs
[ei
];
1477 fix_exterrlog_lba_cmd(entry
.error
);
1478 for (int ci
= 0; ci
< 5; ci
++)
1479 fix_exterrlog_lba_cmd(entry
.commands
[ci
]);
1484 // Read Extended Comprehensive Error Log
1485 bool ataReadExtErrorLog(ata_device
* device
, ata_smart_exterrlog
* log
,
1486 unsigned page
, unsigned nsectors
, firmwarebug_defs firmwarebugs
)
1488 if (!ataReadLogExt(device
, 0x03, 0x00, page
, log
, nsectors
))
1491 check_multi_sector_sum(log
, nsectors
, "SMART Extended Comprehensive Error Log Structure");
1493 if (isbigendian()) {
1494 swapx(&log
->device_error_count
);
1495 swapx(&log
->error_log_index
);
1496 for (unsigned i
= 0; i
< nsectors
; i
++) {
1497 for (unsigned j
= 0; j
< 4; j
++) {
1498 for (unsigned k
= 0; k
< 5; k
++)
1499 swapx(&log
[i
].error_logs
[j
].commands
[k
].timestamp
);
1500 swapx(&log
[i
].error_logs
[j
].error
.timestamp
);
1505 if (firmwarebugs
.is_set(BUG_XERRORLBA
))
1506 fix_exterrlog_lba(log
, nsectors
);
1512 int ataReadSmartThresholds (ata_device
* device
, struct ata_smart_thresholds_pvt
*data
){
1514 // get data from device
1515 if (smartcommandhandler(device
, READ_THRESHOLDS
, 0, (char *)data
)){
1519 // compute its checksum, and issue a warning if needed
1521 checksumwarning("SMART Attribute Thresholds Structure");
1523 // swap endian order if needed
1525 swap2((char *)&(data
->revnumber
));
1530 int ataEnableSmart (ata_device
* device
){
1531 if (smartcommandhandler(device
, ENABLE
, 0, NULL
)){
1537 int ataDisableSmart (ata_device
* device
){
1539 if (smartcommandhandler(device
, DISABLE
, 0, NULL
)){
1545 int ataEnableAutoSave(ata_device
* device
){
1546 if (smartcommandhandler(device
, AUTOSAVE
, 241, NULL
)){
1552 int ataDisableAutoSave(ata_device
* device
){
1554 if (smartcommandhandler(device
, AUTOSAVE
, 0, NULL
)){
1560 // In *ALL* ATA standards the Enable/Disable AutoOffline command is
1561 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1562 // vendors still support it for backwards compatibility. IBM documents
1563 // it for some drives.
1564 int ataEnableAutoOffline (ata_device
* device
){
1566 /* timer hard coded to 4 hours */
1567 if (smartcommandhandler(device
, AUTO_OFFLINE
, 248, NULL
)){
1573 // Another Obsolete Command. See comments directly above, associated
1574 // with the corresponding Enable command.
1575 int ataDisableAutoOffline (ata_device
* device
){
1577 if (smartcommandhandler(device
, AUTO_OFFLINE
, 0, NULL
)){
1583 // If SMART is enabled, supported, and working, then this call is
1584 // guaranteed to return 1, else zero. Note that it should return 1
1585 // regardless of whether the disk's SMART status is 'healthy' or
1587 int ataDoesSmartWork(ata_device
* device
){
1588 int retval
=smartcommandhandler(device
, STATUS
, 0, NULL
);
1596 // This function uses a different interface (DRIVE_TASK) than the
1597 // other commands in this file.
1598 int ataSmartStatus2(ata_device
* device
){
1599 return smartcommandhandler(device
, STATUS_CHECK
, 0, NULL
);
1602 // This is the way to execute ALL tests: offline, short self-test,
1603 // extended self test, with and without captive mode, etc.
1604 // TODO: Move to ataprint.cpp ?
1605 int ataSmartTest(ata_device
* device
, int testtype
, bool force
,
1606 const ata_selective_selftest_args
& selargs
,
1607 const ata_smart_values
* sv
, uint64_t num_sectors
)
1609 char cmdmsg
[128]; const char *type
, *captive
;
1610 int cap
, retval
, select
=0;
1612 // Boolean, if set, says test is captive
1613 cap
=testtype
& CAPTIVE_MASK
;
1615 // Set up strings that describe the type of test
1621 if (testtype
==OFFLINE_FULL_SCAN
)
1623 else if (testtype
==SHORT_SELF_TEST
|| testtype
==SHORT_CAPTIVE_SELF_TEST
)
1624 type
="Short self-test";
1625 else if (testtype
==EXTEND_SELF_TEST
|| testtype
==EXTEND_CAPTIVE_SELF_TEST
)
1626 type
="Extended self-test";
1627 else if (testtype
==CONVEYANCE_SELF_TEST
|| testtype
==CONVEYANCE_CAPTIVE_SELF_TEST
)
1628 type
="Conveyance self-test";
1629 else if ((select
=(testtype
==SELECTIVE_SELF_TEST
|| testtype
==SELECTIVE_CAPTIVE_SELF_TEST
)))
1630 type
="Selective self-test";
1634 // Check whether another test is already running
1635 if (type
&& (sv
->self_test_exec_status
>> 4) == 0xf) {
1637 pout("Can't start self-test without aborting current test (%d0%% remaining),\n"
1638 "%srun 'smartctl -X' to abort test.\n",
1639 sv
->self_test_exec_status
& 0x0f,
1640 (!select
? "add '-t force' option to override, or " : ""));
1647 // If doing a selective self-test, first use WRITE_LOG to write the
1648 // selective self-test log.
1649 ata_selective_selftest_args selargs_io
= selargs
; // filled with info about actual spans
1650 if (select
&& (retval
= ataWriteSelectiveSelfTestLog(device
, selargs_io
, sv
, num_sectors
))) {
1652 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1656 // Print ouf message that we are sending the command to test
1657 if (testtype
==ABORT_SELF_TEST
)
1658 snprintf(cmdmsg
, sizeof(cmdmsg
), "Abort SMART off-line mode self-test routine");
1660 snprintf(cmdmsg
, sizeof(cmdmsg
), "SMART EXECUTE OFF-LINE IMMEDIATE subcommand 0x%02x", testtype
);
1662 snprintf(cmdmsg
, sizeof(cmdmsg
), "Execute SMART %s routine immediately in %s mode", type
, captive
);
1663 pout("Sending command: \"%s\".\n",cmdmsg
);
1667 pout("SPAN STARTING_LBA ENDING_LBA\n");
1668 for (i
= 0; i
< selargs_io
.num_spans
; i
++)
1669 pout(" %d %20" PRId64
" %20" PRId64
"\n", i
,
1670 selargs_io
.span
[i
].start
,
1671 selargs_io
.span
[i
].end
);
1674 // Now send the command to test
1675 if (smartcommandhandler(device
, IMMEDIATE_OFFLINE
, testtype
, NULL
)) {
1676 if (!(cap
&& device
->get_errno() == EIO
)) {
1677 pout("Command \"%s\" failed: %s\n", cmdmsg
, device
->get_errmsg());
1682 // Since the command succeeded, tell user
1683 if (testtype
==ABORT_SELF_TEST
)
1684 pout("Self-testing aborted!\n");
1686 pout("Drive command \"%s\" successful.\n", cmdmsg
);
1688 pout("Testing has begun%s.\n", (force
? " (previous test aborted)" : ""));
1693 /* Test Time Functions */
1694 int TestTime(const ata_smart_values
*data
, int testtype
)
1697 case OFFLINE_FULL_SCAN
:
1698 return (int) data
->total_time_to_complete_off_line
;
1699 case SHORT_SELF_TEST
:
1700 case SHORT_CAPTIVE_SELF_TEST
:
1701 return (int) data
->short_test_completion_time
;
1702 case EXTEND_SELF_TEST
:
1703 case EXTEND_CAPTIVE_SELF_TEST
:
1704 if (data
->extend_test_completion_time_b
== 0xff
1705 && data
->extend_test_completion_time_w
!= 0x0000
1706 && data
->extend_test_completion_time_w
!= 0xffff)
1707 return data
->extend_test_completion_time_w
; // ATA-8
1709 return data
->extend_test_completion_time_b
;
1710 case CONVEYANCE_SELF_TEST
:
1711 case CONVEYANCE_CAPTIVE_SELF_TEST
:
1712 return (int) data
->conveyance_test_completion_time
;
1718 // This function tells you both about the ATA error log and the
1719 // self-test error log capability (introduced in ATA-5). The bit is
1720 // poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1721 // SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1722 // word 84 and 87. Top two bits must match the pattern 01. BEFORE
1723 // ATA-6 these top two bits still had to match the pattern 01, but the
1724 // remaining bits were reserved (==0).
1725 int isSmartErrorLogCapable (const ata_smart_values
* data
, const ata_identify_device
* identity
)
1727 unsigned short word84
=identity
->command_set_extension
;
1728 unsigned short word87
=identity
->csf_default
;
1729 int isata6
=identity
->major_rev_num
& (0x01<<6);
1730 int isata7
=identity
->major_rev_num
& (0x01<<7);
1732 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x01))
1735 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x01))
1738 // otherwise we'll use the poorly documented capability bit
1739 return data
->errorlog_capability
& 0x01;
1742 // See previous function. If the error log exists then the self-test
1743 // log should (must?) also exist.
1744 int isSmartTestLogCapable (const ata_smart_values
* data
, const ata_identify_device
*identity
)
1746 unsigned short word84
=identity
->command_set_extension
;
1747 unsigned short word87
=identity
->csf_default
;
1748 int isata6
=identity
->major_rev_num
& (0x01<<6);
1749 int isata7
=identity
->major_rev_num
& (0x01<<7);
1751 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x02))
1754 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x02))
1758 // otherwise we'll use the poorly documented capability bit
1759 return data
->errorlog_capability
& 0x01;
1763 int isGeneralPurposeLoggingCapable(const ata_identify_device
*identity
)
1765 unsigned short word84
=identity
->command_set_extension
;
1766 unsigned short word87
=identity
->csf_default
;
1768 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1769 // cleared to zero, the contents of word 84 contains valid support
1770 // information. If not, support information is not valid in this
1772 if ((word84
>>14) == 0x01)
1773 // If bit 5 of word 84 is set to one, the device supports the
1774 // General Purpose Logging feature set.
1775 return (word84
& (0x01 << 5));
1777 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1778 // cleared to zero, the contents of words (87:85) contain valid
1779 // information. If not, information is not valid in these words.
1780 if ((word87
>>14) == 0x01)
1781 // If bit 5 of word 87 is set to one, the device supports
1782 // the General Purpose Logging feature set.
1783 return (word87
& (0x01 << 5));
1790 // SMART self-test capability is also indicated in bit 1 of DEVICE
1791 // IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1792 // However this was only introduced in ATA-6 (but self-test log was in
1794 int isSupportExecuteOfflineImmediate(const ata_smart_values
*data
)
1796 return data
->offline_data_collection_capability
& 0x01;
1799 // Note in the ATA-5 standard, the following bit is listed as "Vendor
1800 // Specific". So it may not be reliable. The only use of this that I
1801 // have found is in IBM drives, where it is well-documented. See for
1802 // example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1803 // hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
1804 int isSupportAutomaticTimer(const ata_smart_values
* data
)
1806 return data
->offline_data_collection_capability
& 0x02;
1808 int isSupportOfflineAbort(const ata_smart_values
*data
)
1810 return data
->offline_data_collection_capability
& 0x04;
1812 int isSupportOfflineSurfaceScan(const ata_smart_values
* data
)
1814 return data
->offline_data_collection_capability
& 0x08;
1816 int isSupportSelfTest (const ata_smart_values
* data
)
1818 return data
->offline_data_collection_capability
& 0x10;
1820 int isSupportConveyanceSelfTest(const ata_smart_values
* data
)
1822 return data
->offline_data_collection_capability
& 0x20;
1824 int isSupportSelectiveSelfTest(const ata_smart_values
* data
)
1826 return data
->offline_data_collection_capability
& 0x40;
1829 // Get attribute state
1830 ata_attr_state
ata_get_attr_state(const ata_smart_attribute
& attr
,
1832 const ata_smart_threshold_entry
* thresholds
,
1833 const ata_vendor_attr_defs
& defs
,
1834 unsigned char * threshval
/* = 0 */)
1837 return ATTRSTATE_NON_EXISTING
;
1839 // Normalized values (current,worst,threshold) not valid
1840 // if specified by '-v' option.
1841 // (Some SSD disks uses these bytes to store raw value).
1842 if (defs
[attr
.id
].flags
& ATTRFLAG_NO_NORMVAL
)
1843 return ATTRSTATE_NO_NORMVAL
;
1845 // Normally threshold is at same index as attribute
1847 if (thresholds
[i
].id
!= attr
.id
) {
1848 // Find threshold id in table
1849 for (i
= 0; thresholds
[i
].id
!= attr
.id
; ) {
1850 if (++i
>= NUMBER_ATA_SMART_ATTRIBUTES
)
1851 // Threshold id missing or thresholds cannot be read
1852 return ATTRSTATE_NO_THRESHOLD
;
1855 unsigned char threshold
= thresholds
[i
].threshold
;
1857 // Return threshold if requested
1859 *threshval
= threshold
;
1861 // Don't report a failed attribute if its threshold is 0.
1862 // ATA-3 (X3T13/2008D Revision 7b) declares 0x00 as the "always passing"
1863 // threshold (Later ATA versions declare all thresholds as "obsolete").
1864 // In practice, threshold value 0 is often used for usage attributes.
1866 return ATTRSTATE_OK
;
1868 // Failed now if current value is below threshold
1869 if (attr
.current
<= threshold
)
1870 return ATTRSTATE_FAILED_NOW
;
1872 // Failed in the past if worst value is below threshold
1873 if (!(defs
[attr
.id
].flags
& ATTRFLAG_NO_WORSTVAL
) && attr
.worst
<= threshold
)
1874 return ATTRSTATE_FAILED_PAST
;
1876 return ATTRSTATE_OK
;
1879 // Get attribute raw value.
1880 uint64_t ata_get_attr_raw_value(const ata_smart_attribute
& attr
,
1881 const ata_vendor_attr_defs
& defs
)
1883 const ata_vendor_attr_defs::entry
& def
= defs
[attr
.id
];
1884 // TODO: Allow Byteorder in DEFAULT entry
1886 // Use default byteorder if not specified
1887 const char * byteorder
= def
.byteorder
;
1889 switch (def
.raw_format
) {
1892 byteorder
= "543210wv"; break;
1895 case RAWFMT_RAW24_DIV_RAW32
:
1896 case RAWFMT_MSEC24_HOUR32
:
1897 byteorder
= "r543210"; break;
1899 byteorder
= "543210"; break;
1903 // Build 64-bit value from selected bytes
1904 uint64_t rawvalue
= 0;
1905 for (int i
= 0; byteorder
[i
]; i
++) {
1907 switch (byteorder
[i
]) {
1908 case '0': b
= attr
.raw
[0]; break;
1909 case '1': b
= attr
.raw
[1]; break;
1910 case '2': b
= attr
.raw
[2]; break;
1911 case '3': b
= attr
.raw
[3]; break;
1912 case '4': b
= attr
.raw
[4]; break;
1913 case '5': b
= attr
.raw
[5]; break;
1914 case 'r': b
= attr
.reserv
; break;
1915 case 'v': b
= attr
.current
; break;
1916 case 'w': b
= attr
.worst
; break;
1917 default : b
= 0; break;
1919 rawvalue
<<= 8; rawvalue
|= b
;
1925 // Helper functions for RAWFMT_TEMPMINMAX
1926 static inline int check_temp_word(unsigned word
)
1929 return 0x11; // >= 0, signed byte or word
1931 return 0x01; // < 0, signed byte
1933 return 0x10; // < 0, signed word
1937 static bool check_temp_range(int t
, unsigned char ut1
, unsigned char ut2
,
1940 int t1
= (signed char)ut1
, t2
= (signed char)ut2
;
1942 int tx
= t1
; t1
= t2
; t2
= tx
;
1945 if ( -60 <= t1
&& t1
<= t
&& t
<= t2
&& t2
<= 120
1946 && !(t1
== -1 && t2
<= 0) ) {
1953 // Format attribute raw value.
1954 std::string
ata_format_attr_raw_value(const ata_smart_attribute
& attr
,
1955 const ata_vendor_attr_defs
& defs
)
1957 // Get 48 bit or 64 bit raw value
1958 uint64_t rawvalue
= ata_get_attr_raw_value(attr
, defs
);
1960 // Split into bytes and words
1961 unsigned char raw
[6];
1962 raw
[0] = (unsigned char) rawvalue
;
1963 raw
[1] = (unsigned char)(rawvalue
>> 8);
1964 raw
[2] = (unsigned char)(rawvalue
>> 16);
1965 raw
[3] = (unsigned char)(rawvalue
>> 24);
1966 raw
[4] = (unsigned char)(rawvalue
>> 32);
1967 raw
[5] = (unsigned char)(rawvalue
>> 40);
1969 word
[0] = raw
[0] | (raw
[1] << 8);
1970 word
[1] = raw
[2] | (raw
[3] << 8);
1971 word
[2] = raw
[4] | (raw
[5] << 8);
1974 ata_attr_raw_format format
= defs
[attr
.id
].raw_format
;
1975 if (format
== RAWFMT_DEFAULT
) {
1976 // Get format from DEFAULT entry
1977 format
= get_default_attr_defs()[attr
.id
].raw_format
;
1978 if (format
== RAWFMT_DEFAULT
)
1979 // Unknown Attribute
1980 format
= RAWFMT_RAW48
;
1987 s
= strprintf("%d %d %d %d %d %d",
1988 raw
[5], raw
[4], raw
[3], raw
[2], raw
[1], raw
[0]);
1992 s
= strprintf("%u %u %u", word
[2], word
[1], word
[0]);
1998 s
= strprintf("%" PRIu64
, rawvalue
);
2002 s
= strprintf("0x%012" PRIx64
, rawvalue
);
2006 s
= strprintf("0x%014" PRIx64
, rawvalue
);
2010 s
= strprintf("0x%016" PRIx64
, rawvalue
);
2013 case RAWFMT_RAW16_OPT_RAW16
:
2014 s
= strprintf("%u", word
[0]);
2015 if (word
[1] || word
[2])
2016 s
+= strprintf(" (%u %u)", word
[2], word
[1]);
2019 case RAWFMT_RAW16_OPT_AVG16
:
2020 s
= strprintf("%u", word
[0]);
2022 s
+= strprintf(" (Average %u)", word
[1]);
2025 case RAWFMT_RAW24_OPT_RAW8
:
2026 s
= strprintf("%u", (unsigned)(rawvalue
& 0x00ffffffULL
));
2027 if (raw
[3] || raw
[4] || raw
[5])
2028 s
+= strprintf(" (%d %d %d)", raw
[5], raw
[4], raw
[3]);
2031 case RAWFMT_RAW24_DIV_RAW24
:
2032 s
= strprintf("%u/%u",
2033 (unsigned)(rawvalue
>> 24), (unsigned)(rawvalue
& 0x00ffffffULL
));
2036 case RAWFMT_RAW24_DIV_RAW32
:
2037 s
= strprintf("%u/%u",
2038 (unsigned)(rawvalue
>> 32), (unsigned)(rawvalue
& 0xffffffffULL
));
2041 case RAWFMT_MIN2HOUR
:
2044 int64_t temp
= word
[0]+(word
[1]<<16);
2045 int64_t tmp1
= temp
/60;
2046 int64_t tmp2
= temp
%60;
2047 s
= strprintf("%" PRIu64
"h+%02" PRIu64
"m", tmp1
, tmp2
);
2049 s
+= strprintf(" (%u)", word
[2]);
2053 case RAWFMT_SEC2HOUR
:
2056 int64_t hours
= rawvalue
/3600;
2057 int64_t minutes
= (rawvalue
-3600*hours
)/60;
2058 int64_t seconds
= rawvalue
%60;
2059 s
= strprintf("%" PRIu64
"h+%02" PRIu64
"m+%02" PRIu64
"s", hours
, minutes
, seconds
);
2063 case RAWFMT_HALFMIN2HOUR
:
2065 // 30-second counter
2066 int64_t hours
= rawvalue
/120;
2067 int64_t minutes
= (rawvalue
-120*hours
)/2;
2068 s
+= strprintf("%" PRIu64
"h+%02" PRIu64
"m", hours
, minutes
);
2072 case RAWFMT_MSEC24_HOUR32
:
2074 // hours + milliseconds
2075 unsigned hours
= (unsigned)(rawvalue
& 0xffffffffULL
);
2076 unsigned milliseconds
= (unsigned)(rawvalue
>> 32);
2077 unsigned seconds
= milliseconds
/ 1000;
2078 s
= strprintf("%uh+%02um+%02u.%03us",
2079 hours
, seconds
/ 60, seconds
% 60, milliseconds
% 1000);
2083 case RAWFMT_TEMPMINMAX
:
2086 // Search for possible min/max values
2087 // [5][4][3][2][1][0] raw[]
2088 // [ 2 ] [ 1 ] [ 0 ] word[]
2089 // xx HH xx LL xx TT (Hitachi/HGST)
2090 // xx LL xx HH xx TT (Kingston SSDs)
2091 // 00 00 HH LL xx TT (Maxtor, Samsung, Seagate, Toshiba)
2092 // 00 00 00 HH LL TT (WDC)
2093 // CC CC HH LL xx TT (WDC, CCCC=over temperature count)
2094 // (xx = 00/ff, possibly sign extension of lower byte)
2096 int t
= (signed char)raw
[0];
2100 int ctw0
= check_temp_word(word
[0]);
2102 if (!word
[1] && ctw0
)
2103 // 00 00 00 00 xx TT
2105 else if (ctw0
&& check_temp_range(t
, raw
[2], raw
[3], lo
, hi
))
2106 // 00 00 HL LH xx TT
2108 else if (!raw
[3] && check_temp_range(t
, raw
[1], raw
[2], lo
, hi
))
2109 // 00 00 00 HL LH TT
2115 if ( (ctw0
& check_temp_word(word
[1]) & check_temp_word(word
[2])) != 0x00
2116 && check_temp_range(t
, raw
[2], raw
[4], lo
, hi
) )
2117 // xx HL xx LH xx TT
2119 else if ( word
[2] < 0x7fff
2120 && check_temp_range(t
, raw
[2], raw
[3], lo
, hi
)
2122 // CC CC HL LH xx TT
2132 s
= strprintf("%d", t
);
2134 case 1: case 2: case 3:
2135 s
= strprintf("%d (Min/Max %d/%d)", t
, lo
, hi
);
2138 s
= strprintf("%d (Min/Max %d/%d #%d)", t
, lo
, hi
, word
[2]);
2141 s
= strprintf("%d (%d %d %d %d %d)", raw
[0], raw
[5], raw
[4], raw
[3], raw
[2], raw
[1]);
2147 case RAWFMT_TEMP10X
:
2148 // ten times temperature in Celsius
2149 s
= strprintf("%d.%d", word
[0]/10, word
[0]%10);
2153 s
= "?"; // Should not happen
2160 // Get attribute name
2161 std::string
ata_get_smart_attr_name(unsigned char id
, const ata_vendor_attr_defs
& defs
,
2164 if (!defs
[id
].name
.empty())
2165 return defs
[id
].name
;
2167 const ata_vendor_attr_defs::entry
& def
= get_default_attr_defs()[id
];
2168 if (def
.name
.empty())
2169 return "Unknown_Attribute";
2170 else if ((def
.flags
& ATTRFLAG_HDD_ONLY
) && rpm
== 1)
2171 return "Unknown_SSD_Attribute";
2172 else if ((def
.flags
& ATTRFLAG_SSD_ONLY
) && rpm
> 1)
2173 return "Unknown_HDD_Attribute";
2179 // Find attribute index for attribute id, -1 if not found.
2180 int ata_find_attr_index(unsigned char id
, const ata_smart_values
& smartval
)
2184 for (int i
= 0; i
< NUMBER_ATA_SMART_ATTRIBUTES
; i
++) {
2185 if (smartval
.vendor_attributes
[i
].id
== id
)
2191 // Return Temperature Attribute raw value selected according to possible
2192 // non-default interpretations. If the Attribute does not exist, return 0
2193 unsigned char ata_return_temperature_value(const ata_smart_values
* data
, const ata_vendor_attr_defs
& defs
)
2195 for (int i
= 0; i
< 4; i
++) {
2196 static const unsigned char ids
[4] = {194, 190, 9, 220};
2197 unsigned char id
= ids
[i
];
2198 const ata_attr_raw_format format
= defs
[id
].raw_format
;
2199 if (!( ((id
== 194 || id
== 190) && format
== RAWFMT_DEFAULT
)
2200 || format
== RAWFMT_TEMPMINMAX
|| format
== RAWFMT_TEMP10X
))
2202 int idx
= ata_find_attr_index(id
, *data
);
2205 uint64_t raw
= ata_get_attr_raw_value(data
->vendor_attributes
[idx
], defs
);
2207 // ignore possible min/max values in high words
2208 if (format
== RAWFMT_TEMP10X
) // -v N,temp10x
2209 temp
= ((unsigned short)raw
+ 5) / 10;
2211 temp
= (unsigned char)raw
;
2212 if (!(0 < temp
&& temp
< 128))
2216 // No valid attribute found
2222 int ataReadSCTStatus(ata_device
* device
, ata_sct_status_response
* sts
)
2224 // read SCT status via SMART log 0xe0
2225 memset(sts
, 0, sizeof(*sts
));
2226 if (smartcommandhandler(device
, READ_LOG
, 0xe0, (char *)sts
)){
2227 pout("Read SCT Status failed: %s\n", device
->get_errmsg());
2231 // swap endian order if needed
2233 swapx(&sts
->format_version
);
2234 swapx(&sts
->sct_version
);
2235 swapx(&sts
->sct_spec
);
2236 swapx(&sts
->ext_status_code
);
2237 swapx(&sts
->action_code
);
2238 swapx(&sts
->function_code
);
2239 swapx(&sts
->over_limit_count
);
2240 swapx(&sts
->under_limit_count
);
2241 swapx(&sts
->smart_status
);
2244 // Check format version
2245 if (!(sts
->format_version
== 2 || sts
->format_version
== 3)) {
2246 pout("Unknown SCT Status format version %u, should be 2 or 3.\n", sts
->format_version
);
2252 // Read SCT Temperature History Table
2253 int ataReadSCTTempHist(ata_device
* device
, ata_sct_temperature_history_table
* tmh
,
2254 ata_sct_status_response
* sts
)
2256 // Initial SCT status must be provided by caller
2258 // Do nothing if other SCT command is executing
2259 if (sts
->ext_status_code
== 0xffff) {
2260 pout("Another SCT command is executing, abort Read Data Table\n"
2261 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2262 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2266 ata_sct_data_table_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2267 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2268 cmd
.action_code
= 5; // Data table command
2269 cmd
.function_code
= 1; // Read table
2270 cmd
.table_id
= 2; // Temperature History Table
2272 // swap endian order if needed
2273 if (isbigendian()) {
2274 swapx(&cmd
.action_code
);
2275 swapx(&cmd
.function_code
);
2276 swapx(&cmd
.table_id
);
2279 // write command via SMART log page 0xe0
2280 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2281 pout("Write SCT Data Table failed: %s\n", device
->get_errmsg());
2285 // read SCT data via SMART log page 0xe1
2286 memset(tmh
, 0, sizeof(*tmh
));
2287 if (smartcommandhandler(device
, READ_LOG
, 0xe1, (char *)tmh
)){
2288 pout("Read SCT Data Table failed: %s\n", device
->get_errmsg());
2292 // re-read and check SCT status
2293 if (ataReadSCTStatus(device
, sts
))
2296 if (!(sts
->ext_status_code
== 0 && sts
->action_code
== 5 && sts
->function_code
== 1)) {
2297 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2298 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2302 // swap endian order if needed
2304 swapx(&tmh
->format_version
);
2305 swapx(&tmh
->sampling_period
);
2306 swapx(&tmh
->interval
);
2307 swapx(&tmh
->cb_index
);
2308 swapx(&tmh
->cb_size
);
2313 // Get/Set Write Cache Reordering
2314 int ataGetSetSCTWriteCacheReordering(ata_device
* device
, bool enable
, bool persistent
, bool set
)
2316 // Check initial status
2317 ata_sct_status_response sts
;
2318 if (ataReadSCTStatus(device
, &sts
))
2321 // Do nothing if other SCT command is executing
2322 if (sts
.ext_status_code
== 0xffff) {
2323 pout("Another SCT command is executing, abort Feature Control\n"
2324 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2325 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2329 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2330 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2331 cmd
.action_code
= 4; // Feature Control command
2332 cmd
.function_code
= (set
? 1 : 2); // 1=Set, 2=Get
2333 cmd
.feature_code
= 2; // Enable/Disable Write Cache Reordering
2334 cmd
.state
= (enable
? 1 : 2); // 1 enable, 2 disable
2335 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2337 // swap endian order if needed
2338 if (isbigendian()) {
2339 swapx(&cmd
.action_code
);
2340 swapx(&cmd
.function_code
);
2341 swapx(&cmd
.feature_code
);
2343 swapx(&cmd
.option_flags
);
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("Write SCT (%cet) Feature Control Command failed: %s\n",
2362 (!set
? 'G' : 'S'), device
->get_errmsg());
2365 int state
= out
.out_regs
.sector_count
| (out
.out_regs
.lba_low
<< 8);
2367 // re-read and check SCT status
2368 if (ataReadSCTStatus(device
, &sts
))
2371 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== (set
? 1 : 2))) {
2372 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2373 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2380 // Set SCT Temperature Logging Interval
2381 int ataSetSCTTempInterval(ata_device
* device
, unsigned interval
, bool persistent
)
2383 // Check initial status
2384 ata_sct_status_response sts
;
2385 if (ataReadSCTStatus(device
, &sts
))
2388 // Do nothing if other SCT command is executing
2389 if (sts
.ext_status_code
== 0xffff) {
2390 pout("Another SCT command is executing, abort Feature Control\n"
2391 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2392 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2396 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2397 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2398 cmd
.action_code
= 4; // Feature Control command
2399 cmd
.function_code
= 1; // Set state
2400 cmd
.feature_code
= 3; // Temperature logging interval
2401 cmd
.state
= interval
;
2402 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2404 // swap endian order if needed
2405 if (isbigendian()) {
2406 swapx(&cmd
.action_code
);
2407 swapx(&cmd
.function_code
);
2408 swapx(&cmd
.feature_code
);
2410 swapx(&cmd
.option_flags
);
2413 // write command via SMART log page 0xe0
2414 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2415 pout("Write SCT Feature Control Command failed: %s\n", device
->get_errmsg());
2419 // re-read and check SCT status
2420 if (ataReadSCTStatus(device
, &sts
))
2423 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== 1)) {
2424 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2425 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2431 // Get/Set SCT Error Recovery Control
2432 static int ataGetSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
,
2433 bool set
, unsigned short & time_limit
)
2435 // Check initial status
2436 ata_sct_status_response sts
;
2437 if (ataReadSCTStatus(device
, &sts
))
2440 // Do nothing if other SCT command is executing
2441 if (sts
.ext_status_code
== 0xffff) {
2442 pout("Another SCT command is executing, abort Error Recovery Control\n"
2443 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2444 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2448 ata_sct_error_recovery_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2449 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2450 cmd
.action_code
= 3; // Error Recovery Control command
2451 cmd
.function_code
= (set
? 1 : 2); // 1=Set timer, 2=Get timer
2452 cmd
.selection_code
= type
; // 1=Read timer, 2=Write timer
2454 cmd
.time_limit
= time_limit
;
2456 // swap endian order if needed
2457 if (isbigendian()) {
2458 swapx(&cmd
.action_code
);
2459 swapx(&cmd
.function_code
);
2460 swapx(&cmd
.selection_code
);
2461 swapx(&cmd
.time_limit
);
2464 // write command via SMART log page 0xe0
2465 // TODO: Debug output
2467 in
.in_regs
.command
= ATA_SMART_CMD
;
2468 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
2469 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
2470 in
.in_regs
.lba_low
= 0xe0;
2471 in
.set_data_out(&cmd
, 1);
2474 // Time limit returned in ATA registers
2475 in
.out_needed
.sector_count
= in
.out_needed
.lba_low
= true;
2478 if (!device
->ata_pass_through(in
, out
)) {
2479 pout("Write SCT (%cet) Error Recovery Control Command failed: %s\n",
2480 (!set
? 'G' : 'S'), device
->get_errmsg());
2484 // re-read and check SCT status
2485 if (ataReadSCTStatus(device
, &sts
))
2488 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 3 && sts
.function_code
== (set
? 1 : 2))) {
2489 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2490 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2495 // Check whether registers are properly returned by ioctl()
2496 if (!(out
.out_regs
.sector_count
.is_set() && out
.out_regs
.lba_low
.is_set())) {
2497 // TODO: Output register support should be checked within each ata_pass_through()
2498 // implementation before command is issued.
2499 pout("SMART WRITE LOG does not return COUNT and LBA_LOW register\n");
2502 if ( out
.out_regs
.sector_count
== in
.in_regs
.sector_count
2503 && out
.out_regs
.lba_low
== in
.in_regs
.lba_low
) {
2504 // 0xe001 (5734.5s) - this is most likely a broken ATA pass-through implementation
2505 pout("SMART WRITE LOG returns COUNT and LBA_LOW register unchanged\n");
2509 // Return value to caller
2510 time_limit
= out
.out_regs
.sector_count
| (out
.out_regs
.lba_low
<< 8);
2516 // Get SCT Error Recovery Control
2517 int ataGetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short & time_limit
)
2519 return ataGetSetSCTErrorRecoveryControltime(device
, type
, false/*get*/, time_limit
);
2522 // Set SCT Error Recovery Control
2523 int ataSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short time_limit
)
2525 return ataGetSetSCTErrorRecoveryControltime(device
, type
, true/*set*/, time_limit
);
2529 // Print one self-test log entry.
2531 // -1: self-test failed
2532 // 1: extended self-test completed without error
2534 int ataPrintSmartSelfTestEntry(unsigned testnum
, unsigned char test_type
,
2535 unsigned char test_status
,
2536 unsigned short timestamp
,
2537 uint64_t failing_lba
,
2538 bool print_error_only
, bool & print_header
)
2540 // Check status and type for return value
2542 switch (test_status
>> 4) {
2544 if ((test_type
& 0x0f) == 0x02)
2545 retval
= 1; // extended self-test completed without error
2550 retval
= -1; // self-test failed
2554 if (retval
>= 0 && print_error_only
)
2557 std::string msgtest
;
2558 switch (test_type
) {
2559 case 0x00: msgtest
= "Offline"; break;
2560 case 0x01: msgtest
= "Short offline"; break;
2561 case 0x02: msgtest
= "Extended offline"; break;
2562 case 0x03: msgtest
= "Conveyance offline"; break;
2563 case 0x04: msgtest
= "Selective offline"; break;
2564 case 0x7f: msgtest
= "Abort offline test"; break;
2565 case 0x81: msgtest
= "Short captive"; break;
2566 case 0x82: msgtest
= "Extended captive"; break;
2567 case 0x83: msgtest
= "Conveyance captive"; break;
2568 case 0x84: msgtest
= "Selective captive"; break;
2570 if ((0x40 <= test_type
&& test_type
<= 0x7e) || 0x90 <= test_type
)
2571 msgtest
= strprintf("Vendor (0x%02x)", test_type
);
2573 msgtest
= strprintf("Reserved (0x%02x)", test_type
);
2576 std::string msgstat
;
2577 switch (test_status
>> 4) {
2578 case 0x0: msgstat
= "Completed without error"; break;
2579 case 0x1: msgstat
= "Aborted by host"; break;
2580 case 0x2: msgstat
= "Interrupted (host reset)"; break;
2581 case 0x3: msgstat
= "Fatal or unknown error"; break;
2582 case 0x4: msgstat
= "Completed: unknown failure"; break;
2583 case 0x5: msgstat
= "Completed: electrical failure"; break;
2584 case 0x6: msgstat
= "Completed: servo/seek failure"; break;
2585 case 0x7: msgstat
= "Completed: read failure"; break;
2586 case 0x8: msgstat
= "Completed: handling damage??"; break;
2587 case 0xf: msgstat
= "Self-test routine in progress"; break;
2588 default: msgstat
= strprintf("Unknown status (0x%x)", test_status
>> 4);
2591 // Print header once
2593 print_header
= false;
2594 pout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2598 if (retval
< 0 && failing_lba
< 0xffffffffffffULL
)
2599 snprintf(msglba
, sizeof(msglba
), "%" PRIu64
, failing_lba
);
2601 msglba
[0] = '-'; msglba
[1] = 0;
2604 pout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum
,
2605 msgtest
.c_str(), msgstat
.c_str(), test_status
& 0x0f, timestamp
, msglba
);
2610 // Print Smart self-test log, used by smartctl and smartd.
2612 // bottom 8 bits: number of entries found where self-test showed an error
2613 // remaining bits: if nonzero, power on hours of last self-test where error was found
2614 int ataPrintSmartSelfTestlog(const ata_smart_selftestlog
* data
, bool allentries
,
2615 firmwarebug_defs firmwarebugs
)
2618 pout("SMART Self-test log structure revision number %d\n",(int)data
->revnumber
);
2619 if (data
->revnumber
!= 0x0001 && allentries
&& !firmwarebugs
.is_set(BUG_SAMSUNG
))
2620 pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2621 if (data
->mostrecenttest
==0){
2623 pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n");
2627 bool noheaderprinted
= true;
2628 int errcnt
= 0, hours
= 0, igncnt
= 0;
2629 int testno
= 0, ext_ok_testno
= -1;
2632 for (int i
= 20; i
>= 0; i
--) {
2633 // log is a circular buffer
2634 int j
= (i
+data
->mostrecenttest
)%21;
2635 const ata_smart_selftestlog_struct
* log
= data
->selftest_struct
+j
;
2637 if (nonempty(log
, sizeof(*log
))) {
2638 // count entry based on non-empty structures -- needed for
2639 // Seagate only -- other vendors don't have blank entries 'in
2643 // T13/1321D revision 1c: (Data structure Rev #1)
2645 //The failing LBA shall be the LBA of the uncorrectable sector
2646 //that caused the test to fail. If the device encountered more
2647 //than one uncorrectable sector during the test, this field
2648 //shall indicate the LBA of the first uncorrectable sector
2649 //encountered. If the test passed or the test failed for some
2650 //reason other than an uncorrectable sector, the value of this
2651 //field is undefined.
2653 // This is true in ALL ATA-5 specs
2654 uint64_t lba48
= (log
->lbafirstfailure
< 0xffffffff ? log
->lbafirstfailure
: 0xffffffffffffULL
);
2657 int state
= ataPrintSmartSelfTestEntry(testno
,
2658 log
->selftestnumber
, log
->selfteststatus
,
2659 log
->timestamp
, lba48
, !allentries
, noheaderprinted
);
2662 // Self-test showed an error
2663 if (ext_ok_testno
< 0) {
2666 // keep track of time of most recent error
2668 hours
= log
->timestamp
;
2671 // Newer successful extended self-test exits
2674 else if (state
> 0 && ext_ok_testno
< 0) {
2675 // Latest successful extended self-test
2676 ext_ok_testno
= testno
;
2682 pout("%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2683 igncnt
, igncnt
+errcnt
, ext_ok_testno
);
2685 if (!allentries
&& !noheaderprinted
)
2688 return ((hours
<< 8) | errcnt
);
2692 /////////////////////////////////////////////////////////////////////////////
2693 // Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2694 // an ATA device with same behaviour
2698 class parsed_ata_device
2699 : public /*implements*/ ata_device_with_command_set
2702 parsed_ata_device(smart_interface
* intf
, const char * dev_name
);
2704 virtual ~parsed_ata_device() throw();
2706 virtual bool is_open() const;
2708 virtual bool open();
2710 virtual bool close();
2712 virtual bool ata_identify_is_cached() const;
2715 virtual int ata_command_interface(smart_command_set command
, int select
, char * data
);
2718 // Table of parsed commands, return value, data
2719 struct parsed_ata_command
2721 smart_command_set command
;
2727 enum { max_num_commands
= 32 };
2728 parsed_ata_command m_command_table
[max_num_commands
];
2731 int m_next_replay_command
;
2732 bool m_replay_out_of_sync
;
2733 bool m_ata_identify_is_cached
;
2736 static const char * nextline(const char * s
, int & lineno
)
2738 for (s
+= strcspn(s
, "\r\n"); *s
== '\r' || *s
== '\n'; s
++) {
2739 if (*s
== '\r' && s
[1] == '\n')
2746 static int name2command(const char * s
)
2748 for (int i
= 0; i
< (int)(sizeof(commandstrings
)/sizeof(commandstrings
[0])); i
++) {
2749 if (!strcmp(s
, commandstrings
[i
]))
2755 static bool matchcpy(char * dest
, size_t size
, const char * src
, const regmatch_t
& srcmatch
)
2757 if (srcmatch
.rm_so
< 0)
2759 size_t n
= srcmatch
.rm_eo
- srcmatch
.rm_so
;
2762 memcpy(dest
, src
+ srcmatch
.rm_so
, n
);
2767 static inline int matchtoi(const char * src
, const regmatch_t
& srcmatch
, int defval
)
2769 if (srcmatch
.rm_so
< 0)
2771 return atoi(src
+ srcmatch
.rm_so
);
2774 parsed_ata_device::parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2775 : smart_device(intf
, dev_name
, "ata", ""),
2777 m_next_replay_command(0),
2778 m_replay_out_of_sync(false),
2779 m_ata_identify_is_cached(false)
2781 memset(m_command_table
, 0, sizeof(m_command_table
));
2784 parsed_ata_device::~parsed_ata_device() throw()
2789 bool parsed_ata_device::is_open() const
2791 return (m_num_commands
> 0);
2794 // Parse stdin and build command table
2795 bool parsed_ata_device::open()
2797 const char * pathname
= get_dev_name();
2798 if (strcmp(pathname
, "-"))
2799 return set_err(EINVAL
);
2800 pathname
= "<stdin>";
2802 char buffer
[64*1024];
2804 while (size
< (int)sizeof(buffer
)) {
2805 int nr
= fread(buffer
, 1, sizeof(buffer
), stdin
);
2811 return set_err(ENOENT
, "%s: Unexpected EOF", pathname
);
2812 if (size
>= (int)sizeof(buffer
))
2813 return set_err(EIO
, "%s: Buffer overflow", pathname
);
2816 // Regex to match output from "-r ataioctl,2"
2817 static const char pattern
[] = "^"
2819 "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
2821 "( InputParameter=([0-9]+))?" // (4 (5))
2823 "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2825 "[\r\n]" // EOL match necessary to match optional parts above
2827 "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2829 " *(En|Dis)abled status cached by OS, " // (11)
2833 const regular_expression
regex(pattern
, REG_EXTENDED
);
2836 const char * errmsg
= 0;
2837 int i
= -1, state
= 0, lineno
= 1;
2838 for (const char * line
= buffer
; *line
; line
= nextline(line
, lineno
)) {
2840 if (!(line
[0] == 'R' || line
[0] == '=' || line
[0] == ' '))
2842 const int nmatch
= 1+11;
2843 regmatch_t match
[nmatch
];
2844 if (!regex
.execute(line
, nmatch
, match
))
2848 if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[2])) { // "REPORT-IOCTL:... Command=%s ..."
2849 int nc
= name2command(cmdname
);
2851 errmsg
= "Unknown ATA command name"; break;
2853 if (match
[7].rm_so
< 0) { // "returned %d"
2855 if (!(state
== 0 || state
== 2)) {
2856 errmsg
= "Missing REPORT-IOCTL result"; break;
2858 if (++i
>= max_num_commands
) {
2859 errmsg
= "Too many ATA commands"; break;
2861 m_command_table
[i
].command
= (smart_command_set
)nc
;
2862 m_command_table
[i
].select
= matchtoi(line
, match
[5], 0); // "InputParameter=%d"
2867 if (!(state
== 1 && (int)m_command_table
[i
].command
== nc
)) {
2868 errmsg
= "Missing REPORT-IOCTL start"; break;
2870 m_command_table
[i
].retval
= matchtoi(line
, match
[7], -1); // "returned %d"
2871 m_command_table
[i
].errval
= matchtoi(line
, match
[9], 0); // "errno=%d"
2875 else if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[10])) { // "===== [%s] DATA START "
2876 // Start of sector hexdump
2877 int nc
= name2command(cmdname
);
2878 if (!(state
== (nc
== WRITE_LOG
? 1 : 2) && (int)m_command_table
[i
].command
== nc
)) {
2879 errmsg
= "Unexpected DATA START"; break;
2881 line
= nextline(line
, lineno
);
2882 char * data
= (char *)malloc(512);
2884 for (j
= 0; j
< 32; j
++) {
2886 unsigned u1
, u2
; int n1
= -1;
2887 if (!(sscanf(line
, "%3u-%3u: "
2888 "%2x %2x %2x %2x %2x %2x %2x %2x "
2889 "%2x %2x %2x %2x %2x %2x %2x %2x%n",
2891 b
+ 0, b
+ 1, b
+ 2, b
+ 3, b
+ 4, b
+ 5, b
+ 6, b
+ 7,
2892 b
+ 8, b
+ 9, b
+10, b
+11, b
+12, b
+13, b
+14, b
+15, &n1
) == 18
2893 && n1
>= 56 && u1
== j
*16 && u2
== j
*16+15))
2895 for (unsigned k
= 0; k
< 16; k
++)
2896 data
[j
*16+k
] = b
[k
];
2897 line
= nextline(line
, lineno
);
2901 errmsg
= "Incomplete sector hex dump"; break;
2903 m_command_table
[i
].data
= data
;
2904 if (nc
!= WRITE_LOG
)
2907 else if (match
[11].rm_so
> 0) { // "(En|Dis)abled status cached by OS"
2908 m_ata_identify_is_cached
= true;
2912 if (!(state
== 0 || state
== 2))
2913 errmsg
= "Missing REPORT-IOCTL result";
2915 if (!errmsg
&& i
< 0)
2916 errmsg
= "No information found";
2918 m_num_commands
= i
+1;
2919 m_next_replay_command
= 0;
2920 m_replay_out_of_sync
= false;
2924 return set_err(EIO
, "%s(%d): Syntax error: %s", pathname
, lineno
, errmsg
);
2929 // Report warnings and free command table
2930 bool parsed_ata_device::close()
2932 if (m_replay_out_of_sync
)
2933 pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
2934 else if (m_next_replay_command
!= 0)
2935 pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands
-m_next_replay_command
);
2937 for (int i
= 0; i
< m_num_commands
; i
++) {
2938 if (m_command_table
[i
].data
) {
2939 free(m_command_table
[i
].data
); m_command_table
[i
].data
= 0;
2943 m_next_replay_command
= 0;
2944 m_replay_out_of_sync
= false;
2949 bool parsed_ata_device::ata_identify_is_cached() const
2951 return m_ata_identify_is_cached
;
2955 // Simulate ATA command from command table
2956 int parsed_ata_device::ata_command_interface(smart_command_set command
, int select
, char * data
)
2958 // Find command, try round-robin if out of sync
2959 int i
= m_next_replay_command
;
2960 for (int j
= 0; ; j
++) {
2961 if (j
>= m_num_commands
) {
2962 pout("REPLAY-IOCTL: Warning: Command not found\n");
2966 if (m_command_table
[i
].command
== command
&& m_command_table
[i
].select
== select
)
2968 if (!m_replay_out_of_sync
) {
2969 m_replay_out_of_sync
= true;
2970 pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i
+1);
2972 if (++i
>= m_num_commands
)
2975 m_next_replay_command
= i
;
2976 if (++m_next_replay_command
>= m_num_commands
)
2977 m_next_replay_command
= 0;
2979 // Return command data
2984 case READ_THRESHOLDS
:
2986 if (m_command_table
[i
].data
)
2987 memcpy(data
, m_command_table
[i
].data
, 512);
2990 if (!(m_command_table
[i
].data
&& !memcmp(data
, m_command_table
[i
].data
, 512)))
2991 pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
2993 case CHECK_POWER_MODE
:
2994 data
[0] = (char)0xff;
2999 if (m_command_table
[i
].errval
)
3000 errno
= m_command_table
[i
].errval
;
3001 return m_command_table
[i
].retval
;
3006 ata_device
* get_parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
3008 return new parsed_ata_device(intf
, dev_name
);