4 * Home page of code is: http://www.smartmontools.org
6 * Copyright (C) 2002-11 Bruce Allen
7 * Copyright (C) 2008-18 Christian Franke
8 * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
9 * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
11 * SPDX-License-Identifier: GPL-2.0-or-later
15 #define __STDC_FORMAT_MACROS 1 // enable PRI* for C++
25 #include "knowndrives.h" // get_default_attr_defs()
27 #include "dev_ata_cmd_set.h" // for parsed_ata_device
29 const char * atacmds_cpp_cvsid
= "$Id: atacmds.cpp 4842 2018-12-02 16:07:26Z chrfranke $"
32 // Print ATA debug messages?
33 unsigned char ata_debugmode
= 0;
35 // Suppress serial number?
36 // (also used in scsiprint.cpp)
37 bool dont_print_serial_number
= false;
40 #define SMART_CYL_LOW 0x4F
41 #define SMART_CYL_HI 0xC2
43 // SMART RETURN STATUS yields SMART_CYL_HI,SMART_CYL_LOW to indicate drive
44 // is healthy and SRET_STATUS_HI_EXCEEDED,SRET_STATUS_MID_EXCEEDED to
45 // indicate that a threshold exceeded condition has been detected.
46 // Those values (byte pairs) are placed in ATA register "LBA 23:8".
47 #define SRET_STATUS_HI_EXCEEDED 0x2C
48 #define SRET_STATUS_MID_EXCEEDED 0xF4
51 // Get ID and increase flag of current pending or offline
52 // uncorrectable attribute.
53 unsigned char get_unc_attr_id(bool offline
, const ata_vendor_attr_defs
& defs
,
56 unsigned char id
= (!offline
? 197 : 198);
57 const ata_vendor_attr_defs::entry
& def
= defs
[id
];
58 if (def
.flags
& ATTRFLAG_INCREASING
)
59 increase
= true; // '-v 19[78],increasing' option
60 else if (def
.name
.empty() || (id
== 198 && def
.name
== "Offline_Scan_UNC_SectCt"))
61 increase
= false; // no or '-v 198,offlinescanuncsectorct' option
63 id
= 0; // other '-v 19[78],...' option
67 #if 0 // TODO: never used
68 // This are the meanings of the Self-test failure checkpoint byte.
69 // This is in the self-test log at offset 4 bytes into the self-test
70 // descriptor and in the SMART READ DATA structure at byte offset
71 // 371. These codes are not well documented. The meanings returned by
72 // this routine are used (at least) by Maxtor and IBM. Returns NULL if
73 // not recognized. Currently the maximum length is 15 bytes.
74 const char *SelfTestFailureCodeName(unsigned char which
){
82 return "Servo_Random";
86 return "Handling_Damage";
96 // Table of raw print format names
97 struct format_name_entry
100 ata_attr_raw_format format
;
103 const format_name_entry format_names
[] = {
104 {"raw8" , RAWFMT_RAW8
},
105 {"raw16" , RAWFMT_RAW16
},
106 {"raw48" , RAWFMT_RAW48
},
107 {"hex48" , RAWFMT_HEX48
},
108 {"raw56" , RAWFMT_RAW56
},
109 {"hex56" , RAWFMT_HEX56
},
110 {"raw64" , RAWFMT_RAW64
},
111 {"hex64" , RAWFMT_HEX64
},
112 {"raw16(raw16)" , RAWFMT_RAW16_OPT_RAW16
},
113 {"raw16(avg16)" , RAWFMT_RAW16_OPT_AVG16
},
114 {"raw24(raw8)" , RAWFMT_RAW24_OPT_RAW8
},
115 {"raw24/raw24" , RAWFMT_RAW24_DIV_RAW24
},
116 {"raw24/raw32" , RAWFMT_RAW24_DIV_RAW32
},
117 {"sec2hour" , RAWFMT_SEC2HOUR
},
118 {"min2hour" , RAWFMT_MIN2HOUR
},
119 {"halfmin2hour" , RAWFMT_HALFMIN2HOUR
},
120 {"msec24hour32" , RAWFMT_MSEC24_HOUR32
},
121 {"tempminmax" , RAWFMT_TEMPMINMAX
},
122 {"temp10x" , RAWFMT_TEMP10X
},
125 const unsigned num_format_names
= sizeof(format_names
)/sizeof(format_names
[0]);
127 // Table to map old to new '-v' option arguments
128 const char * const map_old_vendor_opts
[][2] = {
129 { "9,halfminutes" , "9,halfmin2hour,Power_On_Half_Minutes"},
130 { "9,minutes" , "9,min2hour,Power_On_Minutes"},
131 { "9,seconds" , "9,sec2hour,Power_On_Seconds"},
132 { "9,temp" , "9,tempminmax,Temperature_Celsius"},
133 {"192,emergencyretractcyclect" , "192,raw48,Emerg_Retract_Cycle_Ct"},
134 {"193,loadunload" , "193,raw24/raw24"},
135 {"194,10xCelsius" , "194,temp10x,Temperature_Celsius_x10"},
136 {"194,unknown" , "194,raw48,Unknown_Attribute"},
137 {"197,increasing" , "197,raw48+,Total_Pending_Sectors"}, // '+' sets flag
138 {"198,offlinescanuncsectorct" , "198,raw48,Offline_Scan_UNC_SectCt"}, // see also get_unc_attr_id() above
139 {"198,increasing" , "198,raw48+,Total_Offl_Uncorrectabl"}, // '+' sets flag
140 {"200,writeerrorcount" , "200,raw48,Write_Error_Count"},
141 {"201,detectedtacount" , "201,raw48,Detected_TA_Count"},
142 {"220,temp" , "220,tempminmax,Temperature_Celsius"},
145 const unsigned num_old_vendor_opts
= sizeof(map_old_vendor_opts
)/sizeof(map_old_vendor_opts
[0]);
147 // Parse vendor attribute display def (-v option).
148 // Return false on error.
149 bool parse_attribute_def(const char * opt
, ata_vendor_attr_defs
& defs
,
150 ata_vendor_def_prior priority
)
152 // Map old -> new options
154 for (i
= 0; i
< num_old_vendor_opts
; i
++) {
155 if (!strcmp(opt
, map_old_vendor_opts
[i
][0])) {
156 opt
= map_old_vendor_opts
[i
][1];
162 int len
= strlen(opt
);
163 int id
= 0, n1
= -1, n2
= -1;
164 char fmtname
[32+1], attrname
[32+1], hddssd
[3+1];
165 attrname
[0] = hddssd
[0] = 0;
169 if (!( sscanf(opt
, "N,%32[^,]%n,%32[^,]%n", fmtname
, &n1
, attrname
, &n2
) >= 1
170 && (n1
== len
|| n2
== len
)))
174 // "id,format[+][,name[,HDD|SSD]]"
176 if (!( sscanf(opt
, "%d,%32[^,]%n,%32[^,]%n,%3[DHS]%n",
177 &id
, fmtname
, &n1
, attrname
, &n2
, hddssd
, &n3
) >= 2
178 && 1 <= id
&& id
<= 255
179 && ( n1
== len
|| n2
== len
180 // ",HDD|SSD" for DEFAULT settings only
181 || (n3
== len
&& priority
== PRIOR_DEFAULT
))))
186 // For "-v 19[78],increasing" above
187 if (fmtname
[strlen(fmtname
)-1] == '+') {
188 fmtname
[strlen(fmtname
)-1] = 0;
189 flags
= ATTRFLAG_INCREASING
;
192 // Split "format[:byteorder]"
193 char byteorder
[8+1] = "";
194 if (strchr(fmtname
, ':')) {
195 if (priority
== PRIOR_DEFAULT
)
196 // TODO: Allow Byteorder in DEFAULT entry
199 if (!( sscanf(fmtname
, "%*[^:]%n:%8[012345rvwz]%n", &n1
, byteorder
, &n2
) >= 1
200 && n2
== (int)strlen(fmtname
)))
203 if (strchr(byteorder
, 'v'))
204 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
205 if (strchr(byteorder
, 'w'))
206 flags
|= ATTRFLAG_NO_WORSTVAL
;
211 if (i
>= num_format_names
)
212 return false; // Not found
213 if (!strcmp(fmtname
, format_names
[i
].name
))
216 ata_attr_raw_format format
= format_names
[i
].format
;
218 // 64-bit formats use the normalized and worst value bytes.
219 if (!*byteorder
&& (format
== RAWFMT_RAW64
|| format
== RAWFMT_HEX64
))
220 flags
|= (ATTRFLAG_NO_NORMVAL
|ATTRFLAG_NO_WORSTVAL
);
222 // ",HDD|SSD" suffix for DEFAULT settings
224 if (!strcmp(hddssd
, "HDD"))
225 flags
|= ATTRFLAG_HDD_ONLY
;
226 else if (!strcmp(hddssd
, "SSD"))
227 flags
|= ATTRFLAG_SSD_ONLY
;
233 // "N,format" -> set format for all entries
234 for (i
= 0; i
< MAX_ATTRIBUTE_NUM
; i
++) {
235 if (defs
[i
].priority
>= priority
)
238 defs
[i
].name
= attrname
;
239 defs
[i
].priority
= priority
;
240 defs
[i
].raw_format
= format
;
241 defs
[i
].flags
= flags
;
242 snprintf(defs
[i
].byteorder
, sizeof(defs
[i
].byteorder
), "%s", byteorder
);
245 else if (defs
[id
].priority
<= priority
) {
246 // "id,format[,name]"
248 defs
[id
].name
= attrname
;
249 defs
[id
].raw_format
= format
;
250 defs
[id
].priority
= priority
;
251 defs
[id
].flags
= flags
;
252 snprintf(defs
[id
].byteorder
, sizeof(defs
[id
].byteorder
), "%s", byteorder
);
259 // Return a multiline string containing a list of valid arguments for
260 // parse_attribute_def(). The strings are preceded by tabs and followed
261 // (except for the last) by newlines.
262 std::string
create_vendor_attribute_arg_list()
266 for (i
= 0; i
< num_format_names
; i
++)
267 s
+= strprintf("%s\tN,%s[:012345rvwz][,ATTR_NAME]",
268 (i
>0 ? "\n" : ""), format_names
[i
].name
);
269 for (i
= 0; i
< num_old_vendor_opts
; i
++)
270 s
+= strprintf("\n\t%s", map_old_vendor_opts
[i
][0]);
275 // Parse firmwarebug def (-F option).
276 // Return false on error.
277 bool parse_firmwarebug_def(const char * opt
, firmwarebug_defs
& firmwarebugs
)
279 if (!strcmp(opt
, "none"))
280 firmwarebugs
.set(BUG_NONE
);
281 else if (!strcmp(opt
, "nologdir"))
282 firmwarebugs
.set(BUG_NOLOGDIR
);
283 else if (!strcmp(opt
, "samsung"))
284 firmwarebugs
.set(BUG_SAMSUNG
);
285 else if (!strcmp(opt
, "samsung2"))
286 firmwarebugs
.set(BUG_SAMSUNG2
);
287 else if (!strcmp(opt
, "samsung3"))
288 firmwarebugs
.set(BUG_SAMSUNG3
);
289 else if (!strcmp(opt
, "xerrorlba"))
290 firmwarebugs
.set(BUG_XERRORLBA
);
296 // Return a string of valid argument words for parse_firmwarebug_def()
297 const char * get_valid_firmwarebug_args()
299 return "none, nologdir, samsung, samsung2, samsung3, xerrorlba";
303 // swap two bytes. Point to low address
304 void swap2(char *location
){
306 *location
=*(location
+1);
311 // swap four bytes. Point to low address
312 void swap4(char *location
){
314 *location
=*(location
+3);
320 // swap eight bytes. Points to low address
321 void swap8(char *location
){
323 *location
=*(location
+7);
326 *(location
+1)=*(location
+6);
332 // When using the overloaded swapx() function with member of packed ATA structs,
333 // it is required to pass a possibly unaligned pointer as argument.
334 // Clang++ 4.0 prints -Waddress-of-packed-member warning in this case.
335 // The SWAPV() macro below is a replacement which prevents the use of such pointers.
336 template <typename T
>
337 static T
get_swapx_val(T x
)
338 { swapx(&x
); return x
; }
340 #define SWAPV(x) ((x) = get_swapx_val(x))
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 SWAPV(id
->words088_255
[255-88]);
357 if ((id
->words088_255
[255-88] & 0x00ff) == 0x00a5)
358 id
->words088_255
[255-88] += sum
<< 8;
360 SWAPV(id
->words088_255
[255-88]);
363 static const char * const commandstrings
[]={
366 "SMART AUTOMATIC ATTRIBUTE SAVE",
367 "SMART IMMEDIATE OFFLINE",
368 "SMART AUTO OFFLINE",
370 "SMART STATUS CHECK",
371 "SMART READ ATTRIBUTE VALUES",
372 "SMART READ ATTRIBUTE THRESHOLDS",
375 "IDENTIFY PACKET DEVICE",
378 "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT
")\n"
382 static const char * preg(const ata_register
& r
, char (& buf
)[8])
387 snprintf(buf
, sizeof(buf
), "0x%02x", r
.val());
391 static void print_regs(const char * prefix
, const ata_in_regs
& r
, const char * suffix
= "\n")
394 pout("%s FR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, CMD=%s%s", prefix
,
395 preg(r
.features
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
396 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
397 preg(r
.command
, bufs
[6]), suffix
);
400 static void print_regs(const char * prefix
, const ata_out_regs
& r
, const char * suffix
= "\n")
403 pout("%sERR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, STS=%s%s", prefix
,
404 preg(r
.error
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
405 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
406 preg(r
.status
, bufs
[6]), suffix
);
409 static void prettyprint(const unsigned char *p
, const char *name
){
410 pout("\n===== [%s] DATA START (BASE-16) =====\n", name
);
411 for (int i
=0; i
<512; i
+=16, p
+=16)
412 #define P(n) (' ' <= p[n] && p[n] <= '~' ? (int)p[n] : '.')
413 // print complete line to avoid slow tty output and extra lines in syslog.
414 pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x "
415 "%02x %02x %02x %02x %02x %02x %02x %02x"
416 " |%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c|"
419 p
[ 0], p
[ 1], p
[ 2], p
[ 3], p
[ 4], p
[ 5], p
[ 6], p
[ 7],
420 p
[ 8], p
[ 9], p
[10], p
[11], p
[12], p
[13], p
[14], p
[15],
421 P( 0), P( 1), P( 2), P( 3), P( 4), P( 5), P( 6), P( 7),
422 P( 8), P( 9), P(10), P(11), P(12), P(13), P(14), P(15),
425 pout("===== [%s] DATA END (512 Bytes) =====\n\n", name
);
428 // This function provides the pretty-print reporting for SMART
429 // commands: it implements the various -r "reporting" options for ATA
431 int smartcommandhandler(ata_device
* device
, smart_command_set command
, int select
, char *data
){
432 // TODO: Rework old stuff below
433 // This conditional is true for commands that return data
434 int getsdata
=(command
==PIDENTIFY
||
437 command
==READ_THRESHOLDS
||
438 command
==READ_VALUES
||
439 command
==CHECK_POWER_MODE
);
441 int sendsdata
=(command
==WRITE_LOG
);
443 // If reporting is enabled, say what the command will be before it's executed
445 // conditional is true for commands that use parameters
446 int usesparam
=(command
==READ_LOG
||
447 command
==AUTO_OFFLINE
||
449 command
==IMMEDIATE_OFFLINE
||
452 pout("\nREPORT-IOCTL: Device=%s Command=%s", device
->get_dev_name(), commandstrings
[command
]);
454 pout(" InputParameter=%d\n", select
);
459 if ((getsdata
|| sendsdata
) && !data
){
460 pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings
[command
]);
464 // The reporting is cleaner, and we will find coding bugs faster, if
465 // the commands that failed clearly return empty (zeroed) data
468 if (command
==CHECK_POWER_MODE
)
471 memset(data
, '\0', 512);
475 // if requested, pretty-print the input data structure
476 if (ata_debugmode
> 1 && sendsdata
)
477 //pout("REPORT-IOCTL: Device=%s Command=%s\n", device->get_dev_name(), commandstrings[command]);
478 prettyprint((unsigned char *)data
, commandstrings
[command
]);
480 // now execute the command
484 // Set common register values
486 default: // SMART commands
487 in
.in_regs
.command
= ATA_SMART_CMD
;
488 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
490 case IDENTIFY
: case PIDENTIFY
: case CHECK_POWER_MODE
: // Non SMART commands
493 // Set specific values
496 in
.in_regs
.command
= ATA_IDENTIFY_DEVICE
;
497 in
.set_data_in(data
, 1);
500 in
.in_regs
.command
= ATA_IDENTIFY_PACKET_DEVICE
;
501 in
.set_data_in(data
, 1);
503 case CHECK_POWER_MODE
:
504 in
.in_regs
.command
= ATA_CHECK_POWER_MODE
;
505 in
.out_needed
.sector_count
= true; // Powermode returned here
508 in
.in_regs
.features
= ATA_SMART_READ_VALUES
;
509 in
.set_data_in(data
, 1);
511 case READ_THRESHOLDS
:
512 in
.in_regs
.features
= ATA_SMART_READ_THRESHOLDS
;
513 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
514 in
.set_data_in(data
, 1);
517 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
518 in
.in_regs
.lba_low
= select
;
519 in
.set_data_in(data
, 1);
522 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
523 in
.in_regs
.lba_low
= select
;
524 in
.set_data_out(data
, 1);
527 in
.in_regs
.features
= ATA_SMART_ENABLE
;
528 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
531 in
.in_regs
.features
= ATA_SMART_DISABLE
;
532 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
535 in
.out_needed
.lba_high
= in
.out_needed
.lba_mid
= true; // Status returned here
538 in
.in_regs
.features
= ATA_SMART_STATUS
;
541 in
.in_regs
.features
= ATA_SMART_AUTO_OFFLINE
;
542 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
545 in
.in_regs
.features
= ATA_SMART_AUTOSAVE
;
546 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
548 case IMMEDIATE_OFFLINE
:
549 in
.in_regs
.features
= ATA_SMART_IMMEDIATE_OFFLINE
;
550 in
.in_regs
.lba_low
= select
;
553 pout("Unrecognized command %d in smartcommandhandler()\n"
554 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
555 device
->set_err(ENOSYS
);
560 print_regs(" Input: ", in
.in_regs
,
561 (in
.direction
==ata_cmd_in::data_in
? " IN\n":
562 in
.direction
==ata_cmd_in::data_out
? " OUT\n":"\n"));
566 int64_t start_usec
= -1;
568 start_usec
= smi()->get_timer_usec();
570 bool ok
= device
->ata_pass_through(in
, out
);
572 if (start_usec
>= 0) {
573 int64_t duration_usec
= smi()->get_timer_usec() - start_usec
;
574 if (duration_usec
>= 500)
575 pout(" [Duration: %.3fs]\n", duration_usec
/ 1000000.0);
578 if (ata_debugmode
&& out
.out_regs
.is_set())
579 print_regs(" Output: ", out
.out_regs
);
581 if (ok
) switch (command
) {
585 case CHECK_POWER_MODE
:
586 if (out
.out_regs
.sector_count
.is_set()) {
587 data
[0] = out
.out_regs
.sector_count
;
591 pout("CHECK POWER MODE: incomplete response, ATA output registers missing\n");
592 device
->set_err(ENOSYS
);
597 // Cyl low and Cyl high unchanged means "Good SMART status"
598 if ((out
.out_regs
.lba_high
== SMART_CYL_HI
) &&
599 (out
.out_regs
.lba_mid
== SMART_CYL_LOW
))
601 // These values mean "Bad SMART status"
602 else if ((out
.out_regs
.lba_high
== SRET_STATUS_HI_EXCEEDED
) &&
603 (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
))
605 else if (out
.out_regs
.lba_mid
== SMART_CYL_LOW
) {
608 pout("SMART STATUS RETURN: half healthy response sequence, "
609 "probable SAT/USB truncation\n");
610 } else if (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
) {
613 pout("SMART STATUS RETURN: half unhealthy response sequence, "
614 "probable SAT/USB truncation\n");
616 else if (!out
.out_regs
.is_set()) {
617 device
->set_err(ENOSYS
, "Incomplete response, ATA output registers missing");
621 // We haven't gotten output that makes sense; print out some debugging info
622 pout("SMART Status command failed\n");
623 pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE
);
624 pout("Register values returned from SMART Status command are:\n");
625 print_regs(" ", out
.out_regs
);
626 device
->set_err(ENOSYS
, "Invalid ATA output register values");
633 // If requested, invalidate serial number before any printing is done
634 if ((command
== IDENTIFY
|| command
== PIDENTIFY
) && !retval
&& dont_print_serial_number
)
635 invalidate_serno( reinterpret_cast<ata_identify_device
*>(data
) );
637 // If reporting is enabled, say what output was produced by the command
639 if (device
->get_errno())
640 pout("REPORT-IOCTL: Device=%s Command=%s returned %d errno=%d [%s]\n",
641 device
->get_dev_name(), commandstrings
[command
], retval
,
642 device
->get_errno(), device
->get_errmsg());
644 pout("REPORT-IOCTL: Device=%s Command=%s returned %d\n",
645 device
->get_dev_name(), commandstrings
[command
], retval
);
647 // if requested, pretty-print the output data structure
648 if (ata_debugmode
> 1 && getsdata
) {
649 if (command
==CHECK_POWER_MODE
)
650 pout("Sector Count Register (BASE-16): %02x\n", (unsigned char)(*data
));
652 prettyprint((unsigned char *)data
, commandstrings
[command
]);
659 // Get capacity and sector sizes from IDENTIFY data
660 void ata_get_size_info(const ata_identify_device
* id
, ata_size_info
& sizes
)
662 sizes
.sectors
= sizes
.capacity
= 0;
663 sizes
.log_sector_size
= sizes
.phy_sector_size
= 0;
664 sizes
.log_sector_offset
= 0;
666 // Return if no LBA support
667 if (!(id
->words047_079
[49-47] & 0x0200))
670 // Determine 28-bit LBA capacity
671 unsigned lba28
= (unsigned)id
->words047_079
[61-47] << 16
672 | (unsigned)id
->words047_079
[60-47] ;
674 // Determine 48-bit LBA capacity if supported
676 if ((id
->command_set_2
& 0xc400) == 0x4400)
677 lba48
= (uint64_t)id
->words088_255
[103-88] << 48
678 | (uint64_t)id
->words088_255
[102-88] << 32
679 | (uint64_t)id
->words088_255
[101-88] << 16
680 | (uint64_t)id
->words088_255
[100-88] ;
682 // Return if capacity unknown (ATAPI CD/DVD)
683 if (!(lba28
|| lba48
))
686 // Determine sector sizes
687 sizes
.log_sector_size
= sizes
.phy_sector_size
= 512;
689 unsigned short word106
= id
->words088_255
[106-88];
690 if ((word106
& 0xc000) == 0x4000) {
691 // Long Logical/Physical Sectors (LLS/LPS) ?
692 if (word106
& 0x1000)
693 // Logical sector size is specified in 16-bit words
694 sizes
.log_sector_size
= sizes
.phy_sector_size
=
695 ((id
->words088_255
[118-88] << 16) | id
->words088_255
[117-88]) << 1;
697 if (word106
& 0x2000)
698 // Physical sector size is multiple of logical sector size
699 sizes
.phy_sector_size
<<= (word106
& 0x0f);
701 unsigned short word209
= id
->words088_255
[209-88];
702 if ((word209
& 0xc000) == 0x4000)
703 sizes
.log_sector_offset
= (word209
& 0x3fff) * sizes
.log_sector_size
;
706 // Some early 4KiB LLS disks (Samsung N3U-3) return bogus lba28 value
707 if (lba48
>= lba28
|| (lba48
&& sizes
.log_sector_size
> 512))
708 sizes
.sectors
= lba48
;
710 sizes
.sectors
= lba28
;
712 sizes
.capacity
= sizes
.sectors
* sizes
.log_sector_size
;
715 // This function computes the checksum of a single disk sector (512
716 // bytes). Returns zero if checksum is OK, nonzero if the checksum is
717 // incorrect. The size (512) is correct for all SMART structures.
718 unsigned char checksum(const void * data
)
720 unsigned char sum
= 0;
721 for (int i
= 0; i
< 512; i
++)
722 sum
+= ((const unsigned char *)data
)[i
];
726 // Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
728 static void swapbytes(char * out
, const char * in
, size_t n
)
730 for (size_t i
= 0; i
< n
; i
+= 2) {
736 // Copies in to out, but removes leading and trailing whitespace.
737 static void trim(char * out
, const char * in
)
739 // Find the first non-space character (maybe none).
742 for (i
= 0; in
[i
]; i
++)
743 if (!isspace((int)in
[i
])) {
749 // There are no non-space characters.
754 // Find the last non-space character.
755 for (i
= strlen(in
)-1; i
>= first
&& isspace((int)in
[i
]); i
--)
759 strncpy(out
, in
+first
, last
-first
+1);
760 out
[last
-first
+1] = '\0';
763 // Convenience function for formatting strings from ata_identify_device
764 void ata_format_id_string(char * out
, const unsigned char * in
, int n
)
768 swapbytes(tmp
, (const char *)in
, n
);
773 // returns -1 if command fails or the device is in Sleep mode, else
774 // value of Sector Count register. Sector Count result values:
775 // 00h device is in Standby mode.
776 // 80h device is in Idle mode.
777 // FFh device is in Active mode or Idle mode.
779 int ataCheckPowerMode(ata_device
* device
) {
780 unsigned char result
;
782 if ((smartcommandhandler(device
, CHECK_POWER_MODE
, 0, (char *)&result
)))
788 // Issue a no-data ATA command with optional sector count register value
789 bool ata_nodata_command(ata_device
* device
, unsigned char command
,
790 int sector_count
/* = -1 */)
793 in
.in_regs
.command
= command
;
794 if (sector_count
>= 0)
795 in
.in_regs
.sector_count
= sector_count
;
797 return device
->ata_pass_through(in
);
800 // Issue SET FEATURES command with optional sector count register value
801 bool ata_set_features(ata_device
* device
, unsigned char features
,
802 int sector_count
/* = -1 */)
805 in
.in_regs
.command
= ATA_SET_FEATURES
;
806 in
.in_regs
.features
= features
;
807 if (sector_count
>= 0)
808 in
.in_regs
.sector_count
= sector_count
;
810 return device
->ata_pass_through(in
);
813 // Reads current Device Identity info (512 bytes) into buf. Returns 0
814 // if all OK. Returns -1 if no ATA Device identity can be
815 // established. Returns >0 if Device is ATA Packet Device (not SMART
816 // capable). The value of the integer helps identify the type of
817 // Packet device, which is useful so that the user can connect the
818 // formal device number with whatever object is inside their computer.
819 int ata_read_identity(ata_device
* device
, ata_identify_device
* buf
, bool fix_swapped_id
,
820 unsigned char * raw_buf
/* = 0 */)
822 unsigned short *rawshort
=(unsigned short *)buf
;
823 unsigned char *rawbyte
=(unsigned char *)buf
;
825 // See if device responds either to IDENTIFY DEVICE or IDENTIFY
828 if ((smartcommandhandler(device
, IDENTIFY
, 0, (char *)buf
))){
829 if (smartcommandhandler(device
, PIDENTIFY
, 0, (char *)buf
)){
835 if (fix_swapped_id
) {
838 for (i
= 0; i
< sizeof(buf
->serial_no
)-1; i
+= 2)
839 swap2((char *)(buf
->serial_no
+i
));
840 for (i
= 0; i
< sizeof(buf
->fw_rev
)-1; i
+= 2)
841 swap2((char *)(buf
->fw_rev
+i
));
842 for (i
= 0; i
< sizeof(buf
->model
)-1; i
+= 2)
843 swap2((char *)(buf
->model
+i
));
846 // If requested, save raw data before endianness adjustments
848 memcpy(raw_buf
, buf
, sizeof(*buf
));
850 // if machine is big-endian, swap byte order as needed
852 // swap various capability words that are needed
855 swap2((char *)(buf
->words047_079
+i
));
856 for (i
=80; i
<=87; i
++)
857 swap2((char *)(rawshort
+i
));
858 for (i
=0; i
<168; i
++)
859 swap2((char *)(buf
->words088_255
+i
));
862 // If there is a checksum there, validate it
863 if ((rawshort
[255] & 0x00ff) == 0x00a5 && checksum(rawbyte
))
864 checksumwarning("Drive Identity Structure");
866 // AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
867 // T13/1699-D Revision 6a (Final Draft), September 6, 2008.
868 // Sections 7.16.7 and 7.17.6:
870 // Word 0 of IDENTIFY DEVICE data:
871 // Bit 15 = 0 : ATA device
873 // Word 0 of IDENTIFY PACKET DEVICE data:
874 // Bits 15:14 = 10b : ATAPI device
875 // Bits 15:14 = 11b : Reserved
876 // Bits 12:8 : Device type (SPC-4, e.g 0x05 = CD/DVD)
878 // CF+ and CompactFlash Specification Revision 4.0, May 24, 2006.
881 // Word 0 of IDENTIFY DEVICE data:
882 // 848Ah = Signature for CompactFlash Storage Card
883 // 044Ah = Alternate value turns on ATA device while preserving all retired bits
884 // 0040h = Alternate value turns on ATA device while zeroing all retired bits
886 // Assume ATA if IDENTIFY DEVICE returns CompactFlash Signature
887 if (!packet
&& rawbyte
[1] == 0x84 && rawbyte
[0] == 0x8a)
890 // If this is a PACKET DEVICE, return device type
891 if (rawbyte
[1] & 0x80)
892 return 1+(rawbyte
[1] & 0x1f);
894 // Not a PACKET DEVICE
898 // Get World Wide Name (WWN) fields.
899 // Return NAA field or -1 if WWN is unsupported.
900 // Table 34 of T13/1699-D Revision 6a (ATA8-ACS), September 6, 2008.
901 // (WWN was introduced in ATA/ATAPI-7 and is mandatory since ATA8-ACS Revision 3b)
902 int ata_get_wwn(const ata_identify_device
* id
, unsigned & oui
, uint64_t & unique_id
)
904 // Don't use word 84 to be compatible with some older ATA-7 disks
905 unsigned short word087
= id
->csf_default
;
906 if ((word087
& 0xc100) != 0x4100)
907 return -1; // word not valid or WWN support bit 8 not set
909 unsigned short word108
= id
->words088_255
[108-88];
910 unsigned short word109
= id
->words088_255
[109-88];
911 unsigned short word110
= id
->words088_255
[110-88];
912 unsigned short word111
= id
->words088_255
[111-88];
914 oui
= ((word108
& 0x0fff) << 12) | (word109
>> 4);
915 unique_id
= ((uint64_t)(word109
& 0xf) << 32)
916 | (unsigned)((word110
<< 16) | word111
);
917 return (word108
>> 12);
920 // Get nominal media rotation rate.
921 // Returns: 0 = not reported, 1 = SSD, >1 = HDD rpm, < 0 = -(Unknown value)
922 int ata_get_rotation_rate(const ata_identify_device
* id
)
924 // Table 37 of T13/1699-D (ATA8-ACS) Revision 6a, September 6, 2008
925 // Table A.31 of T13/2161-D (ACS-3) Revision 3b, August 25, 2012
926 unsigned short word217
= id
->words088_255
[217-88];
927 if (word217
== 0x0000 || word217
== 0xffff)
929 else if (word217
== 0x0001)
931 else if (word217
> 0x0400)
934 return -(int)word217
;
937 // returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
938 int ataSmartSupport(const ata_identify_device
* drive
)
940 unsigned short word82
=drive
->command_set_1
;
941 unsigned short word83
=drive
->command_set_2
;
943 // check if words 82/83 contain valid info
944 if ((word83
>>14) == 0x01)
945 // return value of SMART support bit
946 return word82
& 0x0001;
948 // since we can're rely on word 82, we don't know if SMART supported
952 // returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
953 int ataIsSmartEnabled(const ata_identify_device
* drive
)
955 unsigned short word85
=drive
->cfs_enable_1
;
956 unsigned short word87
=drive
->csf_default
;
958 // check if words 85/86/87 contain valid info
959 if ((word87
>>14) == 0x01)
960 // return value of SMART enabled bit
961 return word85
& 0x0001;
963 // Since we can't rely word85, we don't know if SMART is enabled.
968 // Reads SMART attributes into *data
969 int ataReadSmartValues(ata_device
* device
, struct ata_smart_values
*data
){
971 if (smartcommandhandler(device
, READ_VALUES
, 0, (char *)data
)){
977 checksumwarning("SMART Attribute Data Structure");
979 // swap endian order if needed
982 swap2((char *)&(data
->revnumber
));
983 swap2((char *)&(data
->total_time_to_complete_off_line
));
984 swap2((char *)&(data
->smart_capability
));
985 SWAPV(data
->extend_test_completion_time_w
);
986 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
987 struct ata_smart_attribute
*x
=data
->vendor_attributes
+i
;
988 swap2((char *)&(x
->flags
));
996 // This corrects some quantities that are byte reversed in the SMART
998 static void fixsamsungselftestlog(ata_smart_selftestlog
* data
)
1000 // bytes 508/509 (numbered from 0) swapped (swap of self-test index
1001 // with one byte of reserved.
1002 swap2((char *)&(data
->mostrecenttest
));
1004 // LBA low register (here called 'selftestnumber", containing
1005 // information about the TYPE of the self-test) is byte swapped with
1006 // Self-test execution status byte. These are bytes N, N+1 in the
1008 for (int i
= 0; i
< 21; i
++)
1009 swap2((char *)&(data
->selftest_struct
[i
].selftestnumber
));
1014 // Reads the Self Test Log (log #6)
1015 int ataReadSelfTestLog (ata_device
* device
, ata_smart_selftestlog
* data
,
1016 firmwarebug_defs firmwarebugs
)
1019 // get data from device
1020 if (smartcommandhandler(device
, READ_LOG
, 0x06, (char *)data
)){
1024 // compute its checksum, and issue a warning if needed
1026 checksumwarning("SMART Self-Test Log Structure");
1028 // fix firmware bugs in self-test log
1029 if (firmwarebugs
.is_set(BUG_SAMSUNG
))
1030 fixsamsungselftestlog(data
);
1032 // swap endian order if needed
1035 swap2((char*)&(data
->revnumber
));
1036 for (i
=0; i
<21; i
++){
1037 struct ata_smart_selftestlog_struct
*x
=data
->selftest_struct
+i
;
1038 swap2((char *)&(x
->timestamp
));
1039 swap4((char *)&(x
->lbafirstfailure
));
1046 // Print checksum warning for multi sector log
1047 static void check_multi_sector_sum(const void * data
, unsigned nsectors
, const char * msg
)
1050 for (unsigned i
= 0; i
< nsectors
; i
++) {
1051 if (checksum((const unsigned char *)data
+ i
*512))
1056 checksumwarning(msg
);
1058 checksumwarning(strprintf("%s (%u/%u)", msg
, errs
, nsectors
).c_str());
1062 // Read SMART Extended Self-test Log
1063 bool ataReadExtSelfTestLog(ata_device
* device
, ata_smart_extselftestlog
* log
,
1066 if (!ataReadLogExt(device
, 0x07, 0x00, 0, log
, nsectors
))
1069 check_multi_sector_sum(log
, nsectors
, "SMART Extended Self-test Log Structure");
1071 if (isbigendian()) {
1072 SWAPV(log
->log_desc_index
);
1073 for (unsigned i
= 0; i
< nsectors
; i
++) {
1074 for (unsigned j
= 0; j
< 19; j
++)
1075 SWAPV(log
->log_descs
[i
].timestamp
);
1081 // Write GP Log page(s)
1082 bool ataWriteLogExt(ata_device
* device
, unsigned char logaddr
,
1083 unsigned page
, void * data
, unsigned nsectors
)
1086 in
.in_regs
.command
= ATA_WRITE_LOG_EXT
;
1087 in
.set_data_out(data
, nsectors
);
1088 in
.in_regs
.lba_low
= logaddr
;
1089 in
.in_regs
.lba_mid_16
= page
;
1090 in
.set_data_out(data
, nsectors
);
1093 if (!device
->ata_pass_through(in
, out
)) { // TODO: Debug output
1094 if (nsectors
<= 1) {
1095 pout("ATA_WRITE_LOG_EXT (addr=0x%02x, page=%u, n=%u) failed: %s\n",
1096 logaddr
, page
, nsectors
, device
->get_errmsg());
1100 // Recurse to retry with single sectors,
1101 // multi-sector reads may not be supported by ioctl.
1102 for (unsigned i
= 0; i
< nsectors
; i
++) {
1103 if (!ataWriteLogExt(device
, logaddr
, page
+ i
,
1104 (char *)data
+ 512*i
, 1))
1112 // Read GP Log page(s)
1113 bool ataReadLogExt(ata_device
* device
, unsigned char logaddr
,
1114 unsigned char features
, unsigned page
,
1115 void * data
, unsigned nsectors
)
1118 in
.in_regs
.command
= ATA_READ_LOG_EXT
;
1119 in
.in_regs
.features
= features
; // log specific
1120 in
.set_data_in_48bit(data
, nsectors
);
1121 in
.in_regs
.lba_low
= logaddr
;
1122 in
.in_regs
.lba_mid_16
= page
;
1124 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1125 if (nsectors
<= 1) {
1126 pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n",
1127 logaddr
, features
, page
, nsectors
, device
->get_errmsg());
1131 // Recurse to retry with single sectors,
1132 // multi-sector reads may not be supported by ioctl.
1133 for (unsigned i
= 0; i
< nsectors
; i
++) {
1134 if (!ataReadLogExt(device
, logaddr
,
1136 (char *)data
+ 512*i
, 1))
1144 // Read SMART Log page(s)
1145 bool ataReadSmartLog(ata_device
* device
, unsigned char logaddr
,
1146 void * data
, unsigned nsectors
)
1149 in
.in_regs
.command
= ATA_SMART_CMD
;
1150 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
1151 in
.set_data_in(data
, nsectors
);
1152 in
.in_regs
.lba_high
= SMART_CYL_HI
;
1153 in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
1154 in
.in_regs
.lba_low
= logaddr
;
1156 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1157 pout("ATA_SMART_READ_LOG failed: %s\n", device
->get_errmsg());
1165 // Reads the SMART or GPL Log Directory (log #0)
1166 int ataReadLogDirectory(ata_device
* device
, ata_smart_log_directory
* data
, bool gpl
)
1168 if (!gpl
) { // SMART Log directory
1169 if (smartcommandhandler(device
, READ_LOG
, 0x00, (char *)data
))
1172 else { // GP Log directory
1173 if (!ataReadLogExt(device
, 0x00, 0x00, 0, data
, 1))
1177 // swap endian order if needed
1179 SWAPV(data
->logversion
);
1185 // Reads the selective self-test log (log #9)
1186 int ataReadSelectiveSelfTestLog(ata_device
* device
, struct ata_selective_self_test_log
*data
){
1188 // get data from device
1189 if (smartcommandhandler(device
, READ_LOG
, 0x09, (char *)data
)){
1193 // compute its checksum, and issue a warning if needed
1195 checksumwarning("SMART Selective Self-Test Log Structure");
1197 // swap endian order if needed
1200 swap2((char *)&(data
->logversion
));
1202 swap8((char *)&(data
->span
[i
].start
));
1203 swap8((char *)&(data
->span
[i
].end
));
1205 swap8((char *)&(data
->currentlba
));
1206 swap2((char *)&(data
->currentspan
));
1207 swap2((char *)&(data
->flags
));
1208 swap2((char *)&(data
->pendingtime
));
1214 // Writes the selective self-test log (log #9)
1215 int ataWriteSelectiveSelfTestLog(ata_device
* device
, ata_selective_selftest_args
& args
,
1216 const ata_smart_values
* sv
, uint64_t num_sectors
,
1217 const ata_selective_selftest_args
* prev_args
)
1219 // Disk size must be known
1221 pout("Disk size is unknown, unable to check selective self-test spans\n");
1226 struct ata_selective_self_test_log sstlog
, *data
=&sstlog
;
1227 unsigned char *ptr
=(unsigned char *)data
;
1228 if (ataReadSelectiveSelfTestLog(device
, data
)) {
1229 pout("SMART Read Selective Self-test Log failed: %s\n", device
->get_errmsg());
1230 pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
1235 data
->logversion
= 1;
1237 // Host is NOT allowed to write selective self-test log if a selective
1238 // self-test is in progress.
1239 if (0<data
->currentspan
&& data
->currentspan
<6 && ((sv
->self_test_exec_status
)>>4)==15) {
1240 pout("SMART Selective or other Self-test in progress\n");
1244 // Set start/end values based on old spans for special -t select,... options
1246 for (i
= 0; i
< args
.num_spans
; i
++) {
1247 int mode
= args
.span
[i
].mode
;
1248 uint64_t start
= args
.span
[i
].start
;
1249 uint64_t end
= args
.span
[i
].end
;
1250 if (mode
== SEL_CONT
) {// redo or next depending on last test status
1251 switch (sv
->self_test_exec_status
>> 4) {
1252 case 1: case 2: // Aborted/Interrupted by host
1253 pout("Continue Selective Self-Test: Redo last span\n");
1256 default: // All others
1257 pout("Continue Selective Self-Test: Start next span\n");
1263 if ( (mode
== SEL_REDO
|| mode
== SEL_NEXT
)
1264 && prev_args
&& i
< prev_args
->num_spans
1265 && !data
->span
[i
].start
&& !data
->span
[i
].end
) {
1266 // Some drives do not preserve the selective self-test log across
1267 // power-cyles. If old span on drive is cleared use span provided
1268 // by caller. This is used by smartd (first span only).
1269 data
->span
[i
].start
= prev_args
->span
[i
].start
;
1270 data
->span
[i
].end
= prev_args
->span
[i
].end
;
1274 case SEL_RANGE
: // -t select,START-END
1276 case SEL_REDO
: // -t select,redo... => Redo current
1277 start
= data
->span
[i
].start
;
1278 if (end
> 0) { // -t select,redo+SIZE
1279 end
--; end
+= start
; // [oldstart, oldstart+SIZE)
1281 else // -t select,redo
1282 end
= data
->span
[i
].end
; // [oldstart, oldend]
1284 case SEL_NEXT
: // -t select,next... => Do next
1285 if (data
->span
[i
].end
== 0) {
1286 start
= end
= 0; break; // skip empty spans
1288 start
= data
->span
[i
].end
+ 1;
1289 if (start
>= num_sectors
)
1290 start
= 0; // wrap around
1291 if (end
> 0) { // -t select,next+SIZE
1292 end
--; end
+= start
; // (oldend, oldend+SIZE]
1294 else { // -t select,next
1295 uint64_t oldsize
= data
->span
[i
].end
- data
->span
[i
].start
+ 1;
1296 end
= start
+ oldsize
- 1; // (oldend, oldend+oldsize]
1297 if (end
>= num_sectors
) {
1298 // Adjust size to allow round-robin testing without future size decrease
1299 uint64_t spans
= (num_sectors
+ oldsize
-1) / oldsize
;
1300 uint64_t newsize
= (num_sectors
+ spans
-1) / spans
;
1301 uint64_t newstart
= num_sectors
- newsize
, newend
= num_sectors
- 1;
1302 pout("Span %d changed from %" PRIu64
"-%" PRIu64
" (%" PRIu64
" sectors)\n",
1303 i
, start
, end
, oldsize
);
1304 pout(" to %" PRIu64
"-%" PRIu64
" (%" PRIu64
" sectors) (%" PRIu64
" spans)\n",
1305 newstart
, newend
, newsize
, spans
);
1306 start
= newstart
; end
= newend
;
1311 pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode
);
1315 if (start
< num_sectors
&& num_sectors
<= end
) {
1316 if (end
!= ~(uint64_t)0) // -t select,N-max
1317 pout("Size of self-test span %d decreased according to disk size\n", i
);
1318 end
= num_sectors
- 1;
1320 if (!(start
<= end
&& end
< num_sectors
)) {
1321 pout("Invalid selective self-test span %d: %" PRIu64
"-%" PRIu64
" (%" PRIu64
" sectors)\n",
1322 i
, start
, end
, num_sectors
);
1325 // Return the actual mode and range to caller.
1326 args
.span
[i
].mode
= mode
;
1327 args
.span
[i
].start
= start
;
1328 args
.span
[i
].end
= end
;
1333 memset(data
->span
+i
, 0, sizeof(struct test_span
));
1335 // Set spans for testing
1336 for (i
= 0; i
< args
.num_spans
; i
++){
1337 data
->span
[i
].start
= args
.span
[i
].start
;
1338 data
->span
[i
].end
= args
.span
[i
].end
;
1341 // host must initialize to zero before initiating selective self-test
1343 data
->currentspan
=0;
1345 // Perform off-line scan after selective test?
1346 if (args
.scan_after_select
== 1)
1348 data
->flags
&= ~SELECTIVE_FLAG_DOSCAN
;
1349 else if (args
.scan_after_select
== 2)
1351 data
->flags
|= SELECTIVE_FLAG_DOSCAN
;
1353 // Must clear active and pending flags before writing
1354 data
->flags
&= ~(SELECTIVE_FLAG_ACTIVE
);
1355 data
->flags
&= ~(SELECTIVE_FLAG_PENDING
);
1357 // modify pending time?
1358 if (args
.pending_time
)
1359 data
->pendingtime
= (unsigned short)(args
.pending_time
-1);
1361 // Set checksum to zero, then compute checksum
1363 unsigned char cksum
=0;
1364 for (i
=0; i
<512; i
++)
1368 data
->checksum
=cksum
;
1370 // swap endian order if needed
1372 swap2((char *)&(data
->logversion
));
1373 for (int b
= 0; b
< 5; b
++) {
1374 swap8((char *)&(data
->span
[b
].start
));
1375 swap8((char *)&(data
->span
[b
].end
));
1377 swap8((char *)&(data
->currentlba
));
1378 swap2((char *)&(data
->currentspan
));
1379 swap2((char *)&(data
->flags
));
1380 swap2((char *)&(data
->pendingtime
));
1383 // write new selective self-test log
1384 if (smartcommandhandler(device
, WRITE_LOG
, 0x09, (char *)data
)){
1385 pout("Write Selective Self-test Log failed: %s\n", device
->get_errmsg());
1392 // This corrects some quantities that are byte reversed in the SMART
1394 static void fixsamsungerrorlog(ata_smart_errorlog
* data
)
1396 // FIXED IN SAMSUNG -25 FIRMWARE???
1397 // Device error count in bytes 452-3
1398 swap2((char *)&(data
->ata_error_count
));
1400 // FIXED IN SAMSUNG -22a FIRMWARE
1401 // step through 5 error log data structures
1402 for (int i
= 0; i
< 5; i
++){
1403 // step through 5 command data structures
1404 for (int j
= 0; j
< 5; j
++)
1405 // Command data structure 4-byte millisec timestamp. These are
1406 // bytes (N+8, N+9, N+10, N+11).
1407 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1408 // Error data structure two-byte hour life timestamp. These are
1409 // bytes (N+28, N+29).
1410 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1415 // NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
1416 static void fixsamsungerrorlog2(ata_smart_errorlog
* data
)
1418 // Device error count in bytes 452-3
1419 swap2((char *)&(data
->ata_error_count
));
1423 // Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1424 // Error Log is #2, and the Extended Comprehensive SMART Error log is
1426 int ataReadErrorLog (ata_device
* device
, ata_smart_errorlog
*data
,
1427 firmwarebug_defs firmwarebugs
)
1430 // get data from device
1431 if (smartcommandhandler(device
, READ_LOG
, 0x01, (char *)data
)){
1435 // compute its checksum, and issue a warning if needed
1437 checksumwarning("SMART ATA Error Log Structure");
1439 // Some disks have the byte order reversed in some SMART Summary
1440 // Error log entries
1441 if (firmwarebugs
.is_set(BUG_SAMSUNG
))
1442 fixsamsungerrorlog(data
);
1443 else if (firmwarebugs
.is_set(BUG_SAMSUNG2
))
1444 fixsamsungerrorlog2(data
);
1446 // swap endian order if needed
1450 // Device error count in bytes 452-3
1451 swap2((char *)&(data
->ata_error_count
));
1453 // step through 5 error log data structures
1454 for (i
=0; i
<5; i
++){
1455 // step through 5 command data structures
1457 // Command data structure 4-byte millisec timestamp
1458 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1459 // Error data structure life timestamp
1460 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1468 // Fix LBA byte ordering of Extended Comprehensive Error Log
1469 // if little endian instead of ATA register ordering is provided
1471 static inline void fix_exterrlog_lba_cmd(T
& cmd
)
1474 cmd
.lba_mid_register_hi
= org
.lba_high_register
;
1475 cmd
.lba_low_register_hi
= org
.lba_mid_register_hi
;
1476 cmd
.lba_high_register
= org
.lba_mid_register
;
1477 cmd
.lba_mid_register
= org
.lba_low_register_hi
;
1480 static void fix_exterrlog_lba(ata_smart_exterrlog
* log
, unsigned nsectors
)
1482 for (unsigned i
= 0; i
< nsectors
; i
++) {
1483 for (int ei
= 0; ei
< 4; ei
++) {
1484 ata_smart_exterrlog_error_log
& entry
= log
[i
].error_logs
[ei
];
1485 fix_exterrlog_lba_cmd(entry
.error
);
1486 for (int ci
= 0; ci
< 5; ci
++)
1487 fix_exterrlog_lba_cmd(entry
.commands
[ci
]);
1492 // Read Extended Comprehensive Error Log
1493 bool ataReadExtErrorLog(ata_device
* device
, ata_smart_exterrlog
* log
,
1494 unsigned page
, unsigned nsectors
, firmwarebug_defs firmwarebugs
)
1496 if (!ataReadLogExt(device
, 0x03, 0x00, page
, log
, nsectors
))
1499 check_multi_sector_sum(log
, nsectors
, "SMART Extended Comprehensive Error Log Structure");
1501 if (isbigendian()) {
1502 SWAPV(log
->device_error_count
);
1503 SWAPV(log
->error_log_index
);
1504 for (unsigned i
= 0; i
< nsectors
; i
++) {
1505 for (unsigned j
= 0; j
< 4; j
++) {
1506 for (unsigned k
= 0; k
< 5; k
++)
1507 SWAPV(log
[i
].error_logs
[j
].commands
[k
].timestamp
);
1508 SWAPV(log
[i
].error_logs
[j
].error
.timestamp
);
1513 if (firmwarebugs
.is_set(BUG_XERRORLBA
))
1514 fix_exterrlog_lba(log
, nsectors
);
1520 int ataReadSmartThresholds (ata_device
* device
, struct ata_smart_thresholds_pvt
*data
){
1522 // get data from device
1523 if (smartcommandhandler(device
, READ_THRESHOLDS
, 0, (char *)data
)){
1527 // compute its checksum, and issue a warning if needed
1529 checksumwarning("SMART Attribute Thresholds Structure");
1531 // swap endian order if needed
1533 swap2((char *)&(data
->revnumber
));
1538 int ataEnableSmart (ata_device
* device
){
1539 if (smartcommandhandler(device
, ENABLE
, 0, NULL
)){
1545 int ataDisableSmart (ata_device
* device
){
1547 if (smartcommandhandler(device
, DISABLE
, 0, NULL
)){
1553 int ataEnableAutoSave(ata_device
* device
){
1554 if (smartcommandhandler(device
, AUTOSAVE
, 241, NULL
)){
1560 int ataDisableAutoSave(ata_device
* device
){
1562 if (smartcommandhandler(device
, AUTOSAVE
, 0, NULL
)){
1568 // In *ALL* ATA standards the Enable/Disable AutoOffline command is
1569 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1570 // vendors still support it for backwards compatibility. IBM documents
1571 // it for some drives.
1572 int ataEnableAutoOffline (ata_device
* device
){
1574 /* timer hard coded to 4 hours */
1575 if (smartcommandhandler(device
, AUTO_OFFLINE
, 248, NULL
)){
1581 // Another Obsolete Command. See comments directly above, associated
1582 // with the corresponding Enable command.
1583 int ataDisableAutoOffline (ata_device
* device
){
1585 if (smartcommandhandler(device
, AUTO_OFFLINE
, 0, NULL
)){
1591 // If SMART is enabled, supported, and working, then this call is
1592 // guaranteed to return 1, else zero. Note that it should return 1
1593 // regardless of whether the disk's SMART status is 'healthy' or
1595 int ataDoesSmartWork(ata_device
* device
){
1596 int retval
=smartcommandhandler(device
, STATUS
, 0, NULL
);
1604 // This function uses a different interface (DRIVE_TASK) than the
1605 // other commands in this file.
1606 int ataSmartStatus2(ata_device
* device
){
1607 return smartcommandhandler(device
, STATUS_CHECK
, 0, NULL
);
1610 // This is the way to execute ALL tests: offline, short self-test,
1611 // extended self test, with and without captive mode, etc.
1612 // TODO: Move to ataprint.cpp ?
1613 int ataSmartTest(ata_device
* device
, int testtype
, bool force
,
1614 const ata_selective_selftest_args
& selargs
,
1615 const ata_smart_values
* sv
, uint64_t num_sectors
)
1617 char cmdmsg
[128]; const char *type
, *captive
;
1618 int cap
, retval
, select
=0;
1620 // Boolean, if set, says test is captive
1621 cap
=testtype
& CAPTIVE_MASK
;
1623 // Set up strings that describe the type of test
1629 if (testtype
==OFFLINE_FULL_SCAN
)
1631 else if (testtype
==SHORT_SELF_TEST
|| testtype
==SHORT_CAPTIVE_SELF_TEST
)
1632 type
="Short self-test";
1633 else if (testtype
==EXTEND_SELF_TEST
|| testtype
==EXTEND_CAPTIVE_SELF_TEST
)
1634 type
="Extended self-test";
1635 else if (testtype
==CONVEYANCE_SELF_TEST
|| testtype
==CONVEYANCE_CAPTIVE_SELF_TEST
)
1636 type
="Conveyance self-test";
1637 else if ((select
=(testtype
==SELECTIVE_SELF_TEST
|| testtype
==SELECTIVE_CAPTIVE_SELF_TEST
)))
1638 type
="Selective self-test";
1642 // Check whether another test is already running
1643 if (type
&& (sv
->self_test_exec_status
>> 4) == 0xf) {
1645 pout("Can't start self-test without aborting current test (%d0%% remaining),\n"
1646 "%srun 'smartctl -X' to abort test.\n",
1647 sv
->self_test_exec_status
& 0x0f,
1648 (!select
? "add '-t force' option to override, or " : ""));
1655 // If doing a selective self-test, first use WRITE_LOG to write the
1656 // selective self-test log.
1657 ata_selective_selftest_args selargs_io
= selargs
; // filled with info about actual spans
1658 if (select
&& (retval
= ataWriteSelectiveSelfTestLog(device
, selargs_io
, sv
, num_sectors
))) {
1660 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1664 // Print ouf message that we are sending the command to test
1665 if (testtype
==ABORT_SELF_TEST
)
1666 snprintf(cmdmsg
, sizeof(cmdmsg
), "Abort SMART off-line mode self-test routine");
1668 snprintf(cmdmsg
, sizeof(cmdmsg
), "SMART EXECUTE OFF-LINE IMMEDIATE subcommand 0x%02x", testtype
);
1670 snprintf(cmdmsg
, sizeof(cmdmsg
), "Execute SMART %s routine immediately in %s mode", type
, captive
);
1671 pout("Sending command: \"%s\".\n",cmdmsg
);
1675 pout("SPAN STARTING_LBA ENDING_LBA\n");
1676 for (i
= 0; i
< selargs_io
.num_spans
; i
++)
1677 pout(" %d %20" PRId64
" %20" PRId64
"\n", i
,
1678 selargs_io
.span
[i
].start
,
1679 selargs_io
.span
[i
].end
);
1682 // Now send the command to test
1683 if (smartcommandhandler(device
, IMMEDIATE_OFFLINE
, testtype
, NULL
)) {
1684 if (!(cap
&& device
->get_errno() == EIO
)) {
1685 pout("Command \"%s\" failed: %s\n", cmdmsg
, device
->get_errmsg());
1690 // Since the command succeeded, tell user
1691 if (testtype
==ABORT_SELF_TEST
)
1692 pout("Self-testing aborted!\n");
1694 pout("Drive command \"%s\" successful.\n", cmdmsg
);
1696 pout("Testing has begun%s.\n", (force
? " (previous test aborted)" : ""));
1701 /* Test Time Functions */
1702 int TestTime(const ata_smart_values
*data
, int testtype
)
1705 case OFFLINE_FULL_SCAN
:
1706 return (int) data
->total_time_to_complete_off_line
;
1707 case SHORT_SELF_TEST
:
1708 case SHORT_CAPTIVE_SELF_TEST
:
1709 return (int) data
->short_test_completion_time
;
1710 case EXTEND_SELF_TEST
:
1711 case EXTEND_CAPTIVE_SELF_TEST
:
1712 if (data
->extend_test_completion_time_b
== 0xff
1713 && data
->extend_test_completion_time_w
!= 0x0000
1714 && data
->extend_test_completion_time_w
!= 0xffff)
1715 return data
->extend_test_completion_time_w
; // ATA-8
1717 return data
->extend_test_completion_time_b
;
1718 case CONVEYANCE_SELF_TEST
:
1719 case CONVEYANCE_CAPTIVE_SELF_TEST
:
1720 return (int) data
->conveyance_test_completion_time
;
1726 // This function tells you both about the ATA error log and the
1727 // self-test error log capability (introduced in ATA-5). The bit is
1728 // poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1729 // SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1730 // word 84 and 87. Top two bits must match the pattern 01. BEFORE
1731 // ATA-6 these top two bits still had to match the pattern 01, but the
1732 // remaining bits were reserved (==0).
1733 bool isSmartErrorLogCapable(const ata_smart_values
* data
, const ata_identify_device
* identity
)
1735 unsigned short word84
=identity
->command_set_extension
;
1736 unsigned short word87
=identity
->csf_default
;
1737 int isata6
=identity
->major_rev_num
& (0x01<<6);
1738 int isata7
=identity
->major_rev_num
& (0x01<<7);
1740 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x01))
1743 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x01))
1746 // otherwise we'll use the poorly documented capability bit
1747 return !!(data
->errorlog_capability
& 0x01);
1750 // See previous function. If the error log exists then the self-test
1751 // log should (must?) also exist.
1752 bool isSmartTestLogCapable(const ata_smart_values
* data
, const ata_identify_device
*identity
)
1754 unsigned short word84
=identity
->command_set_extension
;
1755 unsigned short word87
=identity
->csf_default
;
1756 int isata6
=identity
->major_rev_num
& (0x01<<6);
1757 int isata7
=identity
->major_rev_num
& (0x01<<7);
1759 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x02))
1762 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x02))
1766 // otherwise we'll use the poorly documented capability bit
1767 return !!(data
->errorlog_capability
& 0x01);
1771 bool isGeneralPurposeLoggingCapable(const ata_identify_device
*identity
)
1773 unsigned short word84
=identity
->command_set_extension
;
1774 unsigned short word87
=identity
->csf_default
;
1776 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1777 // cleared to zero, the contents of word 84 contains valid support
1778 // information. If not, support information is not valid in this
1780 if ((word84
>>14) == 0x01)
1781 // If bit 5 of word 84 is set to one, the device supports the
1782 // General Purpose Logging feature set.
1783 return !!(word84
& (0x01 << 5));
1785 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1786 // cleared to zero, the contents of words (87:85) contain valid
1787 // information. If not, information is not valid in these words.
1788 if ((word87
>>14) == 0x01)
1789 // If bit 5 of word 87 is set to one, the device supports
1790 // the General Purpose Logging feature set.
1791 return !!(word87
& (0x01 << 5));
1797 // Get attribute state
1798 ata_attr_state
ata_get_attr_state(const ata_smart_attribute
& attr
,
1800 const ata_smart_threshold_entry
* thresholds
,
1801 const ata_vendor_attr_defs
& defs
,
1802 unsigned char * threshval
/* = 0 */)
1805 return ATTRSTATE_NON_EXISTING
;
1807 // Normalized values (current,worst,threshold) not valid
1808 // if specified by '-v' option.
1809 // (Some SSD disks uses these bytes to store raw value).
1810 if (defs
[attr
.id
].flags
& ATTRFLAG_NO_NORMVAL
)
1811 return ATTRSTATE_NO_NORMVAL
;
1813 // Normally threshold is at same index as attribute
1815 if (thresholds
[i
].id
!= attr
.id
) {
1816 // Find threshold id in table
1817 for (i
= 0; thresholds
[i
].id
!= attr
.id
; ) {
1818 if (++i
>= NUMBER_ATA_SMART_ATTRIBUTES
)
1819 // Threshold id missing or thresholds cannot be read
1820 return ATTRSTATE_NO_THRESHOLD
;
1823 unsigned char threshold
= thresholds
[i
].threshold
;
1825 // Return threshold if requested
1827 *threshval
= threshold
;
1829 // Don't report a failed attribute if its threshold is 0.
1830 // ATA-3 (X3T13/2008D Revision 7b) declares 0x00 as the "always passing"
1831 // threshold (Later ATA versions declare all thresholds as "obsolete").
1832 // In practice, threshold value 0 is often used for usage attributes.
1834 return ATTRSTATE_OK
;
1836 // Failed now if current value is below threshold
1837 if (attr
.current
<= threshold
)
1838 return ATTRSTATE_FAILED_NOW
;
1840 // Failed in the past if worst value is below threshold
1841 if (!(defs
[attr
.id
].flags
& ATTRFLAG_NO_WORSTVAL
) && attr
.worst
<= threshold
)
1842 return ATTRSTATE_FAILED_PAST
;
1844 return ATTRSTATE_OK
;
1847 // Get attribute raw value.
1848 uint64_t ata_get_attr_raw_value(const ata_smart_attribute
& attr
,
1849 const ata_vendor_attr_defs
& defs
)
1851 const ata_vendor_attr_defs::entry
& def
= defs
[attr
.id
];
1852 // TODO: Allow Byteorder in DEFAULT entry
1854 // Use default byteorder if not specified
1855 const char * byteorder
= def
.byteorder
;
1857 switch (def
.raw_format
) {
1860 byteorder
= "543210wv"; break;
1863 case RAWFMT_RAW24_DIV_RAW32
:
1864 case RAWFMT_MSEC24_HOUR32
:
1865 byteorder
= "r543210"; break;
1867 byteorder
= "543210"; break;
1871 // Build 64-bit value from selected bytes
1872 uint64_t rawvalue
= 0;
1873 for (int i
= 0; byteorder
[i
]; i
++) {
1875 switch (byteorder
[i
]) {
1876 case '0': b
= attr
.raw
[0]; break;
1877 case '1': b
= attr
.raw
[1]; break;
1878 case '2': b
= attr
.raw
[2]; break;
1879 case '3': b
= attr
.raw
[3]; break;
1880 case '4': b
= attr
.raw
[4]; break;
1881 case '5': b
= attr
.raw
[5]; break;
1882 case 'r': b
= attr
.reserv
; break;
1883 case 'v': b
= attr
.current
; break;
1884 case 'w': b
= attr
.worst
; break;
1885 default : b
= 0; break;
1887 rawvalue
<<= 8; rawvalue
|= b
;
1893 // Helper functions for RAWFMT_TEMPMINMAX
1894 static inline int check_temp_word(unsigned word
)
1897 return 0x11; // >= 0, signed byte or word
1899 return 0x01; // < 0, signed byte
1901 return 0x10; // < 0, signed word
1905 static bool check_temp_range(int t
, unsigned char ut1
, unsigned char ut2
,
1908 int t1
= (signed char)ut1
, t2
= (signed char)ut2
;
1910 int tx
= t1
; t1
= t2
; t2
= tx
;
1913 if ( -60 <= t1
&& t1
<= t
&& t
<= t2
&& t2
<= 120
1914 && !(t1
== -1 && t2
<= 0) ) {
1921 // Format attribute raw value.
1922 std::string
ata_format_attr_raw_value(const ata_smart_attribute
& attr
,
1923 const ata_vendor_attr_defs
& defs
)
1925 // Get 48 bit or 64 bit raw value
1926 uint64_t rawvalue
= ata_get_attr_raw_value(attr
, defs
);
1928 // Split into bytes and words
1929 unsigned char raw
[6];
1930 raw
[0] = (unsigned char) rawvalue
;
1931 raw
[1] = (unsigned char)(rawvalue
>> 8);
1932 raw
[2] = (unsigned char)(rawvalue
>> 16);
1933 raw
[3] = (unsigned char)(rawvalue
>> 24);
1934 raw
[4] = (unsigned char)(rawvalue
>> 32);
1935 raw
[5] = (unsigned char)(rawvalue
>> 40);
1937 word
[0] = raw
[0] | (raw
[1] << 8);
1938 word
[1] = raw
[2] | (raw
[3] << 8);
1939 word
[2] = raw
[4] | (raw
[5] << 8);
1942 ata_attr_raw_format format
= defs
[attr
.id
].raw_format
;
1943 if (format
== RAWFMT_DEFAULT
) {
1944 // Get format from DEFAULT entry
1945 format
= get_default_attr_defs()[attr
.id
].raw_format
;
1946 if (format
== RAWFMT_DEFAULT
)
1947 // Unknown Attribute
1948 format
= RAWFMT_RAW48
;
1955 s
= strprintf("%d %d %d %d %d %d",
1956 raw
[5], raw
[4], raw
[3], raw
[2], raw
[1], raw
[0]);
1960 s
= strprintf("%u %u %u", word
[2], word
[1], word
[0]);
1966 s
= strprintf("%" PRIu64
, rawvalue
);
1970 s
= strprintf("0x%012" PRIx64
, rawvalue
);
1974 s
= strprintf("0x%014" PRIx64
, rawvalue
);
1978 s
= strprintf("0x%016" PRIx64
, rawvalue
);
1981 case RAWFMT_RAW16_OPT_RAW16
:
1982 s
= strprintf("%u", word
[0]);
1983 if (word
[1] || word
[2])
1984 s
+= strprintf(" (%u %u)", word
[2], word
[1]);
1987 case RAWFMT_RAW16_OPT_AVG16
:
1988 s
= strprintf("%u", word
[0]);
1990 s
+= strprintf(" (Average %u)", word
[1]);
1993 case RAWFMT_RAW24_OPT_RAW8
:
1994 s
= strprintf("%u", (unsigned)(rawvalue
& 0x00ffffffULL
));
1995 if (raw
[3] || raw
[4] || raw
[5])
1996 s
+= strprintf(" (%d %d %d)", raw
[5], raw
[4], raw
[3]);
1999 case RAWFMT_RAW24_DIV_RAW24
:
2000 s
= strprintf("%u/%u",
2001 (unsigned)(rawvalue
>> 24), (unsigned)(rawvalue
& 0x00ffffffULL
));
2004 case RAWFMT_RAW24_DIV_RAW32
:
2005 s
= strprintf("%u/%u",
2006 (unsigned)(rawvalue
>> 32), (unsigned)(rawvalue
& 0xffffffffULL
));
2009 case RAWFMT_MIN2HOUR
:
2012 int64_t temp
= word
[0]+(word
[1]<<16);
2013 int64_t tmp1
= temp
/60;
2014 int64_t tmp2
= temp
%60;
2015 s
= strprintf("%" PRIu64
"h+%02" PRIu64
"m", tmp1
, tmp2
);
2017 s
+= strprintf(" (%u)", word
[2]);
2021 case RAWFMT_SEC2HOUR
:
2024 int64_t hours
= rawvalue
/3600;
2025 int64_t minutes
= (rawvalue
-3600*hours
)/60;
2026 int64_t seconds
= rawvalue
%60;
2027 s
= strprintf("%" PRIu64
"h+%02" PRIu64
"m+%02" PRIu64
"s", hours
, minutes
, seconds
);
2031 case RAWFMT_HALFMIN2HOUR
:
2033 // 30-second counter
2034 int64_t hours
= rawvalue
/120;
2035 int64_t minutes
= (rawvalue
-120*hours
)/2;
2036 s
+= strprintf("%" PRIu64
"h+%02" PRIu64
"m", hours
, minutes
);
2040 case RAWFMT_MSEC24_HOUR32
:
2042 // hours + milliseconds
2043 unsigned hours
= (unsigned)(rawvalue
& 0xffffffffULL
);
2044 unsigned milliseconds
= (unsigned)(rawvalue
>> 32);
2045 unsigned seconds
= milliseconds
/ 1000;
2046 s
= strprintf("%uh+%02um+%02u.%03us",
2047 hours
, seconds
/ 60, seconds
% 60, milliseconds
% 1000);
2051 case RAWFMT_TEMPMINMAX
:
2054 // Search for possible min/max values
2055 // [5][4][3][2][1][0] raw[]
2056 // [ 2 ] [ 1 ] [ 0 ] word[]
2057 // xx HH xx LL xx TT (Hitachi/HGST)
2058 // xx LL xx HH xx TT (Kingston SSDs)
2059 // 00 00 HH LL xx TT (Maxtor, Samsung, Seagate, Toshiba)
2060 // 00 00 00 HH LL TT (WDC)
2061 // CC CC HH LL xx TT (WDC, CCCC=over temperature count)
2062 // (xx = 00/ff, possibly sign extension of lower byte)
2064 int t
= (signed char)raw
[0];
2068 int ctw0
= check_temp_word(word
[0]);
2070 if (!word
[1] && ctw0
)
2071 // 00 00 00 00 xx TT
2073 else if (ctw0
&& check_temp_range(t
, raw
[2], raw
[3], lo
, hi
))
2074 // 00 00 HL LH xx TT
2076 else if (!raw
[3] && check_temp_range(t
, raw
[1], raw
[2], lo
, hi
))
2077 // 00 00 00 HL LH TT
2083 if ( (ctw0
& check_temp_word(word
[1]) & check_temp_word(word
[2])) != 0x00
2084 && check_temp_range(t
, raw
[2], raw
[4], lo
, hi
) )
2085 // xx HL xx LH xx TT
2087 else if ( word
[2] < 0x7fff
2088 && check_temp_range(t
, raw
[2], raw
[3], lo
, hi
)
2090 // CC CC HL LH xx TT
2100 s
= strprintf("%d", t
);
2102 case 1: case 2: case 3:
2103 s
= strprintf("%d (Min/Max %d/%d)", t
, lo
, hi
);
2106 s
= strprintf("%d (Min/Max %d/%d #%d)", t
, lo
, hi
, word
[2]);
2109 s
= strprintf("%d (%d %d %d %d %d)", raw
[0], raw
[5], raw
[4], raw
[3], raw
[2], raw
[1]);
2115 case RAWFMT_TEMP10X
:
2116 // ten times temperature in Celsius
2117 s
= strprintf("%d.%d", word
[0]/10, word
[0]%10);
2121 s
= "?"; // Should not happen
2128 // Get attribute name
2129 std::string
ata_get_smart_attr_name(unsigned char id
, const ata_vendor_attr_defs
& defs
,
2132 if (!defs
[id
].name
.empty())
2133 return defs
[id
].name
;
2135 const ata_vendor_attr_defs::entry
& def
= get_default_attr_defs()[id
];
2136 if (def
.name
.empty())
2137 return "Unknown_Attribute";
2138 else if ((def
.flags
& ATTRFLAG_HDD_ONLY
) && rpm
== 1)
2139 return "Unknown_SSD_Attribute";
2140 else if ((def
.flags
& ATTRFLAG_SSD_ONLY
) && rpm
> 1)
2141 return "Unknown_HDD_Attribute";
2147 // Find attribute index for attribute id, -1 if not found.
2148 int ata_find_attr_index(unsigned char id
, const ata_smart_values
& smartval
)
2152 for (int i
= 0; i
< NUMBER_ATA_SMART_ATTRIBUTES
; i
++) {
2153 if (smartval
.vendor_attributes
[i
].id
== id
)
2159 // Return Temperature Attribute raw value selected according to possible
2160 // non-default interpretations. If the Attribute does not exist, return 0
2161 unsigned char ata_return_temperature_value(const ata_smart_values
* data
, const ata_vendor_attr_defs
& defs
)
2163 for (int i
= 0; i
< 4; i
++) {
2164 static const unsigned char ids
[4] = {194, 190, 9, 220};
2165 unsigned char id
= ids
[i
];
2166 const ata_attr_raw_format format
= defs
[id
].raw_format
;
2167 if (!( ((id
== 194 || id
== 190) && format
== RAWFMT_DEFAULT
)
2168 || format
== RAWFMT_TEMPMINMAX
|| format
== RAWFMT_TEMP10X
))
2170 int idx
= ata_find_attr_index(id
, *data
);
2173 uint64_t raw
= ata_get_attr_raw_value(data
->vendor_attributes
[idx
], defs
);
2175 // ignore possible min/max values in high words
2176 if (format
== RAWFMT_TEMP10X
) // -v N,temp10x
2177 temp
= ((unsigned short)raw
+ 5) / 10;
2179 temp
= (unsigned char)raw
;
2180 if (!(0 < temp
&& temp
< 128))
2184 // No valid attribute found
2190 int ataReadSCTStatus(ata_device
* device
, ata_sct_status_response
* sts
)
2192 // read SCT status via SMART log 0xe0
2193 memset(sts
, 0, sizeof(*sts
));
2194 if (smartcommandhandler(device
, READ_LOG
, 0xe0, (char *)sts
)){
2195 pout("Read SCT Status failed: %s\n", device
->get_errmsg());
2199 // swap endian order if needed
2201 SWAPV(sts
->format_version
);
2202 SWAPV(sts
->sct_version
);
2203 SWAPV(sts
->sct_spec
);
2204 SWAPV(sts
->ext_status_code
);
2205 SWAPV(sts
->action_code
);
2206 SWAPV(sts
->function_code
);
2207 SWAPV(sts
->over_limit_count
);
2208 SWAPV(sts
->under_limit_count
);
2209 SWAPV(sts
->smart_status
);
2210 SWAPV(sts
->min_erc_time
);
2213 // Check format version
2214 if (!(sts
->format_version
== 2 || sts
->format_version
== 3)) {
2215 pout("Unknown SCT Status format version %u, should be 2 or 3.\n", sts
->format_version
);
2221 // Read SCT Temperature History Table
2222 int ataReadSCTTempHist(ata_device
* device
, ata_sct_temperature_history_table
* tmh
,
2223 ata_sct_status_response
* sts
)
2225 // Initial SCT status must be provided by caller
2227 // Do nothing if other SCT command is executing
2228 if (sts
->ext_status_code
== 0xffff) {
2229 pout("Another SCT command is executing, abort Read Data Table\n"
2230 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2231 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2235 ata_sct_data_table_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2236 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2237 cmd
.action_code
= 5; // Data table command
2238 cmd
.function_code
= 1; // Read table
2239 cmd
.table_id
= 2; // Temperature History Table
2241 // swap endian order if needed
2242 if (isbigendian()) {
2243 SWAPV(cmd
.action_code
);
2244 SWAPV(cmd
.function_code
);
2245 SWAPV(cmd
.table_id
);
2248 // write command via SMART log page 0xe0
2249 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2250 pout("Write SCT Data Table failed: %s\n", device
->get_errmsg());
2254 // read SCT data via SMART log page 0xe1
2255 memset(tmh
, 0, sizeof(*tmh
));
2256 if (smartcommandhandler(device
, READ_LOG
, 0xe1, (char *)tmh
)){
2257 pout("Read SCT Data Table failed: %s\n", device
->get_errmsg());
2261 // re-read and check SCT status
2262 if (ataReadSCTStatus(device
, sts
))
2265 if (!(sts
->ext_status_code
== 0 && sts
->action_code
== 5 && sts
->function_code
== 1)) {
2266 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2267 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2271 // swap endian order if needed
2273 SWAPV(tmh
->format_version
);
2274 SWAPV(tmh
->sampling_period
);
2275 SWAPV(tmh
->interval
);
2276 SWAPV(tmh
->cb_index
);
2277 SWAPV(tmh
->cb_size
);
2282 // Common function for Get/Set SCT Feature Control:
2283 // Write Cache, Write Cache Reordering, etc.
2284 static int ataGetSetSCTFeatureControl(ata_device
* device
, unsigned short feature_code
,
2285 unsigned short state
, bool persistent
, bool set
)
2287 // Check initial status
2288 ata_sct_status_response sts
;
2289 if (ataReadSCTStatus(device
, &sts
))
2292 // Do nothing if other SCT command is executing
2293 if (sts
.ext_status_code
== 0xffff) {
2294 pout("Another SCT command is executing, abort Feature Control\n"
2295 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2296 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2300 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2301 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2302 cmd
.action_code
= 4; // Feature Control command
2303 cmd
.function_code
= (set
? 1 : 2); // 1=Set, 2=Get
2304 cmd
.feature_code
= feature_code
;
2306 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2308 // swap endian order if needed
2309 if (isbigendian()) {
2310 SWAPV(cmd
.action_code
);
2311 SWAPV(cmd
.function_code
);
2312 SWAPV(cmd
.feature_code
);
2314 SWAPV(cmd
.option_flags
);
2317 // write command via SMART log page 0xe0
2318 // TODO: Debug output
2320 in
.in_regs
.command
= ATA_SMART_CMD
;
2321 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
2322 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
2323 in
.in_regs
.lba_low
= 0xe0;
2324 in
.set_data_out(&cmd
, 1);
2327 // Time limit returned in ATA registers
2328 in
.out_needed
.sector_count
= in
.out_needed
.lba_low
= true;
2331 if (!device
->ata_pass_through(in
, out
)) {
2332 pout("Write SCT (%cet) Feature Control Command failed: %s\n",
2333 (!set
? 'G' : 'S'), device
->get_errmsg());
2336 state
= out
.out_regs
.sector_count
| (out
.out_regs
.lba_low
<< 8);
2338 // re-read and check SCT status
2339 if (ataReadSCTStatus(device
, &sts
))
2342 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== (set
? 1 : 2))) {
2343 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2344 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2350 // Get/Set Write Cache Reordering
2351 int ataGetSetSCTWriteCacheReordering(ata_device
* device
, bool enable
, bool persistent
, bool set
)
2353 return ataGetSetSCTFeatureControl(device
, 2 /* Enable/Disable Write Cache Reordering */,
2354 (enable
? 1 : 2), persistent
, set
);
2357 // Get/Set Write Cache (force enable, force disable,
2358 int ataGetSetSCTWriteCache(ata_device
* device
, unsigned short state
, bool persistent
, bool set
)
2360 return ataGetSetSCTFeatureControl(device
, 1 /* Enable/Disable Write Cache */,
2361 state
, persistent
, set
);
2364 // Set SCT Temperature Logging Interval
2365 int ataSetSCTTempInterval(ata_device
* device
, unsigned interval
, bool persistent
)
2367 // Check initial status
2368 ata_sct_status_response sts
;
2369 if (ataReadSCTStatus(device
, &sts
))
2372 // Do nothing if other SCT command is executing
2373 if (sts
.ext_status_code
== 0xffff) {
2374 pout("Another SCT command is executing, abort Feature Control\n"
2375 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2376 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2380 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2381 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2382 cmd
.action_code
= 4; // Feature Control command
2383 cmd
.function_code
= 1; // Set state
2384 cmd
.feature_code
= 3; // Temperature logging interval
2385 cmd
.state
= interval
;
2386 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2388 // swap endian order if needed
2389 if (isbigendian()) {
2390 SWAPV(cmd
.action_code
);
2391 SWAPV(cmd
.function_code
);
2392 SWAPV(cmd
.feature_code
);
2394 SWAPV(cmd
.option_flags
);
2397 // write command via SMART log page 0xe0
2398 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2399 pout("Write SCT Feature Control Command failed: %s\n", device
->get_errmsg());
2403 // re-read and check SCT status
2404 if (ataReadSCTStatus(device
, &sts
))
2407 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== 1)) {
2408 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2409 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2415 // Get/Set SCT Error Recovery Control
2416 static int ataGetSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
,
2417 bool set
, unsigned short & time_limit
)
2419 // Check initial status
2420 ata_sct_status_response sts
;
2421 if (ataReadSCTStatus(device
, &sts
))
2424 // Do nothing if other SCT command is executing
2425 if (sts
.ext_status_code
== 0xffff) {
2426 pout("Another SCT command is executing, abort Error Recovery Control\n"
2427 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2428 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2432 ata_sct_error_recovery_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2433 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2434 cmd
.action_code
= 3; // Error Recovery Control command
2435 cmd
.function_code
= (set
? 1 : 2); // 1=Set timer, 2=Get timer
2436 cmd
.selection_code
= type
; // 1=Read timer, 2=Write timer
2438 cmd
.time_limit
= time_limit
;
2440 // swap endian order if needed
2441 if (isbigendian()) {
2442 SWAPV(cmd
.action_code
);
2443 SWAPV(cmd
.function_code
);
2444 SWAPV(cmd
.selection_code
);
2445 SWAPV(cmd
.time_limit
);
2448 // write command via SMART log page 0xe0
2449 // TODO: Debug output
2451 in
.in_regs
.command
= ATA_SMART_CMD
;
2452 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
2453 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
2454 in
.in_regs
.lba_low
= 0xe0;
2455 in
.set_data_out(&cmd
, 1);
2458 // Time limit returned in ATA registers
2459 in
.out_needed
.sector_count
= in
.out_needed
.lba_low
= true;
2462 if (!device
->ata_pass_through(in
, out
)) {
2463 pout("Write SCT (%cet) Error Recovery Control Command failed: %s\n",
2464 (!set
? 'G' : 'S'), device
->get_errmsg());
2468 // re-read and check SCT status
2469 if (ataReadSCTStatus(device
, &sts
))
2472 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 3 && sts
.function_code
== (set
? 1 : 2))) {
2473 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2474 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2479 // Check whether registers are properly returned by ioctl()
2480 if (!(out
.out_regs
.sector_count
.is_set() && out
.out_regs
.lba_low
.is_set())) {
2481 // TODO: Output register support should be checked within each ata_pass_through()
2482 // implementation before command is issued.
2483 pout("SMART WRITE LOG does not return COUNT and LBA_LOW register\n");
2486 if ( out
.out_regs
.sector_count
== in
.in_regs
.sector_count
2487 && out
.out_regs
.lba_low
== in
.in_regs
.lba_low
) {
2488 // 0xe001 (5734.5s) - this is most likely a broken ATA pass-through implementation
2489 pout("SMART WRITE LOG returns COUNT and LBA_LOW register unchanged\n");
2493 // Return value to caller
2494 time_limit
= out
.out_regs
.sector_count
| (out
.out_regs
.lba_low
<< 8);
2500 // Get SCT Error Recovery Control
2501 int ataGetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short & time_limit
)
2503 return ataGetSetSCTErrorRecoveryControltime(device
, type
, false/*get*/, time_limit
);
2506 // Set SCT Error Recovery Control
2507 int ataSetSCTErrorRecoveryControltime(ata_device
* device
, unsigned type
, unsigned short time_limit
)
2509 return ataGetSetSCTErrorRecoveryControltime(device
, type
, true/*set*/, time_limit
);
2513 /////////////////////////////////////////////////////////////////////////////
2514 // Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2515 // an ATA device with same behaviour
2519 class parsed_ata_device
2520 : public /*implements*/ ata_device_with_command_set
2523 parsed_ata_device(smart_interface
* intf
, const char * dev_name
);
2525 virtual ~parsed_ata_device() throw();
2527 virtual bool is_open() const;
2529 virtual bool open();
2531 virtual bool close();
2533 virtual bool ata_identify_is_cached() const;
2536 virtual int ata_command_interface(smart_command_set command
, int select
, char * data
);
2539 // Table of parsed commands, return value, data
2540 struct parsed_ata_command
2542 smart_command_set command
;
2548 enum { max_num_commands
= 32 };
2549 parsed_ata_command m_command_table
[max_num_commands
];
2552 int m_next_replay_command
;
2553 bool m_replay_out_of_sync
;
2554 bool m_ata_identify_is_cached
;
2557 static const char * nextline(const char * s
, int & lineno
)
2559 for (s
+= strcspn(s
, "\r\n"); *s
== '\r' || *s
== '\n'; s
++) {
2560 if (*s
== '\r' && s
[1] == '\n')
2567 static int name2command(const char * s
)
2569 for (int i
= 0; i
< (int)(sizeof(commandstrings
)/sizeof(commandstrings
[0])); i
++) {
2570 if (!strcmp(s
, commandstrings
[i
]))
2576 static bool matchcpy(char * dest
, size_t size
, const char * src
,
2577 const regular_expression::match_range
& srcmatch
)
2579 if (srcmatch
.rm_so
< 0)
2581 size_t n
= srcmatch
.rm_eo
- srcmatch
.rm_so
;
2584 memcpy(dest
, src
+ srcmatch
.rm_so
, n
);
2589 static inline int matchtoi(const char * src
, const regular_expression::match_range
& srcmatch
, int defval
)
2591 if (srcmatch
.rm_so
< 0)
2593 return atoi(src
+ srcmatch
.rm_so
);
2596 parsed_ata_device::parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2597 : smart_device(intf
, dev_name
, "ata", ""),
2599 m_next_replay_command(0),
2600 m_replay_out_of_sync(false),
2601 m_ata_identify_is_cached(false)
2603 memset(m_command_table
, 0, sizeof(m_command_table
));
2606 parsed_ata_device::~parsed_ata_device() throw()
2608 parsed_ata_device::close();
2611 bool parsed_ata_device::is_open() const
2613 return (m_num_commands
> 0);
2616 // Parse stdin and build command table
2617 bool parsed_ata_device::open()
2619 const char * pathname
= get_dev_name();
2620 if (strcmp(pathname
, "-"))
2621 return set_err(EINVAL
);
2622 pathname
= "<stdin>";
2624 char buffer
[64*1024];
2626 while (size
< (int)sizeof(buffer
)) {
2627 int nr
= fread(buffer
, 1, sizeof(buffer
), stdin
);
2633 return set_err(ENOENT
, "%s: Unexpected EOF", pathname
);
2634 if (size
>= (int)sizeof(buffer
))
2635 return set_err(EIO
, "%s: Buffer overflow", pathname
);
2638 // Regex to match output from "-r ataioctl,2"
2639 static const char pattern
[] = "^"
2641 "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
2643 "( InputParameter=([0-9]+))?" // (4 (5))
2645 "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2647 "[\r\n]" // EOL match necessary to match optional parts above
2649 "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2651 " *(En|Dis)abled status cached by OS, " // (11)
2655 const regular_expression
regex(pattern
);
2658 const char * errmsg
= 0;
2659 int i
= -1, state
= 0, lineno
= 1;
2660 for (const char * line
= buffer
; *line
; line
= nextline(line
, lineno
)) {
2662 if (!(line
[0] == 'R' || line
[0] == '=' || line
[0] == ' '))
2664 const int nmatch
= 1+11;
2665 regular_expression::match_range match
[nmatch
];
2666 if (!regex
.execute(line
, nmatch
, match
))
2670 if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[2])) { // "REPORT-IOCTL:... Command=%s ..."
2671 int nc
= name2command(cmdname
);
2673 errmsg
= "Unknown ATA command name"; break;
2675 if (match
[7].rm_so
< 0) { // "returned %d"
2677 if (!(state
== 0 || state
== 2)) {
2678 errmsg
= "Missing REPORT-IOCTL result"; break;
2680 if (++i
>= max_num_commands
) {
2681 errmsg
= "Too many ATA commands"; break;
2683 m_command_table
[i
].command
= (smart_command_set
)nc
;
2684 m_command_table
[i
].select
= matchtoi(line
, match
[5], 0); // "InputParameter=%d"
2689 if (!(state
== 1 && (int)m_command_table
[i
].command
== nc
)) {
2690 errmsg
= "Missing REPORT-IOCTL start"; break;
2692 m_command_table
[i
].retval
= matchtoi(line
, match
[7], -1); // "returned %d"
2693 m_command_table
[i
].errval
= matchtoi(line
, match
[9], 0); // "errno=%d"
2697 else if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[10])) { // "===== [%s] DATA START "
2698 // Start of sector hexdump
2699 int nc
= name2command(cmdname
);
2700 if (!(state
== (nc
== WRITE_LOG
? 1 : 2) && (int)m_command_table
[i
].command
== nc
)) {
2701 errmsg
= "Unexpected DATA START"; break;
2703 line
= nextline(line
, lineno
);
2704 char * data
= (char *)malloc(512);
2706 for (j
= 0; j
< 32; j
++) {
2708 unsigned u1
, u2
; int n1
= -1;
2709 if (!(sscanf(line
, "%3u-%3u: "
2710 "%2x %2x %2x %2x %2x %2x %2x %2x "
2711 "%2x %2x %2x %2x %2x %2x %2x %2x%n",
2713 b
+ 0, b
+ 1, b
+ 2, b
+ 3, b
+ 4, b
+ 5, b
+ 6, b
+ 7,
2714 b
+ 8, b
+ 9, b
+10, b
+11, b
+12, b
+13, b
+14, b
+15, &n1
) == 18
2715 && n1
>= 56 && u1
== j
*16 && u2
== j
*16+15))
2717 for (unsigned k
= 0; k
< 16; k
++)
2718 data
[j
*16+k
] = b
[k
];
2719 line
= nextline(line
, lineno
);
2723 errmsg
= "Incomplete sector hex dump"; break;
2725 m_command_table
[i
].data
= data
;
2726 if (nc
!= WRITE_LOG
)
2729 else if (match
[11].rm_so
> 0) { // "(En|Dis)abled status cached by OS"
2730 m_ata_identify_is_cached
= true;
2734 if (!(state
== 0 || state
== 2))
2735 errmsg
= "Missing REPORT-IOCTL result";
2737 if (!errmsg
&& i
< 0)
2738 errmsg
= "No information found";
2740 m_num_commands
= i
+1;
2741 m_next_replay_command
= 0;
2742 m_replay_out_of_sync
= false;
2746 return set_err(EIO
, "%s(%d): Syntax error: %s", pathname
, lineno
, errmsg
);
2751 // Report warnings and free command table
2752 bool parsed_ata_device::close()
2754 if (m_replay_out_of_sync
)
2755 pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
2756 else if (m_next_replay_command
!= 0)
2757 pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands
-m_next_replay_command
);
2759 for (int i
= 0; i
< m_num_commands
; i
++) {
2760 if (m_command_table
[i
].data
) {
2761 free(m_command_table
[i
].data
); m_command_table
[i
].data
= 0;
2765 m_next_replay_command
= 0;
2766 m_replay_out_of_sync
= false;
2771 bool parsed_ata_device::ata_identify_is_cached() const
2773 return m_ata_identify_is_cached
;
2777 // Simulate ATA command from command table
2778 int parsed_ata_device::ata_command_interface(smart_command_set command
, int select
, char * data
)
2780 // Find command, try round-robin if out of sync
2781 int i
= m_next_replay_command
;
2782 for (int j
= 0; ; j
++) {
2783 if (j
>= m_num_commands
) {
2784 pout("REPLAY-IOCTL: Warning: Command not found\n");
2788 if (m_command_table
[i
].command
== command
&& m_command_table
[i
].select
== select
)
2790 if (!m_replay_out_of_sync
) {
2791 m_replay_out_of_sync
= true;
2792 pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i
+1);
2794 if (++i
>= m_num_commands
)
2797 m_next_replay_command
= i
;
2798 if (++m_next_replay_command
>= m_num_commands
)
2799 m_next_replay_command
= 0;
2801 // Return command data
2806 case READ_THRESHOLDS
:
2808 if (m_command_table
[i
].data
)
2809 memcpy(data
, m_command_table
[i
].data
, 512);
2812 if (!(m_command_table
[i
].data
&& !memcmp(data
, m_command_table
[i
].data
, 512)))
2813 pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
2815 case CHECK_POWER_MODE
:
2816 data
[0] = (char)0xff;
2821 if (m_command_table
[i
].errval
)
2822 errno
= m_command_table
[i
].errval
;
2823 return m_command_table
[i
].retval
;
2828 ata_device
* get_parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2830 return new parsed_ata_device(intf
, dev_name
);