4 * Home page of code is: http://smartmontools.sourceforge.net
6 * Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
7 * Copyright (C) 2008-9 Christian Franke <smartmontools-support@lists.sourceforge.net>
8 * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
9 * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
16 * You should have received a copy of the GNU General Public License
17 * (for example COPYING); if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * This code was originally developed as a Senior Thesis by Michael Cornwell
21 * at the Concurrent Systems Laboratory (now part of the Storage Systems
22 * Research Center), Jack Baskin School of Engineering, University of
23 * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
38 #include "dev_ata_cmd_set.h" // for parsed_ata_device
40 const char * atacmds_cpp_cvsid
= "$Id: atacmds.cpp 2928 2009-10-03 16:24:53Z chrfranke $"
43 // for passing global control variables
44 extern smartmonctrl
*con
;
46 #define SMART_CYL_LOW 0x4F
47 #define SMART_CYL_HI 0xC2
49 // SMART RETURN STATUS yields SMART_CYL_HI,SMART_CYL_LOW to indicate drive
50 // is healthy and SRET_STATUS_HI_EXCEEDED,SRET_STATUS_MID_EXCEEDED to
51 // indicate that a threshhold exceeded condition has been detected.
52 // Those values (byte pairs) are placed in ATA register "LBA 23:8".
53 #define SRET_STATUS_HI_EXCEEDED 0x2C
54 #define SRET_STATUS_MID_EXCEEDED 0xF4
56 // These Drive Identity tables are taken from hdparm 5.2, and are also
57 // given in the ATA/ATAPI specs for the IDENTIFY DEVICE command. Note
58 // that SMART was first added into the ATA/ATAPI-3 Standard with
59 // Revision 3 of the document, July 25, 1995. Look at the "Document
60 // Status" revision commands at the beginning of
61 // http://www.t13.org/project/d2008r6.pdf to see this.
62 #define NOVAL_0 0x0000
63 #define NOVAL_1 0xffff
64 /* word 81: minor version number */
65 #define MINOR_MAX 0x22
66 static const char * const minor_str
[] = { /* word 81 value: */
67 "Device does not report version", /* 0x0000 */
68 "ATA-1 X3T9.2 781D prior to revision 4", /* 0x0001 */
69 "ATA-1 published, ANSI X3.221-1994", /* 0x0002 */
70 "ATA-1 X3T9.2 781D revision 4", /* 0x0003 */
71 "ATA-2 published, ANSI X3.279-1996", /* 0x0004 */
72 "ATA-2 X3T10 948D prior to revision 2k", /* 0x0005 */
73 "ATA-3 X3T10 2008D revision 1", /* 0x0006 */ /* SMART NOT INCLUDED */
74 "ATA-2 X3T10 948D revision 2k", /* 0x0007 */
75 "ATA-3 X3T10 2008D revision 0", /* 0x0008 */
76 "ATA-2 X3T10 948D revision 3", /* 0x0009 */
77 "ATA-3 published, ANSI X3.298-199x", /* 0x000a */
78 "ATA-3 X3T10 2008D revision 6", /* 0x000b */ /* 1st VERSION WITH SMART */
79 "ATA-3 X3T13 2008D revision 7 and 7a", /* 0x000c */
80 "ATA/ATAPI-4 X3T13 1153D revision 6", /* 0x000d */
81 "ATA/ATAPI-4 T13 1153D revision 13", /* 0x000e */
82 "ATA/ATAPI-4 X3T13 1153D revision 7", /* 0x000f */
83 "ATA/ATAPI-4 T13 1153D revision 18", /* 0x0010 */
84 "ATA/ATAPI-4 T13 1153D revision 15", /* 0x0011 */
85 "ATA/ATAPI-4 published, ANSI NCITS 317-1998", /* 0x0012 */
86 "ATA/ATAPI-5 T13 1321D revision 3", /* 0x0013 */
87 "ATA/ATAPI-4 T13 1153D revision 14", /* 0x0014 */
88 "ATA/ATAPI-5 T13 1321D revision 1", /* 0x0015 */
89 "ATA/ATAPI-5 published, ANSI NCITS 340-2000", /* 0x0016 */
90 "ATA/ATAPI-4 T13 1153D revision 17", /* 0x0017 */
91 "ATA/ATAPI-6 T13 1410D revision 0", /* 0x0018 */
92 "ATA/ATAPI-6 T13 1410D revision 3a", /* 0x0019 */
93 "ATA/ATAPI-7 T13 1532D revision 1", /* 0x001a */
94 "ATA/ATAPI-6 T13 1410D revision 2", /* 0x001b */
95 "ATA/ATAPI-6 T13 1410D revision 1", /* 0x001c */
96 "ATA/ATAPI-7 published, ANSI INCITS 397-2005",/* 0x001d */
97 "ATA/ATAPI-7 T13 1532D revision 0", /* 0x001e */
98 "reserved", /* 0x001f */
99 "reserved", /* 0x0020 */
100 "ATA/ATAPI-7 T13 1532D revision 4a", /* 0x0021 */
101 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" /* 0x0022 */
104 // NOTE ATA/ATAPI-4 REV 4 was the LAST revision where the device
105 // attribute structures were NOT completely vendor specific. So any
106 // disk that is ATA/ATAPI-4 or above can not be trusted to show the
107 // vendor values in sensible format.
109 // Negative values below are because it doesn't support SMART
110 static const int actual_ver
[] = {
112 0, /* 0x0000 WARNING: */
113 1, /* 0x0001 WARNING: */
114 1, /* 0x0002 WARNING: */
115 1, /* 0x0003 WARNING: */
116 2, /* 0x0004 WARNING: This array */
117 2, /* 0x0005 WARNING: corresponds */
118 -3, /*<== */ /* 0x0006 WARNING: *exactly* */
119 2, /* 0x0007 WARNING: to the ATA/ */
120 -3, /*<== */ /* 0x0008 WARNING: ATAPI version */
121 2, /* 0x0009 WARNING: listed in */
122 3, /* 0x000a WARNING: the */
123 3, /* 0x000b WARNING: minor_str */
124 3, /* 0x000c WARNING: array */
125 4, /* 0x000d WARNING: above. */
126 4, /* 0x000e WARNING: */
127 4, /* 0x000f WARNING: If you change */
128 4, /* 0x0010 WARNING: that one, */
129 4, /* 0x0011 WARNING: change this one */
130 4, /* 0x0012 WARNING: too!!! */
131 5, /* 0x0013 WARNING: */
132 4, /* 0x0014 WARNING: */
133 5, /* 0x0015 WARNING: */
134 5, /* 0x0016 WARNING: */
135 4, /* 0x0017 WARNING: */
136 6, /* 0x0018 WARNING: */
137 6, /* 0x0019 WARNING: */
138 7, /* 0x001a WARNING: */
139 6, /* 0x001b WARNING: */
140 6, /* 0x001c WARNING: */
141 7, /* 0x001d WARNING: */
142 7, /* 0x001e WARNING: */
143 0, /* 0x001f WARNING: */
144 0, /* 0x0020 WARNING: */
145 7, /* 0x0021 WARNING: */
146 6 /* 0x0022 WARNING: */
149 // When you add additional items to this list, you should then:
150 // 0 -- update this list
151 // 1 -- if needed, modify ataPrintSmartAttribRawValue()
152 // 2 - if needed, modify ataPrintSmartAttribName()
153 // 3 -- add drive in question into builtin_knowndrives[] table in knowndrives.cpp
154 // 4 -- update smartctl.8
155 // 5 -- update smartd.8
156 // 6 -- do "make smartd.conf.5" to update smartd.conf.5
157 // 7 -- update CHANGELOG file
159 struct vendor_attr_arg_entry
161 unsigned char id
; // attribute ID, 0 for all
162 const char * name
; // attribute name
163 unsigned char val
; // value for attribute defs array
166 // The order of these entries is (only) relevant for '-v help' output.
167 const vendor_attr_arg_entry vendor_attribute_args
[] = {
168 { 9,"halfminutes", 4},
172 {192,"emergencyretractcyclect", 1},
173 {193,"loadunload", 1},
174 {194,"10xCelsius", 1},
176 {197,"increasing", 1},
177 {198,"offlinescanuncsectorct", 2},
178 {198,"increasing", 1},
179 {200,"writeerrorcount", 1},
180 {201,"detectedtacount", 1},
187 const unsigned num_vendor_attribute_args
= sizeof(vendor_attribute_args
)/sizeof(vendor_attribute_args
[0]);
189 // Get ID and increase flag of current pending or offline
190 // uncorrectable attribute.
191 unsigned char get_unc_attr_id(bool offline
, const unsigned char * defs
,
194 unsigned char id
= (!offline
? 197 : 198);
195 increase
= (defs
[id
] == 1);
199 // This are the meanings of the Self-test failure checkpoint byte.
200 // This is in the self-test log at offset 4 bytes into the self-test
201 // descriptor and in the SMART READ DATA structure at byte offset
202 // 371. These codes are not well documented. The meanings returned by
203 // this routine are used (at least) by Maxtor and IBM. Returns NULL if
204 // not recognized. Currently the maximum length is 15 bytes.
205 const char *SelfTestFailureCodeName(unsigned char which
){
211 return "Servo_Basic";
213 return "Servo_Random";
215 return "G-list_Scan";
217 return "Handling_Damage";
225 // This is a utility function for parsing pairs like "9,minutes" or
226 // "220,temp", and putting the correct flag into the attributedefs
227 // array. Returns 1 if problem, 0 if pair has been recongized.
228 int parse_attribute_def(const char * pair
, unsigned char * defs
)
232 if (pair
[0] == 'N') {
234 if (!(sscanf(pair
, "N,%32s%n", name
, &nc
) == 1 && nc
== (int)strlen(pair
)))
239 if (!( sscanf(pair
, "%d,%32s%n", &id
, name
, &nc
) == 2
240 && 1 <= id
&& id
<= 255 && nc
== (int)strlen(pair
)))
247 if (i
>= num_vendor_attribute_args
)
248 return 1; // Not found
249 if ( (!vendor_attribute_args
[i
].id
|| vendor_attribute_args
[i
].id
== id
)
250 && !strcmp(vendor_attribute_args
[i
].name
, name
) )
255 // "N,name" -> set all entries
256 for (int j
= 0; j
< MAX_ATTRIBUTE_NUM
; j
++)
257 defs
[j
] = vendor_attribute_args
[i
].val
;
261 defs
[id
] = vendor_attribute_args
[i
].val
;
266 // Return a multiline string containing a list of valid arguments for
267 // parse_attribute_def(). The strings are preceeded by tabs and followed
268 // (except for the last) by newlines.
269 std::string
create_vendor_attribute_arg_list()
272 for (unsigned i
= 0; i
< num_vendor_attribute_args
; i
++) {
275 if (!vendor_attribute_args
[i
].id
)
278 s
+= strprintf("\t%d,", vendor_attribute_args
[i
].id
);
279 s
+= vendor_attribute_args
[i
].name
;
284 // swap two bytes. Point to low address
285 void swap2(char *location
){
287 *location
=*(location
+1);
292 // swap four bytes. Point to low address
293 void swap4(char *location
){
295 *location
=*(location
+3);
301 // swap eight bytes. Points to low address
302 void swap8(char *location
){
304 *location
=*(location
+7);
307 *(location
+1)=*(location
+6);
313 // Invalidate serial number and adjust checksum in IDENTIFY data
314 static void invalidate_serno(ata_identify_device
* id
){
315 unsigned char sum
= 0;
316 for (unsigned i
= 0; i
< sizeof(id
->serial_no
); i
++) {
317 sum
+= id
->serial_no
[i
]; sum
-= id
->serial_no
[i
] = 'X';
320 bool must_swap
= !!isbigendian();
322 swapx(id
->words088_255
+255-88);
324 if ((id
->words088_255
[255-88] & 0x00ff) == 0x00a5)
325 id
->words088_255
[255-88] += sum
<< 8;
328 swapx(id
->words088_255
+255-88);
332 static const char * const commandstrings
[]={
335 "SMART AUTOMATIC ATTRIBUTE SAVE",
336 "SMART IMMEDIATE OFFLINE",
337 "SMART AUTO OFFLINE",
339 "SMART STATUS CHECK",
340 "SMART READ ATTRIBUTE VALUES",
341 "SMART READ ATTRIBUTE THRESHOLDS",
344 "IDENTIFY PACKET DEVICE",
347 "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT
")\n"
351 static const char * preg(const ata_register
& r
, char * buf
)
356 sprintf(buf
, "0x%02x", r
.val()); return buf
;
359 void print_regs(const char * prefix
, const ata_in_regs
& r
, const char * suffix
= "\n")
361 char bufs
[7][4+1+13];
362 pout("%s FR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, CMD=%s%s", prefix
,
363 preg(r
.features
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
364 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
365 preg(r
.command
, bufs
[6]), suffix
);
368 void print_regs(const char * prefix
, const ata_out_regs
& r
, const char * suffix
= "\n")
370 char bufs
[7][4+1+13];
371 pout("%sERR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, STS=%s%s", prefix
,
372 preg(r
.error
, bufs
[0]), preg(r
.sector_count
, bufs
[1]), preg(r
.lba_low
, bufs
[2]),
373 preg(r
.lba_mid
, bufs
[3]), preg(r
.lba_high
, bufs
[4]), preg(r
.device
, bufs
[5]),
374 preg(r
.status
, bufs
[6]), suffix
);
377 static void prettyprint(const unsigned char *p
, const char *name
){
378 pout("\n===== [%s] DATA START (BASE-16) =====\n", name
);
379 for (int i
=0; i
<512; i
+=16, p
+=16)
380 // print complete line to avoid slow tty output and extra lines in syslog.
381 pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x "
382 "%02x %02x %02x %02x %02x %02x %02x %02x\n",
384 p
[ 0], p
[ 1], p
[ 2], p
[ 3], p
[ 4], p
[ 5], p
[ 6], p
[ 7],
385 p
[ 8], p
[ 9], p
[10], p
[11], p
[12], p
[13], p
[14], p
[15]);
386 pout("===== [%s] DATA END (512 Bytes) =====\n\n", name
);
389 // This function provides the pretty-print reporting for SMART
390 // commands: it implements the various -r "reporting" options for ATA
392 int smartcommandhandler(ata_device
* device
, smart_command_set command
, int select
, char *data
){
393 // TODO: Rework old stuff below
394 // This conditional is true for commands that return data
395 int getsdata
=(command
==PIDENTIFY
||
398 command
==READ_THRESHOLDS
||
399 command
==READ_VALUES
||
400 command
==CHECK_POWER_MODE
);
402 int sendsdata
=(command
==WRITE_LOG
);
404 // If reporting is enabled, say what the command will be before it's executed
405 if (con
->reportataioctl
){
406 // conditional is true for commands that use parameters
407 int usesparam
=(command
==READ_LOG
||
408 command
==AUTO_OFFLINE
||
410 command
==IMMEDIATE_OFFLINE
||
413 pout("\nREPORT-IOCTL: Device=%s Command=%s", device
->get_dev_name(), commandstrings
[command
]);
415 pout(" InputParameter=%d\n", select
);
420 if ((getsdata
|| sendsdata
) && !data
){
421 pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings
[command
]);
425 // The reporting is cleaner, and we will find coding bugs faster, if
426 // the commands that failed clearly return empty (zeroed) data
429 if (command
==CHECK_POWER_MODE
)
432 memset(data
, '\0', 512);
436 // if requested, pretty-print the input data structure
437 if (con
->reportataioctl
>1 && sendsdata
)
438 //pout("REPORT-IOCTL: Device=%s Command=%s\n", device->get_dev_name(), commandstrings[command]);
439 prettyprint((unsigned char *)data
, commandstrings
[command
]);
441 // now execute the command
445 // Set common register values
447 default: // SMART commands
448 in
.in_regs
.command
= ATA_SMART_CMD
;
449 in
.in_regs
.lba_high
= SMART_CYL_HI
; in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
451 case IDENTIFY
: case PIDENTIFY
: case CHECK_POWER_MODE
: // Non SMART commands
454 // Set specific values
457 in
.in_regs
.command
= ATA_IDENTIFY_DEVICE
;
458 in
.set_data_in(data
, 1);
461 in
.in_regs
.command
= ATA_IDENTIFY_PACKET_DEVICE
;
462 in
.set_data_in(data
, 1);
464 case CHECK_POWER_MODE
:
465 in
.in_regs
.command
= ATA_CHECK_POWER_MODE
;
466 in
.out_needed
.sector_count
= true; // Powermode returned here
469 in
.in_regs
.features
= ATA_SMART_READ_VALUES
;
470 in
.set_data_in(data
, 1);
472 case READ_THRESHOLDS
:
473 in
.in_regs
.features
= ATA_SMART_READ_THRESHOLDS
;
474 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
475 in
.set_data_in(data
, 1);
478 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
479 in
.in_regs
.lba_low
= select
;
480 in
.set_data_in(data
, 1);
483 in
.in_regs
.features
= ATA_SMART_WRITE_LOG_SECTOR
;
484 in
.in_regs
.lba_low
= select
;
485 in
.set_data_out(data
, 1);
488 in
.in_regs
.features
= ATA_SMART_ENABLE
;
489 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
492 in
.in_regs
.features
= ATA_SMART_DISABLE
;
493 in
.in_regs
.lba_low
= 1; // TODO: CORRECT ???
496 in
.out_needed
.lba_high
= in
.out_needed
.lba_mid
= true; // Status returned here
498 in
.in_regs
.features
= ATA_SMART_STATUS
;
501 in
.in_regs
.features
= ATA_SMART_AUTO_OFFLINE
;
502 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
505 in
.in_regs
.features
= ATA_SMART_AUTOSAVE
;
506 in
.in_regs
.sector_count
= select
; // Caution: Non-DATA command!
508 case IMMEDIATE_OFFLINE
:
509 in
.in_regs
.features
= ATA_SMART_IMMEDIATE_OFFLINE
;
510 in
.in_regs
.lba_low
= select
;
513 pout("Unrecognized command %d in smartcommandhandler()\n"
514 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
515 device
->set_err(ENOSYS
);
520 if (con
->reportataioctl
)
521 print_regs(" Input: ", in
.in_regs
,
522 (in
.direction
==ata_cmd_in::data_in
? " IN\n":
523 in
.direction
==ata_cmd_in::data_out
? " OUT\n":"\n"));
526 bool ok
= device
->ata_pass_through(in
, out
);
528 if (con
->reportataioctl
&& out
.out_regs
.is_set())
529 print_regs(" Output: ", out
.out_regs
);
531 if (ok
) switch (command
) {
535 case CHECK_POWER_MODE
:
536 data
[0] = out
.out_regs
.sector_count
;
540 // Cyl low and Cyl high unchanged means "Good SMART status"
541 if ((out
.out_regs
.lba_high
== SMART_CYL_HI
) &&
542 (out
.out_regs
.lba_mid
== SMART_CYL_LOW
))
544 // These values mean "Bad SMART status"
545 else if ((out
.out_regs
.lba_high
== SRET_STATUS_HI_EXCEEDED
) &&
546 (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
))
548 else if (out
.out_regs
.lba_mid
== SMART_CYL_LOW
) {
550 if (con
->reportataioctl
)
551 pout("SMART STATUS RETURN: half healthy response sequence, "
552 "probable SAT/USB truncation\n");
553 } else if (out
.out_regs
.lba_mid
== SRET_STATUS_MID_EXCEEDED
) {
555 if (con
->reportataioctl
)
556 pout("SMART STATUS RETURN: half unhealthy response sequence, "
557 "probable SAT/USB truncation\n");
559 // We haven't gotten output that makes sense; print out some debugging info
560 pout("Error SMART Status command failed\n"
561 "Please get assistance from %s\n", PACKAGE_HOMEPAGE
);
569 // If requested, invalidate serial number before any printing is done
570 if ((command
== IDENTIFY
|| command
== PIDENTIFY
) && !retval
&& con
->dont_print_serial
)
571 invalidate_serno((ata_identify_device
*)data
);
573 // If reporting is enabled, say what output was produced by the command
574 if (con
->reportataioctl
){
575 if (device
->get_errno())
576 pout("REPORT-IOCTL: Device=%s Command=%s returned %d errno=%d [%s]\n",
577 device
->get_dev_name(), commandstrings
[command
], retval
,
578 device
->get_errno(), device
->get_errmsg());
580 pout("REPORT-IOCTL: Device=%s Command=%s returned %d\n",
581 device
->get_dev_name(), commandstrings
[command
], retval
);
583 // if requested, pretty-print the output data structure
584 if (con
->reportataioctl
>1 && getsdata
) {
585 if (command
==CHECK_POWER_MODE
)
586 pout("Sector Count Register (BASE-16): %02x\n", (unsigned char)(*data
));
588 prettyprint((unsigned char *)data
, commandstrings
[command
]);
592 errno
= device
->get_errno(); // TODO: Callers should not call syserror()
596 // Get number of sectors from IDENTIFY sector. If the drive doesn't
597 // support LBA addressing or has no user writable sectors
598 // (eg, CDROM or DVD) then routine returns zero.
599 uint64_t get_num_sectors(const ata_identify_device
* drive
)
601 unsigned short command_set_2
= drive
->command_set_2
;
602 unsigned short capabilities_0
= drive
->words047_079
[49-47];
603 unsigned short sects_16
= drive
->words047_079
[60-47];
604 unsigned short sects_32
= drive
->words047_079
[61-47];
605 unsigned short lba_16
= drive
->words088_255
[100-88];
606 unsigned short lba_32
= drive
->words088_255
[101-88];
607 unsigned short lba_48
= drive
->words088_255
[102-88];
608 unsigned short lba_64
= drive
->words088_255
[103-88];
611 if (!(capabilities_0
& 0x0200))
614 // if drive supports LBA addressing, determine 32-bit LBA capacity
615 uint64_t lba32
= (unsigned int)sects_32
<< 16 |
616 (unsigned int)sects_16
<< 0 ;
619 // if drive supports 48-bit addressing, determine THAT capacity
620 if ((command_set_2
& 0xc000) == 0x4000 && (command_set_2
& 0x0400))
621 lba64
= (uint64_t)lba_64
<< 48 |
622 (uint64_t)lba_48
<< 32 |
623 (uint64_t)lba_32
<< 16 |
624 (uint64_t)lba_16
<< 0 ;
626 // return the larger of the two possible capacities
627 return (lba32
> lba64
? lba32
: lba64
);
630 // This function computes the checksum of a single disk sector (512
631 // bytes). Returns zero if checksum is OK, nonzero if the checksum is
632 // incorrect. The size (512) is correct for all SMART structures.
633 unsigned char checksum(const void * data
)
635 unsigned char sum
= 0;
636 for (int i
= 0; i
< 512; i
++)
637 sum
+= ((const unsigned char *)data
)[i
];
641 // Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
643 static void swapbytes(char * out
, const char * in
, size_t n
)
645 for (size_t i
= 0; i
< n
; i
+= 2) {
651 // Copies in to out, but removes leading and trailing whitespace.
652 static void trim(char * out
, const char * in
)
654 // Find the first non-space character (maybe none).
657 for (i
= 0; in
[i
]; i
++)
658 if (!isspace((int)in
[i
])) {
664 // There are no non-space characters.
669 // Find the last non-space character.
670 for (i
= strlen(in
)-1; i
>= first
&& isspace((int)in
[i
]); i
--)
674 strncpy(out
, in
+first
, last
-first
+1);
675 out
[last
-first
+1] = '\0';
678 // Convenience function for formatting strings from ata_identify_device
679 void format_ata_string(char * out
, const char * in
, int n
, bool fix_swap
)
681 bool must_swap
= !fix_swap
;
683 /* NetBSD kernel delivers IDENTIFY data in host byte order (but all else is LE) */
685 must_swap
= !must_swap
;
693 swapbytes(tmp
, in
, n
);
698 // returns -1 if command fails or the device is in Sleep mode, else
699 // value of Sector Count register. Sector Count result values:
700 // 00h device is in Standby mode.
701 // 80h device is in Idle mode.
702 // FFh device is in Active mode or Idle mode.
704 int ataCheckPowerMode(ata_device
* device
) {
705 unsigned char result
;
707 if ((smartcommandhandler(device
, CHECK_POWER_MODE
, 0, (char *)&result
)))
710 if (result
!=0 && result
!=0x80 && result
!=0xff)
711 pout("ataCheckPowerMode(): ATA CHECK POWER MODE returned unknown Sector Count Register value %02x\n", result
);
719 // Reads current Device Identity info (512 bytes) into buf. Returns 0
720 // if all OK. Returns -1 if no ATA Device identity can be
721 // established. Returns >0 if Device is ATA Packet Device (not SMART
722 // capable). The value of the integer helps identify the type of
723 // Packet device, which is useful so that the user can connect the
724 // formal device number with whatever object is inside their computer.
725 int ataReadHDIdentity (ata_device
* device
, struct ata_identify_device
*buf
){
726 unsigned short *rawshort
=(unsigned short *)buf
;
727 unsigned char *rawbyte
=(unsigned char *)buf
;
729 // See if device responds either to IDENTIFY DEVICE or IDENTIFY
731 if ((smartcommandhandler(device
, IDENTIFY
, 0, (char *)buf
))){
732 if (smartcommandhandler(device
, PIDENTIFY
, 0, (char *)buf
)){
738 // if machine is big-endian, swap byte order as needed
739 // NetBSD kernel delivers IDENTIFY data in host byte order
743 // swap various capability words that are needed
745 swap2((char *)(buf
->words047_079
+i
));
747 for (i
=80; i
<=87; i
++)
748 swap2((char *)(rawshort
+i
));
750 for (i
=0; i
<168; i
++)
751 swap2((char *)(buf
->words088_255
+i
));
755 // If there is a checksum there, validate it
756 if ((rawshort
[255] & 0x00ff) == 0x00a5 && checksum(rawbyte
))
757 checksumwarning("Drive Identity Structure");
759 // If this is a PACKET DEVICE, return device type
760 if (rawbyte
[1] & 0x80)
761 return 1+(rawbyte
[1] & 0x1f);
763 // Not a PACKET DEVICE
767 // Returns ATA version as an integer, and a pointer to a string
768 // describing which revision. Note that Revision 0 of ATA-3 does NOT
769 // support SMART. For this one case we return -3 rather than +3 as
770 // the version number. See notes above.
771 int ataVersionInfo(const char ** description
, const ata_identify_device
* drive
, unsigned short * minor
)
773 // check that arrays at the top of this file are defined
775 if (sizeof(minor_str
) != sizeof(char *)*(1+MINOR_MAX
)){
776 pout("Internal error in ataVersionInfo(). minor_str[] size %d\n"
777 "is not consistent with value of MINOR_MAX+1 = %d\n",
778 (int)(sizeof(minor_str
)/sizeof(char *)), MINOR_MAX
+1);
782 if (sizeof(actual_ver
) != sizeof(int)*(1+MINOR_MAX
)){
783 pout("Internal error in ataVersionInfo(). actual_ver[] size %d\n"
784 "is not consistent with value of MINOR_MAX = %d\n",
785 (int)(sizeof(actual_ver
)/sizeof(int)), MINOR_MAX
+1);
790 // get major and minor ATA revision numbers
791 unsigned short major
= drive
->major_rev_num
;
792 *minor
=drive
->minor_rev_num
;
794 // First check if device has ANY ATA version information in it
795 if (major
==NOVAL_0
|| major
==NOVAL_1
) {
800 // The minor revision number has more information - try there first
801 if (*minor
&& (*minor
<=MINOR_MAX
)){
802 int std
= actual_ver
[*minor
];
804 *description
=minor_str
[*minor
];
809 // Try new ATA-8 minor revision numbers (Table 31 of T13/1699-D Revision 6)
810 // (not in actual_ver/minor_str to avoid large sparse tables)
813 case 0x0027: desc
= "ATA-8-ACS revision 3c"; break;
814 case 0x0028: desc
= "ATA-8-ACS revision 6"; break;
815 case 0x0029: desc
= "ATA-8-ACS revision 4"; break;
816 case 0x0033: desc
= "ATA-8-ACS revision 3e"; break;
817 case 0x0039: desc
= "ATA-8-ACS revision 4c"; break;
818 case 0x0042: desc
= "ATA-8-ACS revision 3f"; break;
819 case 0x0052: desc
= "ATA-8-ACS revision 3b"; break;
820 case 0x0107: desc
= "ATA-8-ACS revision 2d"; break;
821 default: desc
= 0; break;
828 // HDPARM has a very complicated algorithm from here on. Since SMART only
829 // exists on ATA-3 and later standards, let's punt on this. If you don't
830 // like it, please fix it. The code's in CVS.
833 if (major
& (0x1<<i
))
843 // returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
844 int ataSmartSupport(const ata_identify_device
* drive
)
846 unsigned short word82
=drive
->command_set_1
;
847 unsigned short word83
=drive
->command_set_2
;
849 // check if words 82/83 contain valid info
850 if ((word83
>>14) == 0x01)
851 // return value of SMART support bit
852 return word82
& 0x0001;
854 // since we can're rely on word 82, we don't know if SMART supported
858 // returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
859 int ataIsSmartEnabled(const ata_identify_device
* drive
)
861 unsigned short word85
=drive
->cfs_enable_1
;
862 unsigned short word87
=drive
->csf_default
;
864 // check if words 85/86/87 contain valid info
865 if ((word87
>>14) == 0x01)
866 // return value of SMART enabled bit
867 return word85
& 0x0001;
869 // Since we can't rely word85, we don't know if SMART is enabled.
874 // Reads SMART attributes into *data
875 int ataReadSmartValues(ata_device
* device
, struct ata_smart_values
*data
){
877 if (smartcommandhandler(device
, READ_VALUES
, 0, (char *)data
)){
878 syserror("Error SMART Values Read failed");
884 checksumwarning("SMART Attribute Data Structure");
886 // swap endian order if needed
889 swap2((char *)&(data
->revnumber
));
890 swap2((char *)&(data
->total_time_to_complete_off_line
));
891 swap2((char *)&(data
->smart_capability
));
892 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
893 struct ata_smart_attribute
*x
=data
->vendor_attributes
+i
;
894 swap2((char *)&(x
->flags
));
902 // This corrects some quantities that are byte reversed in the SMART
904 static void fixsamsungselftestlog(ata_smart_selftestlog
* data
)
906 // bytes 508/509 (numbered from 0) swapped (swap of self-test index
907 // with one byte of reserved.
908 swap2((char *)&(data
->mostrecenttest
));
910 // LBA low register (here called 'selftestnumber", containing
911 // information about the TYPE of the self-test) is byte swapped with
912 // Self-test execution status byte. These are bytes N, N+1 in the
914 for (int i
= 0; i
< 21; i
++)
915 swap2((char *)&(data
->selftest_struct
[i
].selftestnumber
));
920 // Reads the Self Test Log (log #6)
921 int ataReadSelfTestLog (ata_device
* device
, ata_smart_selftestlog
* data
,
922 unsigned char fix_firmwarebug
)
925 // get data from device
926 if (smartcommandhandler(device
, READ_LOG
, 0x06, (char *)data
)){
927 syserror("Error SMART Error Self-Test Log Read failed");
931 // compute its checksum, and issue a warning if needed
933 checksumwarning("SMART Self-Test Log Structure");
935 // fix firmware bugs in self-test log
936 if (fix_firmwarebug
== FIX_SAMSUNG
)
937 fixsamsungselftestlog(data
);
939 // swap endian order if needed
942 swap2((char*)&(data
->revnumber
));
943 for (i
=0; i
<21; i
++){
944 struct ata_smart_selftestlog_struct
*x
=data
->selftest_struct
+i
;
945 swap2((char *)&(x
->timestamp
));
946 swap4((char *)&(x
->lbafirstfailure
));
953 // Print checksum warning for multi sector log
954 static void check_multi_sector_sum(const void * data
, unsigned nsectors
, const char * msg
)
957 for (unsigned i
= 0; i
< nsectors
; i
++) {
958 if (checksum((const unsigned char *)data
+ i
*512))
963 checksumwarning(msg
);
965 checksumwarning(strprintf("%s (%u/%u)", msg
, errs
, nsectors
).c_str());
969 // Read SMART Extended Self-test Log
970 bool ataReadExtSelfTestLog(ata_device
* device
, ata_smart_extselftestlog
* log
,
973 if (!ataReadLogExt(device
, 0x07, 0x00, 0, log
, nsectors
))
976 check_multi_sector_sum(log
, nsectors
, "SMART Extended Self-test Log Structure");
979 swapx(&log
->log_desc_index
);
980 for (unsigned i
= 0; i
< nsectors
; i
++) {
981 for (unsigned j
= 0; j
< 19; j
++)
982 swapx(&log
->log_descs
[i
].timestamp
);
989 // Read GP Log page(s)
990 bool ataReadLogExt(ata_device
* device
, unsigned char logaddr
,
991 unsigned char features
, unsigned page
,
992 void * data
, unsigned nsectors
)
995 in
.in_regs
.command
= ATA_READ_LOG_EXT
;
996 in
.in_regs
.features
= features
; // log specific
997 in
.set_data_in_48bit(data
, nsectors
);
998 in
.in_regs
.lba_low
= logaddr
;
999 in
.in_regs
.lba_mid_16
= page
;
1001 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1002 if (nsectors
<= 1) {
1003 pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n",
1004 logaddr
, features
, page
, nsectors
, device
->get_errmsg());
1008 // Recurse to retry with single sectors,
1009 // multi-sector reads may not be supported by ioctl.
1010 for (unsigned i
= 0; i
< nsectors
; i
++) {
1011 if (!ataReadLogExt(device
, logaddr
,
1013 (char *)data
+ 512*i
, 1))
1021 // Read SMART Log page(s)
1022 bool ataReadSmartLog(ata_device
* device
, unsigned char logaddr
,
1023 void * data
, unsigned nsectors
)
1026 in
.in_regs
.command
= ATA_SMART_CMD
;
1027 in
.in_regs
.features
= ATA_SMART_READ_LOG_SECTOR
;
1028 in
.set_data_in(data
, nsectors
);
1029 in
.in_regs
.lba_high
= SMART_CYL_HI
;
1030 in
.in_regs
.lba_mid
= SMART_CYL_LOW
;
1031 in
.in_regs
.lba_low
= logaddr
;
1033 if (!device
->ata_pass_through(in
)) { // TODO: Debug output
1034 pout("ATA_SMART_READ_LOG failed: %s\n", device
->get_errmsg());
1042 // Reads the SMART or GPL Log Directory (log #0)
1043 int ataReadLogDirectory(ata_device
* device
, ata_smart_log_directory
* data
, bool gpl
)
1045 if (!gpl
) { // SMART Log directory
1046 if (smartcommandhandler(device
, READ_LOG
, 0x00, (char *)data
))
1049 else { // GP Log directory
1050 if (!ataReadLogExt(device
, 0x00, 0x00, 0, data
, 1))
1054 // swap endian order if needed
1056 swapx(&data
->logversion
);
1062 // Reads the selective self-test log (log #9)
1063 int ataReadSelectiveSelfTestLog(ata_device
* device
, struct ata_selective_self_test_log
*data
){
1065 // get data from device
1066 if (smartcommandhandler(device
, READ_LOG
, 0x09, (char *)data
)){
1067 syserror("Error SMART Read Selective Self-Test Log failed");
1071 // compute its checksum, and issue a warning if needed
1073 checksumwarning("SMART Selective Self-Test Log Structure");
1075 // swap endian order if needed
1078 swap2((char *)&(data
->logversion
));
1080 swap8((char *)&(data
->span
[i
].start
));
1081 swap8((char *)&(data
->span
[i
].end
));
1083 swap8((char *)&(data
->currentlba
));
1084 swap2((char *)&(data
->currentspan
));
1085 swap2((char *)&(data
->flags
));
1086 swap2((char *)&(data
->pendingtime
));
1089 if (data
->logversion
!= 1)
1090 pout("Note: selective self-test log revision number (%d) not 1 implies that no selective self-test has ever been run\n", data
->logversion
);
1095 // Writes the selective self-test log (log #9)
1096 int ataWriteSelectiveSelfTestLog(ata_device
* device
, ata_selective_selftest_args
& args
,
1097 const ata_smart_values
* sv
, uint64_t num_sectors
)
1099 // Disk size must be known
1101 pout("Disk size is unknown, unable to check selective self-test spans\n");
1106 struct ata_selective_self_test_log sstlog
, *data
=&sstlog
;
1107 unsigned char *ptr
=(unsigned char *)data
;
1108 if (ataReadSelectiveSelfTestLog(device
, data
)) {
1109 pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
1114 data
->logversion
= 1;
1116 // Host is NOT allowed to write selective self-test log if a selective
1117 // self-test is in progress.
1118 if (0<data
->currentspan
&& data
->currentspan
<6 && ((sv
->self_test_exec_status
)>>4)==15) {
1119 pout("Error SMART Selective or other Self-Test in progress.\n");
1123 // Set start/end values based on old spans for special -t select,... options
1125 for (i
= 0; i
< args
.num_spans
; i
++) {
1126 int mode
= args
.span
[i
].mode
;
1127 uint64_t start
= args
.span
[i
].start
;
1128 uint64_t end
= args
.span
[i
].end
;
1129 if (mode
== SEL_CONT
) {// redo or next dependig on last test status
1130 switch (sv
->self_test_exec_status
>> 4) {
1131 case 1: case 2: // Aborted/Interrupted by host
1132 pout("Continue Selective Self-Test: Redo last span\n");
1135 default: // All others
1136 pout("Continue Selective Self-Test: Start next span\n");
1142 case SEL_RANGE
: // -t select,START-END
1144 case SEL_REDO
: // -t select,redo... => Redo current
1145 start
= data
->span
[i
].start
;
1146 if (end
> 0) { // -t select,redo+SIZE
1147 end
--; end
+= start
; // [oldstart, oldstart+SIZE)
1149 else // -t select,redo
1150 end
= data
->span
[i
].end
; // [oldstart, oldend]
1152 case SEL_NEXT
: // -t select,next... => Do next
1153 if (data
->span
[i
].end
== 0) {
1154 start
= end
= 0; break; // skip empty spans
1156 start
= data
->span
[i
].end
+ 1;
1157 if (start
>= num_sectors
)
1158 start
= 0; // wrap around
1159 if (end
> 0) { // -t select,next+SIZE
1160 end
--; end
+= start
; // (oldend, oldend+SIZE]
1162 else { // -t select,next
1163 uint64_t oldsize
= data
->span
[i
].end
- data
->span
[i
].start
+ 1;
1164 end
= start
+ oldsize
- 1; // (oldend, oldend+oldsize]
1165 if (end
>= num_sectors
) {
1166 // Adjust size to allow round-robin testing without future size decrease
1167 uint64_t spans
= (num_sectors
+ oldsize
-1) / oldsize
;
1168 uint64_t newsize
= (num_sectors
+ spans
-1) / spans
;
1169 uint64_t newstart
= num_sectors
- newsize
, newend
= num_sectors
- 1;
1170 pout("Span %d changed from %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors)\n",
1171 i
, start
, end
, oldsize
);
1172 pout(" to %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors) (%"PRIu64
" spans)\n",
1173 newstart
, newend
, newsize
, spans
);
1174 start
= newstart
; end
= newend
;
1179 pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode
);
1183 if (start
< num_sectors
&& num_sectors
<= end
) {
1184 if (end
!= ~(uint64_t)0) // -t select,N-max
1185 pout("Size of self-test span %d decreased according to disk size\n", i
);
1186 end
= num_sectors
- 1;
1188 if (!(start
<= end
&& end
< num_sectors
)) {
1189 pout("Invalid selective self-test span %d: %"PRIu64
"-%"PRIu64
" (%"PRIu64
" sectors)\n",
1190 i
, start
, end
, num_sectors
);
1193 // Return the actual mode and range to caller.
1194 args
.span
[i
].mode
= mode
;
1195 args
.span
[i
].start
= start
;
1196 args
.span
[i
].end
= end
;
1201 memset(data
->span
+i
, 0, sizeof(struct test_span
));
1203 // Set spans for testing
1204 for (i
= 0; i
< args
.num_spans
; i
++){
1205 data
->span
[i
].start
= args
.span
[i
].start
;
1206 data
->span
[i
].end
= args
.span
[i
].end
;
1209 // host must initialize to zero before initiating selective self-test
1211 data
->currentspan
=0;
1213 // Perform off-line scan after selective test?
1214 if (args
.scan_after_select
== 1)
1216 data
->flags
&= ~SELECTIVE_FLAG_DOSCAN
;
1217 else if (args
.scan_after_select
== 2)
1219 data
->flags
|= SELECTIVE_FLAG_DOSCAN
;
1221 // Must clear active and pending flags before writing
1222 data
->flags
&= ~(SELECTIVE_FLAG_ACTIVE
);
1223 data
->flags
&= ~(SELECTIVE_FLAG_PENDING
);
1225 // modify pending time?
1226 if (args
.pending_time
)
1227 data
->pendingtime
= (unsigned short)(args
.pending_time
-1);
1229 // Set checksum to zero, then compute checksum
1231 unsigned char cksum
=0;
1232 for (i
=0; i
<512; i
++)
1236 data
->checksum
=cksum
;
1238 // swap endian order if needed
1240 swap2((char *)&(data
->logversion
));
1241 for (int i
=0;i
<5;i
++){
1242 swap8((char *)&(data
->span
[i
].start
));
1243 swap8((char *)&(data
->span
[i
].end
));
1245 swap8((char *)&(data
->currentlba
));
1246 swap2((char *)&(data
->currentspan
));
1247 swap2((char *)&(data
->flags
));
1248 swap2((char *)&(data
->pendingtime
));
1251 // write new selective self-test log
1252 if (smartcommandhandler(device
, WRITE_LOG
, 0x09, (char *)data
)){
1253 syserror("Error Write Selective Self-Test Log failed");
1260 // This corrects some quantities that are byte reversed in the SMART
1262 static void fixsamsungerrorlog(ata_smart_errorlog
* data
)
1264 // FIXED IN SAMSUNG -25 FIRMWARE???
1265 // Device error count in bytes 452-3
1266 swap2((char *)&(data
->ata_error_count
));
1268 // FIXED IN SAMSUNG -22a FIRMWARE
1269 // step through 5 error log data structures
1270 for (int i
= 0; i
< 5; i
++){
1271 // step through 5 command data structures
1272 for (int j
= 0; j
< 5; j
++)
1273 // Command data structure 4-byte millisec timestamp. These are
1274 // bytes (N+8, N+9, N+10, N+11).
1275 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1276 // Error data structure two-byte hour life timestamp. These are
1277 // bytes (N+28, N+29).
1278 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1283 // NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
1284 static void fixsamsungerrorlog2(ata_smart_errorlog
* data
)
1286 // Device error count in bytes 452-3
1287 swap2((char *)&(data
->ata_error_count
));
1291 // Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1292 // Error Log is #2, and the Extended Comprehensive SMART Error log is
1294 int ataReadErrorLog (ata_device
* device
, ata_smart_errorlog
*data
,
1295 unsigned char fix_firmwarebug
)
1298 // get data from device
1299 if (smartcommandhandler(device
, READ_LOG
, 0x01, (char *)data
)){
1300 syserror("Error SMART Error Log Read failed");
1304 // compute its checksum, and issue a warning if needed
1306 checksumwarning("SMART ATA Error Log Structure");
1308 // Some disks have the byte order reversed in some SMART Summary
1309 // Error log entries
1310 if (fix_firmwarebug
== FIX_SAMSUNG
)
1311 fixsamsungerrorlog(data
);
1312 else if (fix_firmwarebug
== FIX_SAMSUNG2
)
1313 fixsamsungerrorlog2(data
);
1315 // swap endian order if needed
1319 // Device error count in bytes 452-3
1320 swap2((char *)&(data
->ata_error_count
));
1322 // step through 5 error log data structures
1323 for (i
=0; i
<5; i
++){
1324 // step through 5 command data structures
1326 // Command data structure 4-byte millisec timestamp
1327 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1328 // Error data structure life timestamp
1329 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1336 // Read Extended Comprehensive Error Log
1337 bool ataReadExtErrorLog(ata_device
* device
, ata_smart_exterrlog
* log
,
1340 if (!ataReadLogExt(device
, 0x03, 0x00, 0, log
, nsectors
))
1343 check_multi_sector_sum(log
, nsectors
, "SMART Extended Comprehensive Error Log Structure");
1345 if (isbigendian()) {
1346 swapx(&log
->device_error_count
);
1347 swapx(&log
->error_log_index
);
1349 for (unsigned i
= 0; i
< nsectors
; i
++) {
1350 for (unsigned j
= 0; j
< 4; j
++)
1351 swapx(&log
->error_logs
[i
].commands
[j
].timestamp
);
1352 swapx(&log
->error_logs
[i
].error
.timestamp
);
1360 int ataReadSmartThresholds (ata_device
* device
, struct ata_smart_thresholds_pvt
*data
){
1362 // get data from device
1363 if (smartcommandhandler(device
, READ_THRESHOLDS
, 0, (char *)data
)){
1364 syserror("Error SMART Thresholds Read failed");
1368 // compute its checksum, and issue a warning if needed
1370 checksumwarning("SMART Attribute Thresholds Structure");
1372 // swap endian order if needed
1374 swap2((char *)&(data
->revnumber
));
1379 int ataEnableSmart (ata_device
* device
){
1380 if (smartcommandhandler(device
, ENABLE
, 0, NULL
)){
1381 syserror("Error SMART Enable failed");
1387 int ataDisableSmart (ata_device
* device
){
1389 if (smartcommandhandler(device
, DISABLE
, 0, NULL
)){
1390 syserror("Error SMART Disable failed");
1396 int ataEnableAutoSave(ata_device
* device
){
1397 if (smartcommandhandler(device
, AUTOSAVE
, 241, NULL
)){
1398 syserror("Error SMART Enable Auto-save failed");
1404 int ataDisableAutoSave(ata_device
* device
){
1406 if (smartcommandhandler(device
, AUTOSAVE
, 0, NULL
)){
1407 syserror("Error SMART Disable Auto-save failed");
1413 // In *ALL* ATA standards the Enable/Disable AutoOffline command is
1414 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1415 // vendors still support it for backwards compatibility. IBM documents
1416 // it for some drives.
1417 int ataEnableAutoOffline (ata_device
* device
){
1419 /* timer hard coded to 4 hours */
1420 if (smartcommandhandler(device
, AUTO_OFFLINE
, 248, NULL
)){
1421 syserror("Error SMART Enable Automatic Offline failed");
1427 // Another Obsolete Command. See comments directly above, associated
1428 // with the corresponding Enable command.
1429 int ataDisableAutoOffline (ata_device
* device
){
1431 if (smartcommandhandler(device
, AUTO_OFFLINE
, 0, NULL
)){
1432 syserror("Error SMART Disable Automatic Offline failed");
1438 // If SMART is enabled, supported, and working, then this call is
1439 // guaranteed to return 1, else zero. Note that it should return 1
1440 // regardless of whether the disk's SMART status is 'healthy' or
1442 int ataDoesSmartWork(ata_device
* device
){
1443 int retval
=smartcommandhandler(device
, STATUS
, 0, NULL
);
1451 // This function uses a different interface (DRIVE_TASK) than the
1452 // other commands in this file.
1453 int ataSmartStatus2(ata_device
* device
){
1454 return smartcommandhandler(device
, STATUS_CHECK
, 0, NULL
);
1457 // This is the way to execute ALL tests: offline, short self-test,
1458 // extended self test, with and without captive mode, etc.
1459 // TODO: Move to ataprint.cpp ?
1460 int ataSmartTest(ata_device
* device
, int testtype
, const ata_selective_selftest_args
& selargs
,
1461 const ata_smart_values
* sv
, uint64_t num_sectors
)
1463 char cmdmsg
[128]; const char *type
, *captive
;
1464 int errornum
, cap
, retval
, select
=0;
1466 // Boolean, if set, says test is captive
1467 cap
=testtype
& CAPTIVE_MASK
;
1469 // Set up strings that describe the type of test
1475 if (testtype
==OFFLINE_FULL_SCAN
)
1477 else if (testtype
==SHORT_SELF_TEST
|| testtype
==SHORT_CAPTIVE_SELF_TEST
)
1478 type
="Short self-test";
1479 else if (testtype
==EXTEND_SELF_TEST
|| testtype
==EXTEND_CAPTIVE_SELF_TEST
)
1480 type
="Extended self-test";
1481 else if (testtype
==CONVEYANCE_SELF_TEST
|| testtype
==CONVEYANCE_CAPTIVE_SELF_TEST
)
1482 type
="Conveyance self-test";
1483 else if ((select
=(testtype
==SELECTIVE_SELF_TEST
|| testtype
==SELECTIVE_CAPTIVE_SELF_TEST
)))
1484 type
="Selective self-test";
1486 type
="[Unrecognized] self-test";
1488 // If doing a selective self-test, first use WRITE_LOG to write the
1489 // selective self-test log.
1490 ata_selective_selftest_args selargs_io
= selargs
; // filled with info about actual spans
1491 if (select
&& (retval
= ataWriteSelectiveSelfTestLog(device
, selargs_io
, sv
, num_sectors
))) {
1493 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1497 // Print ouf message that we are sending the command to test
1498 if (testtype
==ABORT_SELF_TEST
)
1499 sprintf(cmdmsg
,"Abort SMART off-line mode self-test routine");
1501 sprintf(cmdmsg
,"Execute SMART %s routine immediately in %s mode",type
,captive
);
1502 pout("Sending command: \"%s\".\n",cmdmsg
);
1506 pout("SPAN STARTING_LBA ENDING_LBA\n");
1507 for (i
= 0; i
< selargs_io
.num_spans
; i
++)
1508 pout(" %d %20"PRId64
" %20"PRId64
"\n", i
,
1509 selargs_io
.span
[i
].start
,
1510 selargs_io
.span
[i
].end
);
1513 // Now send the command to test
1514 errornum
=smartcommandhandler(device
, IMMEDIATE_OFFLINE
, testtype
, NULL
);
1516 if (errornum
&& !(cap
&& errno
==EIO
)){
1518 sprintf(errormsg
,"Command \"%s\" failed",cmdmsg
);
1524 // Since the command succeeded, tell user
1525 if (testtype
==ABORT_SELF_TEST
)
1526 pout("Self-testing aborted!\n");
1528 pout("Drive command \"%s\" successful.\nTesting has begun.\n",cmdmsg
);
1532 /* Test Time Functions */
1533 int TestTime(const ata_smart_values
*data
, int testtype
)
1536 case OFFLINE_FULL_SCAN
:
1537 return (int) data
->total_time_to_complete_off_line
;
1538 case SHORT_SELF_TEST
:
1539 case SHORT_CAPTIVE_SELF_TEST
:
1540 return (int) data
->short_test_completion_time
;
1541 case EXTEND_SELF_TEST
:
1542 case EXTEND_CAPTIVE_SELF_TEST
:
1543 return (int) data
->extend_test_completion_time
;
1544 case CONVEYANCE_SELF_TEST
:
1545 case CONVEYANCE_CAPTIVE_SELF_TEST
:
1546 return (int) data
->conveyance_test_completion_time
;
1552 // This function tells you both about the ATA error log and the
1553 // self-test error log capability (introduced in ATA-5). The bit is
1554 // poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1555 // SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1556 // word 84 and 87. Top two bits must match the pattern 01. BEFORE
1557 // ATA-6 these top two bits still had to match the pattern 01, but the
1558 // remaining bits were reserved (==0).
1559 int isSmartErrorLogCapable (const ata_smart_values
* data
, const ata_identify_device
* identity
)
1561 unsigned short word84
=identity
->command_set_extension
;
1562 unsigned short word87
=identity
->csf_default
;
1563 int isata6
=identity
->major_rev_num
& (0x01<<6);
1564 int isata7
=identity
->major_rev_num
& (0x01<<7);
1566 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x01))
1569 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x01))
1572 // otherwise we'll use the poorly documented capability bit
1573 return data
->errorlog_capability
& 0x01;
1576 // See previous function. If the error log exists then the self-test
1577 // log should (must?) also exist.
1578 int isSmartTestLogCapable (const ata_smart_values
* data
, const ata_identify_device
*identity
)
1580 unsigned short word84
=identity
->command_set_extension
;
1581 unsigned short word87
=identity
->csf_default
;
1582 int isata6
=identity
->major_rev_num
& (0x01<<6);
1583 int isata7
=identity
->major_rev_num
& (0x01<<7);
1585 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x02))
1588 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x02))
1592 // otherwise we'll use the poorly documented capability bit
1593 return data
->errorlog_capability
& 0x01;
1597 int isGeneralPurposeLoggingCapable(const ata_identify_device
*identity
)
1599 unsigned short word84
=identity
->command_set_extension
;
1600 unsigned short word87
=identity
->csf_default
;
1602 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1603 // cleared to zero, the contents of word 84 contains valid support
1604 // information. If not, support information is not valid in this
1606 if ((word84
>>14) == 0x01)
1607 // If bit 5 of word 84 is set to one, the device supports the
1608 // General Purpose Logging feature set.
1609 return (word84
& (0x01 << 5));
1611 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1612 // cleared to zero, the contents of words (87:85) contain valid
1613 // information. If not, information is not valid in these words.
1614 if ((word87
>>14) == 0x01)
1615 // If bit 5 of word 87 is set to one, the device supports
1616 // the General Purpose Logging feature set.
1617 return (word87
& (0x01 << 5));
1624 // SMART self-test capability is also indicated in bit 1 of DEVICE
1625 // IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1626 // However this was only introduced in ATA-6 (but self-test log was in
1628 int isSupportExecuteOfflineImmediate(const ata_smart_values
*data
)
1630 return data
->offline_data_collection_capability
& 0x01;
1633 // Note in the ATA-5 standard, the following bit is listed as "Vendor
1634 // Specific". So it may not be reliable. The only use of this that I
1635 // have found is in IBM drives, where it is well-documented. See for
1636 // example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1637 // hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
1638 int isSupportAutomaticTimer(const ata_smart_values
* data
)
1640 return data
->offline_data_collection_capability
& 0x02;
1642 int isSupportOfflineAbort(const ata_smart_values
*data
)
1644 return data
->offline_data_collection_capability
& 0x04;
1646 int isSupportOfflineSurfaceScan(const ata_smart_values
* data
)
1648 return data
->offline_data_collection_capability
& 0x08;
1650 int isSupportSelfTest (const ata_smart_values
* data
)
1652 return data
->offline_data_collection_capability
& 0x10;
1654 int isSupportConveyanceSelfTest(const ata_smart_values
* data
)
1656 return data
->offline_data_collection_capability
& 0x20;
1658 int isSupportSelectiveSelfTest(const ata_smart_values
* data
)
1660 return data
->offline_data_collection_capability
& 0x40;
1665 // Loop over all valid attributes. If they are prefailure attributes
1666 // and are at or below the threshold value, then return the ID of the
1667 // first failing attribute found. Return 0 if all prefailure
1668 // attributes are in bounds. The spec says "Bit 0
1669 // -Pre-failure/advisory - If the value of this bit equals zero, an
1670 // attribute value less than or equal to its corresponding attribute
1671 // threshold indicates an advisory condition where the usage or age of
1672 // the device has exceeded its intended design life period. If the
1673 // value of this bit equals one, an atribute value less than or equal
1674 // to its corresponding attribute threshold indicates a pre-failure
1675 // condition where imminent loss of data is being predicted."
1678 // onlyfailed=0 : are or were any age or prefailure attributes <= threshold
1679 // onlyfailed=1: are any prefailure attributes <= threshold now
1680 int ataCheckSmart(const ata_smart_values
* data
,
1681 const ata_smart_thresholds_pvt
* thresholds
,
1684 // loop over all attributes
1685 for (int i
= 0; i
< NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
1687 // pointers to disk's values and vendor's thresholds
1688 const ata_smart_attribute
* disk
= data
->vendor_attributes
+i
;
1689 const ata_smart_threshold_entry
* thre
= thresholds
->thres_entries
+i
;
1691 // consider only valid attributes
1692 if (disk
->id
&& thre
->id
){
1693 int failednow
,failedever
;
1695 failednow
=disk
->current
<= thre
->threshold
;
1696 failedever
=disk
->worst
<= thre
->threshold
;
1698 if (!onlyfailed
&& failedever
)
1701 if (onlyfailed
&& failednow
&& ATTRIBUTE_FLAGS_PREFAILURE(disk
->flags
))
1710 // This checks the n'th attribute in the attribute list, NOT the
1711 // attribute with id==n. If the attribute does not exist, or the
1712 // attribute is > threshold, then returns zero. If the attribute is
1713 // <= threshold (failing) then we the attribute number if it is a
1714 // prefail attribute. Else we return minus the attribute number if it
1715 // is a usage attribute.
1716 int ataCheckAttribute(const ata_smart_values
* data
,
1717 const ata_smart_thresholds_pvt
* thresholds
,
1720 if (n
<0 || n
>=NUMBER_ATA_SMART_ATTRIBUTES
|| !data
|| !thresholds
)
1723 // pointers to disk's values and vendor's thresholds
1724 const ata_smart_attribute
* disk
= data
->vendor_attributes
+n
;
1725 const ata_smart_threshold_entry
* thre
= thresholds
->thres_entries
+n
;
1730 // consider only valid attributes, check for failure
1731 if (!disk
->id
|| !thre
->id
|| (disk
->id
!= thre
->id
) || disk
->current
> thre
->threshold
)
1734 // We have found a failed attribute. Return positive or negative?
1735 if (ATTRIBUTE_FLAGS_PREFAILURE(disk
->flags
))
1738 return -1*(disk
->id
);
1742 // Print temperature value and Min/Max value if present
1743 static void ataPrintTemperatureValue(char *out
, const unsigned char *raw
, const unsigned *word
)
1745 out
+=sprintf(out
, "%u", word
[0]);
1746 if (!word
[1] && !word
[2])
1747 return; // No Min/Max
1749 unsigned lo
= ~0, hi
= ~0;
1751 // 00 HH 00 LL 00 TT (IBM)
1752 hi
= word
[2]; lo
= word
[1];
1754 else if (!word
[2]) {
1755 // 00 00 HH LL 00 TT (Maxtor)
1756 hi
= raw
[3]; lo
= raw
[2];
1759 unsigned t
= lo
; lo
= hi
; hi
= t
;
1761 if (lo
<= word
[0] && word
[0] <= hi
)
1762 sprintf(out
, " (Lifetime Min/Max %u/%u)", lo
, hi
);
1764 sprintf(out
, " (%u %u %u %u)", raw
[5], raw
[4], raw
[3], raw
[2]);
1768 // This routine prints the raw value of an attribute as a text string
1769 // into out. It also returns this 48-bit number as a long long. The
1770 // array defs[] contains non-zero values if particular attributes have
1771 // non-default interpretations.
1773 int64_t ataPrintSmartAttribRawValue(char *out
,
1774 const ata_smart_attribute
* attribute
,
1775 const unsigned char * defs
){
1779 unsigned char select
;
1781 // convert the six individual bytes to a long long (8 byte) integer.
1782 // This is the value that we'll eventually return.
1784 for (j
=0; j
<6; j
++) {
1785 // This looks a bit roundabout, but is necessary. Don't
1786 // succumb to the temptation to use raw[j]<<(8*j) since under
1787 // the normal rules this will be promoted to the native type.
1788 // On a 32 bit machine this might then overflow.
1790 temp
= attribute
->raw
[j
];
1795 // convert quantities to three two-byte words
1796 for (j
=0; j
<3; j
++){
1797 word
[j
] = attribute
->raw
[2*j
+1];
1799 word
[j
] |= attribute
->raw
[2*j
];
1802 // if no data array, Attributes have default interpretations
1804 select
=defs
[attribute
->id
];
1808 // Print six one-byte quantities.
1811 out
+=sprintf(out
, "%d ", attribute
->raw
[5-j
]);
1812 out
+=sprintf(out
, "%d ", attribute
->raw
[0]);
1816 // Print three two-byte quantities
1818 out
+=sprintf(out
, "%d %d %d", word
[2], word
[1], word
[0]);
1822 // Print one six-byte quantity
1824 out
+=sprintf(out
, "%"PRIu64
, rawvalue
);
1828 // This switch statement is where we handle Raw attributes
1829 // that are stored in an unusual vendor-specific format,
1830 switch (attribute
->id
){
1833 out
+=sprintf(out
, "%d", word
[0]);
1834 // if second nonzero then it stores the average spin-up time
1836 out
+=sprintf(out
, " (Average %d)", word
[1]);
1838 // reallocated sector count
1840 out
+=sprintf(out
, "%u", word
[0]);
1841 if (word
[1] || word
[2])
1842 out
+=sprintf(out
, " (%u, %u)", word
[2], word
[1]);
1848 int64_t temp
=word
[0]+(word
[1]<<16);
1849 int64_t tmp1
=temp
/60;
1850 int64_t tmp2
=temp
%60;
1851 out
+=sprintf(out
, "%"PRIu64
"h+%02"PRIu64
"m", tmp1
, tmp2
);
1853 out
+=sprintf(out
, " (%u)", word
[2]);
1855 else if (select
==3){
1857 int64_t hours
=rawvalue
/3600;
1858 int64_t minutes
=(rawvalue
-3600*hours
)/60;
1859 int64_t seconds
=rawvalue
%60;
1860 out
+=sprintf(out
, "%"PRIu64
"h+%02"PRIu64
"m+%02"PRIu64
"s", hours
, minutes
, seconds
);
1862 else if (select
==4){
1863 // 30-second counter
1864 int64_t tmp1
=rawvalue
/120;
1865 int64_t tmp2
=(rawvalue
-120*tmp1
)/2;
1866 out
+=sprintf(out
, "%"PRIu64
"h+%02"PRIu64
"m", tmp1
, tmp2
);
1870 out
+=sprintf(out
, "%"PRIu64
, rawvalue
); //stored in hours
1874 ataPrintTemperatureValue(out
, attribute
->raw
, word
);
1876 // Load unload cycles
1880 long load
=attribute
->raw
[0] + (attribute
->raw
[1]<<8) + (attribute
->raw
[2]<<16);
1881 long unload
=attribute
->raw
[3] + (attribute
->raw
[4]<<8) + (attribute
->raw
[5]<<16);
1882 out
+=sprintf(out
, "%lu/%lu", load
, unload
);
1886 out
+=sprintf(out
, "%"PRIu64
, rawvalue
);
1891 // ten times temperature in Celsius
1893 int tenths
=word
[0]%10;
1894 out
+=sprintf(out
, "%d.%d", deg
, tenths
);
1897 // unknown attribute
1898 out
+=sprintf(out
, "%"PRIu64
, rawvalue
);
1900 ataPrintTemperatureValue(out
, attribute
->raw
, word
);
1902 // reallocated event count
1904 out
+=sprintf(out
, "%u", word
[0]);
1905 if (word
[1] || word
[2])
1906 out
+=sprintf(out
, " (%u, %u)", word
[2], word
[1]);
1909 out
+=sprintf(out
, "%"PRIu64
, rawvalue
);
1912 // Return the full value
1917 // Note some attribute names appear redundant because different
1918 // manufacturers use different attribute IDs for an attribute with the
1919 // same name. The variable val should contain a non-zero value if a particular
1920 // attributes has a non-default interpretation.
1921 void ataPrintSmartAttribName(char * out
, unsigned char id
, const unsigned char * definitions
){
1925 // If no data array, use default interpretations
1927 val
=definitions
[id
];
1934 name
="Raw_Read_Error_Rate";
1937 name
="Throughput_Performance";
1940 name
="Spin_Up_Time";
1943 name
="Start_Stop_Count";
1946 name
="Reallocated_Sector_Ct";
1949 name
="Read_Channel_Margin";
1952 name
="Seek_Error_Rate";
1955 name
="Seek_Time_Performance";
1960 name
="Power_On_Minutes";
1963 name
="Temperature_Celsius";
1966 name
="Power_On_Seconds";
1969 name
="Power_On_Half_Minutes";
1972 name
="Power_On_Hours";
1977 name
="Spin_Retry_Count";
1980 name
="Calibration_Retry_Count";
1983 name
="Power_Cycle_Count";
1986 name
="Read_Soft_Error_Rate";
1989 name
="Program_Fail_Count_Chip";
1992 name
="Erase_Fail_Count_Chip";
1995 name
="Wear_Leveling_Count";
1998 name
="Used_Rsvd_Blk_Cnt_Chip";
2001 name
="Used_Rsvd_Blk_Cnt_Tot";
2004 name
="Unused_Rsvd_Blk_Cnt_Tot";
2007 name
="Program_Fail_Cnt_Total";
2010 name
="Erase_Fail_Count_Total";
2013 name
="Runtime_Bad_Block";
2016 name
="End-to-End_Error";
2019 name
="Reported_Uncorrect";
2022 name
="Command_Timeout";
2025 name
="High_Fly_Writes";
2028 // Western Digital uses this for temperature.
2029 // It's identical to Attribute 194 except that it
2030 // has a failure threshold set to correspond to the
2031 // max allowed operating temperature of the drive, which
2032 // is typically 55C. So if this attribute has failed
2033 // in the past, it indicates that the drive temp exceeded
2034 // 55C sometime in the past.
2035 name
="Airflow_Temperature_Cel";
2038 name
="G-Sense_Error_Rate";
2044 name
="Emergency_Retract_Cycle_Ct";
2047 name
="Power-Off_Retract_Count";
2052 name
="Load_Cycle_Count";
2057 // Samsung SV1204H with RK100-13 firmware
2058 name
="Temperature_Celsius_x10";
2061 // for disks with no temperature Attribute
2062 name
="Unknown_Attribute";
2065 name
="Temperature_Celsius";
2070 // Fujitsu name="ECC_On_The_Fly_Count";
2071 name
="Hardware_ECC_Recovered";
2074 name
="Reallocated_Event_Count";
2079 name
="Current_Pending_Sector";
2082 // Not reset after sector reallocation
2083 name
="Total_Pending_Sectors";
2090 name
="Offline_Uncorrectable";
2093 // Not reset after sector reallocation
2094 name
="Total_Offl_Uncorrectabl"/*e*/;
2098 name
="Off-line_Scan_UNC_Sector_Ct";
2103 name
="UDMA_CRC_Error_Count";
2108 // Fujitsu MHS2020AT
2109 name
="Write_Error_Count";
2113 name
="Multi_Zone_Error_Rate";
2121 name
="Detected_TA_Count";
2124 name
="Soft_Read_Error_Rate";
2130 name
="TA_Increase_Count";
2131 // Maxtor: Data Address Mark Errors
2135 name
="Run_Out_Cancel";
2136 // Maxtor: ECC Errors
2140 name
="Shock_Count_Write_Opern";
2141 // Maxtor: Soft ECC Correction
2145 name
="Shock_Rate_Write_Opern";
2146 // Maxtor: Thermal Aspirates
2150 name
="Flying_Height";
2154 name
="Spin_High_Current";
2162 name
="Offline_Seek_Performnce";
2167 name
="Temperature_Celsius";
2175 name
="G-Sense_Error_Rate";
2178 name
="Loaded_Hours";
2181 name
="Load_Retry_Count";
2184 name
="Load_Friction";
2187 name
="Load_Cycle_Count";
2190 name
="Load-in_Time";
2193 name
="Torq-amp_Count";
2196 name
="Power-off_Retract_Count";
2199 // seen in IBM DTPA-353750
2200 name
="Head_Amplitude";
2203 name
="Temperature_Celsius";
2206 name
="Head_Flying_Hours";
2209 name
="Read_Error_Retry_Rate";
2212 name
="Unknown_Attribute";
2215 sprintf(out
,"%3hu %s",(short int)id
,name
);
2219 // Returns raw value of Attribute with ID==id. This will be in the
2220 // range 0 to 2^48-1 inclusive. If the Attribute does not exist,
2222 int64_t ATAReturnAttributeRawValue(unsigned char id
, const ata_smart_values
* data
)
2224 // valid Attribute IDs are in the range 1 to 255 inclusive.
2228 // loop over Attributes to see if there is one with the desired ID
2229 for (int i
= 0; i
< NUMBER_ATA_SMART_ATTRIBUTES
; i
++) {
2230 const ata_smart_attribute
* ap
= data
->vendor_attributes
+ i
;
2232 // we've found the desired Attribute. Return its value
2236 for (j
=0; j
<6; j
++) {
2237 // This looks a bit roundabout, but is necessary. Don't
2238 // succumb to the temptation to use raw[j]<<(8*j) since under
2239 // the normal rules this will be promoted to the native type.
2240 // On a 32 bit machine this might then overflow.
2247 } // found desired Attribute
2248 } // loop over Attributes
2250 // fall-through: no such Attribute found
2254 // Return Temperature Attribute raw value selected according to possible
2255 // non-default interpretations. If the Attribute does not exist, return 0
2256 unsigned char ATAReturnTemperatureValue(const ata_smart_values
* data
, const unsigned char * defs
)
2258 for (int i
= 0; i
< 3; i
++) {
2259 static const unsigned char ids
[3] = {194, 9, 220};
2260 unsigned char id
= ids
[i
];
2261 unsigned char select
= (defs
? defs
[id
] : 0);
2262 int64_t raw
; unsigned temp
;
2263 if (!( (id
== 194 && select
<= 1) // ! -v 194,unknown
2264 || (id
== 9 && select
== 2) // -v 9,temp
2265 || (id
== 220 && select
== 1))) // -v 220,temp
2267 raw
= ATAReturnAttributeRawValue(id
, data
);
2270 temp
= (unsigned short)raw
; // ignore possible min/max values in high words
2271 if (id
== 194 && select
== 1) // -v 194,10xCelsius
2272 temp
= (temp
+5) / 10;
2273 if (!(0 < temp
&& temp
<= 255))
2277 // No valid attribute found
2283 int ataReadSCTStatus(ata_device
* device
, ata_sct_status_response
* sts
)
2285 // read SCT status via SMART log 0xe0
2286 memset(sts
, 0, sizeof(*sts
));
2287 if (smartcommandhandler(device
, READ_LOG
, 0xe0, (char *)sts
)){
2288 syserror("Error Read SCT Status failed");
2292 // swap endian order if needed
2294 swapx(&sts
->format_version
);
2295 swapx(&sts
->sct_version
);
2296 swapx(&sts
->sct_spec
);
2297 swapx(&sts
->ext_status_code
);
2298 swapx(&sts
->action_code
);
2299 swapx(&sts
->function_code
);
2300 swapx(&sts
->over_limit_count
);
2301 swapx(&sts
->under_limit_count
);
2304 // Check format version
2305 if (!(sts
->format_version
== 2 || sts
->format_version
== 3)) {
2306 pout("Error unknown SCT Status format version %u, should be 2 or 3.\n", sts
->format_version
);
2312 // Read SCT Temperature History Table and Status
2313 int ataReadSCTTempHist(ata_device
* device
, ata_sct_temperature_history_table
* tmh
,
2314 ata_sct_status_response
* sts
)
2316 // Check initial status
2317 if (ataReadSCTStatus(device
, sts
))
2320 // Do nothing if other SCT command is executing
2321 if (sts
->ext_status_code
== 0xffff) {
2322 pout("Another SCT command is executing, abort Read Data Table\n"
2323 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2324 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2328 ata_sct_data_table_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2329 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2330 cmd
.action_code
= 5; // Data table command
2331 cmd
.function_code
= 1; // Read table
2332 cmd
.table_id
= 2; // Temperature History Table
2334 // write command via SMART log page 0xe0
2335 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2336 syserror("Error Write SCT Data Table command failed");
2340 // read SCT data via SMART log page 0xe1
2341 memset(tmh
, 0, sizeof(*tmh
));
2342 if (smartcommandhandler(device
, READ_LOG
, 0xe1, (char *)tmh
)){
2343 syserror("Error Read SCT Data Table failed");
2347 // re-read and check SCT status
2348 if (ataReadSCTStatus(device
, sts
))
2351 if (!(sts
->ext_status_code
== 0 && sts
->action_code
== 5 && sts
->function_code
== 1)) {
2352 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2353 sts
->ext_status_code
, sts
->action_code
, sts
->function_code
);
2357 // swap endian order if needed
2359 swapx(&tmh
->format_version
);
2360 swapx(&tmh
->sampling_period
);
2361 swapx(&tmh
->interval
);
2364 // Check format version
2365 if (tmh
->format_version
!= 2) {
2366 pout("Error unknown SCT Temperature History Format Version (%u), should be 2.\n", tmh
->format_version
);
2372 // Set SCT Temperature Logging Interval
2373 int ataSetSCTTempInterval(ata_device
* device
, unsigned interval
, bool persistent
)
2375 // Check initial status
2376 ata_sct_status_response sts
;
2377 if (ataReadSCTStatus(device
, &sts
))
2380 // Do nothing if other SCT command is executing
2381 if (sts
.ext_status_code
== 0xffff) {
2382 pout("Another SCT command is executing, abort Feature Control\n"
2383 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2384 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2388 ata_sct_feature_control_command cmd
; memset(&cmd
, 0, sizeof(cmd
));
2389 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2390 cmd
.action_code
= 4; // Feature Control command
2391 cmd
.function_code
= 1; // Set state
2392 cmd
.feature_code
= 3; // Temperature logging interval
2393 cmd
.state
= interval
;
2394 cmd
.option_flags
= (persistent
? 0x01 : 0x00);
2396 // write command via SMART log page 0xe0
2397 if (smartcommandhandler(device
, WRITE_LOG
, 0xe0, (char *)&cmd
)){
2398 syserror("Error Write SCT Feature Control Command failed");
2402 // re-read and check SCT status
2403 if (ataReadSCTStatus(device
, &sts
))
2406 if (!(sts
.ext_status_code
== 0 && sts
.action_code
== 4 && sts
.function_code
== 1)) {
2407 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2408 sts
.ext_status_code
, sts
.action_code
, sts
.function_code
);
2414 // Print one self-test log entry.
2415 // Returns true if self-test showed an error.
2416 bool ataPrintSmartSelfTestEntry(unsigned testnum
, unsigned char test_type
,
2417 unsigned char test_status
,
2418 unsigned short timestamp
,
2419 uint64_t failing_lba
,
2420 bool print_error_only
, bool & print_header
)
2422 const char * msgtest
;
2423 switch (test_type
) {
2424 case 0x00: msgtest
= "Offline"; break;
2425 case 0x01: msgtest
= "Short offline"; break;
2426 case 0x02: msgtest
= "Extended offline"; break;
2427 case 0x03: msgtest
= "Conveyance offline"; break;
2428 case 0x04: msgtest
= "Selective offline"; break;
2429 case 0x7f: msgtest
= "Abort offline test"; break;
2430 case 0x81: msgtest
= "Short captive"; break;
2431 case 0x82: msgtest
= "Extended captive"; break;
2432 case 0x83: msgtest
= "Conveyance captive"; break;
2433 case 0x84: msgtest
= "Selective captive"; break;
2435 if ((0x40 <= test_type
&& test_type
<= 0x7e) || 0x90 <= test_type
)
2436 msgtest
= "Vendor offline";
2438 msgtest
= "Reserved offline";
2441 bool is_error
= false;
2442 const char * msgstat
;
2443 switch (test_status
>> 4) {
2444 case 0x0: msgstat
= "Completed without error"; break;
2445 case 0x1: msgstat
= "Aborted by host"; break;
2446 case 0x2: msgstat
= "Interrupted (host reset)"; break;
2447 case 0x3: msgstat
= "Fatal or unknown error"; is_error
= true; break;
2448 case 0x4: msgstat
= "Completed: unknown failure"; is_error
= true; break;
2449 case 0x5: msgstat
= "Completed: electrical failure"; is_error
= true; break;
2450 case 0x6: msgstat
= "Completed: servo/seek failure"; is_error
= true; break;
2451 case 0x7: msgstat
= "Completed: read failure"; is_error
= true; break;
2452 case 0x8: msgstat
= "Completed: handling damage??"; is_error
= true; break;
2453 case 0xf: msgstat
= "Self-test routine in progress"; break;
2454 default: msgstat
= "Unknown/reserved test status";
2457 if (!is_error
&& print_error_only
)
2460 // Print header once
2462 print_header
= false;
2463 pout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2467 if (is_error
&& failing_lba
< 0xffffffffffffULL
)
2468 snprintf(msglba
, sizeof(msglba
), "%"PRIu64
, failing_lba
);
2470 strcpy(msglba
, "-");
2472 pout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum
, msgtest
, msgstat
,
2473 test_status
& 0x0f, timestamp
, msglba
);
2478 // Print Smart self-test log, used by smartctl and smartd.
2480 // bottom 8 bits: number of entries found where self-test showed an error
2481 // remaining bits: if nonzero, power on hours of last self-test where error was found
2482 int ataPrintSmartSelfTestlog(const ata_smart_selftestlog
* data
, bool allentries
,
2483 unsigned char fix_firmwarebug
)
2486 pout("SMART Self-test log structure revision number %d\n",(int)data
->revnumber
);
2487 if ((data
->revnumber
!=0x0001) && allentries
&& fix_firmwarebug
!= FIX_SAMSUNG
)
2488 pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2489 if (data
->mostrecenttest
==0){
2491 pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
2495 bool noheaderprinted
= true;
2496 int retval
=0, hours
=0, testno
=0;
2499 for (int i
= 20; i
>= 0; i
--) {
2500 // log is a circular buffer
2501 int j
= (i
+data
->mostrecenttest
)%21;
2502 const ata_smart_selftestlog_struct
* log
= data
->selftest_struct
+j
;
2504 if (nonempty(log
, sizeof(*log
))) {
2505 // count entry based on non-empty structures -- needed for
2506 // Seagate only -- other vendors don't have blank entries 'in
2510 // T13/1321D revision 1c: (Data structure Rev #1)
2512 //The failing LBA shall be the LBA of the uncorrectable sector
2513 //that caused the test to fail. If the device encountered more
2514 //than one uncorrectable sector during the test, this field
2515 //shall indicate the LBA of the first uncorrectable sector
2516 //encountered. If the test passed or the test failed for some
2517 //reason other than an uncorrectable sector, the value of this
2518 //field is undefined.
2520 // This is true in ALL ATA-5 specs
2521 uint64_t lba48
= (log
->lbafirstfailure
< 0xffffffff ? log
->lbafirstfailure
: 0xffffffffffffULL
);
2524 bool errorfound
= ataPrintSmartSelfTestEntry(testno
,
2525 log
->selftestnumber
, log
->selfteststatus
, log
->timestamp
,
2526 lba48
, !allentries
, noheaderprinted
);
2528 // keep track of time of most recent error
2529 if (errorfound
&& !hours
)
2530 hours
=log
->timestamp
;
2533 if (!allentries
&& retval
)
2537 return (retval
| hours
);
2541 /////////////////////////////////////////////////////////////////////////////
2542 // Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2543 // an ATA device with same behaviour
2547 class parsed_ata_device
2548 : public /*implements*/ ata_device_with_command_set
2551 parsed_ata_device(smart_interface
* intf
, const char * dev_name
);
2553 virtual ~parsed_ata_device() throw();
2555 virtual bool is_open() const;
2557 virtual bool open();
2559 virtual bool close();
2561 virtual bool ata_identify_is_cached() const;
2564 virtual int ata_command_interface(smart_command_set command
, int select
, char * data
);
2567 // Table of parsed commands, return value, data
2568 struct parsed_ata_command
2570 smart_command_set command
;
2576 enum { max_num_commands
= 32 };
2577 parsed_ata_command m_command_table
[max_num_commands
];
2580 int m_next_replay_command
;
2581 bool m_replay_out_of_sync
;
2582 bool m_ata_identify_is_cached
;
2585 static const char * nextline(const char * s
, int & lineno
)
2587 for (s
+= strcspn(s
, "\r\n"); *s
== '\r' || *s
== '\n'; s
++) {
2588 if (*s
== '\r' && s
[1] == '\n')
2595 static int name2command(const char * s
)
2597 for (int i
= 0; i
< (int)(sizeof(commandstrings
)/sizeof(commandstrings
[0])); i
++) {
2598 if (!strcmp(s
, commandstrings
[i
]))
2604 static bool matchcpy(char * dest
, size_t size
, const char * src
, const regmatch_t
& srcmatch
)
2606 if (srcmatch
.rm_so
< 0)
2608 size_t n
= srcmatch
.rm_eo
- srcmatch
.rm_so
;
2611 memcpy(dest
, src
+ srcmatch
.rm_so
, n
);
2616 static inline int matchtoi(const char * src
, const regmatch_t
& srcmatch
, int defval
)
2618 if (srcmatch
.rm_so
< 0)
2620 return atoi(src
+ srcmatch
.rm_so
);
2623 parsed_ata_device::parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2624 : smart_device(intf
, dev_name
, "ata", ""),
2626 m_next_replay_command(0),
2627 m_replay_out_of_sync(false),
2628 m_ata_identify_is_cached(false)
2630 memset(m_command_table
, 0, sizeof(m_command_table
));
2633 parsed_ata_device::~parsed_ata_device() throw()
2638 bool parsed_ata_device::is_open() const
2640 return (m_num_commands
> 0);
2643 // Parse stdin and build command table
2644 bool parsed_ata_device::open()
2646 const char * pathname
= get_dev_name();
2647 if (strcmp(pathname
, "-"))
2648 return set_err(EINVAL
);
2649 pathname
= "<stdin>";
2651 char buffer
[64*1024];
2653 while (size
< (int)sizeof(buffer
)) {
2654 int nr
= fread(buffer
, 1, sizeof(buffer
), stdin
);
2660 return set_err(ENOENT
, "%s: Unexpected EOF", pathname
);
2661 if (size
>= (int)sizeof(buffer
))
2662 return set_err(EIO
, "%s: Buffer overflow", pathname
);
2665 // Regex to match output from "-r ataioctl,2"
2666 static const char pattern
[] = "^"
2668 "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
2670 "( InputParameter=([0-9]+))?" // (4 (5))
2672 "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2674 "[\r\n]" // EOL match necessary to match optional parts above
2676 "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2678 " *(En|Dis)abled status cached by OS, " // (11)
2682 regular_expression regex
;
2683 if (!regex
.compile(pattern
, REG_EXTENDED
))
2684 return set_err(EIO
, "invalid regex");
2687 const char * errmsg
= 0;
2688 int i
= -1, state
= 0, lineno
= 1;
2689 for (const char * line
= buffer
; *line
; line
= nextline(line
, lineno
)) {
2691 if (!(line
[0] == 'R' || line
[0] == '=' || line
[0] == ' '))
2693 const int nmatch
= 1+11;
2694 regmatch_t match
[nmatch
];
2695 if (!regex
.execute(line
, nmatch
, match
))
2699 if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[2])) { // "REPORT-IOCTL:... Command=%s ..."
2700 int nc
= name2command(cmdname
);
2702 errmsg
= "Unknown ATA command name"; break;
2704 if (match
[7].rm_so
< 0) { // "returned %d"
2706 if (!(state
== 0 || state
== 2)) {
2707 errmsg
= "Missing REPORT-IOCTL result"; break;
2709 if (++i
>= max_num_commands
) {
2710 errmsg
= "Too many ATA commands"; break;
2712 m_command_table
[i
].command
= (smart_command_set
)nc
;
2713 m_command_table
[i
].select
= matchtoi(line
, match
[5], 0); // "InputParameter=%d"
2718 if (!(state
== 1 && (int)m_command_table
[i
].command
== nc
)) {
2719 errmsg
= "Missing REPORT-IOCTL start"; break;
2721 m_command_table
[i
].retval
= matchtoi(line
, match
[7], -1); // "returned %d"
2722 m_command_table
[i
].errval
= matchtoi(line
, match
[9], 0); // "errno=%d"
2726 else if (matchcpy(cmdname
, sizeof(cmdname
), line
, match
[10])) { // "===== [%s] DATA START "
2727 // Start of sector hexdump
2728 int nc
= name2command(cmdname
);
2729 if (!(state
== (nc
== WRITE_LOG
? 1 : 2) && (int)m_command_table
[i
].command
== nc
)) {
2730 errmsg
= "Unexpected DATA START"; break;
2732 line
= nextline(line
, lineno
);
2733 char * data
= (char *)malloc(512);
2735 for (j
= 0; j
< 32; j
++) {
2737 unsigned u1
, u2
; int n1
= -1;
2738 if (!(sscanf(line
, "%3u-%3u: "
2739 "%2x %2x %2x %2x %2x %2x %2x %2x "
2740 "%2x %2x %2x %2x %2x %2x %2x %2x%n",
2742 b
+ 0, b
+ 1, b
+ 2, b
+ 3, b
+ 4, b
+ 5, b
+ 6, b
+ 7,
2743 b
+ 8, b
+ 9, b
+10, b
+11, b
+12, b
+13, b
+14, b
+15, &n1
) == 18
2744 && n1
>= 56 && u1
== j
*16 && u2
== j
*16+15))
2746 for (unsigned k
= 0; k
< 16; k
++)
2747 data
[j
*16+k
] = b
[k
];
2748 line
= nextline(line
, lineno
);
2752 errmsg
= "Incomplete sector hex dump"; break;
2754 m_command_table
[i
].data
= data
;
2755 if (nc
!= WRITE_LOG
)
2758 else if (match
[11].rm_so
> 0) { // "(En|Dis)abled status cached by OS"
2759 m_ata_identify_is_cached
= true;
2763 if (!(state
== 0 || state
== 2))
2764 errmsg
= "Missing REPORT-IOCTL result";
2766 if (!errmsg
&& i
< 0)
2767 errmsg
= "No information found";
2769 m_num_commands
= i
+1;
2770 m_next_replay_command
= 0;
2771 m_replay_out_of_sync
= false;
2775 return set_err(EIO
, "%s(%d): Syntax error: %s", pathname
, lineno
, errmsg
);
2780 // Report warnings and free command table
2781 bool parsed_ata_device::close()
2783 if (m_replay_out_of_sync
)
2784 pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
2785 else if (m_next_replay_command
!= 0)
2786 pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands
-m_next_replay_command
);
2788 for (int i
= 0; i
< m_num_commands
; i
++) {
2789 if (m_command_table
[i
].data
) {
2790 free(m_command_table
[i
].data
); m_command_table
[i
].data
= 0;
2794 m_next_replay_command
= 0;
2795 m_replay_out_of_sync
= false;
2800 bool parsed_ata_device::ata_identify_is_cached() const
2802 return m_ata_identify_is_cached
;
2806 // Simulate ATA command from command table
2807 int parsed_ata_device::ata_command_interface(smart_command_set command
, int select
, char * data
)
2809 // Find command, try round-robin if out of sync
2810 int i
= m_next_replay_command
;
2811 for (int j
= 0; ; j
++) {
2812 if (j
>= m_num_commands
) {
2813 pout("REPLAY-IOCTL: Warning: Command not found\n");
2817 if (m_command_table
[i
].command
== command
&& m_command_table
[i
].select
== select
)
2819 if (!m_replay_out_of_sync
) {
2820 m_replay_out_of_sync
= true;
2821 pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i
+1);
2823 if (++i
>= m_num_commands
)
2826 m_next_replay_command
= i
;
2827 if (++m_next_replay_command
>= m_num_commands
)
2828 m_next_replay_command
= 0;
2830 // Return command data
2835 case READ_THRESHOLDS
:
2837 if (m_command_table
[i
].data
)
2838 memcpy(data
, m_command_table
[i
].data
, 512);
2841 if (!(m_command_table
[i
].data
&& !memcmp(data
, m_command_table
[i
].data
, 512)))
2842 pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
2844 case CHECK_POWER_MODE
:
2845 data
[0] = (char)0xff;
2850 if (m_command_table
[i
].errval
)
2851 errno
= m_command_table
[i
].errval
;
2852 return m_command_table
[i
].retval
;
2857 ata_device
* get_parsed_ata_device(smart_interface
* intf
, const char * dev_name
)
2859 return new parsed_ata_device(intf
, dev_name
);